Index: llvm/trunk/include/llvm/Object/Binary.h =================================================================== --- llvm/trunk/include/llvm/Object/Binary.h +++ llvm/trunk/include/llvm/Object/Binary.h @@ -59,6 +59,8 @@ ID_MachO64L, // MachO 64-bit, little endian ID_MachO64B, // MachO 64-bit, big endian + ID_Wasm, + ID_EndObjects }; @@ -115,6 +117,8 @@ return TypeID == ID_COFF; } + bool isWasm() const { return TypeID == ID_Wasm; } + bool isCOFFImportFile() const { return TypeID == ID_COFFImportFile; } Index: llvm/trunk/include/llvm/Object/ObjectFile.h =================================================================== --- llvm/trunk/include/llvm/Object/ObjectFile.h +++ llvm/trunk/include/llvm/Object/ObjectFile.h @@ -29,6 +29,7 @@ class ObjectFile; class COFFObjectFile; class MachOObjectFile; +class WasmObjectFile; class SymbolRef; class symbol_iterator; @@ -304,6 +305,8 @@ uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0); + static Expected> + createWasmObjectFile(MemoryBufferRef Object); }; // Inline function definitions. Index: llvm/trunk/include/llvm/Object/Wasm.h =================================================================== --- llvm/trunk/include/llvm/Object/Wasm.h +++ llvm/trunk/include/llvm/Object/Wasm.h @@ -0,0 +1,99 @@ +//===- WasmObjectFile.h - Wasm object file implementation -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the WasmObjectFile class, which implements the ObjectFile +// interface for Wasm files. +// +// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_WASM_H +#define LLVM_OBJECT_WASM_H + +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Wasm.h" + +namespace llvm { +namespace object { + +class WasmObjectFile : public ObjectFile { +public: + WasmObjectFile(MemoryBufferRef Object, Error &Err); + const wasm::WasmObjectHeader &getHeader() const; + const wasm::WasmSection *getWasmSection(const SectionRef &Section) const; + static bool classof(const Binary *v) { return v->isWasm(); } + +protected: + void moveSymbolNext(DataRefImpl &Symb) const override; + + std::error_code printSymbolName(raw_ostream &OS, + DataRefImpl Symb) const override; + + uint32_t getSymbolFlags(DataRefImpl Symb) const override; + + basic_symbol_iterator symbol_begin() const override; + + basic_symbol_iterator symbol_end() const override; + Expected getSymbolName(DataRefImpl Symb) const override; + + Expected getSymbolAddress(DataRefImpl Symb) const override; + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; + Expected getSymbolType(DataRefImpl Symb) const override; + Expected getSymbolSection(DataRefImpl Symb) const override; + + // Overrides from SectionRef. + void moveSectionNext(DataRefImpl &Sec) const override; + std::error_code getSectionName(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionSize(DataRefImpl Sec) const override; + std::error_code getSectionContents(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAlignment(DataRefImpl Sec) const override; + bool isSectionCompressed(DataRefImpl Sec) const override; + bool isSectionText(DataRefImpl Sec) const override; + bool isSectionData(DataRefImpl Sec) const override; + bool isSectionBSS(DataRefImpl Sec) const override; + bool isSectionVirtual(DataRefImpl Sec) const override; + bool isSectionBitcode(DataRefImpl Sec) const override; + relocation_iterator section_rel_begin(DataRefImpl Sec) const override; + relocation_iterator section_rel_end(DataRefImpl Sec) const override; + section_iterator getRelocatedSection(DataRefImpl Sec) const override; + + // Overrides from RelocationRef. + void moveRelocationNext(DataRefImpl &Rel) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; + symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const override; + + section_iterator section_begin() const override; + section_iterator section_end() const override; + uint8_t getBytesInAddress() const override; + StringRef getFileFormatName() const override; + unsigned getArch() const override; + SubtargetFeatures getFeatures() const override; + bool isRelocatableObject() const override; + +private: + const uint8_t *getPtr(size_t Offset) const; + Error parseUserSection(wasm::WasmSection &Sec, const uint8_t *Ptr, + size_t Length); + + wasm::WasmObjectHeader Header; + std::vector Sections; +}; +} +} + +#endif Index: llvm/trunk/include/llvm/Support/FileSystem.h =================================================================== --- llvm/trunk/include/llvm/Support/FileSystem.h +++ llvm/trunk/include/llvm/Support/FileSystem.h @@ -262,7 +262,8 @@ coff_object, ///< COFF object file coff_import_library, ///< COFF import library pecoff_executable, ///< PECOFF executable file - windows_resource ///< Windows compiled resource file (.rc) + windows_resource, ///< Windows compiled resource file (.rc) + wasm_object ///< WebAssembly Object file }; bool is_object() const { Index: llvm/trunk/include/llvm/Support/Wasm.h =================================================================== --- llvm/trunk/include/llvm/Support/Wasm.h +++ llvm/trunk/include/llvm/Support/Wasm.h @@ -0,0 +1,58 @@ +//===- Wasm.h - Wasm object file format -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines manifest constants for the wasm object file format. +// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_WASM_H +#define LLVM_SUPPORT_WASM_H + +#include "llvm/ADT/ArrayRef.h" + +namespace llvm { +namespace wasm { + +// Object file magic string. +const char WasmMagic[] = {'\0', 'a', 's', 'm'}; +// Wasm binary format version +const uint32_t WasmVersion = 0xd; + +struct WasmObjectHeader { + StringRef Magic; + uint32_t Version; +}; + +struct WasmSection { + uint32_t Type; // Section type (See below) + uint32_t Offset; // Offset with in the file + StringRef Name; // Section name (User-defined sections only) + ArrayRef Content; // Section content +}; + +enum : unsigned { + WASM_SEC_USER = 0, // User-defined section + WASM_SEC_TYPE = 1, // Function signature declarations + WASM_SEC_IMPORT = 2, // Import declarations + WASM_SEC_FUNCTION = 3, // Function declarations + WASM_SEC_TABLE = 4, // Indirect function table and other tables + WASM_SEC_MEMORY = 5, // Memory attributes + WASM_SEC_GLOBAL = 6, // Global declarations + WASM_SEC_EXPORT = 7, // Exports + WASM_SEC_START = 8, // Start function declaration + WASM_SEC_ELEM = 9, // Elements section + WASM_SEC_CODE = 10, // Function bodies (code) + WASM_SEC_DATA = 11 // Data segments +}; + +} // end namespace wasm +} // end namespace llvm + +#endif Index: llvm/trunk/lib/Object/Binary.cpp =================================================================== --- llvm/trunk/lib/Object/Binary.cpp +++ llvm/trunk/lib/Object/Binary.cpp @@ -63,6 +63,7 @@ case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::pecoff_executable: case sys::fs::file_magic::bitcode: + case sys::fs::file_magic::wasm_object: return ObjectFile::createSymbolicFile(Buffer, Type, Context); case sys::fs::file_magic::macho_universal_binary: return MachOUniversalBinary::create(Buffer); Index: llvm/trunk/lib/Object/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Object/CMakeLists.txt +++ llvm/trunk/lib/Object/CMakeLists.txt @@ -15,6 +15,7 @@ RecordStreamer.cpp SymbolicFile.cpp SymbolSize.cpp + WasmObjectFile.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Object Index: llvm/trunk/lib/Object/ObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/ObjectFile.cpp +++ llvm/trunk/lib/Object/ObjectFile.cpp @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Object/ObjectFile.h" #include "llvm/Object/COFF.h" #include "llvm/Object/MachO.h" -#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Wasm.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -105,6 +106,8 @@ case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::pecoff_executable: return errorOrToExpected(createCOFFObjectFile(Object)); + case sys::fs::file_magic::wasm_object: + return createWasmObjectFile(Object); } llvm_unreachable("Unexpected Object File Type"); } Index: llvm/trunk/lib/Object/SymbolicFile.cpp =================================================================== --- llvm/trunk/lib/Object/SymbolicFile.cpp +++ llvm/trunk/lib/Object/SymbolicFile.cpp @@ -58,6 +58,7 @@ case sys::fs::file_magic::macho_dsym_companion: case sys::fs::file_magic::macho_kext_bundle: case sys::fs::file_magic::pecoff_executable: + case sys::fs::file_magic::wasm_object: return ObjectFile::createObjectFile(Object, Type); case sys::fs::file_magic::coff_import_library: return std::unique_ptr(new COFFImportFile(Object)); Index: llvm/trunk/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/WasmObjectFile.cpp +++ llvm/trunk/lib/Object/WasmObjectFile.cpp @@ -0,0 +1,315 @@ +//===- WasmObjectFile.cpp - Wasm object file implementation -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/Wasm.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/LEB128.h" + +#include + +namespace llvm { +namespace object { + +Expected> +ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) { + Error Err = Error::success(); + auto ObjectFile = llvm::make_unique(Buffer, Err); + if (Err) + return std::move(Err); + + return std::move(ObjectFile); +} + +namespace { + +uint32_t readUint32(const uint8_t *&Ptr) { + uint32_t Result = support::endian::read32le(Ptr); + Ptr += sizeof(Result); + return Result; +} + +uint64_t readULEB128(const uint8_t *&Ptr) { + unsigned Count; + uint64_t Result = decodeULEB128(Ptr, &Count); + Ptr += Count; + return Result; +} + +StringRef readString(const uint8_t *&Ptr) { + uint32_t StringLen = readULEB128(Ptr); + StringRef Return = StringRef(reinterpret_cast(Ptr), StringLen); + Ptr += StringLen; + return Return; +} + +Error readSection(wasm::WasmSection &Section, const uint8_t *&Ptr, + const uint8_t *Start) { + // TODO(sbc): Avoid reading past EOF in the case of malformed files. + Section.Offset = Ptr - Start; + Section.Type = readULEB128(Ptr); + uint32_t Size = readULEB128(Ptr); + if (Size == 0) + return make_error("Zero length section", + object_error::parse_failed); + Section.Content = ArrayRef(Ptr, Size); + Ptr += Size; + return Error::success(); +} +} + +WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err) + : ObjectFile(Binary::ID_Wasm, Buffer) { + ErrorAsOutParameter ErrAsOutParam(&Err); + Header.Magic = getData().substr(0, 4); + if (Header.Magic != StringRef("\0asm", 4)) { + Err = make_error("Bad magic number", + object_error::parse_failed); + return; + } + const uint8_t *Ptr = getPtr(4); + Header.Version = readUint32(Ptr); + if (Header.Version != wasm::WasmVersion) { + Err = make_error("Bad version number", + object_error::parse_failed); + return; + } + + const uint8_t *Eof = getPtr(getData().size()); + wasm::WasmSection Sec; + 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()))) + return; + } + Sections.push_back(Sec); + } +} + +Error WasmObjectFile::parseUserSection(wasm::WasmSection &Sec, + const uint8_t *Ptr, size_t Length) { + Sec.Name = readString(Ptr); + return Error::success(); +} + +const uint8_t *WasmObjectFile::getPtr(size_t Offset) const { + return reinterpret_cast(getData().substr(Offset, 1).data()); +} + +const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const { + return Header; +} + +void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { + llvm_unreachable("not yet implemented"); +} + +std::error_code WasmObjectFile::printSymbolName(raw_ostream &OS, + DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return object_error::invalid_symbol_index; +} + +uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +basic_symbol_iterator WasmObjectFile::symbol_begin() const { + return BasicSymbolRef(DataRefImpl(), this); +} + +basic_symbol_iterator WasmObjectFile::symbol_end() const { + return BasicSymbolRef(DataRefImpl(), this); +} + +Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return errorCodeToError(object_error::invalid_symbol_index); +} + +Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return errorCodeToError(object_error::invalid_symbol_index); +} + +uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +Expected +WasmObjectFile::getSymbolType(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return errorCodeToError(object_error::invalid_symbol_index); +} + +Expected +WasmObjectFile::getSymbolSection(DataRefImpl Symb) const { + llvm_unreachable("not yet implemented"); + return errorCodeToError(object_error::invalid_symbol_index); +} + +void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; } + +std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec, + StringRef &Res) const { + const wasm::WasmSection &S = Sections[Sec.d.a]; +#define ECase(X) \ + case wasm::WASM_SEC_##X: \ + Res = #X; \ + break + switch (S.Type) { + ECase(TYPE); + ECase(IMPORT); + ECase(FUNCTION); + ECase(TABLE); + ECase(MEMORY); + ECase(GLOBAL); + ECase(EXPORT); + ECase(START); + ECase(ELEM); + ECase(CODE); + ECase(DATA); + case wasm::WASM_SEC_USER: + Res = S.Name; + break; + default: + return object_error::invalid_section_index; + } +#undef ECase + return std::error_code(); +} + +uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; } + +uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const { + const wasm::WasmSection &S = Sections[Sec.d.a]; + return S.Content.size(); +} + +std::error_code WasmObjectFile::getSectionContents(DataRefImpl Sec, + StringRef &Res) const { + const wasm::WasmSection &S = Sections[Sec.d.a]; + // This will never fail since wasm sections can never be empty (user-sections + // must have a name and non-user sections each have a defined structure). + Res = StringRef(reinterpret_cast(S.Content.data()), + S.Content.size()); + return std::error_code(); +} + +uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const { + return 1; +} + +bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const { + return false; +} + +bool WasmObjectFile::isSectionText(DataRefImpl Sec) const { + const wasm::WasmSection &S = Sections[Sec.d.a]; + return S.Type == wasm::WASM_SEC_CODE; +} + +bool WasmObjectFile::isSectionData(DataRefImpl Sec) const { + const wasm::WasmSection &S = Sections[Sec.d.a]; + return S.Type == wasm::WASM_SEC_DATA; +} + +bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; } + +bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; } + +bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; } + +relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Sec) const { + llvm_unreachable("not yet implemented"); + RelocationRef Rel; + return relocation_iterator(Rel); +} + +relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Sec) const { + llvm_unreachable("not yet implemented"); + RelocationRef Rel; + return relocation_iterator(Rel); +} + +section_iterator WasmObjectFile::getRelocatedSection(DataRefImpl Sec) const { + llvm_unreachable("not yet implemented"); + SectionRef Ref; + return section_iterator(Ref); +} + +void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const { + llvm_unreachable("not yet implemented"); +} + +uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Rel) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Rel) const { + llvm_unreachable("not yet implemented"); + SymbolRef Ref; + return symbol_iterator(Ref); +} + +uint64_t WasmObjectFile::getRelocationType(DataRefImpl Rel) const { + llvm_unreachable("not yet implemented"); + return 0; +} + +void WasmObjectFile::getRelocationTypeName( + DataRefImpl Rel, SmallVectorImpl &Result) const { + llvm_unreachable("not yet implemented"); +} + +section_iterator WasmObjectFile::section_begin() const { + DataRefImpl Ref; + Ref.d.a = 0; + return section_iterator(SectionRef(Ref, this)); +} + +section_iterator WasmObjectFile::section_end() const { + DataRefImpl Ref; + Ref.d.a = Sections.size(); + return section_iterator(SectionRef(Ref, this)); +} + +uint8_t WasmObjectFile::getBytesInAddress() const { return 4; } + +StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; } + +unsigned WasmObjectFile::getArch() const { return Triple::wasm32; } + +SubtargetFeatures WasmObjectFile::getFeatures() const { + return SubtargetFeatures(); +} + +bool WasmObjectFile::isRelocatableObject() const { return false; } + +const wasm::WasmSection * +WasmObjectFile::getWasmSection(const SectionRef &Section) const { + return &Sections[Section.getRawDataRefImpl().d.a]; +} + +} // end namespace object +} // end namespace llvm Index: llvm/trunk/lib/Support/Path.cpp =================================================================== --- llvm/trunk/lib/Support/Path.cpp +++ llvm/trunk/lib/Support/Path.cpp @@ -1010,6 +1010,8 @@ // 0x0000 = COFF unknown machine type if (Magic[1] == 0) return file_magic::coff_object; + if (startswith(Magic, "\0asm")) + return file_magic::wasm_object; break; } case 0xDE: // 0x0B17C0DE = BC wraper Index: llvm/trunk/test/tools/llvm-objdump/wasm.txt =================================================================== --- llvm/trunk/test/tools/llvm-objdump/wasm.txt +++ llvm/trunk/test/tools/llvm-objdump/wasm.txt @@ -0,0 +1,24 @@ +# RUN: llvm-objdump -h %p/Inputs/test.wasm | FileCheck %s + +# CHECK: Sections: +# CHECK: Idx Name Size Address Type +# CHECK: 0 TYPE 0000000f 0000000000000000 +# CHECK: 1 IMPORT 0000000b 0000000000000000 +# CHECK: 2 FUNCTION 00000003 0000000000000000 +# CHECK: 3 TABLE 00000005 0000000000000000 +# CHECK: 4 EXPORT 0000000e 0000000000000000 +# CHECK: 5 ELEM 00000007 0000000000000000 +# CHECK: 6 CODE 0000002a 0000000000000000 TEXT +# CHECK: 7 name 0000002c 0000000000000000 + +# RUN: llvm-objdump -p %p/Inputs/test.wasm | FileCheck %s -check-prefix CHECK-HEADER + +# CHECK-HEADER: Program Header: +# CHECK-HEADER: Version: 0xd + +# RUN: llvm-objdump -s --section=CODE %p/Inputs/test.wasm | FileCheck %s -check-prefix CHECK-SECTIONS + +# CHECK-SECTIONS: Contents of section CODE: +# CHECK-SECTIONS: 0000 02070043 0000803f 0b200201 7d017c10 ...C...?. ..}.|. +# CHECK-SECTIONS: 0010 001a4100 10011a41 00410111 00001a20 ..A....A.A..... +# CHECK-SECTIONS: 0020 011a4300 00000021 020b ..C....!.. Index: llvm/trunk/tools/llvm-objdump/CMakeLists.txt =================================================================== --- llvm/trunk/tools/llvm-objdump/CMakeLists.txt +++ llvm/trunk/tools/llvm-objdump/CMakeLists.txt @@ -19,6 +19,7 @@ COFFDump.cpp ELFDump.cpp MachODump.cpp + WasmDump.cpp ) if(HAVE_LIBXAR) Index: llvm/trunk/tools/llvm-objdump/WasmDump.cpp =================================================================== --- llvm/trunk/tools/llvm-objdump/WasmDump.cpp +++ llvm/trunk/tools/llvm-objdump/WasmDump.cpp @@ -0,0 +1,28 @@ +//===-- WasmDump.cpp - wasm-specific dumper ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file implements the wasm-specific dumper for llvm-objdump. +/// +//===----------------------------------------------------------------------===// + +#include "llvm-objdump.h" +#include "llvm/Object/Wasm.h" + +using namespace llvm; +using namespace object; + +void llvm::printWasmFileHeader(const object::ObjectFile *Obj) { + const WasmObjectFile *File = dyn_cast(Obj); + + outs() << "Program Header:\n"; + outs() << "Version: 0x"; + outs().write_hex(File->getHeader().Version); + outs() << "\n"; +} Index: llvm/trunk/tools/llvm-objdump/llvm-objdump.h =================================================================== --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h @@ -79,6 +79,7 @@ void printCOFFSymbolTable(const object::COFFObjectFile *o); void printMachOFileHeader(const object::ObjectFile *o); void printMachOLoadCommands(const object::ObjectFile *o); +void printWasmFileHeader(const object::ObjectFile *o); void printExportsTrie(const object::ObjectFile *o); void printRebaseTable(const object::ObjectFile *o); void printBindTable(const object::ObjectFile *o); Index: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp @@ -1910,6 +1910,8 @@ return printELFFileHeader(o); if (o->isCOFF()) return printCOFFFileHeader(o); + if (o->isWasm()) + return printWasmFileHeader(o); if (o->isMachO()) { printMachOFileHeader(o); if (!onlyFirst)