summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2009-06-16 16:37:15 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2009-06-16 16:37:15 +0000
commita3f40e2b55539a27c6990efc4ebff8036b9a4938 (patch)
treec4eb37fc3c701dd46cc8f1fc9cad913bb46daa58
parent91b80125303d8d8b8dcdfd29969a3b360546c468 (diff)
Do not break gcc -Z on powerpc. mprotect the got only if it is padded.
Diff written and tweaked by kurt@ and myself. ok kurt@, now is agood time deraadt@
-rw-r--r--lib/csu/powerpc/crt0.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/lib/csu/powerpc/crt0.c b/lib/csu/powerpc/crt0.c
index 2d2f9104114..e3e1c11eb2a 100644
--- a/lib/csu/powerpc/crt0.c
+++ b/lib/csu/powerpc/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.4 2009/01/14 19:45:20 kurt Exp $ */
+/* $OpenBSD: crt0.c,v 1.5 2009/06/16 16:37:14 drahn Exp $ */
/* $NetBSD: crt0.c,v 1.1 1996/09/12 16:59:02 cgd Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou
@@ -52,10 +52,16 @@ __asm(
" .text \n"
" .section \".text\" \n"
" .align 2 \n"
-" .globl _start \n"
-" .type _start, @function \n"
-" .globl __start \n"
-" .type __start, @function \n"
+" .size __got_start, 0 \n"
+" .type __got_start, @object \n"
+" .size __got_end, 0 \n"
+" .type __got_end, @object \n"
+" .weak __got_start \n"
+" .weak __got_end \n"
+" .globl _start \n"
+" .type _start, @function \n"
+" .globl __start \n"
+" .type __start, @function \n"
"_start: \n"
"__start: \n"
" # move argument registers to saved registers for startup flush \n"
@@ -70,8 +76,8 @@ __asm(
" # to find the virtual address where the page is loaded. \n"
" bl _GLOBAL_OFFSET_TABLE_@local-4 \n"
"1: \n"
-" mflr %r5 # this stores where we are (+4) \n"
-" lwz %r18, 0(%r5) # load the instruction at offset_sym \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"
@@ -82,25 +88,38 @@ __asm(
" * bl _GLOBAL_OFFSET_TABLE_@local-4 \n"
" * operation that would be below would calulate. \n"
" */ \n"
-" add %r28, %r18, %r5 \n"
-" mr %r6, %r5 # save offset for later use \n"
+" add %r28, %r18, %r6 \n"
" \n"
-" /* mprotect GOT-4 for correct execution of blrl instruction */ \n"
+" addi %r3,%r28,4 # calculate the actual got addr \n"
+" lwz %r0,__got_start@got(%r3) \n"
+" cmpwi %r0,0 \n"
+" beq 4f \n"
+" cmpw %r0,%r28 \n"
+" bne 4f \n"
+" lwz %r4,__got_end@got(%r3) \n"
+" cmpwi %r4,0 \n"
+" beq 2f \n"
+" \n"
+" sub %r4, %r4, %r0 \n"
+" b 3f \n"
+"2: \n"
+" li %r4, 4 \n"
+"3: \n"
+" \n"
+" /* mprotect GOT to eliminate W+X regions in static binaries */ \n"
" li %r0, " STR(SYS_mprotect) " \n"
" mr %r3, %r28 \n"
-" li %r4, 4 \n"
" li %r5, 5 /* (PROT_READ|PROT_EXEC) */ \n"
" sc \n"
" \n"
-" mr %r5, %r6 \n"
-" \n"
+"4: \n"
" li %r0, 0 \n"
" # flush the blrl instruction out of the data cache \n"
-" dcbf %r5, %r18 \n"
+" dcbf %r6, %r18 \n"
" sync \n"
" isync \n"
" # make certain that the got table addr is not in the icache \n"
-" icbi %r5, %r18 \n"
+" icbi %r6, %r18 \n"
" sync \n"
" isync \n"
" mtlr %r27 \n"