diff options
Diffstat (limited to 'src/binary-reader-objdump.cc')
-rw-r--r-- | src/binary-reader-objdump.cc | 225 |
1 files changed, 183 insertions, 42 deletions
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 9edee635..aebc92fa 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -45,7 +45,11 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop { StringSlice section_name) override; protected: - const char* GetFunctionName(Index index); + const char* GetFunctionName(Index index) const; + void PrintRelocation(const Reloc& reloc, Offset offset) const; + Offset GetSectionStart(BinarySection section_code) const { + return section_starts[static_cast<size_t>(section_code)]; + } ObjdumpOptions* options; ObjdumpState* objdump_state; @@ -112,7 +116,7 @@ Result BinaryReaderObjdumpBase::BeginModule(uint32_t version) { return Result::Ok; } -const char* BinaryReaderObjdumpBase::GetFunctionName(Index index) { +const char* BinaryReaderObjdumpBase::GetFunctionName(Index index) const { if (index >= objdump_state->function_names.size() || objdump_state->function_names[index].empty()) return nullptr; @@ -120,6 +124,26 @@ const char* BinaryReaderObjdumpBase::GetFunctionName(Index index) { return objdump_state->function_names[index].c_str(); } +void BinaryReaderObjdumpBase::PrintRelocation(const Reloc& reloc, + Offset offset) const { + printf(" %06" PRIzx ": %-18s %" PRIindex "", offset, + get_reloc_type_name(reloc.type), reloc.index); + switch (reloc.type) { + case RelocType::GlobalAddressLEB: + case RelocType::GlobalAddressSLEB: + case RelocType::GlobalAddressI32: + printf(" + %d", reloc.addend); + break; + case RelocType::FuncIndexLEB: + if (const char* name = GetFunctionName(reloc.index)) { + printf(" <%s>", name); + } + default: + break; + } + printf("\n"); +} + Result BinaryReaderObjdumpBase::OnRelocCount(Index count, BinarySection section_code, StringSlice section_name) { @@ -153,6 +177,8 @@ Result BinaryReaderObjdumpPrepass::OnReloc(RelocType type, BinaryReaderObjdumpBase::OnReloc(type, offset, index, addend); if (reloc_section == BinarySection::Code) { objdump_state->code_relocations.emplace_back(type, offset, index, addend); + } else if (reloc_section == BinarySection::Data) { + objdump_state->data_relocations.emplace_back(type, offset, index, addend); } return Result::Ok; } @@ -216,9 +242,9 @@ Result BinaryReaderObjdumpDisassemble::OnOpcode(Opcode opcode) { #define IMMEDIATE_OCTET_COUNT 9 void BinaryReaderObjdumpDisassemble::LogOpcode(const uint8_t* data, - size_t data_size, - const char* fmt, - ...) { + size_t data_size, + const char* fmt, + ...) { Offset offset = current_opcode_offset; // Print binary data @@ -255,27 +281,11 @@ void BinaryReaderObjdumpDisassemble::LogOpcode(const uint8_t* data, last_opcode_end = current_opcode_offset + data_size; if (options->relocs && next_reloc < objdump_state->code_relocations.size()) { - Reloc* reloc = &objdump_state->code_relocations[next_reloc]; - Offset code_start = - section_starts[static_cast<size_t>(BinarySection::Code)]; - Offset abs_offset = code_start + reloc->offset; + const Reloc& reloc = objdump_state->code_relocations[next_reloc]; + Offset code_start = GetSectionStart(BinarySection::Code); + Offset abs_offset = code_start + reloc.offset; if (last_opcode_end > abs_offset) { - printf(" %06" PRIzx ": %-18s %" PRIindex "", abs_offset, - get_reloc_type_name(reloc->type), reloc->index); - switch (reloc->type) { - case RelocType::GlobalAddressLEB: - case RelocType::GlobalAddressSLEB: - case RelocType::GlobalAddressI32: - printf(" + %d", reloc->addend); - break; - case RelocType::FuncIndexLEB: - if (const char* name = GetFunctionName(reloc->index)) { - printf(" <%s>", name); - } - default: - break; - } - printf("\n"); + PrintRelocation(reloc, abs_offset); next_reloc++; } } @@ -394,6 +404,25 @@ Result BinaryReaderObjdumpDisassemble::OnOpcodeBlockSig(Index num_types, return Result::Ok; } +enum class InitExprType { + I32, + F32, + I64, + F64, + Global, +}; + +struct InitExpr { + InitExprType type; + union { + Index global; + uint32_t i32; + uint32_t f32; + uint64_t i64; + uint64_t f64; + } value; +}; + class BinaryReaderObjdump : public BinaryReaderObjdumpBase { public: BinaryReaderObjdump(const uint8_t* data, @@ -465,6 +494,14 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { Result OnElemSegmentFunctionIndex(Index segment_index, Index func_index) override; + Result BeginDataSection(Offset size) override { + in_data_section_ = true; + return Result::Ok; + } + Result EndDataSection() override { + in_data_section_ = false; + return Result::Ok; + } Result OnDataSegmentCount(Index count) override; Result BeginDataSegment(Index index, Index memory_index) override; Result OnDataSegmentData(Index index, @@ -498,10 +535,14 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { private: bool ShouldPrintDetails(); void PrintDetails(const char* fmt, ...); + void PrintInitExpr(const InitExpr &expr); Result OnCount(Index count); std::unique_ptr<FileStream> out_stream_; Index elem_index_ = 0; + Index next_data_reloc_ = 0; + bool in_data_section_ = false; + InitExpr data_init_expr_; }; BinaryReaderObjdump::BinaryReaderObjdump(const uint8_t* data, @@ -552,7 +593,7 @@ Result BinaryReaderObjdump::BeginSection(BinarySection section_code, if (section_match) { printf("\nContents of section %s:\n", name); out_stream_->WriteMemoryDump(data + state->offset, size, state->offset, - nullptr, nullptr, PrintChars::Yes); + PrintChars::Yes); } break; case ObjdumpMode::Prepass: @@ -587,10 +628,17 @@ Result BinaryReaderObjdump::OnCount(Index count) { Result BinaryReaderObjdump::EndModule() { if (options->section_name && !section_found) { - printf("Section not found: %s\n", options->section_name); + fprintf(stderr, "Section not found: %s\n", options->section_name); return Result::Error; } + if (options->relocs) { + if (next_data_reloc_ != objdump_state->data_relocations.size()) { + fprintf(stderr, "Data reloctions outside of segments\n"); + return Result::Error; + } + } + return Result::Ok; } @@ -783,37 +831,94 @@ Result BinaryReaderObjdump::BeginGlobal(Index index, Type type, bool mutable_) { return Result::Ok; } +void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr) { + switch (expr.type) { + case InitExprType::I32: + PrintDetails(" - init i32=%d\n", expr.value.i32); + break; + case InitExprType::I64: + PrintDetails(" - init i64=%" PRId64 "\n", expr.value.i64); + break; + case InitExprType::F64: { + char buffer[WABT_MAX_DOUBLE_HEX]; + write_float_hex(buffer, sizeof(buffer), expr.value.f64); + PrintDetails(" - init f64=%s\n", buffer); + break; + } + case InitExprType::F32: { + char buffer[WABT_MAX_FLOAT_HEX]; + write_float_hex(buffer, sizeof(buffer), expr.value.f32); + PrintDetails(" - init f32=%s\n", buffer); + break; + } + case InitExprType::Global: + PrintDetails(" - init global=%" PRIindex "\n", expr.value.global); + break; + } +} + Result BinaryReaderObjdump::OnInitExprF32ConstExpr(Index index, uint32_t value) { - char buffer[WABT_MAX_FLOAT_HEX]; - write_float_hex(buffer, sizeof(buffer), value); - PrintDetails(" - init f32=%s\n", buffer); + InitExpr expr; + expr.type = InitExprType::F32; + expr.value.f32 = value; + if (in_data_section_) { + data_init_expr_ = expr; + } else { + PrintInitExpr(expr); + } return Result::Ok; } Result BinaryReaderObjdump::OnInitExprF64ConstExpr(Index index, uint64_t value) { - char buffer[WABT_MAX_DOUBLE_HEX]; - write_float_hex(buffer, sizeof(buffer), value); - PrintDetails(" - init f64=%s\n", buffer); + InitExpr expr; + expr.type = InitExprType::F64; + expr.value.f64 = value; + if (in_data_section_) { + data_init_expr_ = expr; + } else { + PrintInitExpr(expr); + } return Result::Ok; } Result BinaryReaderObjdump::OnInitExprGetGlobalExpr(Index index, Index global_index) { - PrintDetails(" - init global=%" PRIindex "\n", global_index); + InitExpr expr; + expr.type = InitExprType::Global; + expr.value.global = global_index; + if (in_data_section_) { + data_init_expr_ = expr; + } else { + PrintInitExpr(expr); + } return Result::Ok; } Result BinaryReaderObjdump::OnInitExprI32ConstExpr(Index index, uint32_t value) { - PrintDetails(" - init i32=%d\n", value); + InitExpr expr; + expr.type = InitExprType::I32; + expr.value.i32 = value; + if (in_data_section_) { + data_init_expr_ = expr; + } else { + PrintInitExpr(expr); + } return Result::Ok; } Result BinaryReaderObjdump::OnInitExprI64ConstExpr(Index index, uint64_t value) { - PrintDetails(" - init i64=%" PRId64 "\n", value); + InitExpr expr; + expr.type = InitExprType::I64; + expr.value.i64 = value; + if (in_data_section_) { + data_init_expr_ = expr; + } else { + PrintInitExpr(expr); + } return Result::Ok; } @@ -839,17 +944,54 @@ Result BinaryReaderObjdump::OnDataSegmentCount(Index count) { } Result BinaryReaderObjdump::BeginDataSegment(Index index, Index memory_index) { - PrintDetails(" - memory[%" PRIindex "]", memory_index); + // TODO(sbc): Display memory_index once multiple memories become a thing + //PrintDetails(" - memory[%" PRIindex "]", memory_index); return Result::Ok; } Result BinaryReaderObjdump::OnDataSegmentData(Index index, const void* src_data, Address size) { - if (ShouldPrintDetails()) { - out_stream_->WriteMemoryDump(src_data, size, state->offset - size, " - ", - nullptr, PrintChars::Yes); + if (!ShouldPrintDetails()) + return Result::Ok; + + PrintDetails(" - segment[%" PRIindex "] size=%" PRIaddress, index, size); + PrintInitExpr(data_init_expr_); + + size_t voffset = 0; + switch (data_init_expr_.type) { + case InitExprType::I32: + voffset = data_init_expr_.value.i32; + break; + case InitExprType::Global: + break; + case InitExprType::I64: + case InitExprType::F32: + case InitExprType::F64: + fprintf(stderr, "Segment offset must be an i32 init expr"); + return Result::Error; + break; } + + out_stream_->WriteMemoryDump(src_data, size, voffset, PrintChars::Yes, + " - "); + + // Print relocations from this segment. + if (!options->relocs) + return Result::Ok; + + Offset data_start = GetSectionStart(BinarySection::Data); + Offset segment_start = state->offset - size; + Offset segment_offset = segment_start - data_start; + while (next_data_reloc_ < objdump_state->data_relocations.size()) { + const Reloc& reloc = objdump_state->data_relocations[next_data_reloc_]; + Offset abs_offset = data_start + reloc.offset; + if (abs_offset > state->offset) + break; + PrintRelocation(reloc, reloc.offset - segment_offset + voffset); + next_data_reloc_++; + } + return Result::Ok; } @@ -865,8 +1007,7 @@ Result BinaryReaderObjdump::OnReloc(RelocType type, Offset offset, Index index, uint32_t addend) { - Offset total_offset = - section_starts[static_cast<size_t>(reloc_section)] + offset; + Offset total_offset = GetSectionStart(reloc_section) + offset; PrintDetails(" - %-18s offset=%#08" PRIoffset "(file=%#08" PRIoffset ") index=%" PRIindex, get_reloc_type_name(type), offset, total_offset, index); |