diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -856,10 +856,21 @@
 }
 
 template <class ELFT> static void readCallGraphsFromObjectFiles() {
+  const uint32_t sizeOfEntry = sizeof(Elf_CGProfile_Impl<ELFT>);
   for (auto file : objectFiles) {
     auto *obj = cast<ObjFile<ELFT>>(file);
+    std::vector<Elf_CGProfile_Impl<ELFT>> cgProfileC(obj->cgProfile.vec());
+    for (uint32_t i = 0, size = obj->cgProfileRela.size(); i < size; i += 2) {
+      const Elf_Rel_Impl<ELFT, true> &relFrom = obj->cgProfileRela[i];
+      const Elf_Rel_Impl<ELFT, true> &relTo = obj->cgProfileRela[i + 1];
+      uint32_t symIndexFrom = relFrom.getSymbol(config->isMips64EL);
+      uint32_t symIndexTo = relTo.getSymbol(config->isMips64EL);
+      uint32_t index = relFrom.r_offset / sizeOfEntry;
+      cgProfileC[index].cgp_from = symIndexFrom;
+      cgProfileC[index].cgp_to = symIndexTo;
+    }
 
-    for (const Elf_CGProfile_Impl<ELFT> &cgpe : obj->cgProfile) {
+    for (const Elf_CGProfile_Impl<ELFT> &cgpe : cgProfileC) {
       auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_from));
       auto *toSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_to));
       if (!fromSym || !toSym)
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<Elf_CGProfile> cgProfile;
+  // SHT_LLVM_CALL_GRAPH_PROFILE relocations.
+  ArrayRef<Elf_Rela> 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<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,8 +669,12 @@
       continue;
     const Elf_Shdr &sec = objSections[i];
 
-    if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
+    if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) {
+      if (sec.sh_info == cgProfileSectionIndex) {
+        cgProfileRela = CHECK(getObj().relas(sec), this);
+      }
       this->sections[i] = createInputSection(sec);
+    }
 
     // A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have
     // the flag.
diff --git a/llvm/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<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 @@
     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
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -490,20 +490,26 @@
     S->setUsedInReloc();
     SRE =
         MCSymbolRefExpr::create(S, SRE->getKind(), getContext(), SRE->getLoc());
-    return;
   }
-  // Not a temporary, referece it as a weak undefined.
-  bool Created;
-  getAssembler().registerSymbol(*S, &Created);
-  if (Created)
-    cast<MCSymbolELF>(S)->setBinding(ELF::STB_WEAK);
+  MCObjectStreamer::emitSymbolValue(S, 4);
 }
 
 void MCELFStreamer::finalizeCGProfile() {
-  for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) {
+  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, 16 /* sizeof(Elf_CGProfile_Impl<>)*/);
+  PushSection();
+  SwitchSection(CGProfile);
+
+  for (MCAssembler::CGProfileEntry &E : Asm.CGProfile) {
     finalizeCGProfileEntry(E.From);
     finalizeCGProfileEntry(E.To);
+    emitIntValue(E.Count, sizeof(uint64_t));
   }
