[lld] a224c51 - [LLD][LLVM] CG Graph profile using relocations

Wenlei He via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 24 09:09:51 PDT 2021


Author: Alexander Yermolovich
Date: 2021-06-24T09:09:33-07:00
New Revision: a224c5199b327ed0efcdcd87b6dbf950cf4d9ee1

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

LOG: [LLD][LLVM] CG Graph profile using relocations

Currently when .llvm.call-graph-profile is created by llvm it explicitly encodes the symbol indices. This section is basically a black box for post processing tools. For example, if we run strip -s on the object files the symbol table changes, but indices in that section do not. In non-visible behavior indices point to wrong symbols. The visible behavior indices point outside of Symbol table: "invalid symbol index".

This patch changes the format by using R_*_NONE relocations to indicate the from/to symbols. The Frequency (Weight) will still be in the .llvm.call-graph-profile, but symbol information will be in relocation section. In LLD information from both sections is used to reconstruct call graph profile. Relocations themselves will never be applied.

With this approach post processing tools that handle relocations correctly work for this section also. Tools can add/remove symbols and as long as they handle relocation sections with this approach information stays correct.

Doing a quick experiment with clang-13.
The size went up from 107KB to 322KB, aggregate of all the input sections. Size of clang-13 binary is ~118MB. For users of -fprofile-use/-fprofile-sample-use the size of object files will go up slightly, it will not impact final binary size.

Reviewed By: jhenderson, MaskRay

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

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h
    llvm/include/llvm/BinaryFormat/ELF.h
    llvm/include/llvm/MC/MCELFStreamer.h
    llvm/include/llvm/Object/ELFTypes.h
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/lib/MC/MCELFStreamer.cpp
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/MC/ELF/cgprofile.s
    llvm/test/Object/multiple-sections.yaml
    llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
    llvm/test/tools/llvm-readobj/ELF/demangle.test
    llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml
    llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml
    llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
    llvm/tools/llvm-readobj/ELFDumper.cpp
    llvm/tools/obj2yaml/elf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index b654bb86d6806..a6aee7a52a53a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -856,12 +856,23 @@ static void readCallGraph(MemoryBufferRef mb) {
 }
 
 template <class ELFT> static void readCallGraphsFromObjectFiles() {
+  auto getIndex = [&](ObjFile<ELFT> *obj, uint32_t index) {
+    const Elf_Rel_Impl<ELFT, true> &rel = obj->cgProfileRela[index];
+    return rel.getSymbol(config->isMips64EL);
+  };
+
   for (auto file : objectFiles) {
     auto *obj = cast<ObjFile<ELFT>>(file);
-
-    for (const Elf_CGProfile_Impl<ELFT> &cgpe : obj->cgProfile) {
-      auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_from));
-      auto *toSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_to));
+    if (obj->cgProfileRela.empty())
+      continue;
+    if (obj->cgProfileRela.size() != obj->cgProfile.size() * 2)
+      fatal("number of relocations doesn't match Weights");
+    for (uint32_t i = 0, size = obj->cgProfile.size(); i < size; ++i) {
+      const Elf_CGProfile_Impl<ELFT> &cgpe = obj->cgProfile[i];
+      uint32_t fromIndex = getIndex(obj, i * 2);
+      uint32_t toIndex = getIndex(obj, i * 2 + 1);
+      auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(fromIndex));
+      auto *toSym = dyn_cast<Defined>(&obj->getSymbol(toIndex));
       if (!fromSym || !toSym)
         continue;
 

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3e0c1d77823fd..77636af6e1fba 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -571,15 +571,19 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
       CHECK(obj.getSectionStringTable(objSections), this);
 
   std::vector<ArrayRef<Elf_Word>> 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<Elf_CGProfile>(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,6 +669,13 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
       continue;
     const Elf_Shdr &sec = objSections[i];
 
+    if (cgProfileSectionIndex && sec.sh_info == cgProfileSectionIndex) {
+      if (sec.sh_type == SHT_RELA)
+        cgProfileRela = CHECK(getObj().relas(sec), this);
+      else
+        warn(toString(this) + ": unsupported call graph section type");
+    }
+
     if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
       this->sections[i] = createInputSection(sec);
 

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index f66d7a25d9549..31bffb91d2755 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -249,8 +249,10 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   // 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<Elf_CGProfile> cgProfile;
+  // SHT_LLVM_CALL_GRAPH_PROFILE relocations.
+  ArrayRef<Elf_Rela> cgProfileRela;
 
   // Get cached DWARF information.
   DWARFCache *getDwarf();

diff  --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 255fa1414191c..99ad345bbcc40 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -926,17 +926,17 @@ enum : unsigned {
   // 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/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index 280eb7ec92cfd..45179378e71c7 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -85,7 +85,7 @@ class MCELFStreamer : public MCObjectStreamer {
   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
index 6cd93efa41a9e..54ebd751d8d22 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -737,8 +737,6 @@ template <class ELFT> class Elf_Note_Iterator_Impl {
 
 template <class ELFT> 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
index 521bdee8b49c8..92a9f78ce7bfd 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -516,17 +516,13 @@ struct DependentLibrariesSection : Section {
 };
 
 // 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<std::vector<CallGraphEntry>> Entries;
+  Optional<std::vector<CallGraphEntryWeight>> Entries;
 
   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
 
@@ -738,7 +734,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
 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)
@@ -932,8 +928,8 @@ template <> struct MappingTraits<ELFYAML::LinkerOption> {
   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
 };
 
-template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
-  static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
+template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
+  static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
 };
 
 template <> struct MappingTraits<ELFYAML::Relocation> {

diff  --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 534c263d735c9..fec77d27eb9a4 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -1127,14 +1127,6 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
     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 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
     }
   }
 
