diff options
| author | Sam Clegg <sbc@chromium.org> | 2019-05-23 10:06:03 +0000 |
|---|---|---|
| committer | Sam Clegg <sbc@chromium.org> | 2019-05-23 10:06:03 +0000 |
| commit | 4bce63a0e7c5bfd0c4ee1642d0fbae89702ad490 (patch) | |
| tree | 5cf0813c090726ed117ca32f252def072e1fb594 /lld/wasm/Writer.cpp | |
| parent | b970fd718851c655c20a3b978b61d3ed63e7c00d (diff) | |
| download | bcm5719-llvm-4bce63a0e7c5bfd0c4ee1642d0fbae89702ad490.tar.gz bcm5719-llvm-4bce63a0e7c5bfd0c4ee1642d0fbae89702ad490.zip | |
Reland: [WebAssembly] Add __start_/_stop_ symbols for data sections
This is a reland of rL361235.
Fixes https://bugs.llvm.org/show_bug.cgi?id=41565
Differential Revision: https://reviews.llvm.org/D61876
llvm-svn: 361476
Diffstat (limited to 'lld/wasm/Writer.cpp')
| -rw-r--r-- | lld/wasm/Writer.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 01dbd82dc35..f43191c7027 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -73,6 +73,8 @@ private: void addSection(OutputSection *Sec); void addSections(); + void addStartStopSymbols(const InputSegment *Seg); + void createCustomSections(); void createSyntheticSections(); void finalizeSections(); @@ -293,6 +295,22 @@ void Writer::addSection(OutputSection *Sec) { OutputSections.push_back(Sec); } +// If a section name is valid as a C identifier (which is rare because of +// the leading '.'), linkers are expected to define __start_<secname> and +// __stop_<secname> symbols. They are at beginning and end of the section, +// respectively. This is not requested by the ELF standard, but GNU ld and +// gold provide the feature, and used by many programs. +void Writer::addStartStopSymbols(const InputSegment *Seg) { + StringRef S = Seg->getName(); + LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n"); + if (!isValidCIdentifier(S)) + return; + uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset; + uint32_t Stop = Start + Seg->getSize(); + Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0); + Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0); +} + void Writer::addSections() { addSection(Out.DylinkSec); addSection(Out.TypeSec); @@ -724,21 +742,40 @@ void Writer::run() { populateTargetFeatures(); log("-- calculateImports"); calculateImports(); + log("-- layoutMemory"); + layoutMemory(); + + if (!Config->Relocatable) { + // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols + // This has to be done after memory layout is performed. + for (const OutputSegment *Seg : Segments) + for (const InputSegment *S : Seg->InputSegments) + addStartStopSymbols(S); + } + log("-- scanRelocations"); scanRelocations(); log("-- assignIndexes"); assignIndexes(); log("-- calculateInitFunctions"); calculateInitFunctions(); - log("-- calculateTypes"); - calculateTypes(); - log("-- layoutMemory"); - layoutMemory(); + if (!Config->Relocatable) { + // Create linker synthesized functions if (Config->Pic) createApplyRelocationsFunction(); createCallCtorsFunction(); + + // Make sure we have resolved all symbols. + if (!Config->AllowUndefined) + Symtab->reportRemainingUndefines(); + + if (errorCount()) + return; } + + log("-- calculateTypes"); + calculateTypes(); log("-- calculateExports"); calculateExports(); log("-- calculateCustomSections"); |

