summaryrefslogtreecommitdiffstats
path: root/lld/COFF/Writer.cpp
diff options
context:
space:
mode:
authorShoaib Meenai <smeenai@fb.com>2018-05-29 19:07:47 +0000
committerShoaib Meenai <smeenai@fb.com>2018-05-29 19:07:47 +0000
commit4e518336112e70007a0ed011733819398df597ea (patch)
treef4c2b61daecf112693339894604ec5a25f4fe84b /lld/COFF/Writer.cpp
parent43b40939fb640bf17ad8bf47852fe90d062fa3b4 (diff)
downloadbcm5719-llvm-4e518336112e70007a0ed011733819398df597ea.tar.gz
bcm5719-llvm-4e518336112e70007a0ed011733819398df597ea.zip
[COFF] Simplify symbol table output section computation
Rather than using a loop to compare symbol RVAs to the starting RVAs of sections to determine which section a symbol belongs to, just get the output section of a symbol directly via its chunk, and bail if the symbol doesn't have an output section, which avoids having to hardcode logic for handling dead symbols, CodeView symbols, etc. This was suggested by Reid Kleckner; thank you. This also fixes writing out symbol tables in the presence of RVA table input sections (e.g. .sxdata and .gfids). Such sections aren't written to the output file directly, so their RVA is 0, and the loop would thus fail to find an output section for them, resulting in a segfault. Extend some existing tests to cover this case. Fixes PR37584. Differential Revision: https://reviews.llvm.org/D47391 llvm-svn: 333450
Diffstat (limited to 'lld/COFF/Writer.cpp')
-rw-r--r--lld/COFF/Writer.cpp23
1 files changed, 9 insertions, 14 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b38bef80ef6..dc2b6ad6de4 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -606,13 +606,14 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
if (isa<DefinedSynthetic>(Def))
return None;
- // Don't write dead symbols or symbols in codeview sections to the symbol
+ // Don't write symbols that won't be written to the output to the symbol
// table.
- if (!Def->isLive())
- return None;
- if (auto *D = dyn_cast<DefinedRegular>(Def))
- if (D->getChunk()->isCodeView())
+ OutputSection *OS = nullptr;
+ if (Chunk *C = Def->getChunk()) {
+ OS = C->getOutputSection();
+ if (!OS)
return None;
+ }
coff_symbol16 Sym;
StringRef Name = Def->getName();
@@ -640,15 +641,9 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
Sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
break;
default: {
- uint64_t RVA = Def->getRVA();
- OutputSection *Sec = nullptr;
- for (OutputSection *S : OutputSections) {
- if (S->getRVA() > RVA)
- break;
- Sec = S;
- }
- Sym.Value = RVA - Sec->getRVA();
- Sym.SectionNumber = Sec->SectionIndex;
+ assert(OS && "Writing dead symbol to symbol table");
+ Sym.Value = Def->getRVA() - OS->getRVA();
+ Sym.SectionNumber = OS->SectionIndex;
break;
}
}
OpenPOWER on IntegriCloud