forked from OSchip/llvm-project
[WebAssembly] Add wasm support for llvm-readobj
Create a WasmDumper subclass of ObjDumper to support Webassembly binary files. Patch by Sam Clegg Differential Revision: https://reviews.llvm.org/D27355 llvm-svn: 293569
This commit is contained in:
parent
642a2365fb
commit
6d76b7b455
|
@ -87,8 +87,8 @@ protected:
|
|||
|
||||
private:
|
||||
const uint8_t *getPtr(size_t Offset) const;
|
||||
Error parseUserSection(wasm::WasmSection &Sec, const uint8_t *Ptr,
|
||||
size_t Length);
|
||||
Error parseCustomSection(wasm::WasmSection &Sec, const uint8_t *Ptr,
|
||||
size_t Length);
|
||||
|
||||
wasm::WasmObjectHeader Header;
|
||||
std::vector<wasm::WasmSection> Sections;
|
||||
|
|
|
@ -38,7 +38,7 @@ struct WasmSection {
|
|||
};
|
||||
|
||||
enum : unsigned {
|
||||
WASM_SEC_USER = 0, // User-defined section
|
||||
WASM_SEC_CUSTOM = 0, // Custom / User-defined section
|
||||
WASM_SEC_TYPE = 1, // Function signature declarations
|
||||
WASM_SEC_IMPORT = 2, // Import declarations
|
||||
WASM_SEC_FUNCTION = 3, // Function declarations
|
||||
|
|
|
@ -83,16 +83,17 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
|
|||
while (Ptr < Eof) {
|
||||
if ((Err = readSection(Sec, Ptr, getPtr(0))))
|
||||
return;
|
||||
if (Sec.Type == wasm::WASM_SEC_USER) {
|
||||
if ((Err = parseUserSection(Sec, Sec.Content.data(), Sec.Content.size())))
|
||||
if (Sec.Type == wasm::WASM_SEC_CUSTOM) {
|
||||
if ((Err =
|
||||
parseCustomSection(Sec, Sec.Content.data(), Sec.Content.size())))
|
||||
return;
|
||||
}
|
||||
Sections.push_back(Sec);
|
||||
}
|
||||
}
|
||||
|
||||
Error WasmObjectFile::parseUserSection(wasm::WasmSection &Sec,
|
||||
const uint8_t *Ptr, size_t Length) {
|
||||
Error WasmObjectFile::parseCustomSection(wasm::WasmSection &Sec,
|
||||
const uint8_t *Ptr, size_t Length) {
|
||||
Sec.Name = readString(Ptr);
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -186,7 +187,7 @@ std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
|
|||
ECase(ELEM);
|
||||
ECase(CODE);
|
||||
ECase(DATA);
|
||||
case wasm::WASM_SEC_USER:
|
||||
case wasm::WASM_SEC_CUSTOM:
|
||||
Res = S.Name;
|
||||
break;
|
||||
default:
|
||||
|
|
Binary file not shown.
|
@ -26,6 +26,12 @@ RUN: llvm-readobj -h %p/Inputs/magic.coff-importlib \
|
|||
RUN: | FileCheck %s -check-prefix COFF-IMPORTLIB
|
||||
RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-lanai \
|
||||
RUN: | FileCheck %s -check-prefix ELF-LANAI
|
||||
# trivial.obj.wasm was generated using wast2wasm which is part of the wabt
|
||||
# project (https://github.com/WebAssembly/wabt) using the following command:
|
||||
# $ wast2wasm --debug-names ./test/roundtrip/generate-some-names.txt -o \
|
||||
# trivial.obj.wasm
|
||||
RUN: llvm-readobj -h %p/Inputs/trivial.obj.wasm \
|
||||
RUN: | FileCheck %s -check-prefix WASM
|
||||
|
||||
COFF-ARM: File: {{(.*[/\\])?}}trivial.obj.coff-arm
|
||||
COFF-ARM-NEXT: Format: COFF-ARM
|
||||
|
@ -367,3 +373,8 @@ ELF-LANAI-NEXT: SectionHeaderEntrySize: 40
|
|||
ELF-LANAI-NEXT: SectionHeaderCount: 8
|
||||
ELF-LANAI-NEXT: StringTableSectionIndex: 1
|
||||
ELF-LANAI-NEXT: }
|
||||
|
||||
WASM: Format: WASM
|
||||
WASM-NEXT: Arch: wasm32
|
||||
WASM-NEXT: AddressSize: 32bit
|
||||
WASM-NEXT: Version: 0xD
|
||||
|
|
|
@ -14,6 +14,8 @@ RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
|
|||
RUN: | FileCheck %s -check-prefix MACHO-PPC64
|
||||
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-arm \
|
||||
RUN: | FileCheck %s -check-prefix MACHO-ARM
|
||||
RUN: llvm-readobj -s %p/Inputs/trivial.obj.wasm \
|
||||
RUN: | FileCheck %s -check-prefix WASM
|
||||
|
||||
COFF: Sections [
|
||||
COFF-NEXT: Section {
|
||||
|
@ -490,3 +492,47 @@ MACHO-ARM-NEXT: Reserved1: 0x0
|
|||
MACHO-ARM-NEXT: Reserved2: 0x0
|
||||
MACHO-ARM-NEXT: }
|
||||
MACHO-ARM-NEXT:]
|
||||
|
||||
WASM: Sections [
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: TYPE (0x1)
|
||||
WASM-NEXT: Size: 15
|
||||
WASM-NEXT: Offset: 8
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: IMPORT (0x2)
|
||||
WASM-NEXT: Size: 11
|
||||
WASM-NEXT: Offset: 25
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: FUNCTION (0x3)
|
||||
WASM-NEXT: Size: 3
|
||||
WASM-NEXT: Offset: 38
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: TABLE (0x4)
|
||||
WASM-NEXT: Size: 5
|
||||
WASM-NEXT: Offset: 43
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: EXPORT (0x7)
|
||||
WASM-NEXT: Size: 14
|
||||
WASM-NEXT: Offset: 50
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: ELEM (0x9)
|
||||
WASM-NEXT: Size: 7
|
||||
WASM-NEXT: Offset: 66
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: CODE (0xA)
|
||||
WASM-NEXT: Size: 42
|
||||
WASM-NEXT: Offset: 75
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: Section {
|
||||
WASM-NEXT: Type: CUSTOM (0x0)
|
||||
WASM-NEXT: Size: 44
|
||||
WASM-NEXT: Offset: 119
|
||||
WASM-NEXT: Name: name
|
||||
WASM-NEXT: }
|
||||
WASM-NEXT: ]
|
||||
|
|
|
@ -15,5 +15,6 @@ add_llvm_tool(llvm-readobj
|
|||
llvm-readobj.cpp
|
||||
MachODumper.cpp
|
||||
ObjDumper.cpp
|
||||
WasmDumper.cpp
|
||||
Win64EHDumper.cpp
|
||||
)
|
||||
|
|
|
@ -96,6 +96,10 @@ std::error_code createMachODumper(const object::ObjectFile *Obj,
|
|||
ScopedPrinter &Writer,
|
||||
std::unique_ptr<ObjDumper> &Result);
|
||||
|
||||
std::error_code createWasmDumper(const object::ObjectFile *Obj,
|
||||
ScopedPrinter &Writer,
|
||||
std::unique_ptr<ObjDumper> &Result);
|
||||
|
||||
void dumpCOFFImportFile(const object::COFFImportFile *File);
|
||||
|
||||
void dumpCodeViewMergedTypes(ScopedPrinter &Writer,
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
//===-- WasmDumper.cpp - Wasm-specific object file dumper -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Wasm-specific dumper for llvm-readobj.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Error.h"
|
||||
#include "ObjDumper.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
namespace {
|
||||
|
||||
const char *wasmSectionTypeToString(uint32_t Type) {
|
||||
#define ECase(X) \
|
||||
case wasm::WASM_SEC_##X: \
|
||||
return #X;
|
||||
switch (Type) {
|
||||
ECase(CUSTOM);
|
||||
ECase(TYPE);
|
||||
ECase(IMPORT);
|
||||
ECase(FUNCTION);
|
||||
ECase(TABLE);
|
||||
ECase(MEMORY);
|
||||
ECase(GLOBAL);
|
||||
ECase(EXPORT);
|
||||
ECase(START);
|
||||
ECase(ELEM);
|
||||
ECase(CODE);
|
||||
ECase(DATA);
|
||||
}
|
||||
#undef ECase
|
||||
return "";
|
||||
}
|
||||
|
||||
class WasmDumper : public ObjDumper {
|
||||
public:
|
||||
WasmDumper(const WasmObjectFile *Obj, ScopedPrinter &Writer)
|
||||
: ObjDumper(Writer), Obj(Obj) {}
|
||||
|
||||
void printFileHeaders() override {
|
||||
W.printHex("Version", Obj->getHeader().Version);
|
||||
}
|
||||
|
||||
void printSections() override {
|
||||
ListScope Group(W, "Sections");
|
||||
for (const SectionRef &Section : Obj->sections()) {
|
||||
const wasm::WasmSection *WasmSec = Obj->getWasmSection(Section);
|
||||
DictScope SectionD(W, "Section");
|
||||
const char *Type = wasmSectionTypeToString(WasmSec->Type);
|
||||
W.printHex("Type", Type, WasmSec->Type);
|
||||
W.printNumber("Size", WasmSec->Content.size());
|
||||
W.printNumber("Offset", WasmSec->Offset);
|
||||
if (WasmSec->Type == wasm::WASM_SEC_CUSTOM) {
|
||||
W.printString("Name", WasmSec->Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
void printRelocations() override { llvm_unreachable("unimplemented"); }
|
||||
void printSymbols() override { llvm_unreachable("unimplemented"); }
|
||||
void printDynamicSymbols() override { llvm_unreachable("unimplemented"); }
|
||||
void printUnwindInfo() override { llvm_unreachable("unimplemented"); }
|
||||
void printStackMap() const override { llvm_unreachable("unimplemented"); }
|
||||
|
||||
private:
|
||||
const WasmObjectFile *Obj;
|
||||
};
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
std::error_code createWasmDumper(const object::ObjectFile *Obj,
|
||||
ScopedPrinter &Writer,
|
||||
std::unique_ptr<ObjDumper> &Result) {
|
||||
const WasmObjectFile *WasmObj = dyn_cast<WasmObjectFile>(Obj);
|
||||
assert(WasmObj && "createWasmDumper called with non-wasm object");
|
||||
|
||||
Result.reset(new WasmDumper(WasmObj, Writer));
|
||||
return readobj_error::success;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
|
@ -358,6 +358,8 @@ static std::error_code createDumper(const ObjectFile *Obj,
|
|||
return createELFDumper(Obj, Writer, Result);
|
||||
if (Obj->isMachO())
|
||||
return createMachODumper(Obj, Writer, Result);
|
||||
if (Obj->isWasm())
|
||||
return createWasmDumper(Obj, Writer, Result);
|
||||
|
||||
return readobj_error::unsupported_obj_file_format;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue