[Wisp-cvs] wisp/users/dig linkie.py,1.34,1.35
Status: Alpha
Brought to you by:
digg
From: <di...@us...> - 2003-04-26 16:52:44
|
Update of /cvsroot/wisp/wisp/users/dig In directory sc8-pr-cvs1:/tmp/cvs-serv11450 Modified Files: linkie.py Log Message: extracted Bits from Linkie Index: linkie.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/linkie.py,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- linkie.py 22 Apr 2003 22:29:29 -0000 1.34 +++ linkie.py 26 Apr 2003 16:52:41 -0000 1.35 @@ -10,73 +10,65 @@ from array import array from types import * -class Linkie (object): - def __init__ (this, byte_order): - this._symbols = [] # symbol -> address - this._alignment = 1 # minimal required alignment constraint - this._binary = array('c') - 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 - this._origin_secondary = 0 # support MS-style RVAs (%foo symbols) - if byte_order == '<': +class Bits (object): + __slots__ = ['_contents'] + def __init__ (this, byte_order = None): + this._contents = array('c') + if byte_order == None: pass + elif byte_order == '<': this.emit_wyde = this.emit_lewyde this.emit_tetra = this.emit_letetra + this.add_wyde = this.add_lewyde + this.add_tetra = this.add_letetra elif byte_order == '>': this.emit_wyde = this.emit_bewyde this.emit_tetra = this.emit_betetra - else: - raise "Unknown byte order", byte_order - this._byte_order = byte_order - this._linker_notes = [] # list of (location, type, data) + this.add_wyde = this.add_bewyde + this.add_tetra = this.add_betetra + else: raise "Unknown byte order", byte_order def emit_byte (this, b): - """emit_byte(b) - Places a byte to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.append(chr(b & 0xff)) + this._contents.append(chr(b & 0xff)) def emit_bewyde (this, w): - """emit_bewyde(w) - Places a BigEndian wyde to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.fromstring(pack('>H', w)) # FIXME? + this._contents.fromstring(pack('>H', w)) # FIXME? def emit_lewyde (this, w): - """emit_bewyde(w) - Places a LittleEndian wyde to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.fromstring(pack('<H', w)) # FIXME? + this._contents.fromstring(pack('<H', w)) # FIXME? def emit_betetra (this, t): - """emit_betetra(t) - Places a BigEndian tetra to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.fromstring(pack('>L', t)) # FIXME? + this._contents.fromstring(pack('>L', t)) # FIXME? def emit_letetra (this, t): - """emit_letetra(t) - Places a LittleEndian tetra to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.fromstring(pack('<L', t)) # FIXME? + this._contents.fromstring(pack('<L', t)) # FIXME? def emit_string (this, s): - """emit_string(s) - Places the specified bytes to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this - this._binary.fromstring(s) + this._contents.fromstring(s) def from_array (this, a): - this._binary.extend(a) - + this._contents.extend(a) def add_byte (this, ofs, value): - this._binary[ofs] = chr((ord(this._binary[ofs]) + value) % 0x100) - def add_wyde (this, ofs, value): - tpl = this._byte_order + 'H' - datum, = unpack(tpl, this._binary[ofs : ofs + 2]) - datum += value - datum %= 0x10000 - this._binary[ofs : ofs + 2] = array('c', pack(tpl, datum)) - def add_tetra (this, ofs, value): - tpl = this._byte_order + 'L' - datum, = unpack(tpl, this._binary[ofs : ofs + 4]) + this._contents[ofs] = chr((ord(this._contents[ofs]) + value) % 0x100) + def _add (this, ofs, value, size, tpl): + datum, = unpack(tpl, this._contents[ofs : ofs + size]) datum += value - datum %= 0x100000000L - this._binary[ofs : ofs + 4] = array('c', pack(tpl, datum)) + datum %= 1L << (size << 3) + this._contents[ofs : ofs + size] = array('c', pack(tpl, datum)) + def add_lewyde (this, ofs, value): this._add(ofs, value, 2, '<H') + def add_bewyde (this, ofs, value): this._add(ofs, value, 2, '>H') + def add_letetra (this, ofs, value): this._add(ofs, value, 4, '<L') + def add_betetra (this, ofs, value): this._add(ofs, value, 4, '>L') + +class Linkie (Bits): + def __init__ (this, byte_order = None): + Bits.__init__(this, byte_order) + this._symbols = [] # symbol -> address + this._alignment = 1 # minimal required alignment constraint + 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 + this._origin_secondary = 0 # support MS-style RVAs (%foo symbols) + this._linker_notes = [] # list of (location, type, data) def notify_linker (this, offset, type, arg): this._linker_notes.append((offset, type, arg)) @@ -97,7 +89,7 @@ if this._locals[a] <> None: # backwards delta += this._locals[a] else: # forwards - this._unresolved_locals.append((a, s, len(this._binary))) + this._unresolved_locals.append((a, s, len(this._contents))) elif type(a) == StringType: # global reference if not a[0] in '#&!%': raise 'unprefixed symbol being referred to', a @@ -119,16 +111,16 @@ def deskip (this): """deskip() Converts all reserved bytes to null bytes.""" - this._binary.fromstring(this._skipped * '\0') + this._contents.fromstring(this._skipped * '\0') this._skipped = 0; def memsz (this): """memsz() -> int Returns the memory image size of the linkie.""" - return len(this._binary) + this._skipped + return len(this._contents) + this._skipped def filesz (this): """filesz() -> int Returns the file image size of the linkie.""" - return len(this._binary) + return len(this._contents) def generate_label (this): """generate_label() -> int Allocates a new local label number. Doesn't place the label. @@ -141,7 +133,7 @@ Places a label previously returned by generate_label.""" if this._locals[label] <> None: raise 'Duplicate label', label - this._locals[label] = len(this._binary) + this._skipped + this._locals[label] = len(this._contents) + this._skipped # Resolve open references to that label, if any i = len(this._unresolved_locals) while i > 0: @@ -167,7 +159,7 @@ if type(symbol) <> StringType: raise 'Not a string', symbol if not symbol[0] in '#&!%': raise 'unprefixed symbol being placed', symbol - if value == None: value = len(this._binary) + this._skipped + if value == None: value = len(this._contents) + this._skipped if symbol[0] in '&%': value += this._origin this._symbols.append((symbol, value)) return value @@ -180,11 +172,11 @@ raise 'Base address violates new alignment', \ (this._origin, boundary) if this._alignment < boundary: this._alignment = boundary - delta = (boundary - 1) & - (len(this._binary) + this._skipped) + delta = (boundary - 1) & - (len(this._contents) + this._skipped) if this._skipped: this._skipped += delta else: - this._binary.fromstring(delta * '\0') + this._contents.fromstring(delta * '\0') def set_origin (this, origin): """set_origin(origin) Sets the base address of the linkie to the specified value. @@ -222,13 +214,13 @@ See also get_memory.""" if this._unresolved_locals: raise 'incomplete linkie', this if this._linker_notes and not force: raise 'unlinked linkie', this - return this._binary[:] + return this._contents[:] def get_memory (this): """get_memory() -> array of chars Returns a copy of the memory image of the linkie. See also get_file and get_alignment.""" if this._unresolved_locals: raise 'Incomplete linkie', this - return this._binary + array('c', '\0') * this._skipped + return this._contents + array('c', '\0') * this._skipped def get_alignment (this): """get_alignment() -> int Returns the alignment constraint of the linkie. @@ -268,7 +260,7 @@ if this._unresolved_locals: raise 'Incomplete linkie', this that = Linkie(this._byte_order) that._alignment = this._alignment - that._binary = this._binary[:] + that._contents = this._contents[:] that._skipped = this._skipped that._symbols = this._symbols[:] that._linker_notes = this._linker_notes[:] @@ -282,7 +274,7 @@ if that.filesz(): this.deskip() this.align(that._alignment) delta = this.memsz() - that._origin - this._binary.extend(that._binary) + this._contents.extend(that._contents) this._skipped = that._skipped for sym, val in that._symbols: this._symbols.append((sym, val)) @@ -311,7 +303,7 @@ thatofs = this.memsz() # carry over all the bits - this._binary.extend(that._binary) + this._contents.extend(that._contents) this._skipped = that._skipped # carry over and process the symbols @@ -348,17 +340,20 @@ elif type == 4: this.add_tetra(offset, symbols[arg]) elif type == -1: - this.add_byte(offset, symbols[arg] - offset) + this.add_byte(offset, symbols[arg] - + (this._origin + offset)) elif type == -2: - this.add_wyde(offset, symbols[arg] - offset) + this.add_wyde(offset, symbols[arg] - + (this._origin + offset)) elif type == -4: - this.add_tetra(offset, symbols[arg] - offset) + this.add_tetra(offset, symbols[arg] - + (this._origin + offset)) else: raise 'Invalid linker note type', (offset, type, arg) del this._linker_notes[i] return len(this._linker_notes) def dump (this): - filesz = len(this._binary) + filesz = len(this._contents) skipsz = this._skipped memsz = filesz + skipsz origin = this._origin @@ -398,7 +393,7 @@ if start <= column < stop: offset = row + column if offset < this.filesz(): - byte = this._binary[offset] + byte = this._contents[offset] hex += '%02x ' % ord(byte) if byte < ' ' or byte > '~': byte = '.' ascii += byte |