Skip to content

Commit 4bce63a

Browse files
committed
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
1 parent b970fd7 commit 4bce63a

File tree

5 files changed

+111
-8
lines changed

5 files changed

+111
-8
lines changed

lld/test/wasm/startstop.ll

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; RUN: llc -filetype=obj -o %t.o %s
2+
; RUN: wasm-ld --no-gc-sections %t.o -o %t.wasm
3+
; RUN: obj2yaml %t.wasm | FileCheck %s
4+
5+
target triple = "wasm32-unknown-unknown"
6+
7+
@foo = global i32 3, section "mysection", align 4
8+
@bar = global i32 4, section "mysection", align 4
9+
10+
@__start_mysection = external global i8*
11+
@__stop_mysection = external global i8*
12+
13+
define i8** @get_start() {
14+
ret i8** @__start_mysection
15+
}
16+
17+
define i8** @get_end() {
18+
ret i8** @__stop_mysection
19+
}
20+
21+
define void @_start() {
22+
entry:
23+
ret void
24+
}
25+
; CHECK: - Type: CODE
26+
; CHECK-NEXT: Functions:
27+
; CHECK-NEXT: - Index: 0
28+
; CHECK-NEXT: Locals: []
29+
; CHECK-NEXT: Body: 0B
30+
; CHECK-NEXT: - Index: 1
31+
; CHECK-NEXT: Locals: []
32+
; CHECK-NEXT: Body: 4180888080000B
33+
; CHECK-NEXT: - Index: 2
34+
; CHECK-NEXT: Locals: []
35+
; CHECK-NEXT: Body: 4188888080000B
36+
; CHECK-NEXT: - Index: 3
37+
; CHECK-NEXT: Locals: []
38+
; CHECK-NEXT: Body: 0B
39+
; CHECK-NEXT: - Type: DATA
40+
; CHECK-NEXT: Segments:
41+
; CHECK-NEXT: - SectionOffset: 7
42+
; CHECK-NEXT: InitFlags: 0
43+
; CHECK-NEXT: Offset:
44+
; CHECK-NEXT: Opcode: I32_CONST
45+
; CHECK-NEXT: Value: 1024
46+
; CHECK-NEXT: Content: '0300000004000000'
47+
; CHECK-NEXT: - Type: CUSTOM
48+
; CHECK-NEXT: Name: name
49+
; CHECK-NEXT: FunctionNames:
50+
; CHECK-NEXT: - Index: 0
51+
; CHECK-NEXT: Name: __wasm_call_ctors
52+
; CHECK-NEXT: - Index: 1
53+
; CHECK-NEXT: Name: get_start
54+
; CHECK-NEXT: - Index: 2
55+
; CHECK-NEXT: Name: get_end
56+
; CHECK-NEXT: - Index: 3
57+
; CHECK-NEXT: Name: _start

lld/wasm/Driver.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
652652
// Add synthetic dummies for weak undefined functions. Must happen
653653
// after LTO otherwise functions may not yet have signatures.
654654
Symtab->handleWeakUndefines();
655-
656-
// Make sure we have resolved all symbols.
657-
if (!Config->AllowUndefined)
658-
Symtab->reportRemainingUndefines();
659655
}
660656

661657
if (EntrySym)

lld/wasm/SymbolTable.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
198198
Flags, nullptr, Function);
199199
}
200200

201+
DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value,
202+
uint32_t Flags) {
203+
Symbol *S = find(Name);
204+
if (!S || S->isDefined())
205+
return nullptr;
206+
LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n");
207+
auto *rtn = replaceSymbol<DefinedData>(S, Name, Flags);
208+
rtn->setVirtualAddress(Value);
209+
return rtn;
210+
}
211+
201212
DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
202213
uint32_t Flags) {
203214
LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");

lld/wasm/SymbolTable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class SymbolTable {
8181
InputGlobal *Global);
8282
DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
8383
InputFunction *Function);
84+
DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value,
85+
uint32_t Flags);
8486

8587
void handleSymbolVariants();
8688
void handleWeakUndefines();

lld/wasm/Writer.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class Writer {
7373
void addSection(OutputSection *Sec);
7474

7575
void addSections();
76+
void addStartStopSymbols(const InputSegment *Seg);
77+
7678
void createCustomSections();
7779
void createSyntheticSections();
7880
void finalizeSections();
@@ -293,6 +295,22 @@ void Writer::addSection(OutputSection *Sec) {
293295
OutputSections.push_back(Sec);
294296
}
295297

298+
// If a section name is valid as a C identifier (which is rare because of
299+
// the leading '.'), linkers are expected to define __start_<secname> and
300+
// __stop_<secname> symbols. They are at beginning and end of the section,
301+
// respectively. This is not requested by the ELF standard, but GNU ld and
302+
// gold provide the feature, and used by many programs.
303+
void Writer::addStartStopSymbols(const InputSegment *Seg) {
304+
StringRef S = Seg->getName();
305+
LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n");
306+
if (!isValidCIdentifier(S))
307+
return;
308+
uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset;
309+
uint32_t Stop = Start + Seg->getSize();
310+
Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0);
311+
Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0);
312+
}
313+
296314
void Writer::addSections() {
297315
addSection(Out.DylinkSec);
298316
addSection(Out.TypeSec);
@@ -724,21 +742,40 @@ void Writer::run() {
724742
populateTargetFeatures();
725743
log("-- calculateImports");
726744
calculateImports();
745+
log("-- layoutMemory");
746+
layoutMemory();
747+
748+
if (!Config->Relocatable) {
749+
// Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
750+
// This has to be done after memory layout is performed.
751+
for (const OutputSegment *Seg : Segments)
752+
for (const InputSegment *S : Seg->InputSegments)
753+
addStartStopSymbols(S);
754+
}
755+
727756
log("-- scanRelocations");
728757
scanRelocations();
729758
log("-- assignIndexes");
730759
assignIndexes();
731760
log("-- calculateInitFunctions");
732761
calculateInitFunctions();
733-
log("-- calculateTypes");
734-
calculateTypes();
735-
log("-- layoutMemory");
736-
layoutMemory();
762+
737763
if (!Config->Relocatable) {
764+
// Create linker synthesized functions
738765
if (Config->Pic)
739766
createApplyRelocationsFunction();
740767
createCallCtorsFunction();
768+
769+
// Make sure we have resolved all symbols.
770+
if (!Config->AllowUndefined)
771+
Symtab->reportRemainingUndefines();
772+
773+
if (errorCount())
774+
return;
741775
}
776+
777+
log("-- calculateTypes");
778+
calculateTypes();
742779
log("-- calculateExports");
743780
calculateExports();
744781
log("-- calculateCustomSections");

0 commit comments

Comments
 (0)