[WebAssembly] Add wasm symbol table support to llvm-objdump

Differential Revision: https://reviews.llvm.org/D32760

llvm-svn: 302185
This commit is contained in:
Sam Clegg 2017-05-04 19:32:43 +00:00
parent 4edf5ccb5f
commit e519d7ce80
3 changed files with 60 additions and 22 deletions

View File

@ -41,10 +41,14 @@ public:
DEBUG_FUNCTION_NAME,
};
WasmSymbol(StringRef Name, SymbolType Type) : Name(Name), Type(Type) {}
WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section,
uint32_t ElementIndex)
: Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {}
StringRef Name;
SymbolType Type;
uint32_t Section;
uint32_t ElementIndex;
};
class WasmSection {

View File

@ -253,11 +253,12 @@ Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
case wasm::WASM_NAMES_FUNCTION: {
uint32_t Count = readVaruint32(Ptr);
while (Count--) {
/*uint32_t Index =*/readVaruint32(Ptr);
uint32_t Index = readVaruint32(Ptr);
StringRef Name = readString(Ptr);
if (!Name.empty())
Symbols.emplace_back(Name,
WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME);
WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME,
Sections.size(), Index);
}
break;
}
@ -384,7 +385,7 @@ Error WasmObjectFile::parseTypeSection(const uint8_t *Ptr, const uint8_t *End) {
Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) {
uint32_t Count = readVaruint32(Ptr);
Imports.reserve(Count);
while (Count--) {
for (uint32_t i = 0; i < Count; i++) {
wasm::WasmImport Im;
Im.Module = readString(Ptr);
Im.Field = readString(Ptr);
@ -392,12 +393,14 @@ Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End)
switch (Im.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
Im.SigIndex = readVaruint32(Ptr);
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT);
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT,
Sections.size(), i);
break;
case wasm::WASM_EXTERNAL_GLOBAL:
Im.GlobalType = readVarint7(Ptr);
Im.GlobalMutable = readVaruint1(Ptr);
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT);
Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
Sections.size(), i);
break;
default:
// TODO(sbc): Handle other kinds of imports
@ -475,7 +478,7 @@ Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End)
Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) {
uint32_t Count = readVaruint32(Ptr);
Exports.reserve(Count);
while (Count--) {
for (uint32_t i = 0; i < Count; i++) {
wasm::WasmExport Ex;
Ex.Name = readString(Ptr);
Ex.Kind = readUint8(Ptr);
@ -483,10 +486,12 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
Exports.push_back(Ex);
switch (Ex.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::FUNCTION_EXPORT);
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::FUNCTION_EXPORT,
Sections.size(), i);
break;
case wasm::WASM_EXTERNAL_GLOBAL:
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::GLOBAL_EXPORT);
Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::GLOBAL_EXPORT,
Sections.size(), i);
break;
default:
// TODO(sbc): Handle other kinds of exports
@ -597,20 +602,28 @@ const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.a++; }
uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
uint32_t Result = SymbolRef::SF_None;
const WasmSymbol &Sym = getWasmSymbol(Symb);
switch (Sym.Type) {
case WasmSymbol::SymbolType::FUNCTION_IMPORT:
return object::SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
break;
case WasmSymbol::SymbolType::FUNCTION_EXPORT:
return object::SymbolRef::SF_Global | SymbolRef::SF_Executable;
Result |= SymbolRef::SF_Global | SymbolRef::SF_Executable;
break;
case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
return object::SymbolRef::SF_Executable;
Result |= SymbolRef::SF_Executable;
break;
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
return object::SymbolRef::SF_Undefined;
Result |= SymbolRef::SF_Undefined;
break;
case WasmSymbol::SymbolType::GLOBAL_EXPORT:
return object::SymbolRef::SF_Global;
Result |= SymbolRef::SF_Global;
break;
}
llvm_unreachable("Unknown WasmSymbol::SymbolType");
return Result;
}
basic_symbol_iterator WasmObjectFile::symbol_begin() const {
@ -635,12 +648,12 @@ Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
}
Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
return (uint64_t)Symb.d.a;
return getSymbolValue(Symb);
}
uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
llvm_unreachable("not yet implemented");
return 0;
const WasmSymbol &Sym = getWasmSymbol(Symb);
return Sym.ElementIndex;
}
uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
@ -655,14 +668,27 @@ uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
Expected<SymbolRef::Type>
WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
llvm_unreachable("not yet implemented");
return errorCodeToError(object_error::invalid_symbol_index);
const WasmSymbol &Sym = getWasmSymbol(Symb);
switch (Sym.Type) {
case WasmSymbol::SymbolType::FUNCTION_IMPORT:
case WasmSymbol::SymbolType::FUNCTION_EXPORT:
case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
return SymbolRef::ST_Function;
case WasmSymbol::SymbolType::GLOBAL_IMPORT:
case WasmSymbol::SymbolType::GLOBAL_EXPORT:
return SymbolRef::ST_Data;
}
llvm_unreachable("Unknown WasmSymbol::SymbolType");
return SymbolRef::ST_Other;
}
Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
llvm_unreachable("not yet implemented");
return errorCodeToError(object_error::invalid_symbol_index);
DataRefImpl Ref;
Ref.d.a = getWasmSymbol(Symb).Section;
return section_iterator(SectionRef(Ref, this));
}
void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }

View File

@ -0,0 +1,8 @@
RUN: llvm-objdump -t %p/../Inputs/test.wasm | FileCheck %s
CHECK: SYMBOL TABLE:
CHECK: 00000000 l F IMPORT bar
CHECK: 00000000 g F EXPORT baz
CHECK: 00000001 g F EXPORT quux
CHECK: 00000000 l F name $import
CHECK: 00000001 l F name $func0