+  PopSection();
 }
 
 void MCELFStreamer::emitInstToFragment(const MCInst &Inst,
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
@@ -22,15 +22,15 @@
 # CHECK-NEXT: Address:
 # CHECK-NEXT: Offset:
 # CHECK-NEXT: Size: 64
-# CHECK-NEXT: Link: 6
+# CHECK-NEXT: Link: 7
 # CHECK-NEXT: Info: 0
 # CHECK-NEXT: AddressAlignment: 1
 # CHECK-NEXT: EntrySize: 16
 # 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: 00000000 00000000 20000000 00000000
+# CHECK-NEXT:   0010: 00000000 00000000 0B000000 00000000
+# CHECK-NEXT:   0020: 00000000 00000000 14000000 00000000
+# CHECK-NEXT:   0030: 00000000 00000000 2A000000 00000000
 # CHECK-NEXT: )
 
 # CHECK: Symbols [
@@ -72,7 +72,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/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -357,6 +357,7 @@
   const Elf_Shdr *DotSymtabSec = nullptr;
   const Elf_Shdr *DotDynsymSec = nullptr;
   const Elf_Shdr *DotCGProfileSec = nullptr;
+  const Elf_Shdr *DotCGProfileSecRela = nullptr;
   const Elf_Shdr *DotAddrsigSec = nullptr;
   DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
   Optional<uint64_t> SONameOffset;
@@ -1772,7 +1773,9 @@
     return;
 
   typename ELFT::ShdrRange Sections = cantFail(Obj.sections());
-  for (const Elf_Shdr &Sec : Sections) {
+  uint32_t DotCGProfileSecIndex = 0;
+  for (unsigned i = 0, Size = Sections.size(); i < Size; ++i) {
+    const Elf_Shdr &Sec = Sections[i];
     switch (Sec.sh_type) {
     case ELF::SHT_SYMTAB:
       if (!DotSymtabSec)
@@ -1837,8 +1840,10 @@
         SymbolVersionNeedSection = &Sec;
       break;
     case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
-      if (!DotCGProfileSec)
+      if (!DotCGProfileSec) {
         DotCGProfileSec = &Sec;
+        DotCGProfileSecIndex = i;
+      }
       break;
     case ELF::SHT_LLVM_ADDRSIG:
       if (!DotAddrsigSec)
@@ -1847,6 +1852,15 @@
     }
   }
 
+  // Following LLD lead and doing a seperate loop in case relocation section
+  // comes before section it applies to.
+  for (const Elf_Shdr &Sec : Sections) {
+    if (Sec.sh_info == DotCGProfileSecIndex) {
+      DotCGProfileSecRela = &Sec;
+      break;
+    }
+  }
+
   loadDynamicTable();
 }
 
@@ -6701,6 +6715,7 @@
   if (!this->DotCGProfileSec)
     return;
 
+  std::vector<Elf_CGProfile> CGProfileVec;
   Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
       this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(
           *this->DotCGProfileSec);
@@ -6711,7 +6726,31 @@
     return;
   }
 
-  for (const Elf_CGProfile &CGPE : *CGProfileOrErr) {
+  CGProfileVec = *CGProfileOrErr;
+  if (this->DotCGProfileSecRela) {
+    Expected<Elf_Rela_Range> CGProfileRelaOrError =
+        this->Obj.relas(*this->DotCGProfileSecRela);
+    if (!CGProfileRelaOrError) {
+      this->reportUniqueWarning(
+          "unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " +
+          toString(CGProfileOrErr.takeError()) + "with relocations.");
+      return;
+    }
+
+    const uint32_t sizeOfEntry = sizeof(Elf_CGProfile_Impl<ELFT>);
+    for (uint32_t i = 0, size = CGProfileRelaOrError->size(); i < size;
+         i += 2) {
+      const Elf_Rel_Impl<ELFT, true> &relFrom = (*CGProfileRelaOrError)[i];
+      const Elf_Rel_Impl<ELFT, true> &relTo = (*CGProfileRelaOrError)[i + 1];
+      uint32_t symIndexFrom = relFrom.getSymbol(this->Obj.isMips64EL());
+      uint32_t symIndexTo = relTo.getSymbol(this->Obj.isMips64EL());
+      uint32_t index = relFrom.r_offset / sizeOfEntry;
+      CGProfileVec[index].cgp_from = symIndexFrom;
+      CGProfileVec[index].cgp_to = symIndexTo;
+    }
+  }
+
+  for (const Elf_CGProfile &CGPE : CGProfileVec) {
     DictScope D(W, "CGProfileEntry");
     W.printNumber("From", this->getStaticSymbolName(CGPE.cgp_from),
                   CGPE.cgp_from);