When having a symbol like: @_typeinfo__rtti_te_Module6_d_Test = private constant i8* bitcast (@_rtti_te_Module6_d_Test to i8*), section "ELRTTLRR", align 4 there is no way to get the start/end of the ELRTTLRR section in wasm currently.
Something like this, except I can't figure out the hashtable (not familiar with StringRef and the hashtable used here) diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp index 914b7313b..0ce7cd576 100644 --- a/wasm/InputFiles.cpp +++ b/wasm/InputFiles.cpp @@ -208,6 +208,8 @@ static void setRelocs(const std::vector<T *> &Chunks, } } +static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false}; + void ObjFile::parse() { // Parse a memory buffer as a wasm file. LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); @@ -264,8 +266,20 @@ void ObjFile::parse() { UsedComdats[I] = Symtab->addComdat(Comdats[I]); // Populate `Segments`. - for (const WasmSegment &S : WasmObj->dataSegments()) + for (const WasmSegment &S : WasmObj->dataSegments()) { Segments.emplace_back(make<InputSegment>(S, this)); + if (S.Data.Name.size() > 0 && !S.Data.Name.contains('.')) { + { + auto Name = (Twine("__start_") + S.Data.Name).str(); + if (!Symtab->find(Name)) + Symtab->addSyntheticDataSymbol(Name, 0); + + Name = (Twine("__end_") + S.Data.Name).str(); + if (!Symtab->find(Name)) + Symtab->addSyntheticDataSymbol(Name, 0); + } + } + } setRelocs(Segments, DataSection); // Populate `Functions`. diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp index 1af186bcb..409eb63e4 100644 --- a/wasm/Writer.cpp +++ b/wasm/Writer.cpp @@ -794,6 +794,16 @@ void Writer::layoutMemory() { MemAlign = std::max(MemAlign, Seg->Alignment); MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); Seg->StartVA = MemoryPtr; + if (Seg->Name.size() > 0 && !Seg->Name.contains('.')) { + auto sym = Symtab->find((Twine("__start_") + Seg->Name).str()); + if (sym && sym->kind() == Symbol::DefinedDataKind) { + cast<DefinedData>(sym)->setVirtualAddress(Seg->StartVA); + } + sym = Symtab->find((Twine("__end_") + Seg->Name).str()); + if (sym && sym->kind() == Symbol::DefinedDataKind) { + cast<DefinedData>(sym)->setVirtualAddress(Seg->StartVA + Seg->Size); + } + } log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, MemoryPtr, Seg->Size, Seg->Alignment)); MemoryPtr += Seg->Size;
Fix is https://reviews.llvm.org/D61876
To be clear the symbols are called __start_foo/__stop_foo, not __start_foo/__end_foo right?
You're right. It's stop not end. Thanks!
Should be fixed now. Please let me know if that works for you.
I finally got around to use this as is, It's not working for me. The first problem is that this code: for (const OutputSegment *Seg : Segments) for (const InputSegment *S : Seg->InputSegments) addStartStopSymbols(S); There are N inputSegments (357 in my case) and they're all named "ELRTTLRR" which is the section name (that's fine). addStartStopSymbols only hits for the first because addOptionalDataSegment bails out if the symbols is already present (which is true for the 356 other items). I have a feeling it also happens too late, because the final executable somehow ends up with 0 in both __start_ELRTTLRR and __end_ELRTTLRR.
OK I'll take a look at your case.
Should be fixed in https://reviews.llvm.org/D64148