diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -77,16 +77,23 @@ return Obj.getHeader().e_type == llvm::ELF::ET_REL; } - void setGraphSection(ELFSectionIndex SecIndex, Section &Sec) { + void setGraphSection(ELFSectionIndex SecIndex, Section *Sec, Block *Block) { assert(!GraphSections.count(SecIndex) && "Duplicate section at index"); - GraphSections[SecIndex] = &Sec; + GraphSections[SecIndex] = {Sec, Block}; } Section *getGraphSection(ELFSectionIndex SecIndex) { auto I = GraphSections.find(SecIndex); if (I == GraphSections.end()) return nullptr; - return I->second; + return I->second.Sec; + } + + Block *getGraphSectionBlock(ELFSectionIndex SecIndex) { + auto I = GraphSections.find(SecIndex); + if (I == GraphSections.end()) + return nullptr; + return I->second.Block; } void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) { @@ -141,7 +148,11 @@ // Maps ELF section indexes to LinkGraph Sections. // Only SHF_ALLOC sections will have graph sections. - DenseMap GraphSections; + struct SectionIdxEntry { + Section *Sec; + Block *Block; + }; + DenseMap GraphSections; DenseMap GraphSymbols; DenseMap> @@ -328,12 +339,13 @@ if (!Data) return Data.takeError(); - G->createContentBlock(GraphSec, *Data, Sec.sh_addr, Sec.sh_addralign, 0); + B = &G->createContentBlock(*GraphSec, *Data, Sec.sh_addr, + Sec.sh_addralign, 0); } else - G->createZeroFillBlock(GraphSec, Sec.sh_size, Sec.sh_addr, - Sec.sh_addralign, 0); + B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size, Sec.sh_addr, + Sec.sh_addralign, 0); - setGraphSection(SecIndex, GraphSec); + setGraphSection(SecIndex, GraphSec, B); } return Error::success(); @@ -432,14 +444,7 @@ Shndx = *NdxOrErr; } if (auto *GraphSec = getGraphSection(Shndx)) { - Block *B = nullptr; - { - auto Blocks = GraphSec->blocks(); - assert(Blocks.begin() != Blocks.end() && "No blocks for section"); - assert(std::next(Blocks.begin()) == Blocks.end() && - "Multiple blocks for section"); - B = *Blocks.begin(); - } + Block *B = getGraphSectionBlock(Shndx); LLVM_DEBUG({ dbgs() << " " << SymIndex @@ -447,12 +452,13 @@ << "\"\n"; }); - if (Sym.getType() == ELF::STT_SECTION) - *Name = GraphSec->getName(); - + // Model the section symbols as anonymous symbol. auto &GSym = - G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, S, - Sym.getType() == ELF::STT_FUNC, false); + Sym.getType() == ELF::STT_SECTION + ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size, false, + false) + : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, + S, Sym.getType() == ELF::STT_FUNC, false); setGraphSymbol(SymIndex, GSym); } } else if (Sym.isUndefined() && Sym.isExternal()) { @@ -504,8 +510,8 @@ } // Lookup the link-graph node corresponding to the target section name. - Section *GraphSect = G->findSectionByName(*Name); - if (!GraphSect) + auto *BlockToFix = getGraphSectionBlock(RelSect.sh_info); + if (!BlockToFix) return make_error( "Refencing a section that wasn't added to the graph: " + *Name, inconvertibleErrorCode()); @@ -516,7 +522,7 @@ // Let the callee process relocation entries one by one. for (const typename ELFT::Rela &R : *RelEntries) - if (Error Err = Func(R, **FixupSection, *GraphSect)) + if (Error Err = Func(R, **FixupSection, *BlockToFix)) return Err; LLVM_DEBUG(dbgs() << "\n"); diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -100,7 +100,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSect, - Section &GraphSection) { + Block &BlockToFix) { using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -123,17 +123,16 @@ return Kind.takeError(); int64_t Addend = Rel.r_addend; - Block *BlockToFix = *(GraphSection.blocks().begin()); JITTargetAddress FixupAddress = FixupSect.sh_addr + Rel.r_offset; - Edge::OffsetT Offset = FixupAddress - BlockToFix->getAddress(); + Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); Edge GE(*Kind, Offset, *GraphSymbol, Addend); LLVM_DEBUG({ dbgs() << " "; - printEdge(dbgs(), *BlockToFix, GE, aarch64::getEdgeKindName(*Kind)); + printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(*Kind)); dbgs() << "\n"; }); - BlockToFix->addEdge(std::move(GE)); + BlockToFix.addEdge(std::move(GE)); return Error::success(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -298,7 +298,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSect, - Section &GraphSection) { + Block &BlockToFix) { using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -321,17 +321,16 @@ return Kind.takeError(); int64_t Addend = Rel.r_addend; - Block *BlockToFix = *(GraphSection.blocks().begin()); JITTargetAddress FixupAddress = FixupSect.sh_addr + Rel.r_offset; - Edge::OffsetT Offset = FixupAddress - BlockToFix->getAddress(); + Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); Edge GE(*Kind, Offset, *GraphSymbol, Addend); LLVM_DEBUG({ dbgs() << " "; - printEdge(dbgs(), *BlockToFix, GE, riscv::getEdgeKindName(*Kind)); + printEdge(dbgs(), BlockToFix, GE, riscv::getEdgeKindName(*Kind)); dbgs() << "\n"; }); - BlockToFix->addEdge(std::move(GE)); + BlockToFix.addEdge(std::move(GE)); return Error::success(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -172,7 +172,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSection, - Section &GraphSection) { + Block &BlockToFix) { using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -246,17 +246,16 @@ } } - Block *BlockToFix = *(GraphSection.blocks().begin()); JITTargetAddress FixupAddress = FixupSection.sh_addr + Rel.r_offset; - Edge::OffsetT Offset = FixupAddress - BlockToFix->getAddress(); + Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); Edge GE(Kind, Offset, *GraphSymbol, Addend); LLVM_DEBUG({ dbgs() << " "; - printEdge(dbgs(), *BlockToFix, GE, getELFX86RelocationKindName(Kind)); + printEdge(dbgs(), BlockToFix, GE, getELFX86RelocationKindName(Kind)); dbgs() << "\n"; }); - BlockToFix->addEdge(std::move(GE)); + BlockToFix.addEdge(std::move(GE)); return Error::success(); } diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_comdat.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_comdat.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_comdat.s @@ -0,0 +1,27 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t +// RUN: llvm-jitlink -noexec %t + +.section .foo,"axG",@progbits,g1,comdat +.globl g1 +g1: +call test1 +retq + +.section .baz,"axG",@progbits,g1,comdat +test1: +retq + +.section .bar,"axG",@progbits,g2,comdat +.globl g2 +g2: +call test2 +retq + +.section .baz,"axG",@progbits,g2,comdat +test2: +retq + +.text +.globl main +main: +retq