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
|
||||
// after LTO otherwise functions may not yet have signatures.
|
||||
Symtab->handleWeakUndefines();
|
||||
|
||||
// Make sure we have resolved all symbols.
|
||||
if (!Config->AllowUndefined)
|
||||
Symtab->reportRemainingUndefines();
|
||||
}
|
||||
|
||||
if (EntrySym)
|
||||
|
|
|
@ -198,6 +198,17 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
|
|||
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,
|
||||
uint32_t Flags) {
|
||||
LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
InputGlobal *Global);
|
||||
DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
|
||||
InputFunction *Function);
|
||||
DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value,
|
||||
uint32_t Flags);
|
||||
|
||||
void handleSymbolVariants();
|
||||
void handleWeakUndefines();
|
||||
|
|
|
@ -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);
|
||||
|
@ -543,8 +561,6 @@ void Writer::assignIndexes() {
|
|||
Out.FunctionSec->addFunction(Func);
|
||||
}
|
||||
|
||||
scanRelocations();
|
||||
|
||||
for (InputGlobal *Global : Symtab->SyntheticGlobals)
|
||||
Out.GlobalSec->addGlobal(Global);
|
||||
|
||||
|
@ -724,19 +740,40 @@ void Writer::run() {
|
|||
populateTargetFeatures();
|
||||
log("-- calculateImports");
|
||||
calculateImports();
|
||||
log("-- assignIndexes");
|
||||
assignIndexes();
|
||||
log("-- calculateInitFunctions");
|
||||
calculateInitFunctions();
|
||||
log("-- calculateTypes");
|
||||
calculateTypes();
|
||||
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("-- assignIndexes");
|
||||
assignIndexes();
|
||||
log("-- scanRelocations");
|
||||
scanRelocations();
|
||||
log("-- calculateInitFunctions");
|
||||
calculateInitFunctions();
|
||||
|
||||
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");
|
||||
|
|
Loading…
Reference in New Issue