make elf symbols optional
and default to false. Smaller executables by at least half also add option for compiler cli
This commit is contained in:
parent
160d860db2
commit
91995dc1b3
@ -7,7 +7,9 @@ require_relative 'string_table_section'
|
|||||||
module Elf
|
module Elf
|
||||||
|
|
||||||
class ObjectWriter
|
class ObjectWriter
|
||||||
def initialize( linker )
|
attr_reader :text
|
||||||
|
|
||||||
|
def initialize( linker , options = {} )
|
||||||
@linker = linker
|
@linker = linker
|
||||||
target = Elf::Constants::TARGET_ARM
|
target = Elf::Constants::TARGET_ARM
|
||||||
@object = Elf::ObjectFile.new(target)
|
@object = Elf::ObjectFile.new(target)
|
||||||
@ -22,7 +24,15 @@ module Elf
|
|||||||
assembler = Risc::TextWriter.new(@linker)
|
assembler = Risc::TextWriter.new(@linker)
|
||||||
set_text assembler.write_as_string
|
set_text assembler.write_as_string
|
||||||
|
|
||||||
# for debug add labels for labels
|
add_debug_symbols(options)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# for debug add labels for labels
|
||||||
|
def add_debug_symbols(options)
|
||||||
|
debug = options[:debug]
|
||||||
|
return unless debug
|
||||||
|
|
||||||
@linker.assemblers.each do |asm|
|
@linker.assemblers.each do |asm|
|
||||||
meth = asm.callable
|
meth = asm.callable
|
||||||
asm.instructions.each do |label|
|
asm.instructions.each do |label|
|
||||||
@ -34,7 +44,6 @@ module Elf
|
|||||||
add_symbol label , Risc::Position.get(code).at
|
add_symbol label , Risc::Position.get(code).at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@linker.object_positions.each do |slot , position|
|
@linker.object_positions.each do |slot , position|
|
||||||
next if slot.is_a?(Parfait::BinaryCode)
|
next if slot.is_a?(Parfait::BinaryCode)
|
||||||
next if slot.class.name.include?("Arm")
|
next if slot.class.name.include?("Arm")
|
||||||
@ -48,8 +57,6 @@ module Elf
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :text
|
|
||||||
|
|
||||||
def set_text(text)
|
def set_text(text)
|
||||||
@text.text = text
|
@text.text = text
|
||||||
add_symbol "_start", 0
|
add_symbol "_start", 0
|
||||||
|
@ -5,6 +5,7 @@ require "risc/interpreter"
|
|||||||
class RubyXC < Thor
|
class RubyXC < Thor
|
||||||
class_option :integers , type: :numeric
|
class_option :integers , type: :numeric
|
||||||
class_option :mesages , type: :numeric
|
class_option :mesages , type: :numeric
|
||||||
|
class_option :elf , type: :boolean
|
||||||
|
|
||||||
|
|
||||||
desc "compile FILE" , "Compile given FILE to binary"
|
desc "compile FILE" , "Compile given FILE to binary"
|
||||||
@ -27,11 +28,13 @@ class RubyXC < Thor
|
|||||||
puts "compiling #{file}"
|
puts "compiling #{file}"
|
||||||
|
|
||||||
linker = ::RubyX::RubyXCompiler.new(extract_options).ruby_to_binary( ruby , :arm )
|
linker = ::RubyX::RubyXCompiler.new(extract_options).ruby_to_binary( ruby , :arm )
|
||||||
writer = Elf::ObjectWriter.new(linker)
|
elf = { debug: options[:elf] || false }
|
||||||
|
writer = Elf::ObjectWriter.new(linker , elf)
|
||||||
|
|
||||||
outfile = file.split("/").last.gsub(".rb" , ".o")
|
outfile = file.split("/").last.gsub(".rb" , ".o")
|
||||||
writer.save outfile
|
writer.save outfile
|
||||||
|
system "arm-linux-gnu-ld -N #{outfile}"
|
||||||
|
File.delete outfile
|
||||||
return outfile
|
return outfile
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -92,16 +95,15 @@ class RubyXC < Thor
|
|||||||
|
|
||||||
def execute(file)
|
def execute(file)
|
||||||
outfile = compile(file)
|
outfile = compile(file)
|
||||||
system "arm-linux-gnu-ld -N #{outfile}"
|
puts "Running #{outfile}\n\n"
|
||||||
puts "Linked ok, now running #{outfile}"
|
system "qemu-arm ./a.out ;echo $?"
|
||||||
system "qemu-arm ./a.out ; echo $?"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def extract_options
|
def extract_options
|
||||||
opt = { Integer: options[:integers] || 1024 ,
|
opt = { Integer: options[:integers] || 1024 ,
|
||||||
Message: options[:messages] || 1024}
|
Message: options[:messages] || 1024}
|
||||||
return {parfait: opt}
|
return {parfait: opt }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
require_relative 'helper'
|
|
||||||
require "yaml"
|
|
||||||
require "parslet/convenience"
|
|
||||||
class TestRunner < MiniTest::Test
|
|
||||||
|
|
||||||
# this creates test methods dynamically , one for each file in runners directory
|
|
||||||
def self.runnable_methods
|
|
||||||
methods = []
|
|
||||||
Dir[File.join(File.dirname(__FILE__) , "runners" , "*.rb")].each do |file|
|
|
||||||
meth = File.basename(file).split(".").first
|
|
||||||
name = "test_#{meth}"
|
|
||||||
methods << name
|
|
||||||
self.send(:define_method, name ) {
|
|
||||||
execute file
|
|
||||||
}
|
|
||||||
end
|
|
||||||
methods
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute file
|
|
||||||
string = File.read(file)
|
|
||||||
parser = Parser::RubyX.new
|
|
||||||
object_space = Risc::Program.new "Arm"
|
|
||||||
#TODO : files would have to include s-expressions now
|
|
||||||
syntax = parser.parse_with_debug(string, reporter: Parslet::ErrorReporter::Deepest.new)
|
|
||||||
assert syntax
|
|
||||||
parts = Parser::Transform.new.apply(syntax)
|
|
||||||
# file is a list of statements, all but the last must be a function
|
|
||||||
# and the last is wrapped as a main
|
|
||||||
parts.each_with_index do |part,index|
|
|
||||||
if index == (parts.length - 1)
|
|
||||||
expr = part.compile( program.context )
|
|
||||||
else
|
|
||||||
expr = part.compile( program.context )
|
|
||||||
raise "should be function definition for now" unless expr.is_a? Risc::Function
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#object writer takes machine
|
|
||||||
writer = Elf::ObjectWriter.new(program , Elf::Constants::TARGET_ARM)
|
|
||||||
|
|
||||||
writer.save(file.gsub(".rb" , ".o"))
|
|
||||||
|
|
||||||
# puts program.to_yaml
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -21,61 +21,5 @@ module Elf
|
|||||||
writer = Elf::ObjectWriter.new(linker)
|
writer = Elf::ObjectWriter.new(linker)
|
||||||
writer.save "test/#{file}.o"
|
writer.save "test/#{file}.o"
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_remote(file)
|
|
||||||
check(file)
|
|
||||||
stdout , exit_code = run_ssh(file)
|
|
||||||
@stdout = "" unless @stdout
|
|
||||||
assert_equal @stdout , stdout
|
|
||||||
assert_equal @exit_code , exit_code
|
|
||||||
end
|
|
||||||
|
|
||||||
def run_ssh( file )
|
|
||||||
host = ENV["ARM_HOST"]
|
|
||||||
return unless host
|
|
||||||
port = (ENV["ARM_PORT"] || 2222)
|
|
||||||
user = (ENV["ARM_USER"] || "pi")
|
|
||||||
binary_file = "/tmp/#{file}"
|
|
||||||
object_file = binary_file + ".o"
|
|
||||||
Net::SCP.start(host, user , port: port ) do |scp|
|
|
||||||
puts "Copying test/#{file}.o to #{object_file}" if DEBUG
|
|
||||||
scp.upload! "test/#{file}.o", object_file
|
|
||||||
end
|
|
||||||
Net::SSH.start(host, user , port: port ) do |ssh|
|
|
||||||
puts "Linking #{object_file}" if DEBUG
|
|
||||||
stdout , exit_code = ssh_exec!(ssh , "ld -N -o #{binary_file} #{object_file}")
|
|
||||||
assert_equal 0 , exit_code , "Linking #{binary_file} failed"
|
|
||||||
puts "Running #{binary_file}" if DEBUG
|
|
||||||
stdout , exit_code = ssh_exec!(ssh , binary_file)
|
|
||||||
puts "Result #{stdout} #{exit_code}" if DEBUG
|
|
||||||
return stdout , exit_code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def ssh_exec!(ssh, command)
|
|
||||||
stdout_data = ""
|
|
||||||
exit_code = nil
|
|
||||||
ssh.open_channel do |channel|
|
|
||||||
channel.exec(command) do |ch, success|
|
|
||||||
unless success
|
|
||||||
raise "FAILED: couldn't execute command (ssh.channel.exec)"
|
|
||||||
end
|
|
||||||
channel.on_data do |c,data|
|
|
||||||
stdout_data+=data
|
|
||||||
end
|
|
||||||
channel.on_extended_data do |c,type,data|
|
|
||||||
raise "#{ssh} received stderr #{data}"
|
|
||||||
end
|
|
||||||
channel.on_request("exit-status") do |c,data|
|
|
||||||
exit_code = data.read_long
|
|
||||||
end
|
|
||||||
channel.on_request("exit-signal") do |c, data|
|
|
||||||
raise "#{ssh} received signal #{data.read_long}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ssh.loop
|
|
||||||
[stdout_data, exit_code]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -15,7 +15,7 @@ module RubyX
|
|||||||
end
|
end
|
||||||
def test_file_open
|
def test_file_open
|
||||||
assert_output(/compiling/) {RubyXC.start(["compile" , "test/mains/source/add__4.rb"])}
|
assert_output(/compiling/) {RubyXC.start(["compile" , "test/mains/source/add__4.rb"])}
|
||||||
File.delete "add__4.o"
|
#File.delete "add__4.o"
|
||||||
end
|
end
|
||||||
def test_interpret
|
def test_interpret
|
||||||
assert_output(/interpreting/) {RubyXC.start(["interpret" , "test/mains/source/add__4.rb"])}
|
assert_output(/interpreting/) {RubyXC.start(["interpret" , "test/mains/source/add__4.rb"])}
|
||||||
|
Loading…
Reference in New Issue
Block a user