-  if (CGProfileSection) {
-    uint64_t SecStart = W.OS.tell();
-    for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
-      W.write<uint32_t>(CGPE.From->getSymbol().getIndex());
-      W.write<uint32_t>(CGPE.To->getSymbol().getIndex());
-      W.write<uint64_t>(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 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
     return;
 
   unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
-  bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
+  const auto *Parent = cast<MCSectionELF>(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
index 5a6c042333dcc..76e69a65996e1 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -477,7 +477,8 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
   }
 }
 
-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,35 @@ void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
     }
     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<MCSymbolELF>(S)->setBinding(ELF::STB_WEAK);
+  const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext());
+  MCObjectStreamer::visitUsedExpr(*SRE);
+  if (Optional<std::pair<bool, std::string>> Err =
+          MCObjectStreamer::emitRelocDirective(
+              *MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(),
+              *getContext().getSubtargetInfo()))
+    report_fatal_error("Relocation for CG Profile could not be created: " +
+                       Err->second);
 }
 
 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
index 7890884711a88..f8f2f0c12020a 100644
--- 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"
@@ -1474,14 +1475,9 @@ void ELFState<ELFT>::writeSectionContent(
   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<uint32_t>(From, ELFT::TargetEndianness);
-    CBA.write<uint32_t>(To, ELFT::TargetEndianness);
+  for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {
     CBA.write<uint64_t>(E.Weight, ELFT::TargetEndianness);
-    SHeader.sh_size += 16;
+    SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);
   }
 }
 

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 31bae6bf1f333..af6247e9339ac 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1834,11 +1834,9 @@ void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
   IO.mapRequired("Value", Opt.Value);
 }
 
