Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-06-25 16:06:15 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-06-25 16:06:15 +0400
commit15b1ed6dc78615f26859146aa764a412b87cee8c (patch)
tree9e4fcc76b73ce964ce5652465328eba6920553f3 /libgloss/aarch64
parentc024ce1422a60f9600b922f081be3ada47a489ae (diff)
* aarch64/crt0.S (GEN_DWORD): New macro definition.
(PTR_REG): Ditto. (PTR_SIZE): Ditto. (PTR_LOG_SIZE): Ditto. (start): Use GEN_DWORD to replace the .dword of HeapBase, __bss_start__, __bss_end__, FUNCTION(_fini), env and CommandLine; when __ILP32__ is defined, set the stack base to the top end of the 32-bit address space if the returned value from the Angel API call is larger than or equal to 4 GiB. Also carry out sanity check on the heap base; abort if the base is larger than or equal to 4 GiB. Use other new macros in the instructions that processes the argv arrays. (StackBase): New lable; replace __stack_base__. (__stack_base__): Set with StackBase or StackBase + 4.
Diffstat (limited to 'libgloss/aarch64')
-rw-r--r--libgloss/aarch64/crt0.S92
1 files changed, 75 insertions, 17 deletions
diff --git a/libgloss/aarch64/crt0.S b/libgloss/aarch64/crt0.S
index 601bb2bb1..1a5cabbb3 100644
--- a/libgloss/aarch64/crt0.S
+++ b/libgloss/aarch64/crt0.S
@@ -41,6 +41,36 @@
#define _fini __libc_fini_array
#endif
+/* In ELF64, the large addressing model is used and R_AARCH64_ABS64
+ reloc is generated to relocate a 64-bit address. Since 64-bit
+ relocation is not available in ELF32, in order to have
+ a single code path for both ELF64 and ELF32 classes, we synthesize
+ a 64-bit relocation by using R_AARCH64_P32_ABS32 on one of the two
+ .word directives, depending on the endianness. */
+
+.macro GEN_DWORD name
+#if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ .word \name
+ .word 0
+#elif defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ .word 0
+ .word \name
+#else
+ .dword \name
+#endif
+.endm
+
+/* Help tackle the pointer size difference between ELF64 and ELF32. */
+#ifdef __ILP32__
+#define PTR_REG(n) w##n
+#define PTR_SIZE 4
+#define PTR_LOG_SIZE 2
+#else
+#define PTR_REG(n) x##n
+#define PTR_SIZE 8
+#define PTR_LOG_SIZE 3
+#endif
+
.text
.macro FUNC_START name
.global \name
@@ -71,10 +101,33 @@
command line options to the AEM in order to define the values
exposed here in the HeapInfo Angel call. */
ldr x0, .LC0 /* point at returned values */
- ldr x0, [x0, #8] /* get heap_limit */
+ ldr x1, [x0, #8] /* get heap_limit */
+#ifdef __ILP32__
+ /* Sanity check on the heap base. */
+ ldr x0, [x0] /* get heap_base */
+ tst x0, #0xffffffff00000000
+ beq 1f
+ /* Exit with 1 if the heap base is not within the 32-bit address
+ space. */
+ mov x0, ADP_Stopped_ApplicationExit & 0xff
+ movk x0, ADP_Stopped_ApplicationExit >> 16, lsl #16
+ adrp x1, HeapBase /* Reuse to construct the parameter block. */
+ add x1, x1, #:lo12:HeapBase
+ str x0, [x1]
+ mov x0, 1
+ str x0, [x1, #8]
+ mov w0, #AngelSVC_Reason_ReportException
+ AngelSVCAsm AngelSVC
+1:
+ /* For the sake of safety, set the stack base to the top end of
+ the 32-bit address space if the returned value from the
+ Angel API call is larger than or equal to 4 GiB. */
+ tst x1, #0xffffffff00000000
+ csinv w1, w1, wzr, eq
+#endif
/* Ensure quad-word stack alignment. */
- and x0, x0, #~15
+ and x0, x1, #~15
mov sp, x0
/* Setup an initial dummy frame with saved fp=0 and saved lr=0 */
@@ -114,7 +167,7 @@
ldr x2, .Lenvp /* envp */
/* Put NULL at end of argv array. */
- str x0, [x1, #-8]!
+ str PTR_REG (0), [x1, #-PTR_SIZE]!
/* Skip leading blanks. */
.Lnext: ldrb w3, [x8], #1
@@ -133,7 +186,7 @@
cinc x8, x8, eq
/* Push arg pointer to argv, and bump argc. */
- str x8, [x1, #-8]!
+ str PTR_REG (8), [x1, #-PTR_SIZE]!
add x0, x0, #1
/* Find end of arg string. */
@@ -149,14 +202,14 @@
/* Reverse argv array. */
.Lendstr:
- add x3, x1, #0 /* sp = &argv[0] */
- add x4, x1, w0, uxtw #3 /* ep = &argv[argc] */
+ add x3, x1, #0 /* sp = &argv[0] */
+ add x4, x1, w0, uxtw #PTR_LOG_SIZE /* ep = &argv[argc] */
cmp x4, x3
b.lo 2f
-1: ldr x5, [x4, #-8] /* x5 = ep[-1] */
- ldr x6, [x3] /* x6 = *sp */
- str x6, [x4, #-8]! /* *--ep = x6 */
- str x5, [x3], #8 /* *sp++ = x5 */
+1: ldr PTR_REG (5), [x4, #-PTR_SIZE] /* PTR_REG (5) = ep[-1] */
+ ldr PTR_REG (6), [x3] /* PTR_REG (6) = *sp */
+ str PTR_REG (6), [x4, #-PTR_SIZE]! /* *--ep = PTR_REG (6) */
+ str PTR_REG (5), [x3], #PTR_SIZE /* *sp++ = PTR_REG (5) */
cmp x4, x3
b.hi 1b
2:
@@ -177,27 +230,32 @@ FUNCTION (_cpu_init_hook):
.align 3
.LC0:
- .dword HeapBase
+ GEN_DWORD HeapBase
.LC1:
- .dword __bss_start__
+ GEN_DWORD __bss_start__
.LC2:
- .dword __bss_end__
+ GEN_DWORD __bss_end__
.Lfini:
- .dword FUNCTION(_fini)
+ GEN_DWORD FUNCTION(_fini)
.Lenvp:
- .dword env
+ GEN_DWORD env
.Lcmdline:
- .dword CommandLine
+ GEN_DWORD CommandLine
.dword 255
/* Workspace for Angel calls. */
.data
.align 3
/* Data returned by monitor SVC. */
+#if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ .set __stack_base__, StackBase + 4
+#else
+ .set __stack_base__, StackBase
+#endif
.global __stack_base__
HeapBase: .dword 0
HeapLimit: .dword 0
-__stack_base__: .dword 0
+StackBase: .dword 0
StackLimit: .dword 0
env: .dword 0 /* Dummy environment array */
CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */