metasm/exe_format/elf_decode.rb in metasm-1.0.3 vs metasm/exe_format/elf_decode.rb in metasm-1.0.4

- old
+ new

@@ -740,10 +740,56 @@ end Metasm::Relocation.new(Expression[target], :u32, @endianness) if target end + def arch_decode_segments_reloc_openrisc(reloc) + if reloc.symbol.kind_of?(Symbol) and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and + s = @sections.find { |s_| s_.name and s_.offset <= @encoded.ptr and s_.offset + s_.size > @encoded.ptr } + @encoded.add_export(new_label("#{s.name}_#{n}"), @encoded.ptr, true) + end + + original_word = decode_word + + # decode addend if needed + case reloc.type + when 'NONE' # no addend + else addend = reloc.addend || Expression.make_signed(original_word, 32) + end + + case reloc.type + when 'NONE' + when '32', '32_PCREL' + target = reloc_target(reloc) + target = Expression[target, :-, reloc.offset] if reloc.type == '32_PCREL' + target = Expression[target, :+, addend] if addend and addend != 0 + when 'INSN_REL_26' + target = reloc_target(reloc) + addend &= 0x3ff_ffff + target = Expression[target, :+, [addend, :<<, 2]] if addend and addend != 0 + target = Expression[[original_word, :&, 0xfc0_0000], :|, [[target, :&, 0x3ff_ffff], :>>, 2]] + when 'HI_16_IN_INSN' + target = reloc_target(reloc) + addend &= 0xffff + target = Expression[target, :+, [addend, :<<, 16]] if addend and addend != 0 + target = Expression[[original_word, :&, 0xffff_0000], :|, [[target, :>>, 16], :&, 0xffff]] + when 'LO_16_IN_INSN' + target = reloc_target(reloc) + addend &= 0xffff + target = Expression[target, :+, addend] if addend and addend != 0 + target = Expression[[original_word, :&, 0xffff_0000], :|, [target, :&, 0xffff]] + when 'JMP_SLOT' + target = reloc_target(reloc) + target = Expression[target, :+, addend] if addend and addend != 0 + else + puts "W: Elf: unhandled MIPS reloc #{reloc.inspect}" if $VERBOSE + target = nil + end + + Metasm::Relocation.new(Expression[target], :u32, @endianness) if target + end + class DwarfDebug # decode a DWARF2 'compilation unit' def decode(elf, info, abbrev, str) super(elf, info) len = @cu_len-7 # @cu_len is size from end of @cu_len field, so we substract ptsz/tag/abroff @@ -928,17 +974,18 @@ # returns a metasm CPU object corresponding to +header.machine+ def cpu_from_headers case @header.machine when 'X86_64'; X86_64.new when '386'; Ia32.new - when 'MIPS'; (@header.flags.include?('32BITMODE') ? MIPS64 : MIPS).new @endianness + when 'MIPS'; (@header.flags.include?('32BITMODE') ? MIPS64 : MIPS).new(@endianness) when 'PPC'; PPC.new when 'ARM'; ARM.new when 'AARCH64'; AArch64.new when 'SH'; Sh4.new when 'ARC_COMPACT'; ARC.new when 'MSP430'; MSP430.new + when 'OPENRISC'; OpenRisc.new(:latest, @endianness, (@header.flags.include?('NODELAY') ? 0 : 1)) else raise "unsupported cpu #{@header.machine}" end end # returns an array including the ELF entrypoint (if not null) and the FUNC symbols addresses @@ -1017,9 +1064,20 @@ noret = DecodedFunction.new noret.noreturn = true %w[__stack_chk_fail abort exit].each { |fn| d.function[Expression[fn]] = noret } + d.function[:default] = @cpu.disassembler_default_func + when 'openrisc' + old_cp = d.c_parser + d.c_parser = nil + d.parse_c <<EOC +void __libc_start_main(void(*)(), int, char**, void(*)(), void(*)()) __attribute__((noreturn)); +void __attribute__((noreturn)) exit(int); +EOC + d.function[Expression['__libc_start_main']] = @cpu.decode_c_function_prototype(d.c_parser, '__libc_start_main') + d.function[Expression['exit']] = @cpu.decode_c_function_prototype(d.c_parser, 'exit') + d.c_parser = old_cp d.function[:default] = @cpu.disassembler_default_func end d end