diff options
author | Callum Farmer <gmbr3@opensuse.org> | 2023-05-06 10:42:27 +0100 |
---|---|---|
committer | Callum Farmer <gmbr3@opensuse.org> | 2023-05-07 16:43:20 +0100 |
commit | 7dac18443fdce2cb99ca5f423104c2c22d415a38 (patch) | |
tree | bf93e18112abc2aaed71511b3d34ac5989bc902a | |
parent | 4c6962457f4ce3f4c18774ce6accd8d20ee29f22 (diff) | |
download | gnu-efi-7dac18443fdce2cb99ca5f423104c2c22d415a38.tar.gz |
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>
-rw-r--r-- | lib/ctors.S | 5 | ||||
-rw-r--r-- | lib/entry.c | 42 |
2 files changed, 25 insertions, 22 deletions
diff --git a/lib/ctors.S b/lib/ctors.S index cdd4629..de3f231 100644 --- a/lib/ctors.S +++ b/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 diff --git a/lib/entry.c b/lib/entry.c index 0ff63fe..3baa91d 100644 --- a/lib/entry.c +++ b/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(); } } |