diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -856,12 +856,21 @@ } template static void readCallGraphsFromObjectFiles() { + auto getIndex = [&](ObjFile *obj, uint32_t index) -> uint32_t { + const Elf_Rel_Impl &rel = obj->cgProfileRela[index]; + return rel.getSymbol(config->isMips64EL); + }; + for (auto file : objectFiles) { auto *obj = cast>(file); - - for (const Elf_CGProfile_Impl &cgpe : obj->cgProfile) { - auto *fromSym = dyn_cast(&obj->getSymbol(cgpe.cgp_from)); - auto *toSym = dyn_cast(&obj->getSymbol(cgpe.cgp_to)); + assert(obj->cgProfileRela.size() == obj->cgProfile.size() * 2 && + "Number of relocations doesn't match Weights."); + for (uint32_t i = 0, size = obj->cgProfile.size(); i < size; ++i) { + const Elf_CGProfile_Impl &cgpe = obj->cgProfile[i]; + auto fromIndex = getIndex(obj, i * 2); + auto toIndex = getIndex(obj, i * 2 + 1); + auto *fromSym = dyn_cast(&obj->getSymbol(fromIndex)); + auto *toSym = dyn_cast(&obj->getSymbol(toIndex)); if (!fromSym || !toSym) continue; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -249,8 +249,10 @@ // Pointer to this input file's .llvm_addrsig section, if it has one. const Elf_Shdr *addrsigSec = nullptr; - // SHT_LLVM_CALL_GRAPH_PROFILE table + // SHT_LLVM_CALL_GRAPH_PROFILE table. ArrayRef cgProfile; + // SHT_LLVM_CALL_GRAPH_PROFILE relocations. + ArrayRef cgProfileRela; // Get cached DWARF information. DWARFCache *getDwarf(); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -571,15 +571,19 @@ CHECK(obj.getSectionStringTable(objSections), this); std::vector> selectedGroups; + // SHT_LLVM_CALL_GRAPH_PROFILE Section Index. + size_t cgProfileSectionIndex = 0; for (size_t i = 0, e = objSections.size(); i < e; ++i) { if (this->sections[i] == &InputSection::discarded) continue; const Elf_Shdr &sec = objSections[i]; - if (sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE) + if (sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE) { cgProfile = check(obj.template getSectionContentsAsArray(sec)); + cgProfileSectionIndex = i; + } // SHF_EXCLUDE'ed sections are discarded by the linker. However, // if -r is given, we'll let the final link discard such sections. @@ -665,8 +669,12 @@ continue; const Elf_Shdr &sec = objSections[i]; - if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) + if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) { + if (sec.sh_info == cgProfileSectionIndex) { + cgProfileRela = CHECK(getObj().relas(sec), this); + } this->sections[i] = createInputSection(sec); + } // A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have // the flag. diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -926,17 +926,17 @@ // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37 SHT_ANDROID_REL = 0x60000001, SHT_ANDROID_RELA = 0x60000002, - SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table. - SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options. - SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile. - SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols - // for safe ICF. + SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table. + SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options. + SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols + // for safe ICF. SHT_LLVM_DEPENDENT_LIBRARIES = 0x6fff4c04, // LLVM Dependent Library Specifiers. SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification. SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition. SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition. SHT_LLVM_BB_ADDR_MAP = 0x6fff4c08, // LLVM Basic Block Address Map. + SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c09, // LLVM Call Graph Profile. // Android's experimental support for SHT_RELR sections. // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512 SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets. diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -84,6 +84,9 @@ /// Map a relocation name used in .reloc to a fixup kind. virtual Optional getFixupKind(StringRef Name) const; + /// Returns Backend specific name of _NONE relocation. + virtual StringRef getNoneRelcationName() const = 0; + /// Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -85,7 +85,7 @@ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; void fixSymbolsInTLSFixups(const MCExpr *expr); - void finalizeCGProfileEntry(const MCSymbolRefExpr *&S); + void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); void finalizeCGProfile(); /// Merge the content of the fragment \p EF into the fragment \p DF. diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -737,8 +737,6 @@ template struct Elf_CGProfile_Impl { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - Elf_Word cgp_from; - Elf_Word cgp_to; Elf_Xword cgp_weight; }; diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -515,17 +515,13 @@ }; // Represents the call graph profile section entry. -struct CallGraphEntry { - // The symbol of the source of the edge. - StringRef From; - // The symbol index of the destination of the edge. - StringRef To; +struct CallGraphEntryWeight { // The weight of the edge. uint64_t Weight; }; struct CallGraphProfileSection : Section { - Optional> Entries; + Optional> Entries; CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {} @@ -737,7 +733,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader) @@ -931,8 +927,8 @@ static void mapping(IO &IO, ELFYAML::LinkerOption &Sym); }; -template <> struct MappingTraits { - static void mapping(IO &IO, ELFYAML::CallGraphEntry &E); +template <> struct MappingTraits { + static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E); }; template <> struct MappingTraits { diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1127,14 +1127,6 @@ OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section); } - MCSectionELF *CGProfileSection = nullptr; - if (!Asm.CGProfile.empty()) { - CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile", - ELF::SHT_LLVM_CALL_GRAPH_PROFILE, - ELF::SHF_EXCLUDE, 16); - SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection); - } - for (MCSectionELF *Group : Groups) { // Remember the offset into the file for this section. const uint64_t SecStart = align(Group->getAlignment()); @@ -1186,17 +1178,6 @@ } } - if (CGProfileSection) { - uint64_t SecStart = W.OS.tell(); - for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) { - W.write(CGPE.From->getSymbol().getIndex()); - W.write(CGPE.To->getSymbol().getIndex()); - W.write(CGPE.Count); - } - uint64_t SecEnd = W.OS.tell(); - SectionOffsets[CGProfileSection] = std::make_pair(SecStart, SecEnd); - } - { uint64_t SecStart = W.OS.tell(); StrTabBuilder.write(W.OS); @@ -1471,7 +1452,11 @@ return; unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel); - bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); + const auto *Parent = cast(Fragment->getParent()); + // Emiting relocation with sybmol for CG Profile to help with --cg-profile. + bool RelocateWithSymbol = + shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type) || + (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE); uint64_t Addend = 0; FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined() diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -477,7 +477,8 @@ } } -void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) { +void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, + uint64_t Offset) { const MCSymbol *S = &SRE->getSymbol(); if (S->isTemporary()) { if (!S->isInSection()) { @@ -488,22 +489,32 @@ } S = S->getSection().getBeginSymbol(); S->setUsedInReloc(); - SRE = - MCSymbolRefExpr::create(S, SRE->getKind(), getContext(), SRE->getLoc()); - return; + SRE = MCSymbolRefExpr::create(S, MCSymbolRefExpr::VK_None, getContext(), + SRE->getLoc()); } - // Not a temporary, referece it as a weak undefined. - bool Created; - getAssembler().registerSymbol(*S, &Created); - if (Created) - cast(S)->setBinding(ELF::STB_WEAK); + const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext()); + MCObjectStreamer::visitUsedExpr(*SRE); + MCObjectStreamer::emitRelocDirective( + *MCOffset, getAssembler().getBackend().getNoneRelcationName(), SRE, + SRE->getLoc(), *getContext().getSubtargetInfo()); } void MCELFStreamer::finalizeCGProfile() { - for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) { - finalizeCGProfileEntry(E.From); - finalizeCGProfileEntry(E.To); + MCAssembler &Asm = getAssembler(); + if (Asm.CGProfile.empty()) + return; + MCSection *CGProfile = getAssembler().getContext().getELFSection( + ".llvm.call-graph-profile", ELF::SHT_LLVM_CALL_GRAPH_PROFILE, + ELF::SHF_EXCLUDE, 8 /* sizeof(Elf_CGProfile_Impl<>)*/); + PushSection(); + SwitchSection(CGProfile); + uint64_t Offset = 0; + for (MCAssembler::CGProfileEntry &E : Asm.CGProfile) { + finalizeCGProfileEntry(E.From, Offset++); + finalizeCGProfileEntry(E.To, Offset++); + emitIntValue(E.Count, sizeof(uint64_t)); } + PopSection(); } void MCELFStreamer::emitInstToFragment(const MCInst &Inst, diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -18,6 +18,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/ELFTypes.h" #include "llvm/ObjectYAML/DWARFEmitter.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h" @@ -1434,14 +1435,9 @@ if (!Section.Entries) return; - for (const ELFYAML::CallGraphEntry &E : *Section.Entries) { - unsigned From = toSymbolIndex(E.From, Section.Name, /*IsDynamic=*/false); - unsigned To = toSymbolIndex(E.To, Section.Name, /*IsDynamic=*/false); - - CBA.write(From, ELFT::TargetEndianness); - CBA.write(To, ELFT::TargetEndianness); + for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) { CBA.write(E.Weight, ELFT::TargetEndianness); - SHeader.sh_size += 16; + SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl); } } diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1833,11 +1833,9 @@ IO.mapRequired("Value", Opt.Value); } -void MappingTraits::mapping( - IO &IO, ELFYAML::CallGraphEntry &E) { +void MappingTraits::mapping( + IO &IO, ELFYAML::CallGraphEntryWeight &E) { assert(IO.getContext() && "The IO context is not initialized"); - IO.mapRequired("From", E.From); - IO.mapRequired("To", E.To); IO.mapRequired("Weight", E.Weight); } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -48,6 +48,8 @@ Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = { // This table *must* be in the order that the fixup_* kinds are defined @@ -326,6 +328,10 @@ } } +StringRef AArch64AsmBackend::getNoneRelcationName() const { + return "R_AARCH64_NONE"; +} + Optional AArch64AsmBackend::getFixupKind(StringRef Name) const { if (!TheTriple.isOSBinFormatELF()) return None; diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -37,6 +37,11 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -39,6 +39,8 @@ Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -47,6 +47,8 @@ }; } // end anonymous namespace +StringRef ARMAsmBackend::getNoneRelcationName() const { return "R_ARM_NONE"; } + Optional ARMAsmBackend::getFixupKind(StringRef Name) const { if (!STI.getTargetTriple().isOSBinFormatELF()) return None; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h @@ -48,6 +48,11 @@ return AVR::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { @@ -67,4 +72,3 @@ } // end namespace llvm #endif // LLVM_AVR_ASM_BACKEND_H - diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp @@ -40,6 +40,10 @@ const MCAsmLayout &Layout) const override { return false; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } unsigned getNumFixupKinds() const override { return 1; } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -202,6 +202,11 @@ return Infos[Kind - FirstTargetFixupKind]; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override { switch(Fixup.getTargetKind()) { diff --git a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp --- a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp +++ b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp @@ -69,6 +69,11 @@ return Lanai::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + bool writeNopData(raw_ostream &OS, uint64_t Count) const override; }; diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp @@ -65,6 +65,11 @@ return MSP430::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo Infos[MSP430::NumTargetFixupKinds] = { // This table must be in the same order of enum in MSP430FixupKinds.h. @@ -83,10 +88,10 @@ }; static_assert((array_lengthof(Infos)) == MSP430::NumTargetFixupKinds, "Not all fixup kinds added to Infos array"); - + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); - + return Infos[Kind - FirstTargetFixupKind]; } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -44,6 +44,7 @@ const MCSubtargetInfo *STI) const override; Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; unsigned getNumFixupKinds() const override { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -300,6 +300,8 @@ } } +StringRef MipsAsmBackend::getNoneRelcationName() const { return "R_MIPS_NONE"; } + Optional MipsAsmBackend::getFixupKind(StringRef Name) const { return StringSwitch>(Name) .Case("R_MIPS_NONE", FK_NONE) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -91,6 +91,11 @@ return PPC::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = { // name offset bits flags @@ -224,6 +229,7 @@ } Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; }; class XCOFFPPCAsmBackend : public PPCAsmBackend { @@ -239,6 +245,10 @@ } // end anonymous namespace +StringRef ELFPPCAsmBackend::getNoneRelcationName() const { + return "R_PPC64_NONE"; +} + Optional ELFPPCAsmBackend::getFixupKind(StringRef Name) const { if (TT.isOSBinFormatELF()) { unsigned Type; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -99,6 +99,8 @@ Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; bool mayNeedRelaxation(const MCInst &Inst, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -23,6 +23,10 @@ using namespace llvm; +StringRef RISCVAsmBackend::getNoneRelcationName() const { + return "R_RISCV_NONE"; +} + Optional RISCVAsmBackend::getFixupKind(StringRef Name) const { if (STI.getTargetTriple().isOSBinFormatELF()) { unsigned Type; diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -131,6 +131,11 @@ return Sparc::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = { // name offset bits flags diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -49,6 +49,10 @@ unsigned getNumFixupKinds() const override { return SystemZ::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef Data, diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -44,6 +44,11 @@ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + return ""; + } + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef Data, uint64_t Value, bool IsPCRel, diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -175,6 +175,8 @@ Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, @@ -672,6 +674,19 @@ Sec->setAlignment(AlignBoundary); } +StringRef X86AsmBackend::getNoneRelcationName() const { + StringRef Name = ""; + if (STI.getTargetTriple().isOSBinFormatELF()) { + if (STI.getTargetTriple().getArch() == Triple::x86_64) + Name = "R_X86_64_NONE"; + else + Name = "R_386_NONE"; + } else + llvm_unreachable("None type not available."); + + return Name; +} + Optional X86AsmBackend::getFixupKind(StringRef Name) const { if (STI.getTargetTriple().isOSBinFormatELF()) { unsigned Type; diff --git a/llvm/test/MC/ELF/cgprofile.s b/llvm/test/MC/ELF/cgprofile.s --- a/llvm/test/MC/ELF/cgprofile.s +++ b/llvm/test/MC/ELF/cgprofile.s @@ -15,22 +15,46 @@ .L.local: # CHECK: Name: .llvm.call-graph-profile -# CHECK-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE (0x6FFF4C02) +# CHECK-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE (0x6FFF4C09) # CHECK-NEXT: Flags [ (0x80000000) # CHECK-NEXT: SHF_EXCLUDE (0x80000000) # CHECK-NEXT: ] # CHECK-NEXT: Address: # CHECK-NEXT: Offset: -# CHECK-NEXT: Size: 64 -# CHECK-NEXT: Link: 6 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Link: 7 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 16 +# CHECK-NEXT: EntrySize: 8 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 02000000 05000000 20000000 00000000 -# CHECK-NEXT: 0010: 07000000 02000000 0B000000 00000000 -# CHECK-NEXT: 0020: 06000000 03000000 14000000 00000000 -# CHECK-NEXT: 0030: 01000000 05000000 2A000000 00000000 +# CHECK-NEXT: 0000: 20000000 00000000 0B000000 00000000 +# CHECK-NEXT: 0010: 14000000 00000000 2A000000 00000000 +# CHECK-NEXT: ) + +# CHECK: Name: .rela.llvm.call-graph-profile (28) +# CHECK-NEXT: Type: SHT_RELA (0x4) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x140 +# CHECK-NEXT: Size: 192 +# CHECK-NEXT: Link: 7 +# CHECK-NEXT: Info: 5 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 24 +# 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: ) # CHECK: Symbols [ @@ -72,7 +96,7 @@ # CHECK: Name: freq # CHECK-NEXT: Value: # CHECK-NEXT: Size: -# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: # CHECK-NEXT: Other: # CHECK-NEXT: Section: Undefined diff --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test --- a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test +++ b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test @@ -26,17 +26,29 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: foo - To: bar - Weight: 89 - - From: bar - To: foo - Weight: 98 + - Weight: 89 + - Weight: 98 EntSize: [[ENTSIZE=]] + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: foo + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: bar + Type: R_X86_64_NONE + - Offset: 0x2 + Symbol: bar + Type: R_X86_64_NONE + - Offset: 0x3 + Symbol: foo + Type: R_X86_64_NONE Symbols: - Name: foo - Name: bar @@ -47,7 +59,7 @@ # RUN: llvm-readelf %t2.o --cg-profile | FileCheck %s --check-prefix=GNU # LLVM-ERR: CGProfile [ -# LLVM-ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has invalid sh_entsize: expected 16, but got 15 +# LLVM-ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has invalid sh_entsize: expected 8, but got 15 # LLVM-ERR-NEXT: ] ## Check we report a warning when unable to dump a name of a symbol. @@ -69,7 +81,7 @@ # LLVM-BROKEN-SYM-NEXT: } # LLVM-BROKEN-SYM-NEXT: CGProfileEntry { # LLVM-BROKEN-SYM-NEXT: From: (0) -# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 4: unable to get symbol from section [index 3]: invalid symbol index (4) +# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 4: unable to get symbol from section [index 4]: invalid symbol index (4) # LLVM-BROKEN-SYM-NEXT: To: (4) # LLVM-BROKEN-SYM-NEXT: Weight: 20 # LLVM-BROKEN-SYM-NEXT: } @@ -80,19 +92,35 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 10 - - From: 2 - To: 3 - Weight: 20 - - From: 0x0 ## Null symbol. - To: 0x4 ## This index goes past the end of the symbol table. - Weight: 20 + - Weight: 10 + - Weight: 20 + - Weight: 20 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x2 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x3 + Symbol: 3 + Type: R_X86_64_NONE + - Offset: 0x4 + Symbol: 0x0 ## Null symbol. + Type: R_X86_64_NONE + - Offset: 0x5 + Symbol: 0x4 ## This index goes past the end of the symbol table. + Type: R_X86_64_NONE - Name: .strtab Type: SHT_STRTAB Content: "0041004200" ## '\0', 'A', '\0', 'B', '\0' diff --git a/llvm/test/tools/llvm-readobj/ELF/demangle.test b/llvm/test/tools/llvm-readobj/ELF/demangle.test --- a/llvm/test/tools/llvm-readobj/ELF/demangle.test +++ b/llvm/test/tools/llvm-readobj/ELF/demangle.test @@ -197,8 +197,17 @@ - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Link: .symtab - EntSize: 16 - Content: "01000000020000002000000000000000" + EntSize: 8 + Content: "2000000000000000" + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE - Name: .llvm_addrsig Type: SHT_LLVM_ADDRSIG Link: .symtab diff --git a/llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml b/llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml --- a/llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml @@ -16,12 +16,24 @@ # BASIC-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # BASIC-NEXT: Link: .symtab # BASIC-NEXT: Entries: -# BASIC-NEXT: - From: foo -# BASIC-NEXT: To: bar -# BASIC-NEXT: Weight: 89 -# BASIC-NEXT: - From: bar -# BASIC-NEXT: To: foo -# BASIC-NEXT: Weight: 98 +# BASIC-NEXT: - Weight: 89 +# BASIC-NEXT: - Weight: 98 +# BASIC-NEXT: - Name: .rela.llvm.call-graph-profile +# BASIC-NEXT: Type: SHT_RELA +# BASIC-NEXT: Link: .symtab +# BASIC-NEXT: Info: .llvm.call-graph-profile +# BASIC-NEXT: Relocations: +# BASIC-NEXT: - Symbol: foo +# BASIC-NEXT: Type: R_X86_64_NONE +# BASIC-NEXT: - Offset: 0x1 +# BASIC-NEXT: Symbol: bar +# BASIC-NEXT: Type: R_X86_64_NONE +# BASIC-NEXT: - Offset: 0x2 +# BASIC-NEXT: Symbol: bar +# BASIC-NEXT: Type: R_X86_64_NONE +# BASIC-NEXT: - Offset: 0x3 +# BASIC-NEXT: Symbol: foo +# BASIC-NEXT: Type: R_X86_64_NONE # BASIC-NEXT: Symbols: --- !ELF @@ -29,16 +41,28 @@ Class: ELFCLASS[[BITS]] Data: ELFDATA2[[ENCODE]] Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 89 - - From: 2 - To: 1 - Weight: 98 + - Weight: 89 + - Weight: 98 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x2 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x3 + Symbol: 1 + Type: R_X86_64_NONE Symbols: - Name: foo - Name: bar @@ -53,63 +77,130 @@ # INVALID-NEXT: Class: ELFCLASS32 # INVALID-NEXT: Data: ELFDATA2MSB # INVALID-NEXT: Type: ET_DYN +# INVALID-NEXT: Machine: EM_X86_64 # INVALID-NEXT: Sections: # INVALID-NEXT: - Name: .empty # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab -# INVALID-NEXT: - Name: .multiple.16.valid +# INVALID-NEXT: - Name: .multiple.8.valid # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab # INVALID-NEXT: Entries: -# INVALID-NEXT: - From: foo -# INVALID-NEXT: To: bar # INVALID-NEXT: Weight: 3 -# INVALID-NEXT: - Name: .non.multiple.16 +# INVALID-NEXT: - Name: .rela.multiple.8.valid +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .multiple.8.valid +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Name: .non.multiple.8 # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab -# INVALID-NEXT: Content: '0000000100000002000000000000000300' -# INVALID-NEXT: - Name: .multiple.16.invalid +# INVALID-NEXT: Content: '000000000000000300' +# INVALID-NEXT: - Name: .rela.non.multiple.8 +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .non.multiple.8 +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Name: .multiple.8.invalid # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab -# INVALID-NEXT: Content: 00112233445566778899AABBCCDDEEFF -# INVALID-NEXT: - Name: .unknown.symbol.1 -# INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE -# INVALID-NEXT: Link: .symtab -# INVALID-NEXT: Content: 000000FF000000020000000000000003 -# INVALID-NEXT: - Name: .unknown.symbol.2 -# INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE -# INVALID-NEXT: Link: .symtab -# INVALID-NEXT: Content: 00000001000000FF0000000000000003 +# INVALID-NEXT: Content: 008899AABBCCDDEEFF +# INVALID-NEXT: - Name: .rela.multiple.8.invalid +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .multiple.8.invalid +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: - Name: .link.to.symtable # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab # INVALID-NEXT: Entries: -# INVALID-NEXT: - From: foo -# INVALID-NEXT: To: bar -# INVALID-NEXT: Weight: 0 +# INVALID-NEXT: - Weight: 0 +# INVALID-NEXT: - Name: .rela.link.to.symtable +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .link.to.symtable +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: - Name: .link.to.non.symtable.1 # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE -# INVALID-NEXT: Content: '00000001000000020000000000000000' +# INVALID-NEXT: Entries: +# INVALID-NEXT: - Weight: 0 +# INVALID-NEXT: - Name: .rela.link.to.non.symtable.1 +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .link.to.non.symtable.1 +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: - Name: .link.to.non.symtable.2 # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .empty -# INVALID-NEXT: Content: '00000001000000020000000000000000' +# INVALID-NEXT: Entries: +# INVALID-NEXT: - Weight: 0 +# INVALID-NEXT: - Name: .rela.link.to.non.symtable.2 +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .link.to.non.symtable.2 +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: - Name: .zero.entry.size # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab # INVALID-NEXT: EntSize: 0x0 # INVALID-NEXT: Entries: -# INVALID-NEXT: - From: foo -# INVALID-NEXT: To: bar -# INVALID-NEXT: Weight: 0 +# INVALID-NEXT: - Weight: 0 +# INVALID-NEXT: - Name: .rela.zero.entry.size +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .zero.entry.size +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: - Name: .invalid.entry.size # INVALID-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE # INVALID-NEXT: Link: .symtab # INVALID-NEXT: EntSize: 0x1 # INVALID-NEXT: Entries: -# INVALID-NEXT: - From: foo -# INVALID-NEXT: To: bar -# INVALID-NEXT: Weight: 0 +# INVALID-NEXT: - Weight: 0 +# INVALID-NEXT: - Name: .rela.invalid.entry.size +# INVALID-NEXT: Type: SHT_RELA +# INVALID-NEXT: Link: .symtab +# INVALID-NEXT: Info: .invalid.entry.size +# INVALID-NEXT: Relocations: +# INVALID-NEXT: - Symbol: foo +# INVALID-NEXT: Type: R_X86_64_NONE +# INVALID-NEXT: - Offset: 0x1 +# INVALID-NEXT: Symbol: bar +# INVALID-NEXT: Type: R_X86_64_NONE # INVALID-NEXT: Symbols: # INVALID-NEXT: - Name: foo # INVALID-NEXT: - Name: bar @@ -119,6 +210,7 @@ Class: ELFCLASS32 Data: ELFDATA2MSB Type: ET_DYN + Machine: EM_X86_64 Sections: ## Case 1: Content is empty. - Name: .empty @@ -129,67 +221,115 @@ ## using the "Content" property otherwise. ## TODO: Teach yaml2obj to accept 'Size' key for SHT_LLVM_CALL_GRAPH_PROFILE ## sections and use Entries for cases below. - - Name: .multiple.16.valid - Type: SHT_LLVM_CALL_GRAPH_PROFILE - Content: "00000001000000020000000000000003" - - Name: .non.multiple.16 + - Name: .multiple.8.valid Type: SHT_LLVM_CALL_GRAPH_PROFILE - Content: "0000000100000002000000000000000300" - - Name: .multiple.16.invalid + Content: "0000000000000003" + - Name: .rela.multiple.8.valid + Type: SHT_RELA + Info: .multiple.8.valid + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE + - Name: .non.multiple.8 Type: SHT_LLVM_CALL_GRAPH_PROFILE - Content: "00112233445566778899AABBCCDDEEFF" -## Case 3: Check we use the "Content" property when unable to match a -## symbol index to a symbol. - - Name: .unknown.symbol.1 + Content: "000000000000000300" + - Name: .rela.non.multiple.8 + Type: SHT_RELA + Info: .non.multiple.8 + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE + - Name: .multiple.8.invalid Type: SHT_LLVM_CALL_GRAPH_PROFILE - Entries: - - From: 0xff - To: 2 - Weight: 3 - - Name: .unknown.symbol.2 - Type: SHT_LLVM_CALL_GRAPH_PROFILE - Entries: - - From: 1 - To: 0xff - Weight: 3 + Content: "008899AABBCCDDEEFF" + - Name: .rela.multiple.8.invalid + Type: SHT_RELA + Info: .multiple.8.invalid + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE ## Case 4: Check we use the "Content" property when a linked section ## is not a symbol table. - Name: .link.to.symtable Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 + - Name: .rela.link.to.symtable + Type: SHT_RELA + Info: .link.to.symtable + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE - Name: .link.to.non.symtable.1 Type: SHT_LLVM_CALL_GRAPH_PROFILE Link: 0 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 + - Name: .rela.link.to.non.symtable.1 + Type: SHT_RELA + Info: .link.to.non.symtable.1 + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE - Name: .link.to.non.symtable.2 Type: SHT_LLVM_CALL_GRAPH_PROFILE Link: 1 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 + - Name: .rela.link.to.non.symtable.2 + Type: SHT_RELA + Info: .link.to.non.symtable.2 + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE ## Case 5: Check we can dump a section that has a sh_entsize that is not a multiple of 16. ## Check that in these cases we print the "EntSize" key. - Name: .zero.entry.size Type: SHT_LLVM_CALL_GRAPH_PROFILE EntSize: 0 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 + - Name: .rela.zero.entry.size + Type: SHT_RELA + Info: .zero.entry.size + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE - Name: .invalid.entry.size Type: SHT_LLVM_CALL_GRAPH_PROFILE EntSize: 1 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 + - Name: .rela.invalid.entry.size + Type: SHT_RELA + Info: .invalid.entry.size + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE Symbols: - Name: foo - Name: bar diff --git a/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml b/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml --- a/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml +++ b/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml @@ -3,13 +3,13 @@ ## Test that the content of SHT_LLVM_CALL_GRAPH_PROFILE sections ## for 32/64-bit little/big endian targets is correct. # RUN: yaml2obj --docnum=1 -D BITS=64 -D ENCODE=LSB %s -o %t.le64 -# RUN: llvm-readobj --cg-profile --sections --section-data %t.le64 | FileCheck %s --check-prefixes=BASIC,BASIC-LE -# RUN: yaml2obj --docnum=1 -D BITS=64 -D ENCODE=MSB %s -o %t.be64 -# RUN: llvm-readobj --cg-profile --sections --section-data %t.be64 | FileCheck %s --check-prefixes=BASIC,BASIC-BE -# RUN: yaml2obj --docnum=1 -D BITS=32 -D ENCODE=LSB %s -o %t.le32 -# RUN: llvm-readobj --cg-profile --sections --section-data %t.le32 | FileCheck %s --check-prefixes=BASIC,BASIC-LE -# RUN: yaml2obj --docnum=1 -D BITS=32 -D ENCODE=MSB %s -o %t.be32 -# RUN: llvm-readobj --cg-profile --sections --section-data %t.be32 | FileCheck %s --check-prefixes=BASIC,BASIC-BE +# RUN: llvm-readobj --cg-profile --sections --section-data %t.le64 | FileCheck %s --check-prefixes=BASIC,BASIC64,BASIC-LE +# RUN: yaml2obj --docnum=1 -D BITS=64 -D ENCODE=MSB %s -o %t.be64 +# RUN: llvm-readobj --cg-profile --sections --section-data %t.be64 | FileCheck %s --check-prefixes=BASIC,BASIC64,BASIC-BE +# RUN: yaml2obj --docnum=1 -D BITS=32 -D ENCODE=LSB %s -o %t.le32 +# RUN: llvm-readobj --cg-profile --sections --section-data %t.le32 | FileCheck %s --check-prefixes=BASIC,BASIC32,BASIC-LE +# RUN: yaml2obj --docnum=1 -D BITS=32 -D ENCODE=MSB %s -o %t.be32 +# RUN: llvm-readobj --cg-profile --sections --section-data %t.be32 | FileCheck %s --check-prefixes=BASIC,BASIC32,BASIC-BE # BASIC: Name: .llvm.call-graph-profile # BASIC-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE @@ -17,20 +17,55 @@ # BASIC-NEXT: ] # BASIC-NEXT: Address: 0x0 # BASIC-NEXT: Offset: -# BASIC-NEXT: Size: 32 +# BASIC-NEXT: Size: 16 ## Check that we link SHT_LLVM_CALL_GRAPH_PROFILE section with .symtab by default. # BASIC-NEXT: Link: [[SYMTABNDX:.*]] # BASIC-NEXT: Info: 0 # BASIC-NEXT: AddressAlignment: 0 ## Check that the entry size is set to 16 by default. -# BASIC-NEXT: EntrySize: 16 +# BASIC-NEXT: EntrySize: 8 # BASIC-NEXT: SectionData ( -# BASIC-LE-NEXT: 0000: 01000000 02000000 59000000 00000000 -# BASIC-LE-NEXT: 0010: 02000000 01000000 62000000 00000000 -# BASIC-BE-NEXT: 0000: 00000001 00000002 00000000 00000059 -# BASIC-BE-NEXT: 0010: 00000002 00000001 00000000 00000062 +# BASIC-LE-NEXT: 0000: 59000000 00000000 62000000 00000000 +# BASIC-BE-NEXT: 0000: 00000000 00000059 00000000 00000062 # BASIC-NEXT: ) # BASIC-NEXT: } +# BASIC-NEXT: Section { +# BASIC-NEXT: Index: 2 +# BASIC-NEXT: Name: .rela.llvm.call-graph-profile (1) +# BASIC-NEXT: Type: SHT_RELA (0x4) +# BASIC-NEXT: Flags [ (0x0) +# BASIC-NEXT: ] +# BASIC-NEXT: Address: 0x0 +# BASIC64: Offset: 0x50 +# BASIC64-NEXT: Size: 96 +# BASIC32: Offset: 0x44 +# BASIC32-NEXT: Size: 48 +# BASIC-NEXT: Link: 3 +# BASIC-NEXT: Info: 1 +# BASIC-NEXT: AddressAlignment: 0 +# BASIC64: EntrySize: 24 +# BASIC32: EntrySize: 12 +# BASIC-NEXT: SectionData ( +# BASIC64-LE: 0000: 00000000 00000000 00000000 01000000 +# BASIC64-LE-NEXT: 0010: 00000000 00000000 01000000 00000000 +# BASIC64-LE-NEXT: 0020: 00000000 02000000 00000000 00000000 +# BASIC64-LE-NEXT: 0030: 02000000 00000000 00000000 02000000 +# BASIC64-LE-NEXT: 0040: 00000000 00000000 03000000 00000000 +# BASIC64-LE-NEXT: 0050: 00000000 01000000 00000000 00000000 +# BASIC64-BE: 0000: 00000000 00000000 00000001 00000000 +# BASIC64-BE-NEXT: 0010: 00000000 00000000 00000000 00000001 +# BASIC64-BE-NEXT: 0020: 00000002 00000000 00000000 00000000 +# BASIC64-BE-NEXT: 0030: 00000000 00000002 00000002 00000000 +# BASIC64-BE-NEXT: 0040: 00000000 00000000 00000000 00000003 +# BASIC64-BE-NEXT: 0050: 00000001 00000000 00000000 00000000 +# BASIC32-LE: 0000: 00000000 00010000 00000000 01000000 +# BASIC64-LE-NEXT: 0010: 00020000 00000000 02000000 00020000 +# BASIC64-LE-NEXT: 0020: 00000000 03000000 00010000 00000000 +# BASIC64-BE: 0000: 00000000 00000100 00000000 00000001 +# BASIC64-BE-NEXT: 0010: 00000200 00000000 00000002 00000200 +# BASIC64-BE-NEXT: 0020: 00000000 00000003 00000100 00000000 +# BASIC: ) +# BASIC-NEXT: } # BASIC-NEXT: Section { # BASIC-NEXT: Index: [[SYMTABNDX]] # BASIC-NEXT: Name: .symtab @@ -53,16 +88,28 @@ Class: ELFCLASS[[BITS]] Data: ELFDATA2[[ENCODE]] Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 89 - - From: 2 - To: 1 - Weight: 98 + - Weight: 89 + - Weight: 98 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x2 + Symbol: 2 + Type: R_X86_64_NONE + - Offset: 0x3 + Symbol: 1 + Type: R_X86_64_NONE Symbols: - Name: foo - Name: bar @@ -113,18 +160,30 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: ## Case 1: Test we can use symbol names to describe an entry. - - From: foo - To: bar - Weight: 10 + - Weight: 10 ## Case 2: Test we can refer to symbols with suffixes. - - From: foo - To: 'foo (1)' - Weight: 30 + - Weight: 30 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: foo + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: bar + Type: R_X86_64_NONE + - Offset: 0x2 + Symbol: foo + Type: R_X86_64_NONE + - Offset: 0x3 + Symbol: 'foo (1)' + Type: R_X86_64_NONE Symbols: - Name: foo - Name: bar @@ -152,21 +211,29 @@ ## Check we can't reference unknown symbols by name. # RUN: not yaml2obj --docnum=5 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN-NAME # RUN: not yaml2obj --docnum=6 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN-NAME -# UNKNOWN-NAME: error: unknown symbol referenced: 'bar' by YAML section '.llvm.call-graph-profile' +# UNKNOWN-NAME: error: unknown symbol referenced: 'bar' by YAML section '.rela.llvm.call-graph-profile' --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE ## The first symbol is valid, but the second is unknown. Entries: - - From: foo - To: bar - Weight: 10 + - Weight: 10 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: foo + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: bar + Type: R_X86_64_NONE Symbols: - Name: foo @@ -175,14 +242,22 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE ## The first symbol is unknown, but the second is valid. Entries: - - From: bar - To: foo - Weight: 10 + - Weight: 10 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: bar + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: foo + Type: R_X86_64_NONE Symbols: - Name: foo @@ -192,21 +267,49 @@ # UNKNOWN-INDEX: Name: .llvm.call-graph-profile # UNKNOWN-INDEX: SectionData ( -# UNKNOWN-INDEX-NEXT: 0000: 01000000 02000000 03000000 00000000 | +# UNKNOWN-INDEX-NEXT: 0000: 03000000 00000000 # UNKNOWN-INDEX-NEXT: ) +# UNKNOWN-INDEX-NEXT: } +# UNKNOWN-INDEX-NEXT: Section { +# UNKNOWN-INDEX-NEXT: Index: 2 +# UNKNOWN-INDEX-NEXT: Name: .rela.llvm.call-graph-profile (1) +# UNKNOWN-INDEX-NEXT: Type: SHT_RELA (0x4) +# UNKNOWN-INDEX-NEXT: Flags [ (0x0) +# UNKNOWN-INDEX-NEXT: ] +# UNKNOWN-INDEX-NEXT: Address: 0x0 +# UNKNOWN-INDEX-NEXT: Offset: 0x48 +# UNKNOWN-INDEX-NEXT: Size: 48 +# UNKNOWN-INDEX-NEXT: Link: 0 +# UNKNOWN-INDEX-NEXT: Info: 1 +# UNKNOWN-INDEX-NEXT: AddressAlignment: 0 +# UNKNOWN-INDEX-NEXT: EntrySize: 24 +# UNKNOWN-INDEX-NEXT: SectionData ( +# UNKNOWN-INDEX-NEXT: 0000: 00000000 00000000 00000000 01000000 +# UNKNOWN-INDEX-NEXT: 0010: 00000000 00000000 01000000 00000000 +# UNKNOWN-INDEX-NEXT: 0020: 00000000 02000000 00000000 00000000 +# UNKNOWN-INDEX-NEXT: ) +# UNKNOWN-INDEX-NEXT: } --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 3 + - Weight: 3 + - Name: .rela.llvm.call-graph-profile + Type: SHT_RELA + Info: .llvm.call-graph-profile + Relocations: + - Symbol: 1 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 2 + Type: R_X86_64_NONE ## Check we can use the "Content" key with the "Size" key when the size is greater ## than or equal to the content size. @@ -221,6 +324,7 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN + Machine: EM_X86_64 Sections: - Name: .llvm.foo Type: SHT_LLVM_CALL_GRAPH_PROFILE diff --git a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml --- a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml +++ b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml @@ -367,7 +367,7 @@ # RUN: llvm-readelf %t7 --section-headers | FileCheck %s --check-prefix=LINK-IMPLICIT # LINK-IMPLICIT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# LINK-IMPLICIT: [ 1] .cgp LLVM_CALL_GRAPH_PROFILE 0000000000000000 000040 000000 10 0 0 0 +# LINK-IMPLICIT: [ 1] .cgp LLVM_CALL_GRAPH_PROFILE 0000000000000000 000040 000000 08 0 0 0 # LINK-IMPLICIT-NEXT: [ 2] .llvm_addrsig LLVM_ADDRSIG 0000000000000000 000040 000000 00 0 0 0 # LINK-IMPLICIT-NEXT: [ 3] .group GROUP 0000000000000000 000040 000000 04 0 0 0 # LINK-IMPLICIT-NEXT: [ 4] .rela RELA 0000000000000000 000040 000000 18 0 0 0 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -357,6 +357,7 @@ const Elf_Shdr *DotSymtabSec = nullptr; const Elf_Shdr *DotDynsymSec = nullptr; const Elf_Shdr *DotCGProfileSec = nullptr; + const Elf_Shdr *DotCGProfileSecRela = nullptr; const Elf_Shdr *DotAddrsigSec = nullptr; DenseMap> ShndxTables; Optional SONameOffset; @@ -1774,7 +1775,9 @@ return; typename ELFT::ShdrRange Sections = cantFail(Obj.sections()); - for (const Elf_Shdr &Sec : Sections) { + uint32_t DotCGProfileSecIndex = 0; + for (unsigned I = 0, Size = Sections.size(); I < Size; ++I) { + const Elf_Shdr &Sec = Sections[I]; switch (Sec.sh_type) { case ELF::SHT_SYMTAB: if (!DotSymtabSec) @@ -1839,8 +1842,10 @@ SymbolVersionNeedSection = &Sec; break; case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: - if (!DotCGProfileSec) + if (!DotCGProfileSec) { DotCGProfileSec = &Sec; + DotCGProfileSecIndex = I; + } break; case ELF::SHT_LLVM_ADDRSIG: if (!DotAddrsigSec) @@ -1849,6 +1854,15 @@ } } + // Following LLD lead and doing a seperate loop in case relocation section + // comes before section it applies to. + for (const Elf_Shdr &Sec : Sections) { + if (Sec.sh_info == DotCGProfileSecIndex) { + DotCGProfileSecRela = &Sec; + break; + } + } + loadDynamicTable(); } @@ -6700,7 +6714,7 @@ template void LLVMELFDumper::printCGProfile() { ListScope L(W, "CGProfile"); - if (!this->DotCGProfileSec) + if (!this->DotCGProfileSec || !this->DotCGProfileSecRela) return; Expected> CGProfileOrErr = @@ -6713,12 +6727,29 @@ return; } - for (const Elf_CGProfile &CGPE : *CGProfileOrErr) { + Expected CGProfileRelaOrError = + this->Obj.relas(*this->DotCGProfileSecRela); + if (!CGProfileRelaOrError) { + this->reportUniqueWarning( + "unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " + + toString(CGProfileOrErr.takeError()) + "with relocations."); + return; + } + assert(CGProfileRelaOrError->size() == (CGProfileOrErr->size() * 2) && + "Number of from/to pairs does not match number of frequencies."); + + auto GetIndex = [&](uint32_t Index) -> uint32_t { + const Elf_Rel_Impl &Rel = (*CGProfileRelaOrError)[Index]; + return Rel.getSymbol(this->Obj.isMips64EL()); + }; + + for (uint32_t I = 0, Size = CGProfileOrErr->size(); I < Size; ++I) { + const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I]; + uint32_t From = GetIndex(I * 2); + uint32_t To = GetIndex(I * 2 + 1); DictScope D(W, "CGProfileEntry"); - W.printNumber("From", this->getStaticSymbolName(CGPE.cgp_from), - CGPE.cgp_from); - W.printNumber("To", this->getStaticSymbolName(CGPE.cgp_to), - CGPE.cgp_to); + W.printNumber("From", this->getStaticSymbolName(From), From); + W.printNumber("To", this->getStaticSymbolName(To), To); W.printNumber("Weight", CGPE.cgp_weight); } } diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -985,41 +985,31 @@ if (!ContentOrErr) return ContentOrErr.takeError(); ArrayRef Content = *ContentOrErr; - + const uint32_t SizeOfEntry = ELFYAML::getDefaultShEntSize( + Obj.getHeader().e_machine, S->Type, S->Name); // Dump the section by using the Content key when it is truncated. // There is no need to create either "Content" or "Entries" fields when the // section is empty. - if (Content.empty() || Content.size() % 16 != 0) { + if (Content.empty() || Content.size() % SizeOfEntry != 0) { if (!Content.empty()) S->Content = yaml::BinaryRef(Content); return S.release(); } - std::vector Entries(Content.size() / 16); + std::vector Entries(Content.size() / + SizeOfEntry); DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); DataExtractor::Cursor Cur(0); - auto ReadEntry = [&](ELFYAML::CallGraphEntry &E) { - uint32_t FromSymIndex = Data.getU32(Cur); - uint32_t ToSymIndex = Data.getU32(Cur); + auto ReadEntry = [&](ELFYAML::CallGraphEntryWeight &E) { E.Weight = Data.getU64(Cur); if (!Cur) { consumeError(Cur.takeError()); return false; } - - Expected From = getSymbolName(Shdr->sh_link, FromSymIndex); - Expected To = getSymbolName(Shdr->sh_link, ToSymIndex); - if (From && To) { - E.From = *From; - E.To = *To; - return true; - } - consumeError(From.takeError()); - consumeError(To.takeError()); - return false; + return true; }; - for (ELFYAML::CallGraphEntry &E : Entries) { + for (ELFYAML::CallGraphEntryWeight &E : Entries) { if (ReadEntry(E)) continue; S->Content = yaml::BinaryRef(Content);