Self-relocation code for powerpc.
authorkurt <kurt@openbsd.org>
Fri, 26 Dec 2014 13:52:01 +0000 (13:52 +0000)
committerkurt <kurt@openbsd.org>
Fri, 26 Dec 2014 13:52:01 +0000 (13:52 +0000)
lib/csu/powerpc/md_init.h

index 3fab44b..8625ce5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: md_init.h,v 1.2 2013/12/03 06:21:41 guenther Exp $ */
+/* $OpenBSD: md_init.h,v 1.3 2014/12/26 13:52:01 kurt Exp $ */
 
 /*-
  * Copyright (c) 2001 Ross Harvey
@@ -148,3 +148,101 @@ __asm(                                                                    \
 "      mr %r6, %r22                                                    \n" \
 "      b ___start                                                      \n" \
 )
+
+#define        MD_RCRT0_START                                                  \
+__asm(                                                                 \
+"      .text                                                           \n" \
+"      .section        \".text\"                                       \n" \
+"      .align 2                                                        \n" \
+"      .globl  _start                                                  \n" \
+"      .type   _start, @function                                       \n" \
+"      .globl  __start                                                 \n" \
+"      .type   __start, @function                                      \n" \
+"_start:                                                               \n" \
+"__start:                                                              \n" \
+"      mr      %r19, %r1               # save stack in r19             \n" \
+"      stwu    1, (-16 -((9+3)*4))(%r1) # allocate dl_data             \n" \
+"                                                                      \n" \
+"      # move argument registers to saved registers for startup flush  \n" \
+"      mr %r20, %r3                    # argc                          \n" \
+"      mr %r21, %r4                    # argv                          \n" \
+"      mr %r22, %r5                    # envp                          \n" \
+"      mflr    %r27    /* save off old link register */                \n" \
+"      stw     %r27, 4(%r19)           # save in normal location       \n" \
+"      bl      1f                                                      \n" \
+"      # this instruction never gets executed but can be used          \n" \
+"      # to find the virtual address where the page is loaded.         \n" \
+"      bl _GLOBAL_OFFSET_TABLE_@local-4                                \n" \
+"      bl _DYNAMIC@local                                               \n" \
+"1:                                                                    \n" \
+"      mflr    %r6             # this stores where we are (+4)         \n" \
+"      lwz     %r18, 0(%r6)    # load the instruction at offset_sym    \n" \
+"                              # it contains an offset to the location \n" \
+"                              # of the GOT.                           \n" \
+"                                                                      \n" \
+"      rlwinm %r18,%r18,0,8,30 # mask off offset portion of the instr. \n" \
+"                                                                      \n" \
+"      /*                                                              \n" \
+"       * these adds effectively calculate the value the               \n" \
+"       * bl _GLOBAL_OFFSET_TABLE_@local-4                             \n" \
+"       * operation that would be below would calculate.               \n" \
+"       */                                                             \n" \
+"      add     %r28, %r18, %r6                                         \n" \
+"                                                                      \n" \
+"      /* mprotect GOT-4 for correct execution of blrl instruction */  \n" \
+"      li      %r0, " STR(SYS_mprotect) "                              \n" \
+"      mr      %r3, %r28                                               \n" \
+"      li      %r4, 4                                                  \n" \
+"      li      %r5, 7  /* (PROT_READ|PROT_WRITE|PROT_EXEC) */          \n" \
+"      sc                                                              \n" \
+"                                                                      \n" \
+"      li      %r0, 0                                                  \n" \
+"      # flush the blrl instruction out of the data cache              \n" \
+"      dcbf    %r6, %r18                                               \n" \
+"      sync                                                            \n" \
+"      isync                                                           \n" \
+"      # make certain that the got table addr is not in the icache     \n" \
+"      icbi    %r6, %r18                                               \n" \
+"      sync                                                            \n" \
+"      isync                                                           \n" \
+"                                                                      \n" \
+"      /* This calculates the address of _DYNAMIC the same way         \n" \
+"       * that the GLOBAL_OFFSET_TABLE was calculated.                 \n" \
+"       */                                                             \n" \
+"      lwz     %r18, 4(%r6)                                            \n" \
+"      rlwinm  %r18,%r18,0,8,30 # mask off offset portion of the instr. \n" \
+"      add     %r8, %r18, %r6  # address of _DYNAMIC (arg6 for _dl_boot) \n" \
+"      addi    %r18, %r8, 4    # correction.                           \n" \
+"      lwz     %r4, 4(%r28)    # load addr of _DYNAMIC according to got. \n" \
+"      sub     %r4, %r18, %r4  # determine load offset                 \n" \
+"                                                                      \n" \
+"      subi    %r3, %r21, 4    # Get stack pointer (arg0 for _dl_boot). \n" \
+"      addi    %r4, %r1, 8     # dl_data                               \n" \
+"      mr      %r5, %r18       # dynamicp                              \n" \
+"                                                                      \n" \
+"      bl      _dl_boot_bind@local                                     \n" \
+"                                                                      \n" \
+"      mtlr %r27                                                       \n" \
+"      # move argument registers back from saved registers             \n" \
+"      mr %r3, %r20                                                    \n" \
+"      mr %r4, %r21                                                    \n" \
+"      mr %r5, %r22                                                    \n" \
+"      li %r6, 0                                                       \n" \
+"      b ___start                                                      \n" \
+"                                                                      \n" \
+"      .text                                                           \n" \
+"      .align 2                                                        \n" \
+"      .globl  _dl_exit                                                \n" \
+"      .type   _dl_exit, @function                                     \n" \
+"_dl_exit:                                                             \n" \
+"      li      %r0, " STR(SYS_exit) "                                  \n" \
+"      sc                                                              \n" \
+"      blr                                                             \n" \
+"                                                                      \n" \
+"      .text                                                           \n" \
+"      .align 2                                                        \n" \
+"      .globl  _dl_printf                                              \n" \
+"      .type   _dl_printf, @function                                   \n" \
+"_dl_printf:                                                           \n" \
+"      blr                                                             \n" \
+)