forked from OSchip/llvm-project
[WebAssembly] Add __start_/_stop_ symbols for data sections
Fixes https://bugs.llvm.org/show_bug.cgi?id=41565 Differential Revision: https://reviews.llvm.org/D61876 llvm-svn: 361236
This commit is contained in:
parent
4a8835c655
commit
7804dbddcc
|
@ -0,0 +1,57 @@
|
||||||
|
; RUN: llc -filetype=obj -o %t.o %s
|
||||||
|
; RUN: wasm-ld --no-gc-sections %t.o -o %t.wasm
|
||||||
|
; RUN: obj2yaml %t.wasm | FileCheck %s
|
||||||
|
|
||||||
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
|
@foo = global i32 3, section "mysection", align 4
|
||||||
|
@bar = global i32 4, section "mysection", align 4
|
||||||
|
|
||||||
|
@__start_mysection = external global i8*
|
||||||
|
@__stop_mysection = external global i8*
|
||||||
|
|
||||||
|
define i8** @get_start() {
|
||||||
|
ret i8** @__start_mysection
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8** @get_end() {
|
||||||
|
ret i8** @__stop_mysection
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @_start() {
|
||||||
|
entry:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
; CHECK: - Type: CODE
|
||||||
|
; CHECK-NEXT: Functions:
|
||||||
|
; CHECK-NEXT: - Index: 0
|
||||||
|
; CHECK-NEXT: Locals: []
|
||||||
|
; CHECK-NEXT: Body: 0B
|
||||||
|
; CHECK-NEXT: - Index: 1
|
||||||
|
; CHECK-NEXT: Locals: []
|
||||||
|
; CHECK-NEXT: Body: 4180888080000B
|
||||||
|
; CHECK-NEXT: - Index: 2
|
||||||
|
; CHECK-NEXT: Locals: []
|
||||||
|
; CHECK-NEXT: Body: 4188888080000B
|
||||||
|
; CHECK-NEXT: - Index: 3
|
||||||
|
; CHECK-NEXT: Locals: []
|
||||||
|
; CHECK-NEXT: Body: 0B
|
||||||
|
; CHECK-NEXT: - Type: DATA
|
||||||
|
; CHECK-NEXT: Segments:
|
||||||
|
; CHECK-NEXT: - SectionOffset: 7
|
||||||
|
; CHECK-NEXT: InitFlags: 0
|
||||||
|
; CHECK-NEXT: Offset:
|
||||||
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
; CHECK-NEXT: Value: 1024
|
||||||
|
; CHECK-NEXT: Content: '0300000004000000'
|
||||||
|
; CHECK-NEXT: - Type: CUSTOM
|
||||||
|
; CHECK-NEXT: Name: name
|
||||||
|
; CHECK-NEXT: FunctionNames:
|
||||||
|
; CHECK-NEXT: - Index: 0
|
||||||
|
; CHECK-NEXT: Name: __wasm_call_ctors
|
||||||
|
; CHECK-NEXT: - Index: 1
|
||||||
|
; CHECK-NEXT: Name: get_start
|
||||||
|
; CHECK-NEXT: - Index: 2
|
||||||
|
; CHECK-NEXT: Name: get_end
|
||||||
|
; CHECK-NEXT: - Index: 3
|
||||||
|
; CHECK-NEXT: Name: _start
|
|
@ -608,10 +608,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||||
// Add synthetic dummies for weak undefined functions. Must happen
|
// Add synthetic dummies for weak undefined functions. Must happen
|
||||||
// after LTO otherwise functions may not yet have signatures.
|
// after LTO otherwise functions may not yet have signatures.
|
||||||
Symtab->handleWeakUndefines();
|
Symtab->handleWeakUndefines();
|
||||||
|
|
||||||
// Make sure we have resolved all symbols.
|
|
||||||
if (!Config->AllowUndefined)
|
|
||||||
Symtab->reportRemainingUndefines();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EntrySym)
|
if (EntrySym)
|
||||||
|
|
|
@ -198,6 +198,17 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
|
||||||
Flags, nullptr, Function);
|
Flags, nullptr, Function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value,
|
||||||
|
uint32_t Flags) {
|
||||||
|
Symbol *S = find(Name);
|
||||||
|
if (!S || S->isDefined())
|
||||||
|
return nullptr;
|
||||||
|
LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n");
|
||||||
|
auto *rtn = replaceSymbol<DefinedData>(S, Name, Flags);
|
||||||
|
rtn->setVirtualAddress(Value);
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
|
DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
|
||||||
uint32_t Flags) {
|
uint32_t Flags) {
|
||||||
LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
|
LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
|
||||||
|
|
|
@ -81,6 +81,8 @@ public:
|
||||||
InputGlobal *Global);
|
InputGlobal *Global);
|
||||||
DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
|
DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
|
||||||
InputFunction *Function);
|
InputFunction *Function);
|
||||||
|
DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value,
|
||||||
|
uint32_t Flags);
|
||||||
|
|
||||||
void handleSymbolVariants();
|
void handleSymbolVariants();
|
||||||
void handleWeakUndefines();
|
void handleWeakUndefines();
|
||||||
|
|
|
@ -73,6 +73,8 @@ private:
|
||||||
void addSection(OutputSection *Sec);
|
void addSection(OutputSection *Sec);
|
||||||
|
|
||||||
void addSections();
|
void addSections();
|
||||||
|
void addStartStopSymbols(const InputSegment *Seg);
|
||||||
|
|
||||||
void createCustomSections();
|
void createCustomSections();
|
||||||
void createSyntheticSections();
|
void createSyntheticSections();
|
||||||
void finalizeSections();
|
void finalizeSections();
|
||||||
|
@ -293,6 +295,22 @@ void Writer::addSection(OutputSection *Sec) {
|
||||||
OutputSections.push_back(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() {
|
void Writer::addSections() {
|
||||||
addSection(Out.DylinkSec);
|
addSection(Out.DylinkSec);
|
||||||
addSection(Out.TypeSec);
|
addSection(Out.TypeSec);
|
||||||
|
@ -543,8 +561,6 @@ void Writer::assignIndexes() {
|
||||||
Out.FunctionSec->addFunction(Func);
|
Out.FunctionSec->addFunction(Func);
|
||||||
}
|
}
|
||||||
|
|
||||||
scanRelocations();
|
|
||||||
|
|
||||||
for (InputGlobal *Global : Symtab->SyntheticGlobals)
|
for (InputGlobal *Global : Symtab->SyntheticGlobals)
|
||||||
Out.GlobalSec->addGlobal(Global);
|
Out.GlobalSec->addGlobal(Global);
|
||||||
|
|
||||||
|
@ -724,19 +740,40 @@ void Writer::run() {
|
||||||
populateTargetFeatures();
|
populateTargetFeatures();
|
||||||
log("-- calculateImports");
|
log("-- calculateImports");
|
||||||
calculateImports();
|
calculateImports();
|
||||||
log("-- assignIndexes");
|
|
||||||
assignIndexes();
|
|
||||||
log("-- calculateInitFunctions");
|
|
||||||
calculateInitFunctions();
|
|
||||||
log("-- calculateTypes");
|
|
||||||
calculateTypes();
|
|
||||||
log("-- layoutMemory");
|
log("-- layoutMemory");
|
||||||
layoutMemory();
|
layoutMemory();
|
||||||
|
|
||||||
if (!Config->Relocatable) {
|
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("-- assignIndexes");
|
||||||
|
assignIndexes();
|
||||||
|
log("-- scanRelocations");
|
||||||
|
scanRelocations();
|
||||||
|
log("-- calculateInitFunctions");
|
||||||
|
calculateInitFunctions();
|
||||||
|
|
||||||
|
if (!Config->Relocatable) {
|
||||||
|
// Create linker synthesized functions
|
||||||
if (Config->Pic)
|
if (Config->Pic)
|
||||||
createApplyRelocationsFunction();
|
createApplyRelocationsFunction();
|
||||||
createCallCtorsFunction();
|
createCallCtorsFunction();
|
||||||
|
|
||||||
|
// Make sure we have resolved all symbols.
|
||||||
|
if (!Config->AllowUndefined)
|
||||||
|
Symtab->reportRemainingUndefines();
|
||||||
|
|
||||||
|
if (errorCount())
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log("-- calculateTypes");
|
||||||
|
calculateTypes();
|
||||||
log("-- calculateExports");
|
log("-- calculateExports");
|
||||||
calculateExports();
|
calculateExports();
|
||||||
log("-- calculateCustomSections");
|
log("-- calculateCustomSections");
|
||||||
|
|
Loading…
Reference in New Issue