[llvm] 091e364 - [JITLink][ELF] Support duplicated section names from object file

Steven Wu via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 18 08:38:40 PST 2022


Author: Steven Wu
Date: 2022-01-18T08:38:28-08:00
New Revision: 091e364866fb123fce090d0f511625dcbdfb5501

URL: https://github.com/llvm/llvm-project/commit/091e364866fb123fce090d0f511625dcbdfb5501
DIFF: https://github.com/llvm/llvm-project/commit/091e364866fb123fce090d0f511625dcbdfb5501.diff

LOG: [JITLink][ELF] Support duplicated section names from object file

ELF object files can contain duplicated sections (thus section symbols
as well), espeically when comdats/section groups are present. This patch
adds support for generating LinkGraph from object files that have
duplicated section names. This is the first step to properly model
comdats/section groups.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D114753

Added: 
    llvm/test/ExecutionEngine/JITLink/X86/ELF_comdat.s

Modified: 
    llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
    llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
    llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
    llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
index 23c8b77b913bd..931a60224ee2f 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
@@ -77,14 +77,14 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
     return Obj.getHeader().e_type == llvm::ELF::ET_REL;
   }
 
-  void setGraphSection(ELFSectionIndex SecIndex, Section &Sec) {
-    assert(!GraphSections.count(SecIndex) && "Duplicate section at index");
-    GraphSections[SecIndex] = &Sec;
+  void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
+    assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
+    GraphBlocks[SecIndex] = B;
   }
 
-  Section *getGraphSection(ELFSectionIndex SecIndex) {
-    auto I = GraphSections.find(SecIndex);
-    if (I == GraphSections.end())
+  Block *getGraphBlock(ELFSectionIndex SecIndex) {
+    auto I = GraphBlocks.find(SecIndex);
+    if (I == GraphBlocks.end())
       return nullptr;
     return I->second;
   }
@@ -139,9 +139,9 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
   const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
   StringRef SectionStringTab;
 
-  // Maps ELF section indexes to LinkGraph Sections.
-  // Only SHF_ALLOC sections will have graph sections.
-  DenseMap<ELFSectionIndex, Section *> GraphSections;
+  // Maps ELF section indexes to LinkGraph Blocks.
+  // Only SHF_ALLOC sections will have graph blocks.
+  DenseMap<ELFSectionIndex, Block *> GraphBlocks;
   DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
   DenseMap<const typename ELFFile::Elf_Shdr *,
            ArrayRef<typename ELFFile::Elf_Word>>
@@ -316,20 +316,27 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
     else
       Prot = MemProt::Read | MemProt::Write;
 
-    auto &GraphSec = G->createSection(*Name, Prot);
+    // Look for existing sections first.
+    auto *GraphSec = G->findSectionByName(*Name);
+    if (!GraphSec)
+      GraphSec = &G->createSection(*Name, Prot);
+    assert(GraphSec->getMemProt() == Prot && "MemProt should match");
+
+    Block *B = nullptr;
     if (Sec.sh_type != ELF::SHT_NOBITS) {
       auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
       if (!Data)
         return Data.takeError();
 
-      G->createContentBlock(GraphSec, *Data, orc::ExecutorAddr(Sec.sh_addr),
-                            Sec.sh_addralign, 0);
+      B = &G->createContentBlock(*GraphSec, *Data,
+                                 orc::ExecutorAddr(Sec.sh_addr),
+                                 Sec.sh_addralign, 0);
     } else
-      G->createZeroFillBlock(GraphSec, Sec.sh_size,
-                             orc::ExecutorAddr(Sec.sh_addr), Sec.sh_addralign,
-                             0);
+      B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
+                                  orc::ExecutorAddr(Sec.sh_addr),
+                                  Sec.sh_addralign, 0);
 
-    setGraphSection(SecIndex, GraphSec);
+    setGraphBlock(SecIndex, B);
   }
 
   return Error::success();
@@ -427,28 +434,20 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
           return NdxOrErr.takeError();
         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();
-        }
-
+      if (auto *B = getGraphBlock(Shndx)) {
         LLVM_DEBUG({
           dbgs() << "      " << SymIndex
                  << ": Creating defined graph symbol for ELF symbol \"" << *Name
                  << "\"\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()) {
@@ -500,8 +499,8 @@ Error ELFLinkGraphBuilder<ELFT>::forEachRelocation(
   }
 
   // Lookup the link-graph node corresponding to the target section name.
-  Section *GraphSect = G->findSectionByName(*Name);
-  if (!GraphSect)
+  auto *BlockToFix = getGraphBlock(RelSect.sh_info);
+  if (!BlockToFix)
     return make_error<StringError>(
         "Refencing a section that wasn't added to the graph: " + *Name,
         inconvertibleErrorCode());
@@ -512,7 +511,7 @@ Error ELFLinkGraphBuilder<ELFT>::forEachRelocation(
 
   // 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
index 35b70d533907c..a228c2ca0b233 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
@@ -101,7 +101,7 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
 
   Error addSingleRelocation(const typename ELFT::Rela &Rel,
                             const typename ELFT::Shdr &FixupSect,
-                            Section &GraphSection) {
+                            Block &BlockToFix) {
     using Base = ELFLinkGraphBuilder<ELFT>;
 
     uint32_t SymbolIndex = Rel.getSymbol(false);
@@ -124,18 +124,17 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
       return Kind.takeError();
 
     int64_t Addend = Rel.r_addend;
-    Block *BlockToFix = *(GraphSection.blocks().begin());
     orc::ExecutorAddr FixupAddress =
         orc::ExecutorAddr(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
index 34a00debc9272..291a2ac46bd06 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
@@ -349,7 +349,7 @@ class ELFLinkGraphBuilder_riscv : public ELFLinkGraphBuilder<ELFT> {
 
   Error addSingleRelocation(const typename ELFT::Rela &Rel,
                             const typename ELFT::Shdr &FixupSect,
-                            Section &GraphSection) {
+                            Block &BlockToFix) {
     using Base = ELFLinkGraphBuilder<ELFT>;
 
     uint32_t SymbolIndex = Rel.getSymbol(false);
@@ -372,17 +372,16 @@ class ELFLinkGraphBuilder_riscv : public ELFLinkGraphBuilder<ELFT> {
       return Kind.takeError();
 
     int64_t Addend = Rel.r_addend;
-    Block *BlockToFix = *(GraphSection.blocks().begin());
     auto FixupAddress = orc::ExecutorAddr(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
index cebe9e9dac78b..79d2cdbb30f18 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -172,7 +172,7 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
 
   Error addSingleRelocation(const typename ELFT::Rela &Rel,
                             const typename ELFT::Shdr &FixupSection,
-                            Section &GraphSection) {
+                            Block &BlockToFix) {
     using Base = ELFLinkGraphBuilder<ELFT>;
 
     uint32_t SymbolIndex = Rel.getSymbol(false);
@@ -248,17 +248,16 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
     }
     }
 
-    Block *BlockToFix = *(GraphSection.blocks().begin());
     auto FixupAddress = orc::ExecutorAddr(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, x86_64::getEdgeKindName(Kind));
+      printEdge(dbgs(), BlockToFix, GE, x86_64::getEdgeKindName(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
index 0000000000000..7a3f9fef75085
--- /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", at progbits,g1,comdat
+.globl  g1
+g1:
+call test1
+retq
+
+.section	.baz,"axG", at progbits,g1,comdat
+test1:
+retq
+
+.section	.bar,"axG", at progbits,g2,comdat
+.globl  g2
+g2:
+call test2
+retq
+
+.section	.baz,"axG", at progbits,g2,comdat
+test2:
+retq
+
+.text
+.globl  main
+main:
+retq


        


More information about the llvm-commits mailing list