1 /* 2 * ctors.c 3 * Copyright 2019 Peter Jones <pjones@redhat.com> 4 * 5 */ 6 7 #include <efi.h> 8 #include <efilib.h> 9 10 /* 11 * Note that these aren't the using the GNU "CONSTRUCTOR" output section 12 * command, so they don't start with a size. Because of p2align and the 13 * end/END definitions, and the fact that they're mergeable, they can also 14 * have NULLs which aren't guaranteed to be at the end. 15 */ 16 extern UINTN __init_array_start, __init_array_end; 17 extern UINTN __CTOR_LIST__, __CTOR_END__; 18 extern UINTN __fini_array_start, __fini_array_end; 19 extern UINTN __DTOR_LIST__, __DTOR_END__; 20 21 typedef void (*funcp)(void); 22 23 static void ctors(void) 24 { 25 for (funcp *location = (void *)&__init_array_start; location < (funcp *)&__init_array_end; location++) { 26 funcp func = *location; 27 if (*location != NULL) 28 func(); 29 } 30 31 for (funcp *location = (void *)&__CTOR_END__; location > (funcp *)&__CTOR_LIST__; location--) { 32 funcp func = *location; 33 if (*location != NULL) 34 func(); 35 } 36 } 37 38 static void dtors(void) 39 { 40 for (funcp *location = (void *)&__DTOR_LIST__; location < (funcp *)&__DTOR_END__; location++) { 41 funcp func = *location; 42 if (*location != NULL) 43 func(); 44 } 45 46 for (funcp *location = (void *)&__fini_array_end; location > (funcp *)&__fini_array_start; location--) { 47 funcp func = *location; 48 if (*location != NULL) 49 func(); 50 } 51 } 52 53 extern EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab); 54 55 EFI_STATUS _entry(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 56 { 57 EFI_STATUS status; 58 InitializeLib(image, systab); 59 60 ctors(); 61 status = efi_main(image, systab); 62 dtors(); 63 64 return status; 65 } 66 67 // vim:fenc=utf-8:tw=75:noet 68