[llvm] ca3bdb5 - [MC][ELF] Change SHT_LLVM_CALL_GRAPH_PROFILE relocations from SHT_RELA to SHT_REL

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 24 21:35:55 PDT 2021


Author: Fangrui Song
Date: 2021-06-24T21:35:48-07:00
New Revision: ca3bdb57fa1ac98b711a735de048c12b5fdd8086

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

LOG: [MC][ELF] Change SHT_LLVM_CALL_GRAPH_PROFILE relocations from SHT_RELA to SHT_REL

... even on targets preferring RELA. The section is only consumed by ld.lld
which can handle REL.

Follow-up to D104080 as I explained in the review. There are two advantages:

* The D104080 code only handles RELA, so arm/i386/mips32 etc may warn for -fprofile-use=/-fprofile-sample-use= usage.
* Decrease object file size for RELA targets

While here, change the relocation to relocate weights, instead of 0,1,2,3,..
I failed to catch the issue during review.

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/lib/MC/MCELFStreamer.cpp
    llvm/test/MC/ELF/cgprofile.s
    llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
    llvm/test/tools/llvm-readobj/ELF/demangle.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a6aee7a52a53..cb08516f72cc 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -857,15 +857,15 @@ static void readCallGraph(MemoryBufferRef mb) {
 
 template <class ELFT> static void readCallGraphsFromObjectFiles() {
   auto getIndex = [&](ObjFile<ELFT> *obj, uint32_t index) {
-    const Elf_Rel_Impl<ELFT, true> &rel = obj->cgProfileRela[index];
+    const Elf_Rel_Impl<ELFT, false> &rel = obj->cgProfileRel[index];
     return rel.getSymbol(config->isMips64EL);
   };
 
   for (auto file : objectFiles) {
     auto *obj = cast<ObjFile<ELFT>>(file);
-    if (obj->cgProfileRela.empty())
+    if (obj->cgProfileRel.empty())
       continue;
-    if (obj->cgProfileRela.size() != obj->cgProfile.size() * 2)
+    if (obj->cgProfileRel.size() != obj->cgProfile.size() * 2)
       fatal("number of relocations doesn't match Weights");
     for (uint32_t i = 0, size = obj->cgProfile.size(); i < size; ++i) {
       const Elf_CGProfile_Impl<ELFT> &cgpe = obj->cgProfile[i];

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 8a986d404792..93ca1f1f265c 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -672,8 +672,8 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
     if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) {
       this->sections[i] = createInputSection(sec);
       if (cgProfileSectionIndex && sec.sh_info == cgProfileSectionIndex) {
-        if (sec.sh_type == SHT_RELA)
-          cgProfileRela = CHECK(getObj().relas(sec), this);
+        if (sec.sh_type == SHT_REL)
+          cgProfileRel = CHECK(getObj().rels(sec), this);
       }
     }
 

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 31bffb91d275..7b35fd7ea98d 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -251,8 +251,8 @@ template <class ELFT> class ObjFile : public ELFFileBase {
 
   // SHT_LLVM_CALL_GRAPH_PROFILE table.
   ArrayRef<Elf_CGProfile> cgProfile;
-  // SHT_LLVM_CALL_GRAPH_PROFILE relocations.
-  ArrayRef<Elf_Rela> cgProfileRela;
+  // SHT_LLVM_CALL_GRAPH_PROFILE relocations, always in the REL format.
+  ArrayRef<Elf_Rel> cgProfileRel;
 
   // Get cached DWARF information.
   DWARFCache *getDwarf();

diff  --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index fec77d27eb9a..e0ea44626b7f 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -142,7 +142,7 @@ struct ELFWriter {
 
   // TargetObjectWriter wrappers.
   bool is64Bit() const;
-  bool hasRelocationAddend() const;
+  bool usesRela(const MCSectionELF &Sec) const;
 
   uint64_t align(unsigned Alignment);
 
@@ -392,8 +392,9 @@ bool ELFWriter::is64Bit() const {
   return OWriter.TargetObjectWriter->is64Bit();
 }
 
-bool ELFWriter::hasRelocationAddend() const {
-  return OWriter.hasRelocationAddend();
+bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
+  return OWriter.hasRelocationAddend() &&
+         Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
 }
 
 // Emit the ELF header.
@@ -785,11 +786,12 @@ MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
     return nullptr;
 
   const StringRef SectionName = Sec.getName();
-  std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
+  bool Rela = usesRela(Sec);
+  std::string RelaSectionName = Rela ? ".rela" : ".rel";
   RelaSectionName += SectionName;
 
   unsigned EntrySize;
-  if (hasRelocationAddend())
+  if (Rela)
     EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
   else
     EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
@@ -799,8 +801,8 @@ MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
     Flags = ELF::SHF_GROUP;
 
   MCSectionELF *RelaSection = Ctx.createELFRelSection(
-      RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
-      Flags, EntrySize, Sec.getGroup(), &Sec);
+      RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
+      Sec.getGroup(), &Sec);
   RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
   return RelaSection;
 }
@@ -925,6 +927,7 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm,
   // Sort the relocation entries. MIPS needs this.
   OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
 
+  const bool Rela = usesRela(Sec);
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
     const ELFRelocationEntry &Entry = Relocs[e - i - 1];
     unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
@@ -943,7 +946,7 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm,
         ERE64.setSymbolAndType(Index, Entry.Type);
         write(ERE64.r_info);
       }
-      if (hasRelocationAddend())
+      if (Rela)
         write(Entry.Addend);
     } else {
       write(uint32_t(Entry.Offset));
@@ -952,7 +955,7 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm,
       ERE32.setSymbolAndType(Index, Entry.Type);
       write(ERE32.r_info);
 
-      if (hasRelocationAddend())
+      if (Rela)
         write(uint32_t(Entry.Addend));
 
       if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {

diff  --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 76e69a65996e..6c8bfeca1765 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -513,9 +513,10 @@ void MCELFStreamer::finalizeCGProfile() {
   SwitchSection(CGProfile);
   uint64_t Offset = 0;
   for (MCAssembler::CGProfileEntry &E : Asm.CGProfile) {
-    finalizeCGProfileEntry(E.From, Offset++);
-    finalizeCGProfileEntry(E.To, Offset++);
+    finalizeCGProfileEntry(E.From, Offset);
+    finalizeCGProfileEntry(E.To, Offset);
     emitIntValue(E.Count, sizeof(uint64_t));
+    Offset += sizeof(uint64_t);
   }
   PopSection();
 }

diff  --git a/llvm/test/MC/ELF/cgprofile.s b/llvm/test/MC/ELF/cgprofile.s
index 11c7464976db..26f60bcd8af0 100644
--- a/llvm/test/MC/ELF/cgprofile.s
+++ b/llvm/test/MC/ELF/cgprofile.s
@@ -31,30 +31,26 @@ late3:
 # CHECK-NEXT:   0010: 14000000 00000000 2A000000 00000000
 # CHECK-NEXT: )
 
-# CHECK:      Name: .rela.llvm.call-graph-profile (28)
-# CHECK-NEXT: Type: SHT_RELA (0x4)
+# CHECK:      Name: .rel.llvm.call-graph-profile (28)
+# CHECK-NEXT: Type: SHT_REL (0x9)
 # CHECK-NEXT: Flags [ (0x0)
 # CHECK-NEXT: ]
 # CHECK-NEXT: Address: 0x0
 # CHECK-NEXT: Offset: 0x140
-# CHECK-NEXT: Size: 192
+# CHECK-NEXT: Size: 128
 # CHECK-NEXT: Link: 7
 # CHECK-NEXT: Info: 5
 # CHECK-NEXT: AddressAlignment: 8
-# CHECK-NEXT: EntrySize: 24
+# CHECK-NEXT: EntrySize: 16
 # CHECK-NEXT: SectionData (
 # CHECK-NEXT:   0000: 00000000 00000000 00000000 02000000
-# CHECK-NEXT:   0010: 00000000 00000000 01000000 00000000
-# CHECK-NEXT:   0020: 00000000 05000000 00000000 00000000
-# CHECK-NEXT:   0030: 02000000 00000000 00000000 07000000
-# CHECK-NEXT:   0040: 00000000 00000000 03000000 00000000
-# CHECK-NEXT:   0050: 00000000 02000000 00000000 00000000
-# CHECK-NEXT:   0060: 04000000 00000000 00000000 06000000
-# CHECK-NEXT:   0070: 00000000 00000000 05000000 00000000
-# CHECK-NEXT:   0080: 00000000 03000000 00000000 00000000
-# CHECK-NEXT:   0090: 06000000 00000000 00000000 01000000
-# CHECK-NEXT:   00A0: 00000000 00000000 07000000 00000000
-# CHECK-NEXT:   00B0: 00000000 05000000 00000000 00000000
+# CHECK-NEXT:   0010: 00000000 00000000 00000000 05000000
+# CHECK-NEXT:   0020: 08000000 00000000 00000000 07000000
+# CHECK-NEXT:   0030: 08000000 00000000 00000000 02000000
+# CHECK-NEXT:   0040: 10000000 00000000 00000000 06000000
+# CHECK-NEXT:   0050: 10000000 00000000 00000000 03000000
+# CHECK-NEXT:   0060: 18000000 00000000 00000000 01000000
+# CHECK-NEXT:   0070: 18000000 00000000 00000000 05000000
 # CHECK-NEXT: )
 
 # CHECK: Symbols [

diff  --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
index d0115b4c6c11..9ddc8e540571 100644
--- a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
+++ b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
@@ -34,8 +34,8 @@ Sections:
       - Weight: 89
       - Weight: 98
     EntSize: [[ENTSIZE=<none>]]
-  - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+  - Name: .rel.llvm.call-graph-profile
+    Type: SHT_REL
     Info: .llvm.call-graph-profile
     Relocations:
       - Symbol: foo
@@ -98,8 +98,8 @@ Sections:
       - Weight: 10
       - Weight: 20
       - Weight: 20
-  - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+  - Name: .rel.llvm.call-graph-profile
+    Type: SHT_REL
     Info: .llvm.call-graph-profile
     Relocations:
       - Symbol: 1
@@ -186,8 +186,8 @@ Sections:
       - Weight: 89
       - Weight: 98
     EntSize: [[ENTSIZE=<none>]]
-  - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+  - Name: .rel.llvm.call-graph-profile
+    Type: SHT_REL
     Info: .llvm.call-graph-profile
     Relocations:
       - Symbol: foo
@@ -213,7 +213,7 @@ Symbols:
 # RUN: llvm-readobj %t6.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t6.o --check-prefix=LLVM-RELOC-WRONG-SIZE
 # RUN: llvm-readobj %t6.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t6.o --check-prefix=LLVM-RELOC-WRONG-SIZE
 
-# LLVM-RELOC-WRONG-SIZE:      warning: '[[FILE]]': unable to load relocations for SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 2] has invalid sh_entsize: expected 24, but got 32
+# LLVM-RELOC-WRONG-SIZE:      warning: '[[FILE]]': unable to load relocations for SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 2] has invalid sh_entsize: expected 16, but got 24
 # LLVM-RELOC-WRONG-SIZE-NEXT: CGProfile [
 # LLVM-RELOC-WRONG-SIZE-NEXT:  CGProfileEntry {
 # LLVM-RELOC-WRONG-SIZE-NEXT:    Weight: 89
@@ -236,8 +236,8 @@ Sections:
       - Weight: 89
       - Weight: 98
     EntSize: [[ENTSIZE=<none>]]
-  - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+  - Name: .rel.llvm.call-graph-profile
+    Type: SHT_REL
     Info: .llvm.call-graph-profile
     Relocations:
       - Symbol: foo
@@ -251,7 +251,7 @@ Sections:
       - Offset: 0x3
         Symbol: foo
         Type:   R_X86_64_NONE
-    EntSize: 32
+    EntSize: 24
 Symbols:
   - Name: foo
   - Name: bar

diff  --git a/llvm/test/tools/llvm-readobj/ELF/demangle.test b/llvm/test/tools/llvm-readobj/ELF/demangle.test
index 25be40a72b94..e58887b95a6a 100644
--- a/llvm/test/tools/llvm-readobj/ELF/demangle.test
+++ b/llvm/test/tools/llvm-readobj/ELF/demangle.test
@@ -199,8 +199,8 @@ Sections:
     Link: .symtab
     EntSize: 8
     Content: "2000000000000000"
-  - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+  - Name: .rel.llvm.call-graph-profile
+    Type: SHT_REL
     Info: .llvm.call-graph-profile
     Relocations:
       - Symbol: 1

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 11914fc808f6..79824728982d 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -6723,20 +6723,20 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
       return;
     }
 
-    Elf_Rela_Range CGProfileRela;
+    Elf_Rel_Range CGProfileRel;
     bool UseReloc = (CGRelSection != nullptr);
     if (UseReloc) {
-      Expected<Elf_Rela_Range> CGProfileRelaOrError =
-          this->Obj.relas(*CGRelSection);
+      Expected<Elf_Rel_Range> CGProfileRelaOrError =
+          this->Obj.rels(*CGRelSection);
       if (!CGProfileRelaOrError) {
         this->reportUniqueWarning("unable to load relocations for "
                                   "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
                                   toString(CGProfileRelaOrError.takeError()));
         UseReloc = false;
       } else
-        CGProfileRela = *CGProfileRelaOrError;
+        CGProfileRel = *CGProfileRelaOrError;
 
-      if (UseReloc && CGProfileRela.size() != (CGProfileOrErr->size() * 2)) {
+      if (UseReloc && CGProfileRel.size() != (CGProfileOrErr->size() * 2)) {
         this->reportUniqueWarning(
             "number of from/to pairs does not match number of frequencies");
         UseReloc = false;
@@ -6746,7 +6746,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
           "relocation section for a call graph section doesn't exist");
 
     auto GetIndex = [&](uint32_t Index) {
-      const Elf_Rel_Impl<ELFT, true> &Rel = CGProfileRela[Index];
+      const Elf_Rel_Impl<ELFT, false> &Rel = CGProfileRel[Index];
       return Rel.getSymbol(this->Obj.isMips64EL());
     };
 


        


More information about the llvm-commits mailing list