mirror of
https://github.com/samsonjs/compiler.git
synced 2026-04-27 14:57:45 +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
|
include MachO
|
||||||
|
|
||||||
def const_offset
|
def make_symbols(vars, base_addr, type, segnum)
|
||||||
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)
|
|
||||||
# Note: Sorting a Ruby hash gives an alist, e.g. [[<key>, <value>], ...]
|
# 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.
|
# We can use map on it as if it were a hash so it works nicely.
|
||||||
vars.sort { |a,b| a[1] <=> b[1] }.
|
vars.sort { |a,b| a[1] <=> b[1] }.
|
||||||
map do |name, addr|
|
map do |name, offset|
|
||||||
MachOSym.new(name, type, segnum, 0, addr)
|
MachOSym.new(name, type, segnum, 0, base_addr + offset)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -31,12 +21,32 @@ module Assembler
|
||||||
# TODO FIXME:
|
# TODO FIXME:
|
||||||
# - the last var exported ends up after main somewhere... WTF?!
|
# - the last var exported ends up after main somewhere... WTF?!
|
||||||
# - All labels are exported. This should be changed and only functions exported!
|
# - 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)
|
section = 1
|
||||||
make_symbols(@vars, N_SECT, 3) # Variables (section #3, __bss)
|
|
||||||
|
# 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
|
return symbols
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this is fairly stupid but works
|
||||||
|
def bss_section
|
||||||
|
@consts.size > 0 ? 3 : 2
|
||||||
|
end
|
||||||
|
|
||||||
def nlist_ary
|
def nlist_ary
|
||||||
symbols = {}
|
symbols = {}
|
||||||
strx = 1
|
strx = 1
|
||||||
|
|
@ -53,10 +63,26 @@ module Assembler
|
||||||
end
|
end
|
||||||
|
|
||||||
def stab
|
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")
|
['', all_symbols, ''].flatten.map { |sym| sym.to_s }.join("\0")
|
||||||
end
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,22 @@
|
||||||
module Assembler
|
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
|
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
|
def initialize
|
||||||
@vars = {} # Map of variable names to addresses. (bss vars)
|
@vars = {} # Map of variable names to offsets. (bss vars)
|
||||||
@consts = {} # Map of constant names to addresses.
|
@consts = {} # Map of constant names to offsets.
|
||||||
@funcs = {} # map of function names to addresses.
|
@funcs = {} # map of function names to offsets.
|
||||||
|
|
||||||
# Initial data to load into memory (data for __DATA segment).
|
# Initial data to load into memory (data for __DATA segment).
|
||||||
@const_data = ''
|
@const_data = ''
|
||||||
|
|
@ -19,15 +28,15 @@ module Assembler
|
||||||
@labels = Hash.new {|h, key| raise "undefined label: #{key}"}
|
@labels = Hash.new {|h, key| raise "undefined label: #{key}"}
|
||||||
@num_labels = 0 # Used to generate unique labels.
|
@num_labels = 0 # Used to generate unique labels.
|
||||||
@num_labels_with_suffix = Hash.new(0)
|
@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
|
end
|
||||||
|
|
||||||
|
|
||||||
####
|
|
||||||
## NB: Concrete subclasses must define methods named:
|
|
||||||
## bss_offset, and const_offset
|
|
||||||
####
|
|
||||||
|
|
||||||
|
|
||||||
# Generate a unique label.
|
# Generate a unique label.
|
||||||
def unique_label(suffix=nil)
|
def unique_label(suffix=nil)
|
||||||
@num_labels += 1
|
@num_labels += 1
|
||||||
|
|
@ -39,8 +48,8 @@ module Assembler
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
def deflabel(name, addr)
|
def deflabel(name, offset)
|
||||||
@labels[name] = addr
|
@labels[name] = offset
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -63,25 +72,25 @@ module Assembler
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def defun(name, addr)
|
def defun(name, offset)
|
||||||
@funcs[name] = addr
|
@funcs[name] = offset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def var(name)
|
def var(name)
|
||||||
bss_offset + @vars[name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def var?(name)
|
|
||||||
@vars[name]
|
@vars[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def var?(name)
|
||||||
|
@vars.has_key?(name)
|
||||||
|
end
|
||||||
|
|
||||||
def const(name)
|
def const(name)
|
||||||
const_offset + @consts[name]
|
@consts[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def const?(name)
|
def const?(name)
|
||||||
@consts[name]
|
@consts.has_key?(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue