diff --git a/package.py b/package.py index 4fdfa2d..c05499b 100644 --- a/package.py +++ b/package.py @@ -5,10 +5,21 @@ from elftools.elf.sections import Section, SymbolTableSection from typing import List, Tuple, Dict, Generator, Union import os, sys +import json -# A set of sections that we want to include in the image -INCLUDE_THESE_SECTIONS = set(('.text', '.stack', '.bss', '.sdata', '.sbss', '.data', '.stack')) +## Configuration: +# A set of sections that we want to include in the image +INCLUDE_THESE_SECTIONS = set(( + '.text', '.stack', '.bss', '.sdata', + '.sbss', '.data', '.stack', '.init', + '.fini', '.preinit_array', '.init_array', + '.fini_array', '.rodata' +)) +# these sections are empty, so we don't want to read the elf here +EMPTY_SECTIONS = set(( + '.bss', '.sbss', '.stack' +)) # sector size of the img file in bytes SECTOR_SIZE = 512 @@ -18,7 +29,8 @@ MEM_START = 0x100 # process control block struct name KERNEL_BINARY_TABLE = 'binary_table' -KERNEL_BINARY_TABLE_ENTRY_SIZE = 4 * 4 # loaded_binary struct size (4 integers) +# loaded_binary struct size (4 integers) +KERNEL_BINARY_TABLE_ENTRY_SIZE = 4 * 4 def overlaps(p1, l1, p2, l2) -> bool: return (p1 <= p2 and p1 + l1 > p2) or (p2 <= p1 and p2 + l2 > p1) @@ -32,7 +44,7 @@ class Section: def __init__(self, sec): self.name = sec.name self.start = sec.header.sh_addr - if sec.name in ('.text', '.data', '.sdata'): + if sec.name not in EMPTY_SECTIONS: self.data = sec.data() else: self.data = bytes(sec.header.sh_size) @@ -52,7 +64,7 @@ class Bin: entry: int start: int - def __init__(self, name) -> Generator[Section, None, None]: + def __init__(self, name): self.name = name self.secs = list() with open(self.name, 'rb') as f: @@ -81,12 +93,20 @@ class Bin: return sum(sec.size for sec in self) class MemImageCreator: + """ + Interface for writing the img file + """ data: bytes patches: List[Tuple[int, bytes]] + dbg_nfo: Dict def __init__(self): self.data = b'' self.patches = list() + self.dbg_nfo = { + 'sections': dict(), + 'symbols': dict() + } def seek(self, pos): if len(self.data) > pos: @@ -94,27 +114,33 @@ class MemImageCreator: if len(self.data) == pos: return print(f" - zeros {pos-len(self.data):8x} {len(self.data):x}:{pos:x}") - self.put(bytes(pos - len(self.data))) + self.put(bytes(pos - len(self.data)), '', '.empty') assert len(self.data) == pos def align(self, bound): if len(self.data) % bound != 0: - self.put(bytes(bound - (len(self.data) % bound))) + self.put(bytes(bound - (len(self.data) % bound)), '', '.empty') assert len(self.data) % bound == 0 - def put(self, stuff: bytes) -> int: + def put(self, stuff: bytes, parent: str, name: str) -> int: pos = len(self.data) self.data += stuff + self.dbg_nfo['sections'][pos] = parent + ':' + name return pos def putBin(self, bin: Bin) -> int: - pos = len(self.data) + bin_start = len(self.data) for sec in bin: - img_pos = pos + sec.start - bin.start + img_pos = bin_start + sec.start - bin.start self.seek(img_pos) print(f" - section {sec.name:<6} {img_pos:x}:{img_pos + sec.size:x}") - self.put(sec.data) - return pos + self.put(sec.data, bin.name, sec.name) + self.dbg_nfo['symbols'][bin.name] = { + name: bin_start + val - bin.start + for name, val in bin.symtab.items() + if val != 0 + } + return bin_start def patch(self, pos, bytes): for ppos, pbytes in self.patches: @@ -146,10 +172,14 @@ class MemImageCreator: print(f" - zeros {len(self.data):x}:{(SECTOR_SIZE - (len(self.data) % SECTOR_SIZE))+len(self.data):x}") f.write(bytes(SECTOR_SIZE - (len(self.data) % SECTOR_SIZE))) # done! + print(f"writing debug info to {fname}.dbg") + with open(fname + '.dbg', 'w') as f: + json.dump(self.dbg_nfo, f, indent = 2) + def package(kernel: str, binaries: List[str], out: str): """ - create an image + Main logic for creating the image file """ img = MemImageCreator() @@ -179,14 +209,15 @@ def package(kernel: str, binaries: List[str], out: str): def pcb_patch(binid: int, entrypoint: int, start: int, end: int): + """ + Creates the binary data to populate the KERNEL_BINARY_TABLE structs + """ return b''.join(num.to_bytes(4, 'little') for num in (binid, entrypoint, start, end)) - - - if __name__ == '__main__': if '--help' in sys.argv or len(sys.argv) == 1: print_help() else: + print(f"creating image {sys.argv[-1]}") package(sys.argv[1], sys.argv[2:-1], sys.argv[-1])