[Wisp-cvs] wisp/users/dig elf.py,1.9,1.10 linkie.py,1.9,1.10 makehello.py,1.7,1.8
Status: Alpha
Brought to you by:
digg
From: <di...@us...> - 2003-02-15 22:17:19
|
Update of /cvsroot/wisp/wisp/users/dig In directory sc8-pr-cvs1:/tmp/cvs-serv2245 Modified Files: elf.py linkie.py makehello.py Log Message: advanced makehello.py a bit Index: elf.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/elf.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- elf.py 12 Feb 2003 23:05:08 -0000 1.9 +++ elf.py 15 Feb 2003 22:17:16 -0000 1.10 @@ -364,20 +364,22 @@ h.emit_tetra_sum([name + '/alignment']) return h -def make_ELF32_sheader (byte_order, name): - h = Linkie(byte_order) - h.align(4) - h.emit_tetra_sum(['.shstr/strings/' + name]) - h.emit_tetra_sum([name + '/sh_type']) - h.emit_tetra_sum([name + '/sh_flags']) - h.emit_tetra_sum([name]) - h.emit_tetra_sum([name + '/offset']) - h.emit_tetra_sum([name + '/sh_size']) - h.emit_tetra_sum([name + '/sh_link']) - h.emit_tetra_sum([name + '/sh_info']) - h.emit_tetra_sum([name + '/alignment']) - h.emit_tetra_sum([name + '/sh_entsize']) - return h +def make_ELF32_shtable (byte_order, names): + t = Linkie(byte_order) + t.align(4) + t.emit_string('\0' * 40) # the null entry + for name in names: + t.emit_tetra_sum(['.shstr/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 + '/alignment']) + t.emit_tetra_sum([name + '/sh_entsize']) + return t # Thoughts of generating ELF32 files # * In ELF parlance, linker notes are called relocations. Index: linkie.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/linkie.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- linkie.py 15 Feb 2003 15:42:52 -0000 1.9 +++ linkie.py 15 Feb 2003 22:17:16 -0000 1.10 @@ -58,6 +58,8 @@ Places the specified bytes to the byte collector.""" if this._skipped <> 0: raise "Events out of order", this this._binary.fromstring(s) + def from_array (this, a): + this._binary.extend(a) def add_byte (this, ofs, value): this._binary[ofs] = chr(ord(this._binary[ofs]) + value) @@ -282,6 +284,6 @@ if rnotes.has_key(offset): for typ, arg in rnotes[offset]: print ' ' * (14 + (offset & 15) * 3) + \ - "`'-" * abs(typ) + arg + "``-" * abs(typ) + arg start = stop row += 16 Index: makehello.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/makehello.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- makehello.py 15 Feb 2003 15:35:30 -0000 1.7 +++ makehello.py 15 Feb 2003 22:17:16 -0000 1.8 @@ -33,16 +33,99 @@ data.place_symbol('message') data.emit_string('Hello, world!\n') +def infer_by_prefix (name, dict): + for l in range(len(name), -1, -1): + prefix = name[:l] + try: return dict[prefix] + except: pass + return None +def guess_shtype (name): + return infer_by_prefix(name, {'': SHT.PROGBITS, + '.bss': SHT.NOBITS, + '.note': SHT.NOTE, + '.shstr': SHT.STRTAB}) +def guess_ptype (name): + return infer_by_prefix(name, {'': PT.LOAD, + '.note': PT.NOTE}) +def guess_flags (name): + return infer_by_prefix(name, {'': 'rw--', + '.bss': 'rw--', + '.comment': '----', + '.data': 'rw--', + '.debug': '----', + '.line': '----', + '.note': '----', + '.rodata': 'r---', + '.shstr': '---s', + '.text': 'r-x-'}) +def guess_shflags (name): + flags = guess_flags(name) + sh_flags = 0 + if 'r' in flags: sh_flags |= SHF.ALLOC + if 'w' in flags: sh_flags |= SHF.ALLOC | SHF.WRITE + if 'x' in flags: sh_flags |= SHF.ALLOC | SHF.EXECINSTR + if 's' in flags: sh_flags |= SHF.STRINGS + return sh_flags +def guess_pflags (name): + flags = guess_flags(name) + p_flags = 0 + if 'r' in flags: p_flags |= PF.R + if 'w' in flags: p_flags |= PF.W + if 'x' in flags: p_flags |= PF.X + return p_flags + +symbols = {} + +shstr = Linkie('<') +shstr.emit_byte(0) +symbols['.shstr/strings/.text'] = shstr.filesz() +shstr.emit_string('.text\0') +symbols['.shstr/strings/.data'] = shstr.filesz() +shstr.emit_string('.data\0') +symbols['.shstr/strings/.shstr'] = shstr.filesz() +shstr.emit_string('.shstr\0') + hello = Linkie('<') -memory_boundary = 0x8048000 +memory_boundary = 0x8048000 # must be at page boundary hello.extend(make_ELF32_header('<')) -symbols = {} symbols['elf/type'] = ET.EXEC symbols['elf/machine'] = EM.I386 symbols['elf/flags'] = 0 # no flags for ia386 -program_header_table = make_ELF32_pheader('<', '.text') +program_header_table = make_ELF32_pheader('<', '.text') + \ + make_ELF32_pheader('<', '.data') symbols['elf/phoff'] = hello.extend(program_header_table) -# process the text segment -symbols['.text/offset'] = hello.extend(code) +symbols['elf/phnum'] = 2 +# process the segments +for name, section in (('.text', code), ('.data', data), ('.shstr', shstr)): + alignment = section.get_alignment() + symbols[name + '/alignment'] = alignment + hello.align(min(alignment, 0x1000)) + offset = hello.filesz() + address = memory_boundary | (offset & 0xFFF) + # take into account alignments larger than a page + address = (address + alignment - 1) & ~(alignment - 1) + symbols[name] = address + 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_flags'] = guess_shflags(name) + symbols[name + '/p_flags'] = guess_pflags(name) + symbols[name + '/p_type'] = guess_ptype(name) + data = section.get_file() + hello.from_array(data) + for symbol, value in section.get_symbols(): + symbols[symbol] = address + value + hello.place_symbol(symbol, offset + value) # for dump to work nicely + memory_boundary += section.memsz() + memory_boundary = (memory_boundary + 0xFFF) & ~0xFFF + +# create section header table +section_header_table = make_ELF32_shtable('<', ['.text', '.data', '.shstr']) +symbols['elf/shoff'] = hello.extend(section_header_table) +symbols['elf/shnum'] = 4 +symbols['elf/shstrndx'] = 3 hello.link(symbols) hello.dump() |