From 32ca4c44b522bce9de893471a29f86e763ba9833 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 31 Dec 2021 16:44:09 -0700 Subject: [PATCH] Fix Clang/LLD woes! Several changes to get Clang and LLD working again: - LLD will always place non-allocated sections at LMA(0x0). Flagged the .zip section as 'a' to fix this. - LLD interprets DEFINED(x) in a subtly-different way, where any symbol declaration counts as defining. Changed several default-value definitions that used DEFINED to instead use PROVIDE_HIDDEN. - Due to the same LLD/DEFINED behavior, EfiMain was always getting linked in. Updated to use a separate flagging variable (USE_EFI). - Clang needed a few new flags to match GCC frame/stack behavior. --- ape/ape.lds | 6 ++--- libc/nexgen32e/zip.S | 4 ++-- libc/runtime/efimain.greg.c | 2 +- test/libc/release/clang.sh | 45 ++++++++++++++++++++----------------- test/libc/release/lld.sh | 45 ++++++++++++++++++++----------------- 5 files changed, 54 insertions(+), 48 deletions(-) diff --git a/ape/ape.lds b/ape/ape.lds index ac41b1bc5..18c3a1d84 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -498,10 +498,10 @@ HIDDEN(ape_ram_align = PAGESIZE); HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr)); HIDDEN(ape_stack_offset = ape_ram_offset + ape_ram_filesz); -HIDDEN(ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000 - STACKSIZE); +PROVIDE_HIDDEN(ape_stack_vaddr = 0x700000000000 - STACKSIZE); HIDDEN(ape_stack_paddr = ape_ram_paddr + ape_ram_filesz); HIDDEN(ape_stack_filesz = 0); -HIDDEN(ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : STACKSIZE); +PROVIDE_HIDDEN(ape_stack_memsz = STACKSIZE); HIDDEN(ape_stack_align = 16); HIDDEN(ape_note_offset = ape_rom_offset + (ape_note - ape_rom_vaddr)); @@ -543,7 +543,7 @@ SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8); #endif #if SupportsWindows() || SupportsMetal() -#define LINK_WINDOWS (SupportsWindows() && !DEFINED(EfiMain)) +#define LINK_WINDOWS (SupportsWindows() && !DEFINED(USE_EFI)) PFSTUB4(ape_pe_offset, ape_pe - ape_mz); HIDDEN(ape_pe_optsz = ape_pe_sections - (ape_pe + 24)); HIDDEN(ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40); diff --git a/libc/nexgen32e/zip.S b/libc/nexgen32e/zip.S index ba51602f0..de27d2048 100644 --- a/libc/nexgen32e/zip.S +++ b/libc/nexgen32e/zip.S @@ -21,7 +21,7 @@ #include "libc/zip.h" // ZIP Central Directory. - .section .zip.3,"",@progbits + .section .zip.3,"a",@progbits .hidden __zip_start .globl __zip_start .type __zip_start,@object @@ -30,7 +30,7 @@ __zip_start: ... decentralized content ... - */.section .zip.5,"",@progbits + */.section .zip.5,"a",@progbits __zip_end: .long kZipCdirHdrMagic # magic .short 0 # disk diff --git a/libc/runtime/efimain.greg.c b/libc/runtime/efimain.greg.c index e6ac87bc3..8ae074c8f 100644 --- a/libc/runtime/efimain.greg.c +++ b/libc/runtime/efimain.greg.c @@ -45,7 +45,7 @@ static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL; * So if you want to trade away Windows so that you can use * UEFI instead of the normal BIOS boot process, do this: * - * STATIC_YOINK("EfiMain"); + * STATIC_YOINK("USE_EFI"); * int main() { ... } * * You can use QEMU to test this, but please note that UEFI diff --git a/test/libc/release/clang.sh b/test/libc/release/clang.sh index dee70c864..43ba00a08 100755 --- a/test/libc/release/clang.sh +++ b/test/libc/release/clang.sh @@ -4,24 +4,27 @@ # TODO: someone who uses clang please mantain this -# if CLANG=$(command -v clang); then -# mkdir -p o/$MODE/test/libc/release -# $CLANG \ -# -o o/$MODE/test/libc/release/smokeclang2.com.dbg \ -# -Os \ -# -Wall \ -# -Werror \ -# -static \ -# -fno-pie \ -# -nostdlib \ -# -nostdinc \ -# -fuse-ld=lld \ -# -mno-red-zone \ -# -Wl,-T,o/$MODE/ape/ape.lds \ -# -include o/cosmopolitan.h \ -# test/libc/release/smoke.c \ -# o/$MODE/libc/crt/crt.o \ -# o/$MODE/ape/ape.o \ -# o/$MODE/cosmopolitan.a || exit -# o/$MODE/test/libc/release/smokeclang2.com.dbg || exit -# fi +if CLANG=$(command -v clang); then + mkdir -p o/$MODE/test/libc/release + $CLANG \ + -o o/$MODE/test/libc/release/smoke_clang.com.dbg \ + -Os \ + -Wall \ + -Werror \ + -fuse-ld=ld \ + -static \ + -fno-pie \ + -nostdlib \ + -nostdinc \ + -fno-omit-frame-pointer \ + -mno-omit-leaf-frame-pointer \ + -fno-stack-protector \ + -mno-red-zone \ + -Wl,-T,o/$MODE/ape/ape.lds \ + -include o/cosmopolitan.h \ + test/libc/release/smoke.c \ + o/$MODE/libc/crt/crt.o \ + o/$MODE/ape/ape.o \ + o/$MODE/cosmopolitan.a || exit + o/$MODE/test/libc/release/smoke_clang.com.dbg || exit +fi diff --git a/test/libc/release/lld.sh b/test/libc/release/lld.sh index 7482ea3c3..840fac1de 100755 --- a/test/libc/release/lld.sh +++ b/test/libc/release/lld.sh @@ -4,24 +4,27 @@ # TODO: someone who uses clang please mantain this -# if CLANG=$(command -v clang); then -# mkdir -p o/$MODE/test/libc/release -# $CLANG \ -# -o o/$MODE/test/libc/release/smokeclang.com.dbg \ -# -Os \ -# -Wall \ -# -Werror \ -# -static \ -# -fno-pie \ -# -nostdlib \ -# -nostdinc \ -# -fuse-ld=lld \ -# -mno-red-zone \ -# -Wl,-T,o/$MODE/ape/ape.lds \ -# -include o/cosmopolitan.h \ -# test/libc/release/smoke.c \ -# o/$MODE/libc/crt/crt.o \ -# o/$MODE/ape/ape.o \ -# o/$MODE/cosmopolitan.a || exit -# o/$MODE/test/libc/release/smokeclang.com.dbg || exit -# fi +if CLANG=$(command -v clang); then + mkdir -p o/$MODE/test/libc/release + $CLANG \ + -o o/$MODE/test/libc/release/smoke_lld.com.dbg \ + -Os \ + -Wall \ + -Werror \ + -fuse-ld=lld \ + -static \ + -fno-pie \ + -nostdlib \ + -nostdinc \ + -fno-omit-frame-pointer \ + -mno-omit-leaf-frame-pointer \ + -fno-stack-protector \ + -mno-red-zone \ + -Wl,-T,o/$MODE/ape/ape.lds \ + -include o/cosmopolitan.h \ + test/libc/release/smoke.c \ + o/$MODE/libc/crt/crt.o \ + o/$MODE/ape/ape.o \ + o/$MODE/cosmopolitan.a || exit + o/$MODE/test/libc/release/smoke_lld.com.dbg || exit +fi