summaryrefslogtreecommitdiff
path: root/src/binary-reader-objdump.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/binary-reader-objdump.cc')
-rw-r--r--src/binary-reader-objdump.cc217
1 files changed, 133 insertions, 84 deletions
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc
index 0a8b7dc8..adae0761 100644
--- a/src/binary-reader-objdump.cc
+++ b/src/binary-reader-objdump.cc
@@ -50,6 +50,7 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop {
BinarySection section_type,
Offset size) override;
+ Result OnOpcode(Opcode Opcode) override;
Result OnRelocCount(Index count, Index section_index) override;
protected:
@@ -78,6 +79,7 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop {
std::vector<BinarySection> section_types_;
bool section_found_ = false;
std::string module_name_;
+ Opcode current_opcode = Opcode::Unreachable;
std::unique_ptr<FileStream> err_stream_;
};
@@ -211,6 +213,11 @@ Offset BinaryReaderObjdumpBase::GetPrintOffset(Offset offset) const {
: offset;
}
+Result BinaryReaderObjdumpBase::OnOpcode(Opcode opcode) {
+ current_opcode = opcode;
+ return Result::Ok;
+}
+
Result BinaryReaderObjdumpBase::OnRelocCount(Index count, Index section_index) {
if (section_index >= section_types_.size()) {
err_stream_->Writef("invalid relocation section index: %" PRIindex "\n",
@@ -529,7 +536,6 @@ class BinaryReaderObjdumpDisassemble : public BinaryReaderObjdumpBase {
private:
void LogOpcode(const char* fmt, ...);
- Opcode current_opcode = Opcode::Unreachable;
Offset current_opcode_offset = 0;
Offset last_opcode_end = 0;
int indent_level = 0;
@@ -550,6 +556,7 @@ std::string BinaryReaderObjdumpDisassemble::BlockSigToString(Type type) const {
}
Result BinaryReaderObjdumpDisassemble::OnOpcode(Opcode opcode) {
+ BinaryReaderObjdumpBase::OnOpcode(opcode);
if (!in_function_body) {
return Result::Ok;
}
@@ -573,7 +580,6 @@ Result BinaryReaderObjdumpDisassemble::OnOpcode(Opcode opcode) {
}
current_opcode_offset = state->offset;
- current_opcode = opcode;
return Result::Ok;
}
@@ -921,8 +927,8 @@ enum class InitExprType {
NullRef,
};
-struct InitExpr {
- InitExprType type;
+struct InitInst {
+ Opcode opcode;
union {
Index index;
uint32_t i32;
@@ -931,7 +937,12 @@ struct InitExpr {
uint64_t f64;
v128 v128_v;
Type type;
- } value;
+ } imm;
+};
+
+struct InitExpr {
+ InitExprType type;
+ std::vector<InitInst> insts;
};
class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
@@ -1023,35 +1034,31 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) override;
+ void BeginInitExpr() { current_init_expr_.insts.clear(); }
+
Result BeginElemSegmentInitExpr(Index index) override {
reading_elem_init_expr_ = true;
+ BeginInitExpr();
return Result::Ok;
}
- Result EndElemSegmentInitExpr(Index index) override {
- reading_elem_init_expr_ = false;
- return Result::Ok;
- }
+ Result EndElemSegmentInitExpr(Index index) override { return EndInitExpr(); }
Result BeginDataSegmentInitExpr(Index index) override {
reading_data_init_expr_ = true;
+ BeginInitExpr();
return Result::Ok;
}
- Result EndDataSegmentInitExpr(Index index) override {
- reading_data_init_expr_ = false;
- return Result::Ok;
- }
+ Result EndDataSegmentInitExpr(Index index) override { return EndInitExpr(); }
Result BeginGlobalInitExpr(Index index) override {
reading_global_init_expr_ = true;
+ BeginInitExpr();
return Result::Ok;
}
- Result EndGlobalInitExpr(Index index) override {
- reading_global_init_expr_ = false;
- return Result::Ok;
- }
+ Result EndGlobalInitExpr(Index index) override { return EndInitExpr(); }
Result OnDataSegmentCount(Index count) override;
Result BeginDataSegment(Index index,
@@ -1134,6 +1141,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
Result OnTagCount(Index count) override;
Result OnTagType(Index index, Index sig_index) override;
+ Result OnOpcode(Opcode Opcode) override;
Result OnI32ConstExpr(uint32_t value) override;
Result OnI64ConstExpr(uint64_t value) override;
Result OnF32ConstExpr(uint32_t value) override;
@@ -1145,8 +1153,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
Address size) override;
private:
- Result InitExprToConstOffset(const InitExpr& expr, uint64_t* out_offset);
- Result HandleInitExpr(const InitExpr& expr);
+ Result EndInitExpr();
bool ShouldPrintDetails();
void PrintDetails(const char* fmt, ...);
Result PrintSymbolFlags(uint32_t flags);
@@ -1161,8 +1168,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
bool reading_elem_init_expr_ = false;
bool reading_data_init_expr_ = false;
bool reading_global_init_expr_ = false;
- InitExpr data_init_expr_;
- InitExpr elem_init_expr_;
+ InitExpr current_init_expr_;
uint8_t data_flags_ = 0;
uint8_t elem_flags_ = 0;
Index data_mem_index_ = 0;
@@ -1621,7 +1627,7 @@ Result BinaryReaderObjdump::OnElemSegmentElemExprCount(Index index,
if (elem_flags_ & SegPassive) {
PrintDetails("\n");
} else {
- PrintInitExpr(elem_init_expr_);
+ PrintInitExpr(current_init_expr_);
}
return Result::Ok;
}
@@ -1641,34 +1647,85 @@ Result BinaryReaderObjdump::BeginGlobal(Index index, Type type, bool mutable_) {
}
void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr) {
+ assert(expr.insts.size() > 0);
+
+ // We have two different way to print init expressions. One for
+ // extended expressions involving more than one instruction, and
+ // a short form for the more traditional single instruction form.
+ if (expr.insts.size() > 1) {
+ PrintDetails(" - init (");
+ bool first = true;
+ for (auto& inst : expr.insts) {
+ if (!first) {
+ PrintDetails(", ");
+ }
+ first = false;
+ PrintDetails("%s", inst.opcode.GetName());
+ switch (inst.opcode) {
+ case Opcode::I32Const:
+ PrintDetails(" %d", inst.imm.i32);
+ break;
+ case Opcode::I64Const:
+ PrintDetails(" %" PRId64, inst.imm.i64);
+ break;
+ case Opcode::F32Const: {
+ char buffer[WABT_MAX_FLOAT_HEX];
+ WriteFloatHex(buffer, sizeof(buffer), inst.imm.f32);
+ PrintDetails(" %s\n", buffer);
+ break;
+ }
+ case Opcode::F64Const: {
+ char buffer[WABT_MAX_DOUBLE_HEX];
+ WriteDoubleHex(buffer, sizeof(buffer), inst.imm.f64);
+ PrintDetails(" %s\n", buffer);
+ break;
+ }
+ case Opcode::GlobalGet: {
+ PrintDetails(" %" PRIindex, inst.imm.index);
+ std::string_view name = GetGlobalName(inst.imm.index);
+ if (!name.empty()) {
+ PrintDetails(" <" PRIstringview ">",
+ WABT_PRINTF_STRING_VIEW_ARG(name));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ PrintDetails(")\n");
+ return;
+ }
+
switch (expr.type) {
case InitExprType::I32:
- PrintDetails(" - init i32=%d\n", expr.value.i32);
+ PrintDetails(" - init i32=%d\n", expr.insts[0].imm.i32);
break;
case InitExprType::I64:
- PrintDetails(" - init i64=%" PRId64 "\n", expr.value.i64);
+ PrintDetails(" - init i64=%" PRId64 "\n", expr.insts[0].imm.i64);
break;
case InitExprType::F64: {
char buffer[WABT_MAX_DOUBLE_HEX];
- WriteDoubleHex(buffer, sizeof(buffer), expr.value.f64);
+ WriteDoubleHex(buffer, sizeof(buffer), expr.insts[0].imm.f64);
PrintDetails(" - init f64=%s\n", buffer);
break;
}
case InitExprType::F32: {
char buffer[WABT_MAX_FLOAT_HEX];
- WriteFloatHex(buffer, sizeof(buffer), expr.value.f32);
+ WriteFloatHex(buffer, sizeof(buffer), expr.insts[0].imm.f32);
PrintDetails(" - init f32=%s\n", buffer);
break;
}
case InitExprType::V128: {
- PrintDetails(" - init v128=0x%08x 0x%08x 0x%08x 0x%08x \n",
- expr.value.v128_v.u32(0), expr.value.v128_v.u32(1),
- expr.value.v128_v.u32(2), expr.value.v128_v.u32(3));
+ PrintDetails(
+ " - init v128=0x%08x 0x%08x 0x%08x 0x%08x \n",
+ expr.insts[0].imm.v128_v.u32(0), expr.insts[0].imm.v128_v.u32(1),
+ expr.insts[0].imm.v128_v.u32(2), expr.insts[0].imm.v128_v.u32(3));
break;
}
case InitExprType::Global: {
- PrintDetails(" - init global=%" PRIindex, expr.value.index);
- std::string_view name = GetGlobalName(expr.value.index);
+ PrintDetails(" - init global=%" PRIindex, expr.insts[0].imm.index);
+ std::string_view name = GetGlobalName(expr.insts[0].imm.index);
if (!name.empty()) {
PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
}
@@ -1676,106 +1733,98 @@ void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr) {
break;
}
case InitExprType::FuncRef: {
- PrintDetails(" - init ref.func:%" PRIindex, expr.value.index);
- std::string_view name = GetFunctionName(expr.value.index);
+ PrintDetails(" - init ref.func:%" PRIindex, expr.insts[0].imm.index);
+ std::string_view name = GetFunctionName(expr.insts[0].imm.index);
if (!name.empty()) {
PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
}
PrintDetails("\n");
break;
}
- case InitExprType::NullRef: {
+ case InitExprType::NullRef:
PrintDetails(" - init null\n");
break;
- }
+ break;
}
}
-Result BinaryReaderObjdump::InitExprToConstOffset(const InitExpr& expr,
- uint64_t* out_offset) {
- switch (expr.type) {
- case InitExprType::I32:
- *out_offset = expr.value.i32;
- break;
- case InitExprType::I64:
- *out_offset = expr.value.i64;
- break;
- case InitExprType::Global:
- *out_offset = 0;
- break;
- case InitExprType::F32:
- case InitExprType::F64:
- case InitExprType::V128:
- case InitExprType::FuncRef:
- case InitExprType::NullRef:
- err_stream_->Writef("Invalid init expr for segment/elem offset");
- return Result::Error;
- break;
+static void InitExprToConstOffset(const InitExpr& expr, uint64_t* out_offset) {
+ if (expr.insts.size() == 1) {
+ switch (expr.type) {
+ case InitExprType::I32:
+ *out_offset = expr.insts[0].imm.i32;
+ break;
+ case InitExprType::I64:
+ *out_offset = expr.insts[0].imm.i64;
+ break;
+ default:
+ break;
+ }
}
- return Result::Ok;
}
-Result BinaryReaderObjdump::HandleInitExpr(const InitExpr& expr) {
+Result BinaryReaderObjdump::EndInitExpr() {
if (reading_data_init_expr_) {
- data_init_expr_ = expr;
- return InitExprToConstOffset(expr, &data_offset_);
+ reading_data_init_expr_ = false;
+ InitExprToConstOffset(current_init_expr_, &data_offset_);
} else if (reading_elem_init_expr_) {
- elem_init_expr_ = expr;
- return InitExprToConstOffset(expr, &elem_offset_);
+ reading_elem_init_expr_ = false;
+ InitExprToConstOffset(current_init_expr_, &elem_offset_);
} else if (reading_global_init_expr_) {
- PrintInitExpr(expr);
- return Result::Ok;
+ reading_global_init_expr_ = false;
+ PrintInitExpr(current_init_expr_);
} else {
WABT_UNREACHABLE;
}
+ return Result::Ok;
}
Result BinaryReaderObjdump::OnI32ConstExpr(uint32_t value) {
if (ReadingInitExpr()) {
- InitExpr expr;
- expr.type = InitExprType::I32;
- expr.value.i32 = value;
- return HandleInitExpr(expr);
+ current_init_expr_.type = InitExprType::I32;
+ current_init_expr_.insts.back().imm.i32 = value;
}
return Result::Ok;
}
Result BinaryReaderObjdump::OnI64ConstExpr(uint64_t value) {
if (ReadingInitExpr()) {
- InitExpr expr;
- expr.type = InitExprType::I64;
- expr.value.i64 = value;
- return HandleInitExpr(expr);
+ current_init_expr_.type = InitExprType::I64;
+ current_init_expr_.insts.back().imm.i64 = value;
}
return Result::Ok;
}
Result BinaryReaderObjdump::OnF32ConstExpr(uint32_t value) {
if (ReadingInitExpr()) {
- InitExpr expr;
- expr.type = InitExprType::F32;
- expr.value.f32 = value;
- return HandleInitExpr(expr);
+ current_init_expr_.type = InitExprType::F32;
+ current_init_expr_.insts.back().imm.f32 = value;
}
return Result::Ok;
}
Result BinaryReaderObjdump::OnF64ConstExpr(uint64_t value) {
if (ReadingInitExpr()) {
- InitExpr expr;
- expr.type = InitExprType::F64;
- expr.value.f64 = value;
- return HandleInitExpr(expr);
+ current_init_expr_.type = InitExprType::F64;
+ current_init_expr_.insts.back().imm.f64 = value;
+ }
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdump::OnOpcode(Opcode opcode) {
+ BinaryReaderObjdumpBase::OnOpcode(opcode);
+ if (ReadingInitExpr() && opcode != Opcode::End) {
+ InitInst i;
+ i.opcode = current_opcode;
+ current_init_expr_.insts.push_back(i);
}
return Result::Ok;
}
Result BinaryReaderObjdump::OnGlobalGetExpr(Index global_index) {
if (ReadingInitExpr()) {
- InitExpr expr;
- expr.type = InitExprType::Global;
- expr.value.index = global_index;
- return HandleInitExpr(expr);
+ current_init_expr_.type = InitExprType::Global;
+ current_init_expr_.insts.back().imm.index = global_index;
}
return Result::Ok;
}
@@ -1845,7 +1894,7 @@ Result BinaryReaderObjdump::OnDataSegmentData(Index index,
if (data_flags_ & SegPassive) {
PrintDetails("\n");
} else {
- PrintInitExpr(data_init_expr_);
+ PrintInitExpr(current_init_expr_);
}
out_stream_->WriteMemoryDump(src_data, size, data_offset_, PrintChars::Yes,