diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp index 6acc9b20eed..ce91a3444fb 100644 --- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp +++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp @@ -15,6 +15,7 @@ /// //===----------------------------------------------------------------------===// +#include "InstPrinter/WebAssemblyInstPrinter.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -45,6 +46,10 @@ class WebAssemblyDisassembler final : public MCDisassembler { ArrayRef<uint8_t> Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const override; + DecodeStatus onSymbolStart(StringRef Name, uint64_t &Size, + ArrayRef<uint8_t> Bytes, uint64_t Address, + raw_ostream &VStream, + raw_ostream &CStream) const override; public: WebAssemblyDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, @@ -77,7 +82,7 @@ static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) { } static bool nextLEB(int64_t &Val, ArrayRef<uint8_t> Bytes, uint64_t &Size, - bool Signed = false) { + bool Signed) { unsigned N = 0; const char *Error = nullptr; Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N, @@ -116,6 +121,41 @@ bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes) { return true; } +MCDisassembler::DecodeStatus WebAssemblyDisassembler::onSymbolStart( + StringRef Name, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, + raw_ostream &VStream, raw_ostream &CStream) const { + Size = 0; + if (Address == 0) { + // Start of a code section: we're parsing only the function count. + int64_t FunctionCount; + if (!nextLEB(FunctionCount, Bytes, Size, false)) + return MCDisassembler::Fail; + outs() << " # " << FunctionCount << " functions in section."; + } else { + // Parse the start of a single function. + int64_t BodySize, LocalEntryCount; + if (!nextLEB(BodySize, Bytes, Size, false) || + !nextLEB(LocalEntryCount, Bytes, Size, false)) + return MCDisassembler::Fail; + if (LocalEntryCount) { + outs() << " .local "; + for (int64_t I = 0; I < LocalEntryCount; I++) { + int64_t Count, Type; + if (!nextLEB(Count, Bytes, Size, false) || + !nextLEB(Type, Bytes, Size, false)) + return MCDisassembler::Fail; + for (int64_t J = 0; J < Count; J++) { + if (I || J) + outs() << ", "; + outs() << WebAssembly::anyTypeToString(Type); + } + } + } + } + outs() << "\n"; + return MCDisassembler::Success; +} + MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t /*Address*/, raw_ostream & /*OS*/, raw_ostream &CS) const { @@ -138,7 +178,7 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( if (!WasmInst) return MCDisassembler::Fail; int64_t PrefixedOpc; - if (!nextLEB(PrefixedOpc, Bytes, Size)) + if (!nextLEB(PrefixedOpc, Bytes, Size, false)) return MCDisassembler::Fail; if (PrefixedOpc < 0 || PrefixedOpc >= WebAssemblyInstructionTableSize) return MCDisassembler::Fail; |