1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Wed, 19 Sep 2007 10:03:35 +0200
Subject: [Avr-gnu-toolchain] [uClibc PATCH] Load GOT pointer at the
beginning of .init and .fini
I don't know why this seems to have worked before, but the .init and
.fini sections typically consist of a bunch of mcalls using r6 as the
base pointer. This can cause "interesting" behaviour when r6 hasn't
been initialized to point to the GOT.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
libc/sysdeps/linux/avr32/crti.S | 15 ++++++++++++---
libc/sysdeps/linux/avr32/crtn.S | 4 ++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/libc/sysdeps/linux/avr32/crti.S b/libc/sysdeps/linux/avr32/crti.S
index 3e132d0..660f47c 100644
--- a/libc/sysdeps/linux/avr32/crti.S
+++ b/libc/sysdeps/linux/avr32/crti.S
@@ -4,14 +4,23 @@
.global _init
.type _init, @function
_init:
- /* Use a four-byte instruction to avoid NOPs */
- stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
.align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
.section .fini
.align 2
.global _fini
.type _fini, @function
_fini:
- stm --sp, r0-r7,lr
+ stm --sp, r6, lr
+ lddpc r6, 2f
+1: rsub r6, pc
+ rjmp 3f
.align 2
+2: .long 1b - _GLOBAL_OFFSET_TABLE_
+3:
diff --git a/libc/sysdeps/linux/avr32/crtn.S b/libc/sysdeps/linux/avr32/crtn.S
index 577adcc..f7d1040 100644
--- a/libc/sysdeps/linux/avr32/crtn.S
+++ b/libc/sysdeps/linux/avr32/crtn.S
@@ -3,12 +3,12 @@
.align 2
.global _init
.type _init, @function
- ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
.size _init, . - _init
.section .fini
.align 2
.global _fini
.type _fini, @function
- ldm sp++, r0-r7,pc
+ ldm sp++, r6, pc
.size _fini, . - _fini
--
1.5.3.1
|