mirror of
https://github.com/samsonjs/compiler.git
synced 2026-03-25 08:45:52 +00:00
symbol table now uses offsets instead of absolute addresses
This commit is contained in:
parent
ce1f5bb4dc
commit
19d79c8836
2 changed files with 76 additions and 41 deletions
|
|
@ -8,22 +8,12 @@ module Assembler
|
|||
|
||||
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
|
||||
|
||||
|
|
@ -31,11 +21,31 @@ module Assembler
|
|||
# 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 @@ module Assembler
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 @@ module Assembler
|
|||
# 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 @@ module Assembler
|
|||
return name
|
||||
end
|
||||
|
||||
def deflabel(name, addr)
|
||||
@labels[name] = addr
|
||||
def deflabel(name, offset)
|
||||
@labels[name] = offset
|
||||
return name
|
||||
end
|
||||
|
||||
|
|
@ -63,27 +72,27 @@ module Assembler
|
|||
end
|
||||
|
||||
|
||||
def defun(name, addr)
|
||||
@funcs[name] = addr
|
||||
def defun(name, offset)
|
||||
@funcs[name] = offset
|
||||
end
|
||||
|
||||
|
||||
def var(name)
|
||||
bss_offset + @vars[name]
|
||||
end
|
||||
|
||||
def var?(name)
|
||||
@vars[name]
|
||||
end
|
||||
|
||||
def var?(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
|
||||
|
|
|
|||
Loading…
Reference in a new issue