فهرست منبع

Re-write entry.c/ctors.S to work better

* Make entry.c work correctly in reverse order
* Remove incorrectly sized (on non-32bit) NULLs from ctors.S

Signed-off-by: Callum Farmer <gmbr3@opensuse.org>
Callum Farmer 1 سال پیش
والد
کامیت
7dac18443f
2فایلهای تغییر یافته به همراه25 افزوده شده و 22 حذف شده
  1. 1 4
      lib/ctors.S
  2. 24 18
      lib/entry.c

+ 1 - 4
lib/ctors.S

@@ -15,7 +15,6 @@ __init_array_start:
 	.p2align 3, 0
 	.globl __init_array_end
 __init_array_end:
-	.long 0
 	.section .ctors, "aw", @progbits
 	.p2align 3, 0
 	.globl __CTOR_LIST__
@@ -23,7 +22,6 @@ __CTOR_LIST__:
 	.p2align 3, 0
 	.globl __CTOR_END__
 __CTOR_END__:
-	.long 0
 	.section .dtors, "aw", @progbits
 	.p2align 3, 0
 	.globl __DTOR_LIST__
@@ -31,7 +29,6 @@ __DTOR_LIST__:
 	.p2align 3, 0
 	.globl __DTOR_END__
 __DTOR_END__:
-	.long 0
 	.section .fini_array, "aw", @fini_array
 	.p2align 3, 0
 	.globl __fini_array_start
@@ -39,7 +36,7 @@ __fini_array_start:
 	.p2align 3, 0
 	.globl __fini_array_end
 __fini_array_end:
-	.long 0
+	.p2align 3, 0
 
 #if defined(__ELF__) && defined(__linux__)
 	.section .note.GNU-stack,"",%progbits

+ 24 - 18
lib/entry.c

@@ -7,45 +7,51 @@
 #include <efi.h>
 #include <efilib.h>
 
+typedef void (*funcp)(void);
+
 /*
  * Note that these aren't the using the GNU "CONSTRUCTOR" output section
  * command, so they don't start with a size.  Because of p2align and the
  * end/END definitions, and the fact that they're mergeable, they can also
  * have NULLs which aren't guaranteed to be at the end.
  */
-extern UINTN __init_array_start, __init_array_end;
-extern UINTN __CTOR_LIST__, __CTOR_END__;
-extern UINTN __fini_array_start, __fini_array_end;
-extern UINTN __DTOR_LIST__, __DTOR_END__;
-
-typedef void (*funcp)(void);
+extern funcp __init_array_start[], __init_array_end[];
+extern funcp __CTOR_LIST__[], __CTOR_END__[];
+extern funcp __fini_array_start[], __fini_array_end[];
+extern funcp __DTOR_LIST__[], __DTOR_END__[];
 
 static void ctors(void)
 {
-	for (funcp *location = (void *)&__init_array_start; location < (funcp *)&__init_array_end; location++) {
-		funcp func = *location;
-		if (*location != NULL)
+	size_t __init_array_length = __init_array_end - __init_array_start;
+	for (size_t i = 0; i < __init_array_length; i++) {
+		funcp func = __init_array_start[i];
+		if (func != NULL)
 			func();
 	}
 
-	for (funcp *location = (void *)&__CTOR_END__; location > (funcp *)&__CTOR_LIST__; location--) {
-		funcp func = *location;
-		if (*location != NULL)
+	size_t __CTOR_length = __CTOR_END__ - __CTOR_LIST__;
+	for (size_t i = 0; i < __CTOR_length; i++) {
+		size_t current = __CTOR_length - i - 1;
+		funcp func = __CTOR_LIST__[current];
+		if (func != NULL)
 			func();
 	}
 }
 
 static void dtors(void)
 {
-	for (funcp *location = (void *)&__DTOR_LIST__; location < (funcp *)&__DTOR_END__; location++) {
-		funcp func = *location;
-		if (*location != NULL)
+	size_t __DTOR_length = __DTOR_END__ - __DTOR_LIST__;
+	for (size_t i = 0; i < __DTOR_length; i++) {
+		funcp func = __DTOR_LIST__[i];
+		if (func != NULL)
 			func();
 	}
 
-	for (funcp *location = (void *)&__fini_array_end; location > (funcp *)&__fini_array_start; location--) {
-		funcp func = *location;
-		if (*location != NULL)
+	size_t __fini_array_length = __fini_array_end - __fini_array_start;
+	for (size_t i = 0; i < __fini_array_length; i++) {
+		size_t current = __fini_array_length - i - 1;
+		funcp func = __fini_array_start[current];
+		if (func != NULL)
 			func();
 	}
 }