-void MappingTraits<ELFYAML::CallGraphEntry>::mapping(
-    IO &IO, ELFYAML::CallGraphEntry &E) {
+void MappingTraits<ELFYAML::CallGraphEntryWeight>::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/test/MC/ELF/cgprofile.s b/llvm/test/MC/ELF/cgprofile.s
index 7938c2db8ebb6..11c7464976db5 100644
--- a/llvm/test/MC/ELF/cgprofile.s
+++ b/llvm/test/MC/ELF/cgprofile.s
@@ -15,22 +15,46 @@ late3:
 .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 @@ late3:
 # 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/Object/multiple-sections.yaml b/llvm/test/Object/multiple-sections.yaml
index 07af9252e26a3..a0f8df7cfeb57 100644
--- a/llvm/test/Object/multiple-sections.yaml
+++ b/llvm/test/Object/multiple-sections.yaml
@@ -8,15 +8,16 @@
 # CHECK: VersionDefinitions [
 # CHECK: VersionRequirements [
 # CHECK: CGProfile [
+# CHECK: CGProfile [
 # CHECK: Addrsig [
 
 --- !ELF
-FileHeader:      
+FileHeader:
   Class:           ELFCLASS64
   Data:            ELFDATA2LSB
   Type:            ET_REL
   Machine:         EM_X86_64
-Sections:        
+Sections:
   - Name:            .symtab2
     Type:            SHT_SYMTAB
     Link:            .strtab
@@ -49,18 +50,18 @@ Sections:
   - Name:            .llvm.call-graph-profile
     Type:            SHT_LLVM_CALL_GRAPH_PROFILE
     Content:         ''
-    EntSize:         16
+    EntSize:         8
   - Name:            .llvm.call-graph-profile2
     Type:            SHT_LLVM_CALL_GRAPH_PROFILE
     Content:         ''
-    EntSize:         16
+    EntSize:         8
   - Name:            .llvm_addrsig
     Type:            SHT_LLVM_ADDRSIG
     Content:         ''
   - Name:            .llvm_addrsig2
     Type:            SHT_LLVM_ADDRSIG
     Content:         ''
-Symbols:         
+Symbols:
   - Name:            f
 DynamicSymbols: []
 ...

diff  --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
index 92539a4601d21..d0115b4c6c112 100644
--- 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 @@ 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:   foo
-        To:     bar
-        Weight: 89
-      - From:   bar
-        To:     foo
-        Weight: 98
+      - Weight: 89
+      - Weight: 98
     EntSize: [[ENTSIZE=<none>]]
+  - 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 @@ Symbols:
 # 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 @@ Symbols:
 # 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 @@ 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: 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 @@ Symbols:
   - StName: 1    ## 'A'
   - StName: 0xFF ## An arbitrary currupted index in the string table.
   - StName: 3    ## 'B'
+
+## Check we report a warning when a 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=<none>]]
+Symbols:
+  - Name: foo
+  - Name: bar
+
+## Check we report a warning when the number of relocation section entries does not match the number of 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=<none>]]
+  - 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 a 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 32
+# 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=<none>]]
+  - 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
index 4369a9e948122..25be40a72b94c 100644
--- a/llvm/test/tools/llvm-readobj/ELF/demangle.test
+++ b/llvm/test/tools/llvm-readobj/ELF/demangle.test
@@ -197,8 +197,17 @@ Sections:
   - 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
index 88ea98af4bdd0..a1ac4d9f58f5c 100644
--- 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 @@ 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
 Symbols:
   - Name: foo
   - Name: bar
@@ -57,59 +49,45 @@ Symbols:
 # 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 @@ Sections:
 ##         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
index c52add3a02178..121b1e950c39a 100644
--- 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 @@ 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
 Symbols:
   - Name: foo
   - Name: bar
@@ -91,47 +81,8 @@ Sections:
     Link:    0xFF
     EntSize: 0xFF
 
-## Check we can refer to symbols by name.
-# RUN: yaml2obj --docnum=3 %s -o %t.sym
-# RUN: llvm-readobj --cg-profile %t.sym | FileCheck %s --check-prefix=SYMBOL-NAMES
-
-# 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: ]
-
---- !ELF
-FileHeader:
-  Class:  ELFCLASS64
-  Data:   ELFDATA2LSB
-  Type:   ET_DYN
-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
-## Case 2: Test we can refer to symbols with suffixes.
-      - From:   foo
-        To:     'foo (1)'
-        Weight: 30
-Symbols:
-  - Name: foo
-  - Name: bar
-  - Name: 'foo (1)'
-
 ## Check we can describe SHT_LLVM_CALL_GRAPH_PROFILE sections using the "Content" tag.
-# RUN: yaml2obj --docnum=4 %s -o %t.content
+# RUN: yaml2obj --docnum=3 %s -o %t.content
 # RUN: llvm-readobj --sections --section-data %t.content | FileCheck %s --check-prefix=CONTENT
 
 # CONTENT:      Name: .llvm.call-graph-profile
@@ -149,69 +100,10 @@ Sections:
     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: 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: )
