diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 5696a597..2940c1f1 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -21,26 +21,27 @@ module Risc @risc_init = nil @constants = [] end - attr_reader :constants , :cpu_init , :binary_init + attr_reader :constants , :cpu_init attr_reader :booted , :translated + attr_reader :platform # translate to arm, ie instantiate an arm translator and pass it to translate # # currently we have no machanism to translate to other cpu's (nor such translators) # but the mechanism is ready def translate_arm + @platform = Platform.for("Arm") @translated = true - translate(Arm::Translator.new) + translate(@platform.translator) end # translate code to whatever cpu the translator translates to - # this means translating the initial jump (cpu_init into binary_init) + # this means translating the initial jump # and then translating all methods def translate( translator ) methods = Parfait.object_space.get_all_methods translate_methods( methods , translator ) @cpu_init = risc_init.to_cpu(translator) - @binary_init = Parfait::BinaryCode.new(1) end # go through all methods and translate them to cpu, given the translator @@ -77,9 +78,8 @@ module Risc def position_all translate_arm unless @translated #need the initial jump at 0 and then functions - Position.set(binary_init,0) - Position.set(cpu_init , 12 , binary_init) - @code_start = position_objects( binary_init.padded_length ) + Position.set(cpu_init , 0 , cpu_init) + @code_start = position_objects( @platform.padding ) # and then everything code position_code end @@ -91,6 +91,7 @@ module Risc # want to have the objects first in the executable objects.each do | id , objekt| next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label ) + next if objekt.is_a?( Parfait::TypedMethod) before = at Position.set(objekt,at) at += objekt.padded_length @@ -111,15 +112,10 @@ module Risc objects.each do |id , method| next unless method.is_a? Parfait::TypedMethod before = at + Position.set(method,at) + at += method.padded_length Position.set( method.binary , at , method) Position.set( method.cpu_instructions, at + 12 , method.binary) - # before = at - # nekst = method.binary - # while(nekst) - # Position.set(nekst , at , method) - # at += nekst.padded_length - # nekst = nekst.next - # end log.debug "Method #{method.name}:#{before.to_s(16)} len: #{(at - before).to_s(16)}" log.debug "Instructions #{method.cpu_instructions.object_id.to_s(16)}:#{(before+12).to_s(16)}" end @@ -139,7 +135,6 @@ module Risc writer.assemble(method.cpu_instructions) end log.debug "BinaryInit #{cpu_init.first.object_id.to_s(16)}" - BinaryWriter.new(binary_init).assemble(cpu_init) end def boot diff --git a/lib/risc/position/code_position.rb b/lib/risc/position/code_position.rb index a5ffbc48..e610ee15 100644 --- a/lib/risc/position/code_position.rb +++ b/lib/risc/position/code_position.rb @@ -15,8 +15,12 @@ module Risc @method = method end def init(at) - return unless code.next - Position.set(code.next , at + code.padded_length, method) + next_pos = at + code.padded_length + if code.next + Position.set(code.next , next_pos, method) + else + Position.set(method , next_pos) + end end def reset_to(pos) super(pos) diff --git a/lib/risc/text_writer.rb b/lib/risc/text_writer.rb index d91236ad..8f8b6ce0 100644 --- a/lib/risc/text_writer.rb +++ b/lib/risc/text_writer.rb @@ -18,7 +18,7 @@ module Risc MARKER = 0xBAD4C0DE - def initialize( machine) + def initialize(machine) @machine = machine @load_at = 0x10054 # this is linux/arm end @@ -29,7 +29,7 @@ module Risc # - all BinaryCode def write_as_string @stream = StringIO.new - write_init(@machine.binary_init) + write_init(@machine.cpu_init) write_debug write_objects write_code @@ -150,15 +150,9 @@ module Risc log.debug "Data4 witten stream 0x#{@stream.length.to_s(16)}" end - # first jump, treated as a binary code, but this one needs - # the actual jump as the first - def write_init( code ) - code.each_word do |word| - @stream.write_unsigned_int_32( word || 0 ) - end - write_ref_for( code.next ) - write_ref_for( code.get_type ) - @stream.write_signed_int_32( MARKER ) + # first jump, + def write_init( cpu_init ) + cpu_init.assemble(@stream) log.debug "Init witten stream 0x#{@stream.length.to_s(16)}" end diff --git a/test/arm/test_call.rb b/test/arm/test_call.rb index d1888139..c622b31a 100644 --- a/test/arm/test_call.rb +++ b/test/arm/test_call.rb @@ -8,8 +8,8 @@ module Arm # the address is what an assembler calculates (a signed number for the amount of instructions), # ie the relative (to pc) address -8 (pipeline) /4 so save space # so the cpu adds the value*4 and starts loading that (load, decode, execute) - code = @machine.b( -4 ) #this jumps to the next instruction - assert_code code , :b , [0xff,0xff,0xff,0xea] #ea ff ff fe + code = @machine.b( 0 ) #this jumps to the next next instruction + assert_code code , :b , [0x0,0x0,0x0,0xea] #ea 00 00 00 end def test_call #see comment above. bx not implemented (as it means into thumb, and no thumb here) code = @machine.call( -4 ,{} )#this jumps to the next instruction diff --git a/test/risc/test_machine.rb b/test/risc/test_machine.rb index cf748f42..a140bfba 100644 --- a/test/risc/test_machine.rb +++ b/test/risc/test_machine.rb @@ -35,23 +35,14 @@ module Risc @machine.position_all @machine.create_binary end - def test_has_binary - assert_equal Parfait::BinaryCode , @machine.binary_init.class - end - def test_has_jump - assert_equal "ea000fb4" , @machine.binary_init.get_word(1).to_s(16) - end - def test_pos_bin - assert_equal "0x0" , Position.get(@machine.binary_init).to_s - end def test_pos_cpu - assert_equal 12 , Position.get(@machine.cpu_init).at + assert_equal 0 , Position.get(@machine.cpu_init).at end def test_cpu_at - assert_equal "0x3ee4" , Position.get(@machine.cpu_init.first).to_s + assert_equal "0x4d50" , Position.get(@machine.cpu_init.first).to_s end def test_cpu_bin - assert_equal "0x3ed8" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s + assert_equal "0x4d44" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s end def test_cpu_label assert_equal Position::InstructionPosition , Position.get(@machine.cpu_init.first).class