[Wisp-cvs] wisp/users/dig linkie.py,1.13,1.14
Status: Alpha
Brought to you by:
digg
From: <di...@us...> - 2003-03-09 13:11:43
|
Update of /cvsroot/wisp/wisp/users/dig In directory sc8-pr-cvs1:/tmp/cvs-serv32215 Modified Files: linkie.py Log Message: added origin attributes to the Linkie instances Index: linkie.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/linkie.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- linkie.py 9 Mar 2003 07:10:28 -0000 1.13 +++ linkie.py 9 Mar 2003 13:11:40 -0000 1.14 @@ -18,6 +18,7 @@ this._skipped = 0 # uninitialized space after bits this._locals = [] # label no -> address this._unresolved_locals = [] # order is irrelevant + this._origin = 0 # the base address of this linkie if byte_order == '<': this.emit_wyde = this.emit_lewyde this.emit_tetra = this.emit_letetra @@ -142,22 +143,43 @@ def place_symbol (this, symbol, value = None): """place_symbol(symbol, value = None) => value Places a globally visible symbol in the linkie. + Takes care of adding the base address if the symbol starts in '&'. Does NOT check uniqueness. None signifies the current offset.""" if type(symbol) <> StringType: raise 'Not a string', symbol if value == None: value = len(this._binary) + this._skipped + if symbol[0] == '&': value += this._origin this._symbols.append((symbol, value)) return value def align (this, boundary): """align(boundary) Ensures that the following byte's memory address is divisible by - the specified boundary (which must be a power of 2).""" + the specified boundary (which must be a power of 2). Error if + the current base address doesn't match the alignment.""" + if (this._origin % boundary) != 0: + raise 'Base address violates new alignment', \ + (this._origin, boundary) if this._alignment < boundary: this._alignment = boundary delta = (boundary - 1) & - (len(this._binary) + this._skipped) if this._skipped: this._skipped += delta else: this._binary.fromstring(delta * '\0') + def set_origin (this, origin): + """set_origin(origin) + Sets the base address of the linkie to the specified value. + Recalculates the &foo symbols. Does NOT influence already + resolved references to changing labels, so be careful if + using after partial linkage.""" + if (origin % this._alignment) != 0: + raise 'New base address violates alignment', \ + (boundary, this._origin) + delta = origin - this._origin + for i in range(len(this._symbols)): + symbol, value = this._symbols[i] + if symbol[0] == '&': + this._symbols[i] = symbol, value + delta + this._origin = origin def get_file (this): """get_file() -> array of chars @@ -198,6 +220,8 @@ Returns a list of the linker notes from the linkie.""" if this._unresolved_locals: raise 'Incomplete linkie', this return this._linker_notes[:] + def get_origin (this): + return this._origin def copy (this): if this._unresolved_locals: raise 'Incomplete linkie', this @@ -244,11 +268,14 @@ filesz = len(this._binary) skipsz = this._skipped memsz = filesz + skipsz - print 'Linkie (0x%x + 0x%x = 0x%x)' % (filesz, skipsz, memsz), + origin = this._origin + print 'Linkie (0x%x + 0x%x = 0x%x @ 0x%x)' % \ + (filesz, skipsz, memsz, origin), print 'aligned at 0x%x' % this._alignment rsymbols = {}; othersymbols = [] rnotes = {}; othernotes = [] for sym, val in this._symbols: + if sym[0] == '&': val -= this._origin if sym[0] != '#' and 0 <= val < this.memsz(): if rsymbols.has_key(val): rsymbols[val].append(sym) else: rsymbols[val] = [sym] |