-
---- !ELF
-FileHeader:
-  Class: ELFCLASS64
-  Data:  ELFDATA2LSB
-  Type:  ET_DYN
-Sections:
-  - Name: .llvm.call-graph-profile
-    Type: SHT_LLVM_CALL_GRAPH_PROFILE
-    Entries:
-      - From:   1
-        To:     2
-        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=4 -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 +122,11 @@ Sections:
     Content: [[CONTENT=<none>]]
     Entries: [[ENTRIES=<none>]]
 
-# RUN: yaml2obj --docnum=8 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: yaml2obj --docnum=4 -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=4 -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 +147,21 @@ Sections:
 
 ## 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=4 -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=4 -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=4 -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=4 -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
index ce19696a35a9d..016af7e031a52 100644
--- a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
@@ -367,7 +367,7 @@ Sections:
 # 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
index 1a6fa0d6e2ddd..bf2b642c69557 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -318,6 +318,12 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   void printRelocatableStackSizes(std::function<void()> PrintHeader);
   void printNonRelocatableStackSizes(std::function<void()> PrintHeader);
 
+  /// Retrieves sections with corresponding relocation sections based on
+  /// IsMatch.
+  void getSectionAndRelocations(
+      std::function<bool(const Elf_Shdr &)> IsMatch,
+      llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> &SecToRelocMap);
+
   const object::ELFObjectFile<ELFT> &ObjF;
   const ELFFile<ELFT> &Obj;
   StringRef FileName;
@@ -356,7 +362,6 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   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<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
   Optional<uint64_t> SONameOffset;
@@ -1838,10 +1843,6 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,
       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 @@ void ELFDumper<ELFT>::printNonRelocatableStackSizes(
 }
 
 template <class ELFT>
-void ELFDumper<ELFT>::printRelocatableStackSizes(
-    std::function<void()> PrintHeader) {
-  // Build a map between stack size sections and their corresponding relocation
-  // sections.
-  llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> StackSizeRelocMap;
+void ELFDumper<ELFT>::getSectionAndRelocations(
+    std::function<bool(const Elf_Shdr &)> IsMatch,
+    llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> &SecToRelocMap) {
   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
-    StringRef SectionName;
-    if (Expected<StringRef> 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 @@ void ELFDumper<ELFT>::printRelocatableStackSizes(
                           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 <class ELFT>
+void ELFDumper<ELFT>::printRelocatableStackSizes(
+    std::function<void()> PrintHeader) {
+  // Build a map between stack size sections and their corresponding relocation
+  // sections.
+  llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> StackSizeRelocMap;
+  auto IsMatch = [&](const Elf_Shdr &Sec) -> bool {
+    StringRef SectionName;
+    if (Expected<StringRef> 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,65 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printHashHistograms() {
 }
 
 template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
-  ListScope L(W, "CGProfile");
-  if (!this->DotCGProfileSec)
-    return;
+  llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;
 
-  Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
-      this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(
-          *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<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
+        this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(*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<Elf_Rela_Range> CGProfileRelaOrError =
+          this->Obj.relas(*CGRelSection);
+      if (!CGProfileRelaOrError) {
+        this->reportUniqueWarning("unable to load relocations for "
+                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
+                                  toString(CGProfileRelaOrError.takeError()));
+        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) {
+      const Elf_Rel_Impl<ELFT, true> &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
index a72020fb752fe..028758d68d95c 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -1022,41 +1022,31 @@ ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) {
   if (!ContentOrErr)
     return ContentOrErr.takeError();
   ArrayRef<uint8_t> Content = *ContentOrErr;
-
+  const uint32_t SizeOfEntry = ELFYAML::getDefaultShEntSize<ELFT>(
+      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<ELFYAML::CallGraphEntry> Entries(Content.size() / 16);
+  std::vector<ELFYAML::CallGraphEntryWeight> 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<StringRef> From = getSymbolName(Shdr->sh_link, FromSymIndex);
-    Expected<StringRef> 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);


        


More information about the llvm-commits mailing list