diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2025-01-16 20:04:36 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2025-01-19 11:05:53 +0000 |
commit | dc3f24ea8a2505cc17b26e081a7de9376e6934e1 (patch) | |
tree | 5540ac6155eeda855eef1d57992b8adf36011542 /contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp | |
parent | 6ede5a29d5e7faa852a193d8fcbbbdf874d143c2 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp | 111 |
1 files changed, 67 insertions, 44 deletions
diff --git a/contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp index f25dc92fa235..852646924567 100644 --- a/contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp +++ b/contrib/llvm-project/llvm/lib/MC/WasmObjectWriter.cpp @@ -1326,6 +1326,22 @@ static bool isInSymtab(const MCSymbolWasm &Sym) { return true; } +static bool isSectionReferenced(MCAssembler &Asm, MCSectionWasm &Section) { + StringRef SectionName = Section.getName(); + + for (const MCSymbol &S : Asm.symbols()) { + const auto &WS = static_cast<const MCSymbolWasm &>(S); + if (WS.isData() && WS.isInSection()) { + auto &RefSection = static_cast<MCSectionWasm &>(WS.getSection()); + if (RefSection.getName() == SectionName) { + return true; + } + } + } + + return false; +} + void WasmObjectWriter::prepareImports( SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm) { // For now, always emit the memory import, since loads and stores are not @@ -1482,8 +1498,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group " << Section.getGroup() << "\n";); - // .init_array sections are handled specially elsewhere. - if (SectionName.starts_with(".init_array")) + // .init_array sections are handled specially elsewhere, include them in + // data segments if and only if referenced by a symbol. + if (SectionName.starts_with(".init_array") && + !isSectionReferenced(Asm, Section)) continue; // Code is handled separately @@ -1853,49 +1871,54 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, if (EmptyFrag.getKind() != MCFragment::FT_Data) report_fatal_error(".init_array section should be aligned"); - const MCFragment &AlignFrag = *EmptyFrag.getNext(); - if (AlignFrag.getKind() != MCFragment::FT_Align) - report_fatal_error(".init_array section should be aligned"); - if (cast<MCAlignFragment>(AlignFrag).getAlignment() != - Align(is64Bit() ? 8 : 4)) - report_fatal_error(".init_array section should be aligned for pointers"); - - const MCFragment &Frag = *AlignFrag.getNext(); - if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data) - report_fatal_error("only data supported in .init_array section"); - - uint16_t Priority = UINT16_MAX; - unsigned PrefixLength = strlen(".init_array"); - if (WS.getName().size() > PrefixLength) { - if (WS.getName()[PrefixLength] != '.') + const MCFragment *nextFrag = EmptyFrag.getNext(); + while (nextFrag != nullptr) { + const MCFragment &AlignFrag = *nextFrag; + if (AlignFrag.getKind() != MCFragment::FT_Align) + report_fatal_error(".init_array section should be aligned"); + if (cast<MCAlignFragment>(AlignFrag).getAlignment() != + Align(is64Bit() ? 8 : 4)) report_fatal_error( - ".init_array section priority should start with '.'"); - if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority)) - report_fatal_error("invalid .init_array section priority"); - } - const auto &DataFrag = cast<MCDataFragment>(Frag); - const SmallVectorImpl<char> &Contents = DataFrag.getContents(); - for (const uint8_t * - P = (const uint8_t *)Contents.data(), - *End = (const uint8_t *)Contents.data() + Contents.size(); - P != End; ++P) { - if (*P != 0) - report_fatal_error("non-symbolic data in .init_array section"); - } - for (const MCFixup &Fixup : DataFrag.getFixups()) { - assert(Fixup.getKind() == - MCFixup::getKindForSize(is64Bit() ? 8 : 4, false)); - const MCExpr *Expr = Fixup.getValue(); - auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr); - if (!SymRef) - report_fatal_error("fixups in .init_array should be symbol references"); - const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol()); - if (TargetSym.getIndex() == InvalidIndex) - report_fatal_error("symbols in .init_array should exist in symtab"); - if (!TargetSym.isFunction()) - report_fatal_error("symbols in .init_array should be for functions"); - InitFuncs.push_back( - std::make_pair(Priority, TargetSym.getIndex())); + ".init_array section should be aligned for pointers"); + + const MCFragment &Frag = *AlignFrag.getNext(); + nextFrag = Frag.getNext(); + if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data) + report_fatal_error("only data supported in .init_array section"); + + uint16_t Priority = UINT16_MAX; + unsigned PrefixLength = strlen(".init_array"); + if (WS.getName().size() > PrefixLength) { + if (WS.getName()[PrefixLength] != '.') + report_fatal_error( + ".init_array section priority should start with '.'"); + if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority)) + report_fatal_error("invalid .init_array section priority"); + } + const auto &DataFrag = cast<MCDataFragment>(Frag); + const SmallVectorImpl<char> &Contents = DataFrag.getContents(); + for (const uint8_t * + P = (const uint8_t *)Contents.data(), + *End = (const uint8_t *)Contents.data() + Contents.size(); + P != End; ++P) { + if (*P != 0) + report_fatal_error("non-symbolic data in .init_array section"); + } + for (const MCFixup &Fixup : DataFrag.getFixups()) { + assert(Fixup.getKind() == + MCFixup::getKindForSize(is64Bit() ? 8 : 4, false)); + const MCExpr *Expr = Fixup.getValue(); + auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr); + if (!SymRef) + report_fatal_error( + "fixups in .init_array should be symbol references"); + const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol()); + if (TargetSym.getIndex() == InvalidIndex) + report_fatal_error("symbols in .init_array should exist in symtab"); + if (!TargetSym.isFunction()) + report_fatal_error("symbols in .init_array should be for functions"); + InitFuncs.push_back(std::make_pair(Priority, TargetSym.getIndex())); + } } } |