Skip to content
Browse files

symbol table now uses offsets instead of absolute addresses

  • Loading branch information...
1 parent ce1f5bb commit 19d79c88367f64437245a6b98031f3a8c09928d3 @samsonjs committed Jan 19, 2010
Showing with 74 additions and 39 deletions.
  1. +43 −17 asm/machosymtab.rb
  2. +31 −22 asm/symtab.rb
View
60 asm/machosymtab.rb
@@ -8,34 +8,44 @@ class MachOSymtab < Symtab
include MachO
- def const_offset
- return 0x2000
- end
-
- def bss_offset
- # TODO figure out how to calculate these, or how to let the linker do it!
- # ... relocation tables perhaps?
- return 0x2800
- end
-
- def make_symbols(vars, type, segnum)
+ def make_symbols(vars, base_addr, type, segnum)
# Note: Sorting a Ruby hash gives an alist, e.g. [[<key>, <value>], ...]
# We can use map on it as if it were a hash so it works nicely.
vars.sort { |a,b| a[1] <=> b[1] }.
- map do |name, addr|
- MachOSym.new(name, type, segnum, 0, addr)
+ map do |name, offset|
+ MachOSym.new(name, type, segnum, 0, base_addr + offset)
end
end
def all_symbols
# TODO FIXME:
# - the last var exported ends up after main somewhere... WTF?!
# - All labels are exported. This should be changed and only functions exported!
- symbols = make_symbols(@labels, N_SECT | N_EXT, 1) + # Functions (section #1, __text)
- make_symbols(@consts, N_SECT, 2) + # Constants (section #2, __const)
- make_symbols(@vars, N_SECT, 3) # Variables (section #3, __bss)
+
+ section = 1
+
+ # Functions (section #1, __text)
+ symbols = make_symbols(@labels, text_offset, N_SECT | N_EXT, section)
+ section += 1
+
+ # Constants (section #2, __const)
+ if @consts.size > 0
+ symbols += make_symbols(@consts, const_offset, N_SECT, section)
+ section += 1
+ end
+
+ # Variables (section #3, __bss)
+ if @vars.size > 0
+ symbols += make_symbols(@vars, bss_offset, N_SECT, section)
+ end
+
return symbols
end
+
+ # this is fairly stupid but works
+ def bss_section
+ @consts.size > 0 ? 3 : 2
+ end
def nlist_ary
symbols = {}
@@ -53,10 +63,26 @@ def nlist_ary
end
def stab
- # The empty strings result in a string that begins and ends with
+ # The empty strings result in a string that begins and ends with a null byte
['', all_symbols, ''].flatten.map { |sym| sym.to_s }.join("\0")
end
+ def reloc(r_address, r_symbolnum=0, r_length=2, r_extern=0, r_pcrel=0, r_type=0)
+ r_info = (r_type << 28) | (r_extern << 27) | (r_length << 25) |
+ (r_pcrel << 24) | r_symbolnum
+ @reloc_info << RelocationInfo.new(r_address, r_info)
+ end
+
+ def reloc_info
+ n = bss_section
+ @reloc_info.each {|r| r[:r_info] |= n}
+ end
+
+ def calculate_offsets(text_size)
+ @const_offset = @text_offset + text_size
+ @bss_offset = @const_offset + @const_size
+ end
+
end
end
View
53 asm/symtab.rb
@@ -1,13 +1,22 @@
module Assembler
-
+
+
+ # Abstract symbol table.
+ #
+ # Basically a big map of variable, constant, and label names to
+ # offsets within their respective sections. Final addresses are
+ # calculated from these offsets on the 2nd pass when we know where
+ # things will actually live in memory.
+
class Symtab
- attr_reader :const_data, :bss_size
+ attr_accessor :text_offset, :bss_offset, :const_offset
+ attr_reader :const_data, :const_size, :bss_size, :reloc_info
def initialize
- @vars = {} # Map of variable names to addresses. (bss vars)
- @consts = {} # Map of constant names to addresses.
- @funcs = {} # map of function names to addresses.
+ @vars = {} # Map of variable names to offsets. (bss vars)
+ @consts = {} # Map of constant names to offsets.
+ @funcs = {} # map of function names to offsets.
# Initial data to load into memory (data for __DATA segment).
@const_data = ''
@@ -18,15 +27,15 @@ def initialize
# Map names to locations.
@labels = Hash.new {|h, key| raise "undefined label: #{key}"}
@num_labels = 0 # Used to generate unique labels.
- @num_labels_with_suffix = Hash.new(0)
- end
-
-
- ####
- ## NB: Concrete subclasses must define methods named:
- ## bss_offset, and const_offset
- ####
+ @num_labels_with_suffix = Hash.new(0)
+ # Relocation info. Subclasses should define a reloc method.
+ @reloc_info = []
+
+ @text_offset = 0
+ @bss_offset = 0
+ @const_offset = 0
+ end
# Generate a unique label.
def unique_label(suffix=nil)
@@ -39,8 +48,8 @@ def unique_label(suffix=nil)
return name
end
- def deflabel(name, addr)
- @labels[name] = addr
+ def deflabel(name, offset)
+ @labels[name] = offset
return name
end
@@ -63,27 +72,27 @@ def defconst(name, value, bytes)
end
- def defun(name, addr)
- @funcs[name] = addr
+ def defun(name, offset)
+ @funcs[name] = offset
end
def var(name)
- bss_offset + @vars[name]
+ @vars[name]
end
def var?(name)
- @vars[name]
+ @vars.has_key?(name)
end
def const(name)
- const_offset + @consts[name]
+ @consts[name]
end
def const?(name)
- @consts[name]
+ @consts.has_key?(name)
end
-
+
end
end

0 comments on commit 19d79c8

Please sign in to comment.
Something went wrong with that request. Please try again.