
Fixes #85578, a use-after-free caused by some `MCSymbolWasm` data being freed too early. Previously, `WebAssemblyAsmParser` owned the data that is moved to `MCContext` by this PR, which caused problems when handling module ASM, because the ASM parser was destroyed after parsing the module ASM, but the symbols persisted. The added test passes locally with an LLVM build with AddressSanitizer enabled. Implementation notes: * I've called the added method <code>allocate<b><i>Generic</i></b>String</code> and added the second paragraph of its documentation to maybe guide people a bit on when to use this method (based on my (limited) understanding of the `MCContext` class). We could also just call it `allocateString` and remove that second paragraph. * The added `createWasmSignature` method does not support taking the return and parameter types as arguments: Specifying them afterwards is barely any longer and prevents them from being accidentally specified in the wrong order. * This removes a _"TODO: Do the uniquing of Signatures here instead of ObjectFileWriter?"_ since the field it's attached to is also removed. Let me know if you think that TODO should be preserved somewhere.
82 lines
3.1 KiB
C++
82 lines
3.1 KiB
C++
// WebAssemblyAsmPrinter.h - WebAssembly implementation of AsmPrinter-*- C++ -*-
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYASMPRINTER_H
|
|
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYASMPRINTER_H
|
|
|
|
#include "WebAssemblyMachineFunctionInfo.h"
|
|
#include "WebAssemblySubtarget.h"
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
namespace llvm {
|
|
class WebAssemblyTargetStreamer;
|
|
|
|
class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
|
|
const WebAssemblySubtarget *Subtarget;
|
|
const MachineRegisterInfo *MRI;
|
|
WebAssemblyFunctionInfo *MFI;
|
|
bool signaturesEmitted = false;
|
|
|
|
public:
|
|
explicit WebAssemblyAsmPrinter(TargetMachine &TM,
|
|
std::unique_ptr<MCStreamer> Streamer)
|
|
: AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr), MRI(nullptr),
|
|
MFI(nullptr) {}
|
|
|
|
StringRef getPassName() const override {
|
|
return "WebAssembly Assembly Printer";
|
|
}
|
|
|
|
const WebAssemblySubtarget &getSubtarget() const { return *Subtarget; }
|
|
|
|
//===------------------------------------------------------------------===//
|
|
// MachineFunctionPass Implementation.
|
|
//===------------------------------------------------------------------===//
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override {
|
|
Subtarget = &MF.getSubtarget<WebAssemblySubtarget>();
|
|
MRI = &MF.getRegInfo();
|
|
MFI = MF.getInfo<WebAssemblyFunctionInfo>();
|
|
return AsmPrinter::runOnMachineFunction(MF);
|
|
}
|
|
|
|
//===------------------------------------------------------------------===//
|
|
// AsmPrinter Implementation.
|
|
//===------------------------------------------------------------------===//
|
|
|
|
void emitEndOfAsmFile(Module &M) override;
|
|
void EmitProducerInfo(Module &M);
|
|
void EmitTargetFeatures(Module &M);
|
|
void EmitFunctionAttributes(Module &M);
|
|
void emitSymbolType(const MCSymbolWasm *Sym);
|
|
void emitGlobalVariable(const GlobalVariable *GV) override;
|
|
void emitJumpTableInfo() override;
|
|
void emitConstantPool() override;
|
|
void emitFunctionBodyStart() override;
|
|
void emitInstruction(const MachineInstr *MI) override;
|
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|
const char *ExtraCode, raw_ostream &OS) override;
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
|
const char *ExtraCode, raw_ostream &OS) override;
|
|
|
|
MVT getRegType(unsigned RegNo) const;
|
|
std::string regToString(const MachineOperand &MO);
|
|
WebAssemblyTargetStreamer *getTargetStreamer();
|
|
MCSymbolWasm *getMCSymbolForFunction(const Function *F, bool EnableEmEH,
|
|
wasm::WasmSignature *Sig,
|
|
bool &InvokeDetected);
|
|
MCSymbol *getOrCreateWasmSymbol(StringRef Name);
|
|
void emitDecls(const Module &M);
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|