Skip to content

Commit 46ec46b

Browse files
authored
wasm-objdump: Improve disassembly of call_indirect (#1866)
Use the text format convention of putting the table before the type. Also track type names so they can be reported along with the table name, if available. Fixes: #1865
1 parent d0e5fe7 commit 46ec46b

File tree

9 files changed

+358
-288
lines changed

9 files changed

+358
-288
lines changed

src/binary-reader-objdump.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop {
5454
Result OnRelocCount(Index count, Index section_index) override;
5555

5656
protected:
57+
std::string_view GetTypeName(Index index) const;
5758
std::string_view GetFunctionName(Index index) const;
5859
std::string_view GetGlobalName(Index index) const;
5960
std::string_view GetLocalName(Index function_index, Index local_index) const;
@@ -141,6 +142,10 @@ Result BinaryReaderObjdumpBase::BeginModule(uint32_t version) {
141142
return Result::Ok;
142143
}
143144

145+
std::string_view BinaryReaderObjdumpBase::GetTypeName(Index index) const {
146+
return objdump_state_->type_names.Get(index);
147+
}
148+
144149
std::string_view BinaryReaderObjdumpBase::GetFunctionName(Index index) const {
145150
return objdump_state_->function_names.Get(index);
146151
}
@@ -276,6 +281,9 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
276281
SetFunctionName(index, name);
277282
break;
278283
*/
284+
case NameSectionSubsection::Type:
285+
SetTypeName(index, name);
286+
break;
279287
case NameSectionSubsection::Global:
280288
SetGlobalName(index, name);
281289
break;
@@ -445,6 +453,7 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
445453
}
446454

447455
protected:
456+
void SetTypeName(Index index, std::string_view name);
448457
void SetFunctionName(Index index, std::string_view name);
449458
void SetGlobalName(Index index, std::string_view name);
450459
void SetLocalName(Index function_index,
@@ -455,6 +464,11 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
455464
void SetSegmentName(Index index, std::string_view name);
456465
};
457466

467+
void BinaryReaderObjdumpPrepass::SetTypeName(Index index,
468+
std::string_view name) {
469+
objdump_state_->type_names.Set(index, name);
470+
}
471+
458472
void BinaryReaderObjdumpPrepass::SetFunctionName(Index index,
459473
std::string_view name) {
460474
objdump_state_->function_names.Set(index, name);
@@ -517,6 +531,7 @@ class BinaryReaderObjdumpDisassemble : public BinaryReaderObjdumpBase {
517531
Result OnOpcodeIndexIndex(Index value, Index value2) override;
518532
Result OnOpcodeUint32(uint32_t value) override;
519533
Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override;
534+
Result OnCallIndirectExpr(uint32_t sig_indix, uint32_t table_index) override;
520535
Result OnOpcodeUint32Uint32Uint32(uint32_t value,
521536
uint32_t value2,
522537
uint32_t value3) override;
@@ -543,6 +558,7 @@ class BinaryReaderObjdumpDisassemble : public BinaryReaderObjdumpBase {
543558
Index current_function_index = 0;
544559
Index local_index_ = 0;
545560
bool in_function_body = false;
561+
bool skip_next_opcode_ = false;
546562
};
547563

548564
std::string BinaryReaderObjdumpDisassemble::BlockSigToString(Type type) const {
@@ -630,6 +646,10 @@ void BinaryReaderObjdumpDisassemble::LogOpcode(const char* fmt, ...) {
630646
// so this should never be called for instructions outside of function bodies
631647
// (i.e. init expresions).
632648
assert(in_function_body);
649+
if (skip_next_opcode_) {
650+
skip_next_opcode_ = false;
651+
return;
652+
}
633653
const Offset immediate_len = state->offset - current_opcode_offset;
634654
const Offset opcode_size = current_opcode.GetLength();
635655
const Offset total_size = opcode_size + immediate_len;
@@ -776,6 +796,28 @@ Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32(uint32_t value,
776796
return Result::Ok;
777797
}
778798

799+
Result BinaryReaderObjdumpDisassemble::OnCallIndirectExpr(
800+
uint32_t sig_index,
801+
uint32_t table_index) {
802+
std::string_view table_name = GetTableName(table_index);
803+
std::string_view type_name = GetTypeName(sig_index);
804+
if (!type_name.empty() && !table_name.empty()) {
805+
LogOpcode("%u <" PRIstringview "> (type %u <" PRIstringview ">)",
806+
table_index, WABT_PRINTF_STRING_VIEW_ARG(table_name), sig_index,
807+
WABT_PRINTF_STRING_VIEW_ARG(type_name));
808+
} else if (!table_name.empty()) {
809+
LogOpcode("%u <" PRIstringview "> (type %u)", table_index,
810+
WABT_PRINTF_STRING_VIEW_ARG(table_name), sig_index);
811+
} else if (!type_name.empty()) {
812+
LogOpcode("%u (type %u <" PRIstringview ">)", table_index, sig_index,
813+
WABT_PRINTF_STRING_VIEW_ARG(type_name));
814+
} else {
815+
LogOpcode("%u (type %u)", table_index, sig_index);
816+
}
817+
skip_next_opcode_ = true;
818+
return Result::Ok;
819+
}
820+
779821
Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32Uint32(
780822
uint32_t value,
781823
uint32_t value2,

src/binary-reader-objdump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct ObjdumpLocalNames {
7676
struct ObjdumpState {
7777
std::vector<Reloc> code_relocations;
7878
std::vector<Reloc> data_relocations;
79+
ObjdumpNames type_names;
7980
ObjdumpNames function_names;
8081
ObjdumpNames global_names;
8182
ObjdumpNames section_names;

test/dump/callindirect.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ Code Disassembly:
7575
000027 func[0]:
7676
000028: 41 00 | i32.const 0
7777
00002a: 41 00 | i32.const 0
78-
00002c: 11 00 00 | call_indirect 0 0
78+
00002c: 11 00 00 | call_indirect 0 (type 0)
7979
00002f: 0b | end
8080
;;; STDOUT ;;)

0 commit comments

Comments
 (0)