[WebAssembly] Prevent data inside text sections in assembly

This is not supported in Wasm, unless the data was encoded instructions, but that wouldn't work with the assembler's other functionality (enforcing nesting etc.).

Fixes: https://bugs.llvm.org/show_bug.cgi?id=48971

Differential Revision: https://reviews.llvm.org/D95838
This commit is contained in:
Wouter van Oortmerssen 2021-02-01 17:28:00 -08:00
parent 5f76044c25
commit 5e5b2cb131
4 changed files with 37 additions and 14 deletions

View File

@ -14,7 +14,7 @@
namespace llvm {
class MCSymbolWasm : public MCSymbol {
wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_DATA;
Optional<wasm::WasmSymbolType> Type;
bool IsWeak = false;
bool IsHidden = false;
bool IsComdat = false;
@ -41,12 +41,15 @@ public:
void setSize(const MCExpr *SS) { SymbolSize = SS; }
bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
// Data is the default value if not set.
bool isData() const { return !Type || Type == wasm::WASM_SYMBOL_TYPE_DATA; }
bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
wasm::WasmSymbolType getType() const { return Type; }
Optional<wasm::WasmSymbolType> getType() const { return Type; }
void setType(wasm::WasmSymbolType type) { Type = type; }
bool isExported() const {

View File

@ -488,10 +488,14 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
const MCSymbol *SectionSymbol = nullptr;
const MCSection &SecA = SymA->getSection();
if (SecA.getKind().isText())
SectionSymbol = SectionFunctions.find(&SecA)->second;
else
if (SecA.getKind().isText()) {
auto SecSymIt = SectionFunctions.find(&SecA);
if (SecSymIt == SectionFunctions.end())
report_fatal_error("section doesn\'t have defining symbol");
SectionSymbol = SecSymIt->second;
} else {
SectionSymbol = SecA.getBeginSymbol();
}
if (!SectionSymbol)
report_fatal_error("section symbol is required for relocation");
@ -1458,8 +1462,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
continue;
const auto &WS = static_cast<const MCSymbolWasm &>(S);
LLVM_DEBUG(
dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'"
LLVM_DEBUG(dbgs()
<< "MCSymbol: "
<< toString(WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA))
<< " '" << S << "'"
<< " isDefined=" << S.isDefined() << " isExternal="
<< S.isExternal() << " isTemporary=" << S.isTemporary()
<< " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden()
@ -1699,7 +1705,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
wasm::WasmSymbolInfo Info;
Info.Name = WS.getName();
Info.Kind = WS.getType();
Info.Kind = WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA);
Info.Flags = Flags;
if (!WS.isData()) {
assert(WasmIndices.count(&WS) > 0);

View File

@ -999,6 +999,20 @@ public:
}
void doBeforeLabelEmit(MCSymbol *Symbol) override {
// Code below only applies to labels in text sections.
auto CWS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
if (!CWS || !CWS->getKind().isText())
return;
auto WasmSym = cast<MCSymbolWasm>(Symbol);
// Unlike other targets, we don't allow data in text sections (labels
// declared with .type @object).
if (WasmSym->getType() == wasm::WASM_SYMBOL_TYPE_DATA) {
Parser.Error(Parser.getTok().getLoc(),
"Wasm doesn\'t support data symbols in text sections");
return;
}
// Start a new section for the next function automatically, since our
// object writer expects each function to have its own section. This way
// The user can't forget this "convention".
@ -1006,14 +1020,10 @@ public:
if (SymName.startswith(".L"))
return; // Local Symbol.
// Only create a new text section if we're already in one.
// TODO: If the user explicitly creates a new function section, we ignore
// its name when we create this one. It would be nice to honor their
// choice, while still ensuring that we create one if they forget.
// (that requires coordination with WasmAsmParser::parseSectionDirective)
auto CWS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
if (!CWS || !CWS->getKind().isText())
return;
auto SecName = ".text." + SymName;
auto *Group = CWS->getGroup();
@ -1022,7 +1032,7 @@ public:
// for importing comdat functions. But there's no way to specify that in
// assembly currently.
if (Group)
cast<MCSymbolWasm>(Symbol)->setComdat(true);
WasmSym->setComdat(true);
auto *WS =
getContext().getWasmSection(SecName, SectionKind::getText(), Group,
MCContext::GenericSectionID, nullptr);

View File

@ -4,6 +4,10 @@
# (must be 0.0 or similar)
f32.const 0
# CHECK: Wasm doesn't support data symbols in text sections
.type objerr,@object
objerr:
# CHECK: End of block construct with no start: end_try
end_try
test0: