From 2f53a4c56aff5bd3a880f87fda414f5123dab6b4 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 28 Aug 2023 10:10:40 -0700 Subject: [PATCH 1/2] [JITLink] Truncate ELF symbol sizes to fit containing block. LLVM currently emits dubious symbol sizes for aliases. E.g. assembling the following with LLVM top-of-tree... ``` $ cat foo.s .data .globl base base: .dword 42 .size base, 8 .set alias, base+4 ``` results in both base and alias having symbol size 8, even alias starts at base + 4. This also means that alias extends past the end of the .data section in this example. We should probably teach LLVM not to do this in the future, but as a short-term fix this patch teaches JITLink to simply truncate symbols that would extend past the end of their containing block. rdar://114207607 (cherry picked from commit 6267697a4c88688a89d2d770d00d52eab8aa72c7) Conflicts: llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h --- .../ExecutionEngine/JITLink/ELFLinkGraphBuilder.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h index 5dae600629395..e0a01e84b756c 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -528,6 +528,11 @@ template Error ELFLinkGraphBuilder::graphifySymbols() { return make_error(std::move(ErrMsg)); } + // Truncate symbol if it would overflow -- ELF size fields can't be + // trusted. + uint64_t Size = + std::min(static_cast(Sym.st_size), B->getSize() - Offset); + // In RISCV, temporary symbols (Used to generate dwarf, eh_frame // sections...) will appear in object code's symbol table, and LLVM does // not use names on these temporary symbols (RISCV gnu toolchain uses @@ -535,11 +540,9 @@ template Error ELFLinkGraphBuilder::graphifySymbols() { // anonymous symbol. auto &GSym = Name->empty() - ? G->addAnonymousSymbol(*B, Offset, Sym.st_size, - false, false) - : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L, - S, Sym.getType() == ELF::STT_FUNC, - false); + ? G->addAnonymousSymbol(*B, Offset, Size, false, false) + : G->addDefinedSymbol(*B, Offset, *Name, Size, L, S, + Sym.getType() == ELF::STT_FUNC, false); GSym.setTargetFlags(Flags); setGraphSymbol(SymIndex, GSym); From a655fbef92eed9133c66c6d6d21db5b1e5dcddcb Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 28 Aug 2023 22:30:46 -0700 Subject: [PATCH 2/2] [JITLink] Use the union of ELF section permissions rdar://114207428. Swift is currently generating multiple .rodata sections with a combination of SHF_ALLOC and (SHF_ALLOC | SHF_WRITABLE) flags and this was tripping an assert in the ELFLinkGraphBuilder. As a temporary workaround this patch just uses the union of the requested permissions. rdar://114207428 (cherry picked from commit ead32e1f2de2dc1f35297c17a2e7911df90605b7) Conflicts: llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h --- llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h index e0a01e84b756c..550a55705943b 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -374,14 +374,7 @@ template Error ELFLinkGraphBuilder::graphifySections() { } } - if (GraphSec->getMemProt() != Prot) { - std::string ErrMsg; - raw_string_ostream(ErrMsg) - << "In " << G->getName() << ", section " << *Name - << " is present more than once with different permissions: " - << GraphSec->getMemProt() << " vs " << Prot; - return make_error(std::move(ErrMsg)); - } + GraphSec->setMemProt(GraphSec->getMemProt() | Prot); Block *B = nullptr; if (Sec.sh_type != ELF::SHT_NOBITS) {