[Wisp-cvs] wisp/users/dig Makefile.am,1.5,1.6 elf.py,1.13,1.14 linkie.py,1.18,1.19 make-pe-exe.py,1.
Status: Alpha
Brought to you by:
digg
From: <di...@us...> - 2003-03-24 21:18:19
|
Update of /cvsroot/wisp/wisp/users/dig In directory sc8-pr-cvs1:/tmp/cvs-serv20661/users/dig Modified Files: Makefile.am elf.py linkie.py make-pe-exe.py makehello.py Log Message: improved linkie labeling Index: Makefile.am =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/Makefile.am,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Makefile.am 9 Feb 2003 09:31:12 -0000 1.5 +++ Makefile.am 24 Mar 2003 21:18:12 -0000 1.6 @@ -12,4 +12,4 @@ all: clean: clean-am - -rm -f *~ *.pyc *.pyo + -rm -f *~ *.pyc *.pyo hello Index: elf.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/elf.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- elf.py 14 Mar 2003 19:01:16 -0000 1.13 +++ elf.py 24 Mar 2003 21:18:13 -0000 1.14 @@ -336,50 +336,54 @@ raise 'Invalid byte order', byte_order h.emit_byte(EV.CURRENT) h.emit_string('\0' * 9) - h.emit_wyde_sum(['elf/type']) - h.emit_wyde_sum(['elf/machine']) + h.emit_wyde_sum(['#elf/type']) + h.emit_wyde_sum(['#elf/machine']) h.emit_tetra(EV.CURRENT) h.emit_tetra_sum(['&_start']) - h.emit_tetra_sum(['elf/phoff']) - h.emit_tetra_sum(['elf/shoff']) - h.emit_tetra_sum(['elf/flags']) + h.emit_tetra_sum(['!elf/proghdr']) + h.emit_tetra_sum(['!elf/secthdr']) + h.emit_tetra_sum(['#elf/flags']) h.emit_wyde(0x34) # e_ehsize h.emit_wyde(32) # e_phentsize - h.emit_wyde_sum(['elf/phnum']) + h.emit_wyde_sum(['#elf/phnum']) h.emit_wyde(40) # e_shentsize - h.emit_wyde_sum(['elf/shnum']) - h.emit_wyde_sum(['elf/shstrndx']) + h.emit_wyde_sum(['#elf/shnum']) + h.emit_wyde_sum(['#elf/shstrndx']) return h def make_ELF32_phtable (byte_order, names): t = Linkie(byte_order) t.align(4) + t.place_symbol('!elf/proghdr') for name in names: - t.emit_tetra_sum([name + '/p_type']) - t.emit_tetra_sum([name + '/offset']) - t.emit_tetra_sum([name]) # p_vaddr - t.emit_tetra_sum([name]) # p_paddr - t.emit_tetra_sum([name + '/filesz']) - t.emit_tetra_sum([name + '/memsz']) - t.emit_tetra_sum([name + '/p_flags']) - t.emit_tetra_sum([name + '/p_align']) + t.emit_tetra_sum(['#' + name + '/p_type']) + t.emit_tetra_sum(['!' + name]) # offset + t.emit_tetra_sum(['&' + name]) # p_vaddr + t.emit_tetra_sum(['&' + name]) # p_paddr + t.emit_tetra_sum(['#' + name + '/filesz']) + t.emit_tetra_sum(['#' + name + '/memsz']) + t.emit_tetra_sum(['#' + name + '/p_flags']) + t.emit_tetra_sum(['#' + name + '/p_align']) + t.place_symbol('#elf/phnum', len(names)) return t def make_ELF32_shtable (byte_order, names): t = Linkie(byte_order) t.align(4) + t.place_symbol('!elf/secthdr') t.emit_string('\0' * 40) # the null entry for name in names: - t.emit_tetra_sum(['.shstrtab/strings/' + name]) - t.emit_tetra_sum([name + '/sh_type']) - t.emit_tetra_sum([name + '/sh_flags']) - t.emit_tetra_sum([name]) - t.emit_tetra_sum([name + '/offset']) - t.emit_tetra_sum([name + '/sh_size']) - t.emit_tetra_sum([name + '/sh_link']) - t.emit_tetra_sum([name + '/sh_info']) - t.emit_tetra_sum([name + '/sh_align']) - t.emit_tetra_sum([name + '/sh_entsize']) + t.emit_tetra_sum(['#.shstrtab/strings/' + name]) + t.emit_tetra_sum(['#' + name + '/sh_type']) + t.emit_tetra_sum(['#' + name + '/sh_flags']) + t.emit_tetra_sum(['&' + name]) + t.emit_tetra_sum(['!' + name]) + t.emit_tetra_sum(['#' + name + '/sh_size']) + t.emit_tetra_sum(['#' + name + '/sh_link']) + t.emit_tetra_sum(['#' + name + '/sh_info']) + t.emit_tetra_sum(['#' + name + '/sh_align']) + t.emit_tetra_sum(['#' + name + '/sh_entsize']) + t.place_symbol('#elf/shnum', len(names) + 1) return t # Thoughts of generating ELF32 files Index: linkie.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/linkie.py,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- linkie.py 14 Mar 2003 07:01:05 -0000 1.18 +++ linkie.py 24 Mar 2003 21:18:13 -0000 1.19 @@ -144,15 +144,15 @@ """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 '&' or '$'. + starts in '&'. Does NOT check uniqueness. None signifies the current offset.""" if type(symbol) <> StringType: raise 'Not a string', symbol - if not symbol[0] in '#&$!': + if not symbol[0] in '#&!': # FIXME: backwards compatibility print 'WARNING: unprefixed symbol', symbol, 'being placed' if value == None: value = len(this._binary) + this._skipped - if symbol[0] in '&$': value += this._origin + if symbol[0] == '&': value += this._origin this._symbols.append((symbol, value)) return value def align (this, boundary): @@ -172,8 +172,8 @@ def set_origin (this, origin): """set_origin(origin) Sets the base address of the linkie to the specified value. - Recalculates the &foo and $foo symbols. Does NOT influence - already resolved references to changing labels, so be careful + 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', \ @@ -181,7 +181,7 @@ delta = origin - this._origin for i in range(len(this._symbols)): symbol, value = this._symbols[i] - if symbol[0] in '&$': + if symbol[0] == '&': this._symbols[i] = symbol, value + delta this._origin = origin @@ -237,41 +237,70 @@ that._linker_notes = this._linker_notes[:] that._origin = this._origin return that - def fall (this): - # forces the base address to zero and converts $foo to !foo - for sym, val in this._symbols: - if sym[0] == '$': - this._symbols.append(('!' + sym[1:], val - this._origin)) - this._origin = 0 def extend (this, that): # Returns the offset of /that/ inside /this/ after extension. if this._unresolved_locals: raise 'Incomplete linkie', this if that._unresolved_locals: raise 'Incomplete linkie', that - if this._origin != 0: - this.fall() + this._origin = 0 if that.filesz(): this.deskip() this.align(that._alignment) delta = this.memsz() - that._origin this._binary.extend(that._binary) this._skipped = that._skipped for sym, val in that._symbols: - if sym[0] in '#&$!': + if sym[0] in '#&!': this._symbols.append((sym, val)) else: # FIXME: backwards compatibility print 'WARNING: unprefixed symbol', sym this._symbols.append((sym, val + delta)) - if sym[0] == '$': - this._symbols.append(('!' + sym[1:], val + delta)) for ofs, typ, arg in that._linker_notes: this._linker_notes.append((ofs + delta, typ, arg)) return delta + def paste (this, offset, that): + # Pastes /that/ into /this/ at specified /offset/ (if negative + # /offset/ is treated as an alignment restriction and the actual + # offset is automatically calculated from that). + # Note that the specified alignment of /that/ is IGNORED. + # Origin of /this/ *should* be zero. + + if this._unresolved_locals: raise 'Incomplete linkie', this + if that._unresolved_locals: raise 'Incomplete linkie', that + + # provide sufficient padding + if offset < 0: this.align(- offset) + else: this.skip(offset - this.memsz()) + + # convert any padding to hard zeroes if needed + if that.filesz(): this.deskip() + + # remember the start offset of /that/ + thatofs = this.memsz() + + # carry over all the bits + this._binary.extend(that._binary) + this._skipped = that._skipped + + # carry over and process the symbols + for sym, val in that._symbols: + if sym[0] == '!': + this._symbols.append((sym, val + thatofs)) + elif sym[0] in '#&': + this._symbols.append((sym, val)) + else: + raise 'unprefixed symbol', sym + + # carry over the linker notes + for ofs, typ, arg in that._linker_notes: + this._linker_notes.append((ofs + thatofs, typ, arg)) + # return nothing def __add__ (this, that): this = this.copy() this.extend(that) return this - def link (this, symbols): + def link (this): + symbols = this.get_symbol_dict() i = len(this._linker_notes) while i > 0: i = i - 1 @@ -295,7 +324,7 @@ rsymbols = {}; othersymbols = [] rnotes = {}; othernotes = [] for sym, val in this._symbols: - if sym[0] in '&$': val -= this._origin + 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] Index: make-pe-exe.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/make-pe-exe.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- make-pe-exe.py 9 Mar 2003 14:20:59 -0000 1.1 +++ make-pe-exe.py 24 Mar 2003 21:18:13 -0000 1.2 @@ -61,7 +61,7 @@ b.emit_string(message) b.place_symbol('#mz/bytes-in-last-block', b.filesz() % 0x200) b.place_symbol('#mz/blocks-in-file', (b.filesz() + 0x1FF) / 0x200) - b.link(b.get_symbol_dict()) + b.link() return b p = make_mz_prefix('OS too broken') Index: makehello.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/makehello.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- makehello.py 14 Mar 2003 19:01:18 -0000 1.14 +++ makehello.py 24 Mar 2003 21:18:13 -0000 1.15 @@ -81,17 +81,18 @@ return p_flags def make_executable (text = None, data = None, memory_bottom = 0x08048000): + # Will set given sections' origins. + sections = {} sections['.text'] = code sections['.data'] = data - symbols = {} binary = Linkie('<') memory_boundary = memory_bottom # must be at page boundary - binary.extend(make_ELF32_header('<')) - symbols['elf/type'] = ET.EXEC - symbols['elf/machine'] = EM.I386 - symbols['elf/flags'] = 0 # no flags for ia386 + binary.paste(0, make_ELF32_header('<')) + binary.place_symbol('#elf/type', ET.EXEC) + binary.place_symbol('#elf/machine', EM.I386) + binary.place_symbol('#elf/flags', 0) # no flags for ia386 shentnames = ['.text', '.data', '.symstr', '.symtab', '.shstrtab'] @@ -109,81 +110,76 @@ for name in shentnames: if guess_pflags(name) <> 0: phentnames.append(name) - symbols['.shstrtab/strings/' + name] = sections['.shstrtab'].filesz() + sections['.shstrtab'].place_symbol('#.shstrtab/strings/' + name) sections['.shstrtab'].emit_string(name) sections['.shstrtab'].emit_byte(0) program_header_table = make_ELF32_phtable('<', phentnames) - symbols['elf/phoff'] = binary.extend(program_header_table) - symbols['elf/phnum'] = len(phentnames) + binary.paste(-4, program_header_table) for name in shentnames: section = sections[name] p_flags = guess_pflags(name) alignment = section.get_alignment() - symbols[name + '/sh_align'] = alignment + binary.place_symbol('#' + name + '/sh_align', alignment) if p_flags <> 0: - symbols[name + '/p_align'] = 0x1000 + binary.place_symbol('#' + name + '/p_align', 0x1000) binary.align(min(alignment, 0x1000)) else: # No program header entry => not loaded # thusly no larger alignment necessary. binary.align(min(alignment, 4)) - binary.place_symbol(name) offset = binary.filesz() if p_flags <> 0: address = memory_boundary | (offset & 0xFFF) # take into account alignments larger than a page address = (address + alignment - 1) & ~(alignment - 1) - symbols[name + '/p_flags'] = guess_pflags(name) - symbols[name + '/p_type'] = guess_ptype(name) - symbols[name] = address + binary.place_symbol('#' + name + '/p_flags', guess_pflags(name)) + binary.place_symbol('#' + name + '/p_type', guess_ptype(name)) + section.set_origin(address) + binary.place_symbol('&' + name, address) else: address = None - symbols[name] = 0 - symbols[name + '/offset'] = offset - symbols[name + '/memsz'] = section.memsz() - symbols[name + '/filesz'] = section.filesz() - symbols[name + '/sh_size'] = section.filesz() - symbols[name + '/sh_type'] = guess_shtype(name) - symbols[name + '/sh_info'] = 0 - symbols[name + '/sh_link'] = SHN.UNDEF - symbols[name + '/sh_entsize'] = 0 - symbols[name + '/sh_flags'] = guess_shflags(name) + binary.place_symbol('#' + name + '/memsz', section.memsz()) + binary.place_symbol('#' + name + '/filesz', section.filesz()) + binary.place_symbol('#' + name + '/sh_size', section.filesz()) + binary.place_symbol('#' + name + '/sh_type', guess_shtype(name)) + binary.place_symbol('#' + name + '/sh_info', 0) + if name == '.symtab': sh_link = shentnames.index('.symstr') + 1 + else: sh_link = SHN.UNDEF + binary.place_symbol('#' + name + '/sh_link', sh_link) + binary.place_symbol('#' + name + '/sh_entsize', 0) + binary.place_symbol('#' + name + '/sh_flags', guess_shflags(name)) - binary.from_array(section.get_file()) - if address <> None: - for symbol, value in section.get_symbols(): - symbols[symbol] = address + value + # alignment has been processed already + binary.place_symbol('!' + name) + binary.paste(-1, section) for symbol, value in section.get_symbols(): if symbol[0] != '&': continue # only process memory references - sofs = sections['.symstr'].filesz() - symbols['.symstr/strings/' + symbol] = sofs + symbol = symbol[1:] # but not their prefixen + symstr = sections['.symstr'] + symstr.place_symbol('#.symstr/strings/' + symbol) sections['.symstr'].emit_string(symbol) sections['.symstr'].emit_byte(0) - sections['.symtab'].emit_tetra(sofs) - sections['.symtab'].emit_tetra_sum([name]) + sections['.symtab'].emit_tetra_sum(['#.symstr/strings/' + symbol]) + sections['.symtab'].emit_tetra_sum(['&' + name]) sections['.symtab'].emit_tetra(0) sections['.symtab'].emit_byte(STB.GLOBAL << 4 | STT.NOTYPE) sections['.symtab'].emit_byte(0) sections['.symtab'].emit_wyde(shentnames.index(name) + 1) - for loc, typ, arg in section.get_notes(): - binary.notify_linker(offset + loc, typ, arg) memory_boundary += section.memsz() memory_boundary = (memory_boundary + 0xFFF) & ~0xFFF # create section header table section_header_table = make_ELF32_shtable('<', shentnames) - symbols['elf/shoff'] = binary.extend(section_header_table) - symbols['elf/shnum'] = len(shentnames) + 1 - symbols['elf/shstrndx'] = shentnames.index('.shstrtab') + 1 - symbols['.symtab/sh_link'] = shentnames.index('.symstr') + 1 - binary.link(symbols) + binary.paste(-4, section_header_table) + binary.place_symbol('#elf/shstrndx', shentnames.index('.shstrtab') + 1) + binary.link() return binary hello = make_executable(text = code, data = data) |