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]; + uint32_t fromIndex = getIndex(obj, i * 2); + uint32_t 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,11 @@ 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, /*sizeof(Elf_CGProfile_Impl<>)*/ 8); + 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,10 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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,10 @@ return AVR::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { @@ -67,4 +71,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,9 @@ const MCAsmLayout &Layout) const override { return false; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } 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,10 @@ return Infos[Kind - FirstTargetFixupKind]; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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,10 @@ return Lanai::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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,10 @@ return MSP430::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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 +87,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,10 @@ return PPC::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = { // name offset bits flags @@ -224,6 +228,7 @@ } Optional getFixupKind(StringRef Name) const override; + StringRef getNoneRelcationName() const override; }; class XCOFFPPCAsmBackend : public PPCAsmBackend { @@ -239,6 +244,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,10 @@ return Sparc::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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,9 @@ unsigned getNumFixupKinds() const override { return SystemZ::NumTargetFixupKinds; } + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } 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,10 @@ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + StringRef getNoneRelcationName() const override { + llvm_unreachable("getNoneRelcationName() unimplemented"); + } + 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 @@ -46,9 +58,7 @@ # RUN: llvm-readobj %t2.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=LLVM-ERR # 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: ] +# LLVM-ERR: warning: '[[FILE]]': unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has invalid sh_entsize: expected 8, but got 15 ## Check we report a warning when unable to dump a name of a symbol. # RUN: yaml2obj %s --docnum=2 -o %t3.o @@ -69,7 +79,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 +90,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' @@ -100,3 +126,132 @@ - StName: 1 ## 'A' - StName: 0xFF ## An arbitrary currupted index in the string table. - StName: 3 ## 'B' + +## Check we report a warning when relocation section is not present. +# RUN: yaml2obj %s --docnum=3 -o %t4.o +# RUN: llvm-readobj %t4.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t4.o --check-prefix=LLVM-NO-RELOC +# RUN: llvm-readobj %t4.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t4.o --check-prefix=LLVM-NO-RELOC + +# LLVM-NO-RELOC: warning: '[[FILE]]': Relocation section for a call graph section doesn't exist +# LLVM-NO-RELOC-NEXT: CGProfile [ +# LLVM-NO-RELOC-NEXT: CGProfileEntry { +# LLVM-NO-RELOC-NEXT: Weight: 89 +# LLVM-NO-RELOC-NEXT: } +# LLVM-NO-RELOC-NEXT: CGProfileEntry { +# LLVM-NO-RELOC-NEXT: Weight: 98 +# LLVM-NO-RELOC-NEXT: } +# LLVM-NO-RELOC-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .llvm.call-graph-profile + Type: SHT_LLVM_CALL_GRAPH_PROFILE + Entries: + - Weight: 89 + - Weight: 98 + EntSize: [[ENTSIZE=]] +Symbols: + - Name: foo + - Name: bar + +## Check we report a warning when relocation section entries do not match call graph entries. +# RUN: yaml2obj %s --docnum=4 -o %t5.o +# RUN: llvm-readobj %t5.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t5.o --check-prefix=LLVM-RELOC-GRAPH-NOT-MATCH +# RUN: llvm-readobj %t5.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t5.o --check-prefix=LLVM-RELOC-GRAPH-NOT-MATCH + +# LLVM-RELOC-GRAPH-NOT-MATCH: warning: '[[FILE]]': Number of from/to pairs does not match number of frequencies +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: CGProfile [ +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: CGProfileEntry { +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: Weight: 89 +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: } +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: CGProfileEntry { +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: Weight: 98 +# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: } +# LLVM-RELOC-GRAPH-NOT-MATCH-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: + - 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 + - Offset: 0x4 + Symbol: foo + Type: R_X86_64_NONE +Symbols: + - Name: foo + - Name: bar + +## Check we report a warning when relocation section cant't be loaded. +# RUN: yaml2obj %s --docnum=5 -o %t6.o +# 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 32with relocations +# LLVM-RELOC-WRONG-SIZE-NEXT: CGProfile [ +# LLVM-RELOC-WRONG-SIZE-NEXT: CGProfileEntry { +# LLVM-RELOC-WRONG-SIZE-NEXT: Weight: 89 +# LLVM-RELOC-WRONG-SIZE-NEXT: } +# LLVM-RELOC-WRONG-SIZE-NEXT: CGProfileEntry { +# LLVM-RELOC-WRONG-SIZE-NEXT: Weight: 98 +# LLVM-RELOC-WRONG-SIZE-NEXT: } +# LLVM-RELOC-WRONG-SIZE-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: + - 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 + EntSize: 32 +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 --- 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,8 @@ # 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: Symbols: --- !ELF @@ -33,12 +29,8 @@ - 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 Symbols: - Name: foo - Name: bar @@ -57,59 +49,45 @@ # 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: .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: .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: .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: .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: .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: .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: .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: Symbols: # INVALID-NEXT: - Name: foo # INVALID-NEXT: - Name: bar @@ -129,67 +107,43 @@ ## 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: .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: .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" ## 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: .link.to.non.symtable.1 Type: SHT_LLVM_CALL_GRAPH_PROFILE Link: 0 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 - Name: .link.to.non.symtable.2 Type: SHT_LLVM_CALL_GRAPH_PROFILE Link: 1 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 ## 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: .invalid.entry.size Type: SHT_LLVM_CALL_GRAPH_PROFILE EntSize: 1 Entries: - - From: 1 - To: 2 - Weight: 0 + - Weight: 0 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 @@ -4,11 +4,11 @@ ## 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: 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: 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: 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 # BASIC: Name: .llvm.call-graph-profile @@ -17,33 +17,27 @@ # 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: [[SYMTABNDX]] -# BASIC-NEXT: Name: .symtab +# BASIC-NEXT: Index: [[SYMTABNDX]] +# BASIC-NEXT: Name: .symtab # BASIC: CGProfile [ # BASIC-NEXT: CGProfileEntry { -# BASIC-NEXT: From: foo (1) -# BASIC-NEXT: To: bar (2) # BASIC-NEXT: Weight: 89 # BASIC-NEXT: } # BASIC-NEXT: CGProfileEntry { -# BASIC-NEXT: From: bar (2) -# BASIC-NEXT: To: foo (1) # BASIC-NEXT: Weight: 98 # BASIC-NEXT: } # BASIC-NEXT: ] @@ -57,12 +51,8 @@ - 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 Symbols: - Name: foo - Name: bar @@ -97,13 +87,9 @@ # SYMBOL-NAMES: CGProfile [ # SYMBOL-NAMES-NEXT: CGProfileEntry { -# SYMBOL-NAMES-NEXT: From: foo (1) -# SYMBOL-NAMES-NEXT: To: bar (2) # SYMBOL-NAMES-NEXT: Weight: 10 # SYMBOL-NAMES-NEXT: } # SYMBOL-NAMES-NEXT: CGProfileEntry { -# SYMBOL-NAMES-NEXT: From: foo (1) -# SYMBOL-NAMES-NEXT: To: foo (3) # SYMBOL-NAMES-NEXT: Weight: 30 # SYMBOL-NAMES-NEXT: } # SYMBOL-NAMES-NEXT: ] @@ -118,13 +104,9 @@ 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 Symbols: - Name: foo - Name: bar @@ -149,51 +131,15 @@ Type: SHT_LLVM_CALL_GRAPH_PROFILE Content: "11223344" -## 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' - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN -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 -Symbols: - - Name: foo - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN -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 -Symbols: - - Name: foo - ## Check we can specify arbitrary symbol indexes for an SHT_LLVM_CALL_GRAPH_PROFILE section entry. -# RUN: yaml2obj --docnum=7 %s -o %t.unk +# RUN: yaml2obj --docnum=5 %s -o %t.unk # RUN: llvm-readobj --sections --section-data %t.unk | FileCheck %s --check-prefix=UNKNOWN-INDEX # 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: } --- !ELF FileHeader: @@ -204,14 +150,12 @@ - Name: .llvm.call-graph-profile Type: SHT_LLVM_CALL_GRAPH_PROFILE Entries: - - From: 1 - To: 2 - Weight: 3 + - Weight: 3 ## Check we can use the "Content" key with the "Size" key when the size is greater ## than or equal to the content size. -# RUN: not yaml2obj --docnum=8 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \ +# RUN: not yaml2obj --docnum=6 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \ # RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR # CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size @@ -230,11 +174,11 @@ Content: [[CONTENT=]] Entries: [[ENTRIES=]] -# RUN: yaml2obj --docnum=8 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o +# RUN: yaml2obj --docnum=6 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o # RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \ # RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011" -# RUN: yaml2obj --docnum=8 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o +# RUN: yaml2obj --docnum=6 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o # RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \ # RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100" @@ -255,21 +199,21 @@ ## Check we can use the "Size" key alone to create the section. -# RUN: yaml2obj --docnum=8 -DSIZE=3 %s -o %t.size.o +# RUN: yaml2obj --docnum=6 -DSIZE=3 %s -o %t.size.o # RUN: llvm-readobj --sections --section-data %t.size.o | \ # RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000" ## Check we can use the "Content" key alone to create the section. -# RUN: yaml2obj --docnum=8 -DCONTENT="'112233'" %s -o %t.content.o +# RUN: yaml2obj --docnum=6 -DCONTENT="'112233'" %s -o %t.content.o # RUN: llvm-readobj --sections --section-data %t.content.o | \ # RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233" ## Check we can't use the "Entries" key together with the "Content" or "Size" keys. -# RUN: not yaml2obj --docnum=8 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \ +# RUN: not yaml2obj --docnum=6 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \ # RUN: FileCheck %s --check-prefix=ENTRIES-ERR -# RUN: not yaml2obj --docnum=8 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \ +# RUN: not yaml2obj --docnum=6 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \ # RUN: FileCheck %s --check-prefix=ENTRIES-ERR # ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size" 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 @@ -318,6 +318,12 @@ void printRelocatableStackSizes(std::function PrintHeader); void printNonRelocatableStackSizes(std::function PrintHeader); + /// Retrieves sections with corresponding relocation sections based on + /// IsMatch. + void getSectionAndRelocations( + std::function IsMatch, + llvm::MapVector &SecToRelocMap); + const object::ELFObjectFile &ObjF; const ELFFile &Obj; StringRef FileName; @@ -356,7 +362,6 @@ const Elf_GnuHash *GnuHashTable = nullptr; const Elf_Shdr *DotSymtabSec = nullptr; const Elf_Shdr *DotDynsymSec = nullptr; - const Elf_Shdr *DotCGProfileSec = nullptr; const Elf_Shdr *DotAddrsigSec = nullptr; DenseMap> ShndxTables; Optional SONameOffset; @@ -1838,10 +1843,6 @@ if (!SymbolVersionNeedSection) SymbolVersionNeedSection = &Sec; break; - case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: - if (!DotCGProfileSec) - DotCGProfileSec = &Sec; - break; case ELF::SHT_LLVM_ADDRSIG: if (!DotAddrsigSec) DotAddrsigSec = &Sec; @@ -5898,28 +5899,15 @@ } template -void ELFDumper::printRelocatableStackSizes( - std::function PrintHeader) { - // Build a map between stack size sections and their corresponding relocation - // sections. - llvm::MapVector StackSizeRelocMap; +void ELFDumper::getSectionAndRelocations( + std::function IsMatch, + llvm::MapVector &SecToRelocMap) { for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { - StringRef SectionName; - if (Expected NameOrErr = Obj.getSectionName(Sec)) - SectionName = *NameOrErr; - else - consumeError(NameOrErr.takeError()); - - // A stack size section that we haven't encountered yet is mapped to the - // null section until we find its corresponding relocation section. - if (SectionName == ".stack_sizes") - if (StackSizeRelocMap - .insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr)) + if (IsMatch(Sec)) + if (SecToRelocMap.insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr)) .second) continue; - // Check relocation sections if they are relocating contents of a - // stack sizes section. if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL) continue; @@ -5930,14 +5918,28 @@ toString(RelSecOrErr.takeError())); continue; } - const Elf_Shdr *ContentsSec = *RelSecOrErr; - if (this->getPrintableSectionName(**RelSecOrErr) != ".stack_sizes") - continue; - - // Insert a mapping from the stack sizes section to its relocation section. - StackSizeRelocMap[ContentsSec] = &Sec; + if (IsMatch(*ContentsSec)) + SecToRelocMap[ContentsSec] = &Sec; } +} + +template +void ELFDumper::printRelocatableStackSizes( + std::function PrintHeader) { + // Build a map between stack size sections and their corresponding relocation + // sections. + llvm::MapVector StackSizeRelocMap; + auto IsMatch = [&](const Elf_Shdr &Sec) -> bool { + StringRef SectionName; + if (Expected NameOrErr = Obj.getSectionName(Sec)) + SectionName = *NameOrErr; + else + consumeError(NameOrErr.takeError()); + + return SectionName == ".stack_sizes"; + }; + getSectionAndRelocations(IsMatch, StackSizeRelocMap); for (const auto &StackSizeMapEntry : StackSizeRelocMap) { PrintHeader(); @@ -6699,27 +6701,66 @@ } template void LLVMELFDumper::printCGProfile() { - ListScope L(W, "CGProfile"); - if (!this->DotCGProfileSec) - return; + llvm::MapVector SecToRelocMap; - Expected> CGProfileOrErr = - this->Obj.template getSectionContentsAsArray( - *this->DotCGProfileSec); - if (!CGProfileOrErr) { - this->reportUniqueWarning( - "unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " + - toString(CGProfileOrErr.takeError())); - return; - } + auto IsMatch = [](const Elf_Shdr &Sec) -> bool { + return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE; + }; + this->getSectionAndRelocations(IsMatch, SecToRelocMap); + + for (const auto &CGMapEntry : SecToRelocMap) { + const Elf_Shdr *CGSection = CGMapEntry.first; + const Elf_Shdr *CGRelSection = CGMapEntry.second; - for (const Elf_CGProfile &CGPE : *CGProfileOrErr) { - 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("Weight", CGPE.cgp_weight); + Expected> CGProfileOrErr = + this->Obj.template getSectionContentsAsArray(*CGSection); + if (!CGProfileOrErr) { + this->reportUniqueWarning( + "unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: " + + toString(CGProfileOrErr.takeError())); + return; + } + + Elf_Rela_Range CGProfileRela; + bool UseReloc = (CGRelSection != nullptr); + if (UseReloc) { + Expected CGProfileRelaOrError = + this->Obj.relas(*CGRelSection); + if (!CGProfileRelaOrError) { + this->reportUniqueWarning("unable to load relocations for " + "SHT_LLVM_CALL_GRAPH_PROFILE section: " + + toString(CGProfileRelaOrError.takeError()) + + "with relocations"); + UseReloc = false; + } else + CGProfileRela = *CGProfileRelaOrError; + + if (UseReloc && CGProfileRela.size() != (CGProfileOrErr->size() * 2)) { + this->reportUniqueWarning( + "Number of from/to pairs does not match number of frequencies"); + UseReloc = false; + } + } else + this->reportUniqueWarning( + "Relocation section for a call graph section doesn't exist"); + + auto GetIndex = [&](uint32_t Index) -> uint32_t { + const Elf_Rel_Impl &Rel = CGProfileRela[Index]; + return Rel.getSymbol(this->Obj.isMips64EL()); + }; + + ListScope L(W, "CGProfile"); + for (uint32_t I = 0, Size = CGProfileOrErr->size(); I < Size; ++I) { + const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I]; + DictScope D(W, "CGProfileEntry"); + if (UseReloc) { + uint32_t From = GetIndex(I * 2); + uint32_t To = GetIndex(I * 2 + 1); + 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);