diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2014-12-26 13:52:02 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2014-12-26 13:52:02 +0000 |
commit | 5702505e2e0db38792c1d194969f502336e85296 (patch) | |
tree | 702872d91ca6af6d59aac966a2199ea479891e7e | |
parent | b1c5433101e97703831a018cdbf79fefebb56ad6 (diff) |
Self-relocation code for powerpc.
-rw-r--r-- | lib/csu/powerpc/md_init.h | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/lib/csu/powerpc/md_init.h b/lib/csu/powerpc/md_init.h index 3fab44b9a98..8625ce57cf1 100644 --- a/lib/csu/powerpc/md_init.h +++ b/lib/csu/powerpc/md_init.h @@ -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" \ +) |