@@ -48,14 +48,6 @@ if efi_cc.length() == 0
4848 efi_cc = cc.cmd_array()
4949endif
5050
51- efi_ld = find_program (get_option (' efi-ld' ))
52- efi_ld_name = efi_ld.path().split(' /' )[- 1 ]
53- if efi_ld_name == ' lld' or efi_ld_name == ' ld.lld'
54- # LLVM/LLD does not support PE/COFF relocations
55- # https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
56- error (' LLVM/lld does not support PE/COFF relocations. Use different linker for EFI image.' )
57- endif
58-
5951efi_libdir = ''
6052foreach dir : [get_option (' efi-libdir' ),
6153 ' /usr/lib/gnuefi' / efi_arch[0 ],
@@ -260,26 +252,52 @@ foreach arg : get_option('c_args')
260252 endif
261253endforeach
262254
263- efi_ldflags = [' -T' , efi_lds,
264- ' -shared' ,
265- ' -Bsymbolic' ,
266- ' -nostdlib' ,
267- ' --no-undefined' ,
268- ' --warn-common' ,
269- ' --fatal-warnings' ,
270- ' -znocombreloc' ,
271- ' --build-id=sha1' ,
272- ' -L' , efi_libdir,
273- efi_crt0]
255+ efi_ldflags = [
256+ ' -fuse-ld=' + get_option (' efi-ld' ),
257+ ' -L' , efi_libdir,
258+ ' -nostdlib' ,
259+ ' -shared' ,
260+ ' -T' , efi_lds,
261+ ' -Wl,--build-id=sha1' ,
262+ ' -Wl,--fatal-warnings' ,
263+ ' -Wl,--no-undefined' ,
264+ ' -Wl,--warn-common' ,
265+ ' -Wl,-Bsymbolic' ,
266+ ' -z' , ' nocombreloc' ,
267+ efi_crt0,
268+ ]
274269if efi_arch[1 ] in [' aarch64' , ' arm' , ' riscv64' ]
275270 # Aarch64, ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
276271 # Use 'binary' instead, and add required symbols manually.
277- efi_ldflags += [' --defsym=EFI_SUBSYSTEM=0xa' ]
272+ efi_ldflags += [' -Wl,- -defsym=EFI_SUBSYSTEM=0xa' ]
278273 efi_format = [' -O' , ' binary' ]
279274else
280275 efi_format = [' --target=efi-app-@0@' .format(efi_arch[1 ])]
281276endif
282277
278+ if run_command (' grep' , ' -q' , ' __CTOR_LIST__' , efi_lds).returncode() == 0
279+ # fedora has a patched gnu-efi that adds support for ELF constructors.
280+ # If ld is called by gcc something about these symbols breaks, resulting
281+ # in sd-boot freezing when gnu-efi runs the constructors. Force defining
282+ # them seems to work around this.
283+ efi_ldflags += [
284+ ' -Wl,--defsym=_init_array=0' ,
285+ ' -Wl,--defsym=_init_array_end=0' ,
286+ ' -Wl,--defsym=_fini_array=0' ,
287+ ' -Wl,--defsym=_fini_array_end=0' ,
288+ ' -Wl,--defsym=__CTOR_LIST__=0' ,
289+ ' -Wl,--defsym=__CTOR_END__=0' ,
290+ ' -Wl,--defsym=__DTOR_LIST__=0' ,
291+ ' -Wl,--defsym=__DTOR_END__=0' ,
292+ ]
293+ endif
294+
295+ efi_cc_version = run_command (efi_cc, ' --version' ).stdout().split(' \n ' )[0 ]
296+ if efi_cc_version.contains(' clang' ) and efi_cc_version.split(' .' )[0 ].split(' ' )[- 1 ].to_int() <= 10
297+ # clang <= 10 doesn't pass -T to the linker and then even complains about it being unused
298+ efi_ldflags += [' -Wl,-T,' + efi_lds, ' -Wno-unused-command-line-argument' ]
299+ endif
300+
283301systemd_boot_objects = []
284302stub_objects = []
285303foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
@@ -308,7 +326,7 @@ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects
308326 tuple[0 ],
309327 input : tuple[2 ],
310328 output : tuple[0 ],
311- command : [efi_ld , ' -o' , ' @OUTPUT@' , efi_ldflags, tuple[2 ], ' -lefi' , ' -lgnuefi' , libgcc_file_name],
329+ command : [efi_cc , ' -o' , ' @OUTPUT@' , efi_ldflags, tuple[2 ], ' -lefi' , ' -lgnuefi' , libgcc_file_name],
312330 install : tuple[3 ],
313331 install_dir : bootlibdir)
314332
0 commit comments