This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, AArch64] Update crt0.S to be ILP32-friendly


Hi,

This patch makes a number of changes to the crt0.S file in order to support the ILP32 ABI.

Because the Angel APIs are kept the same between LP64 and ILP32, some changes are needed to make sure the heap info can be obtained properly from the HeapInfo Angel call.

The patch also fixes the argv handling where the pointers pushed to the stack shall be 4-byte size when __ILP32__ is defined.

The gcc patches for ILP32 (including the one that defines __ILP32__) will be sent shortly, but this patch can be committed independently.

OK for the trunk?

Thanks,
Yufeng


libgloss/

	* 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.
diff --git a/libgloss/aarch64/crt0.S b/libgloss/aarch64/crt0.S
index 601bb2b..1a5cabb 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.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]