summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-06-26 08:09:08 +0000
committerFangrui Song <maskray@google.com>2019-06-26 08:09:08 +0000
commitba51fd5664e3e15fbc1d350acdb56b4d8fc52ebc (patch)
tree85971b95475bea6bf976f1037ea986042d2c0f84 /lld/ELF/InputSection.cpp
parent8bfe0fc1d9b52337baceb89ac39fb58498b17d71 (diff)
downloadbcm5719-llvm-ba51fd5664e3e15fbc1d350acdb56b4d8fc52ebc.tar.gz
bcm5719-llvm-ba51fd5664e3e15fbc1d350acdb56b4d8fc52ebc.zip
Reland D61583 [ELF] Error on relocations to STT_SECTION symbols if the sections were discarded
This restores r361830 "[ELF] Error on relocations to STT_SECTION symbols if the sections were discarded" and dependent commits (r362218, r362497) which were reverted by r364321, with a fix of a --gdb-index issue. .rela.debug_ranges contains relocations of range list entries: // start address of a range list entry // old: 0; after r361830: 0 00000000000033a0 R_X86_64_64 .text._ZN2v88internal7Isolate7factoryEv + 0 // end address of a range list entry // old: 0xe; after r361830: 0 00000000000033a8 R_X86_64_64 .text._ZN2v88internal7Isolate7factoryEv + e If both start and end addresses of a range list entry resolve to 0, DWARFDebugRangeList::isEndOfListEntry() will return true, then the .debug_range decoding loop will terminate prematurely: while (true) { decode StartAddress decode EndAddress if (Entry.isEndOfListEntry()) // prematurely break; Entries.push_back(Entry); } In lld/ELF/SyntheticSections.cpp, readAddressAreas() will read incomplete address ranges and the resulting .gdb_index will be incomplete. For files that gdb hasn't loaded their debug info, gdb uses .gdb_index to map addresses to CUs. The absent entries make gdb fail to symbolize some addresses. To address this issue, we simply allow relocations to undefined symbols in DWARF.cpp:findAux() and let RelocationResolver resolve them. This patch should fix: [1] http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20190603/659848.html [2] https://bugs.chromium.org/p/chromium/issues/detail?id=978067 llvm-svn: 364391
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 3e8d093e6d2..d077c017ca7 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -412,7 +412,8 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
for (const RelTy &Rel : Rels) {
RelType Type = Rel.getType(Config->IsMips64EL);
- Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
+ const ObjFile<ELFT> *File = getFile<ELFT>();
+ Symbol &Sym = File->getRelocTargetSym(Rel);
auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
Buf += sizeof(RelTy);
@@ -435,10 +436,23 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// .eh_frame is horribly special and can reference discarded sections. To
// avoid having to parse and recreate .eh_frame, we just replace any
// relocation in it pointing to discarded sections with R_*_NONE, which
- // hopefully creates a frame that is ignored at runtime.
+ // hopefully creates a frame that is ignored at runtime. Also, don't warn
+ // on .gcc_except_table and debug sections.
+ //
+ // See the comment in maybeReportUndefined for PPC64 .toc .
auto *D = dyn_cast<Defined>(&Sym);
if (!D) {
- error("STT_SECTION symbol should be defined");
+ if (!Sec->Name.startswith(".debug") &&
+ !Sec->Name.startswith(".zdebug") && Sec->Name != ".eh_frame" &&
+ Sec->Name != ".gcc_except_table" && Sec->Name != ".toc") {
+ uint32_t SecIdx = cast<Undefined>(Sym).DiscardedSecIdx;
+ Elf_Shdr_Impl<ELFT> Sec =
+ CHECK(File->getObj().sections(), File)[SecIdx];
+ warn("relocation refers to a discarded section: " +
+ CHECK(File->getObj().getSectionName(&Sec), File) +
+ "\n>>> referenced by " + getObjMsg(P->r_offset));
+ }
+ P->setSymbolAndType(0, 0, false);
continue;
}
SectionBase *Section = D->Section->Repl;
OpenPOWER on IntegriCloud