forked from OSchip/llvm-project
[llvm-objdump][WebAssembly] Fix llvm-objdump on files without symbols
If a file has no symbols, perhaps because it is a linked executable, synthesize some symbols by walking the code section. Otherwise the disassembler will try to treat the whole code section as a function, which won't parse. Fixes https://bugs.llvm.org/show_bug.cgi?id=50957. Differential Revision: https://reviews.llvm.org/D105539
This commit is contained in:
parent
4504e1134c
commit
db69ea40a9
|
@ -0,0 +1,49 @@
|
|||
# RUN: yaml2obj -o %t.wasm %s
|
||||
# RUN: llvm-objdump -d %t.wasm | FileCheck %s
|
||||
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Index: 1
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 1 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 20000B
|
||||
- Type: CUSTOM
|
||||
Name: name
|
||||
FunctionNames:
|
||||
- Index: 0
|
||||
Name: f
|
||||
- Index: 1
|
||||
Name: g
|
||||
...
|
||||
|
||||
# CHECK: Disassembly of section CODE:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000000 <CODE>:
|
||||
# CHECK-NEXT: # 2 functions in section.
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000001 <f>:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 3: 0b end
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000004 <g>:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 6: 20 00 local.get 0
|
||||
# CHECK-NEXT: 8: 0b end
|
|
@ -0,0 +1,42 @@
|
|||
# RUN: yaml2obj -o %t.wasm %s
|
||||
# RUN: llvm-objdump -d %t.wasm | FileCheck %s
|
||||
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x1
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ParamTypes: []
|
||||
ReturnTypes: []
|
||||
- Index: 1
|
||||
ParamTypes:
|
||||
- I32
|
||||
ReturnTypes:
|
||||
- I32
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0, 1 ]
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals: []
|
||||
Body: 0B
|
||||
- Index: 1
|
||||
Locals: []
|
||||
Body: 20000B
|
||||
...
|
||||
|
||||
# CHECK: Disassembly of section CODE:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000000 <CODE>:
|
||||
# CHECK-NEXT: # 2 functions in section.
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000001 <>:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 3: 0b end
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 00000004 <>:
|
||||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: 6: 20 00 local.get 0
|
||||
# CHECK-NEXT: 8: 0b end
|
|
@ -736,6 +736,43 @@ addDynamicElfSymbols(const ObjectFile *Obj,
|
|||
llvm_unreachable("Unsupported binary format");
|
||||
}
|
||||
|
||||
static Optional<SectionRef> getWasmCodeSection(const WasmObjectFile *Obj) {
|
||||
for (auto SecI : Obj->sections()) {
|
||||
const WasmSection &Section = Obj->getWasmSection(SecI);
|
||||
if (Section.Type == wasm::WASM_SEC_CODE)
|
||||
return SecI;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
static void
|
||||
addMissingWasmCodeSymbols(const WasmObjectFile *Obj,
|
||||
std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
|
||||
Optional<SectionRef> Section = getWasmCodeSection(Obj);
|
||||
if (!Section)
|
||||
return;
|
||||
SectionSymbolsTy &Symbols = AllSymbols[*Section];
|
||||
|
||||
std::set<uint64_t> SymbolAddresses;
|
||||
for (const auto &Sym : Symbols)
|
||||
SymbolAddresses.insert(Sym.Addr);
|
||||
|
||||
for (const wasm::WasmFunction &Function : Obj->functions()) {
|
||||
uint64_t Address = Function.CodeSectionOffset;
|
||||
// Only add fallback symbols for functions not already present in the symbol
|
||||
// table.
|
||||
if (SymbolAddresses.count(Address))
|
||||
continue;
|
||||
// This function has no symbol, so it should have no SymbolName.
|
||||
assert(Function.SymbolName.empty());
|
||||
// We use DebugName for the name, though it may be empty if there is no
|
||||
// "name" custom section, or that section is missing a name for this
|
||||
// function.
|
||||
StringRef Name = Function.DebugName;
|
||||
Symbols.emplace_back(Address, Name, ELF::STT_NOTYPE);
|
||||
}
|
||||
}
|
||||
|
||||
static void addPltEntries(const ObjectFile *Obj,
|
||||
std::map<SectionRef, SectionSymbolsTy> &AllSymbols,
|
||||
StringSaver &Saver) {
|
||||
|
@ -1126,6 +1163,9 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
|
|||
if (AllSymbols.empty() && Obj->isELF())
|
||||
addDynamicElfSymbols(Obj, AllSymbols);
|
||||
|
||||
if (Obj->isWasm())
|
||||
addMissingWasmCodeSymbols(cast<WasmObjectFile>(Obj), AllSymbols);
|
||||
|
||||
BumpPtrAllocator A;
|
||||
StringSaver Saver(A);
|
||||
addPltEntries(Obj, AllSymbols, Saver);
|
||||
|
|
Loading…
Reference in New Issue