[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