def __init__(self, alloc, path_mgr=None): self.alloc = alloc self.path_mgr = path_mgr self.mem = alloc.get_mem() self.binfmt = BinFmt() # map seglist baddr to bin_img self.infos = {}
def __init__(self, mem, alloc, label_mgr, path_mgr): self.mem = mem self.alloc = alloc self.label_mgr = label_mgr self.path_mgr = path_mgr self.error = None self.loaded_seg_lists = {} self.binfmt = BinFmt()
class SegmentLoader(object): def __init__(self, alloc, path_mgr=None): self.alloc = alloc self.path_mgr = path_mgr self.mem = alloc.get_mem() self.binfmt = BinFmt() # map seglist baddr to bin_img self.infos = {} def load_sys_seglist(self, sys_bin_file): """load seglist, register it, and return seglist baddr or 0""" info = self.int_load_sys_seglist(sys_bin_file) if info: baddr = info.seglist.get_baddr() self.infos[baddr] = info log_segload.info("loaded sys seglist: %s", info) return baddr else: log_segload.info("can't load sys seglist: %s", sys_bin_file) return 0 def load_ami_seglist(self, ami_bin_file, lock=None): """load seglist, register it, and return seglist baddr or 0""" info = self.int_load_ami_seglist(ami_bin_file, lock) if info: baddr = info.seglist.get_baddr() self.infos[baddr] = info log_segload.info("loaded ami seglist: %s", info) return baddr else: log_segload.info("can't load ami seglist: %s", ami_bin_file) return 0 def unload_seglist(self, seglist_baddr): """unregister given seglist baddr and free seglist. return True if seglist was unloaded""" if seglist_baddr not in self.infos: log_segload.error("unknown seglist at @%06x", seglist_baddr) return False info = self.infos[seglist_baddr] log_segload.info("unload seglist: %s", info) del self.infos[seglist_baddr] info.seglist.free() return True def get_info(self, seglist_baddr): """return associated bin_img for given registered seglist baddr or None""" if seglist_baddr in self.infos: return self.infos[seglist_baddr] def register_seglist(self, baddr): """register custom seglist""" info = SegLoadInfo(SegList(self.alloc, baddr)) log_segload.info("register seglist: %s", info) self.infos[baddr] = info def unregister_seglist(self, baddr): """remove custom seglist""" info = self.infos[baddr] log_segload.info("unregister seglist: %s", info) del self.infos[baddr] def shutdown(self): """check orphan seglists on shutdown and return number of orphans""" log_segload.info("shutdown") for baddr in self.infos: info = self.infos[baddr] log_segload.warning("orphaned seglist: %s", info) # try to free list info.seglist.free() return len(self.infos) def int_load_ami_seglist(self, ami_bin_file, lock=None): """load seglist given by ami binary path and return SegLoadInfo""" if self.path_mgr is None: return None # try to map path sys_path = self.path_mgr.ami_to_sys_path(lock, ami_bin_file, mustExist=True) if sys_path: info = self.int_load_sys_seglist(sys_path) info.ami_file = ami_bin_file return info def int_load_sys_seglist(self, sys_bin_file): """load seglist given by sys binary path and return SegLoadInfo""" base_name = os.path.basename(sys_bin_file) # does file exist? if not os.path.isfile(sys_bin_file): log_segload.debug("no file: %s", sys_bin_file) return None # try to load bin image in supported format (e.g. HUNK or ELF) bin_img = self.binfmt.load_image(sys_bin_file) if bin_img is None: log_segload.debug("load_image failed: %s", sys_bin_file) return None # create relocator relocator = Relocate(bin_img) # get info about segments to allocate sizes = relocator.get_sizes() names = bin_img.get_segment_names() bin_img_segs = bin_img.get_segments() # build label names if self.alloc.label_mgr: labels = [] for i in range(len(sizes)): name = "%s_%d:%s" % (base_name, i, names[i].lower()) labels.append(name) else: labels = None # allocate seg list seg_list = SegList.alloc(self.alloc, sizes, labels, bin_img_segs) # retrieve addr addrs = seg_list.get_all_addrs() # relocate to addresses and return data datas = relocator.relocate(addrs) # write contents to allocated memory for i in range(len(sizes)): # write data to segments self.mem.w_block(addrs[i], datas[i]) return SegLoadInfo(seg_list, bin_img, sys_bin_file)
def do_build_cmd(args): # get options rom_size = args.rom_size kick_addr = int(args.kick_addr, 16) ext_addr = int(args.ext_addr, 16) kickety_split = args.kickety_split rom_type = args.rom_type fill_byte = int(args.fill_byte, 16) rom_rev = args.rom_rev if rom_rev is not None: rom_rev = map(int, rom_rev.split(".")) add_footer = args.add_footer # select rom builder if rom_type == 'kick': logging.info("building %d KiB Kick ROM @%08x", rom_size, kick_addr) rb = KickRomBuilder(rom_size, base_addr=kick_addr, fill_byte=fill_byte, kickety_split=kickety_split, rom_ver=rom_rev) elif rom_type == 'ext': logging.info("building %d KiB Ext ROM @%08x Rev %r for Kick @%08x", rom_size, ext_addr, rom_rev, kick_addr) rb = ExtRomBuilder(rom_size, base_addr=ext_addr, fill_byte=fill_byte, add_footer=add_footer, rom_ver=rom_rev, kick_addr=kick_addr) else: logging.error("Unknown rom_type=%s", rom_type) return 1 # build file list if args.modules is None: logging.error("No modules given!") return 1 file_list = rb.build_file_list(args.modules) # load modules bf = BinFmt() for f in file_list: name = os.path.basename(f) # load image if bf.is_image(f): bin_img = bf.load_image(f) size = bin_img.get_size() data = None else: # load raw data bin_img = None with open(f, "rb") as fh: data = fh.read() size = len(data) # handle kickety split if kickety_split and rb.cross_kickety_split(size): off = rb.get_rom_offset() logging.info("@%08x: adding kickety split", off) rb.add_kickety_split() off = rb.get_rom_offset() # add image if bin_img is not None: logging.info("@%08x: adding module '%s'", off, f) e = rb.add_bin_img(name, bin_img) if e is None: logging.error("@%08x: can't add module '%s': %s", off, f, rb.get_error()) return 3 # add data else: logging.info("@%08x: adding raw data '%s'", off, f) e = rb.add_module(name, data) if e is None: logging.error("@%08x: can't add raw data '%s': %s", off, f, rb.get_error()) return 3 # build rom off = rb.get_rom_offset() logging.info("@%08x: padding %d bytes with %02x", off, rb.get_bytes_left(), fill_byte) rom_data = rb.build_rom() if rom_data is None: logging.error("building ROM failed: %s", rb.get_error()) return 4 # save rom output = args.output if output is not None: logging.info("saving ROM to '%s'", output) with open(output, "wb") as fh: fh.write(rom_data) return 0
offs += (34, 38, 42) # get relocs to myself (seg 0) relocs = seg.get_reloc(seg) if relocs is not None: raise ValueError("no relocations expected in BlizKick module") relocs = BinImage.Relocations(seg) seg.add_reloc(seg, relocs) # add relocs for o in offs: relocs.add_reloc(BinImage.Reloc(o)) # check if we can remove last data segment (contains only version info) if len(segs) == 2 and segs[1].get_type() == BinImage.SEGMENT_TYPE_DATA: data = segs[1].get_data() if data[:5] == "$VER:": self.bin_img.segments = [seg] # test if __name__ == "__main__": import sys from amitools.binfmt.BinFmt import BinFmt bfmt = BinFmt() for f in sys.argv[1:]: if bfmt.is_image(f): my_bin_img = bfmt.load_image(f) print(my_bin_img) bkm = BlizKickModule(my_bin_img) print((bkm.bk_type)) bkm.fix_module()
offs += ( 34, 38, 42 ) # get relocs to myself (seg 0) relocs = seg.get_reloc(seg) if relocs is not None: raise ValueError("no relocations expected in BlizKick module") relocs = BinImage.Relocations(seg) seg.add_reloc(seg, relocs) # add relocs for o in offs: relocs.add_reloc(BinImage.Reloc(o)) # check if we can remove last data segment (contains only version info) if len(segs) == 2 and segs[1].get_type() == BinImage.SEGMENT_TYPE_DATA: data = segs[1].get_data() if data[:5] == '$VER:': self.bin_img.segments = [seg] # test if __name__ == '__main__': import sys from amitools.binfmt.BinFmt import BinFmt bf = BinFmt() for f in sys.argv[1:]: if bf.is_image(f): bin_img = bf.load_image(f) print(bin_img) bkm = BlizKickModule(bin_img) print(bkm.bk_type) bkm.fix_module()
class SegmentLoader: def __init__(self, mem, alloc, label_mgr, path_mgr): self.mem = mem self.alloc = alloc self.label_mgr = label_mgr self.path_mgr = path_mgr self.error = None self.loaded_seg_lists = {} self.binfmt = BinFmt() def can_load_seg(self, lock, ami_bin_file): return self.path_mgr.ami_command_to_sys_path(lock, ami_bin_file) != None # load ami_bin_file def load_seg(self, lock, ami_bin_file, allow_reuse = True): # map file name sys_bin_file = self.path_mgr.ami_command_to_sys_path(lock, ami_bin_file) if sys_bin_file == None: self.error = "failed mapping binary path: '%s'" % ami_bin_file return None # check if seg list already loaded in a parent process # Bummer! This cannot work unless commands are resident! if allow_reuse and self.loaded_seg_lists.has_key(sys_bin_file): seg_list = self.loaded_seg_lists[sys_bin_file] seg_list.usage += 1 return seg_list # really load new seg list seg_list = self._load_seg(ami_bin_file,sys_bin_file) if seg_list == None: return None # store in cache if allowed by caller if allow_reuse: self.loaded_seg_lists[sys_bin_file] = seg_list return seg_list # unload seg list def unload_seg(self, seg_list, allow_reuse = True): sys_bin_file = seg_list.sys_bin_file # check that file is in cache if not allow_reuse or sys_bin_file in self.loaded_seg_lists: seg_list.usage -= 1 # no more used if seg_list.usage == 0: if sys_bin_file in self.loaded_seg_lists: del self.loaded_seg_lists[sys_bin_file] self._unload_seg(seg_list) return True else: self.error = "seglist not found in loaded seglists!" return False # load sys_bin_file def _load_seg(self, ami_bin_file, sys_bin_file): base_name = os.path.basename(sys_bin_file) # does file exist? if not os.path.isfile(sys_bin_file): self.error = "Can't find '%s'" % sys_bin_file return None # try to load bin image in supported format (e.g. HUNK or ELF) try: bin_img = self.binfmt.load_image(sys_bin_file) if bin_img is None: self.error = "Error loading '%s': unsupported format" % sys_bin_file return None except Exception as e: self.error = "Error loading '%s': %s" % (sys_bin_file, e) return None # create relocator relocator = Relocate(bin_img) # allocate segment memory sizes = relocator.get_sizes() names = bin_img.get_segment_names() bin_img_segs = bin_img.get_segments() seg_list = SegList(ami_bin_file, sys_bin_file, bin_img) addrs = [] for i in xrange(len(sizes)): size = sizes[i] seg_size = size + 8 # add segment pointer and size of segment seg_addr = self.alloc.alloc_mem(seg_size) # create label label = None name = "%s_%d:%s" % (base_name,i,names[i].lower()) bin_img_seg = bin_img_segs[i] if self.alloc.label_mgr != None: label = LabelSegment(name, seg_addr, seg_size, bin_img_seg) self.alloc.label_mgr.add_label(label) seg = Segment(name, seg_addr, seg_size, label, bin_img_seg) seg_list.add(seg) addrs.append(seg.addr + 8) # begin of segment data/code # relocate to addresses and return data datas = relocator.relocate(addrs) # write to allocated memory last_addr = None for i in xrange(len(sizes)): # write data to segments addr = addrs[i] self.mem.access.w_data(addr, datas[i]) # link segment pointers if last_addr != None: b_addr = (addr-4) >> 2 # BCPL segment 'next' pointer self.mem.access.w32(last_addr - 4, b_addr) # write size before segment pointer total_size = (sizes[i] + 8) self.mem.access.w32(addr - 8, total_size) last_addr = addr # clear final 'next' pointer self.mem.access.w32(addr - 4, 0) return seg_list def _unload_seg(self, seg_list): for seg in seg_list.segments: # free memory of segment self.alloc.free_mem(seg.addr, seg.size) # remove label of segment if self.alloc.label_mgr != None: self.alloc.label_mgr.remove_label(seg.label)
def do_build_cmd(args): # get options rom_size = args.rom_size kick_addr = int(args.kick_addr, 16) ext_addr = int(args.ext_addr, 16) kickety_split = args.kickety_split rom_type = args.rom_type fill_byte = int(args.fill_byte, 16) rom_rev = args.rom_rev if rom_rev is not None: rom_rev = list(map(int, rom_rev.split("."))) add_footer = args.add_footer # select rom builder if rom_type == "kick": logging.info("building %d KiB Kick ROM @%08x", rom_size, kick_addr) rb = rom.KickRomBuilder( rom_size, base_addr=kick_addr, fill_byte=fill_byte, kickety_split=kickety_split, rom_ver=rom_rev, ) elif rom_type == "ext": logging.info( "building %d KiB Ext ROM @%08x Rev %r for Kick @%08x", rom_size, ext_addr, rom_rev, kick_addr, ) rb = rom.ExtRomBuilder( rom_size, base_addr=ext_addr, fill_byte=fill_byte, add_footer=add_footer, rom_ver=rom_rev, kick_addr=kick_addr, ) else: logging.error("Unknown rom_type=%s", rom_type) return 1 # build file list if args.modules is None: logging.error("No modules given!") return 1 file_list = rb.build_file_list(args.modules) # load modules bf = BinFmt() for f in file_list: logging.info("adding file '%s'", f) name = os.path.basename(f) # load image if bf.is_image(f): bin_img = bf.load_image(f) # is it a blizkick module? bkm = rom.BlizKickModule(bin_img) if bkm.get_type() == "module": bkm.fix_module() elif bkm.get_type() == "patch": logging.error("BlizKick Patches are not supported, yet: %s", name) return 5 # get image params size = bin_img.get_size() data = None else: # load raw data bin_img = None with open(f, "rb") as fh: data = fh.read() size = len(data) # calc long word padding padding = 0 if size & 3 != 0: padding = 4 - size & 3 # handle kickety split if kickety_split and rb.cross_kickety_split(size + padding): off = rb.get_rom_offset() logging.info("@%08x: adding kickety split", off) rb.add_kickety_split() off = rb.get_rom_offset() # add image if bin_img is not None: logging.info("@%08x: adding module '%s'", off, f) e = rb.add_bin_img(name, bin_img) if e is None: logging.error("@%08x: can't add module '%s': %s", off, f, rb.get_error()) return 3 # add data else: logging.info("@%08x: adding raw data '%s'", off, f) e = rb.add_module(name, data) if e is None: logging.error("@%08x: can't add raw data '%s': %s", off, f, rb.get_error()) return 3 # add long word padding? if padding != 0: off = rb.get_rom_offset() logging.info("@%08x: adding padding: +%d" % (off, padding)) e = rb.add_padding(padding) if e is None: logging.error("@%08x: can't add padding: %s", off, rb.get_error()) return 3 # build rom off = rb.get_rom_offset() logging.info("@%08x: padding %d bytes with %02x", off, rb.get_bytes_left(), fill_byte) rom_data = rb.build_rom() if rom_data is None: logging.error("building ROM failed: %s", rb.get_error()) return 4 # save rom output = args.output if output is not None: logging.info("saving ROM to '%s'", output) with open(output, "wb") as fh: fh.write(rom_data) return 0
class SegmentLoader(object): def __init__(self, alloc, path_mgr=None): self.alloc = alloc self.path_mgr = path_mgr self.mem = alloc.get_mem() self.binfmt = BinFmt() # map seglist baddr to bin_img self.infos = {} def load_sys_seglist(self, sys_bin_file): """load seglist, register it, and return seglist baddr or 0""" info = self.int_load_sys_seglist(sys_bin_file) if info: baddr = info.seglist.get_baddr() self.infos[baddr] = info log_segload.info("loaded sys seglist: %s", info) return baddr else: log_segload.info("can't load sys seglist: %s", sys_bin_file) return 0 def load_ami_seglist(self, ami_bin_file, lock=None): """load seglist, register it, and return seglist baddr or 0""" info = self.int_load_ami_seglist(ami_bin_file, lock) if info: baddr = info.seglist.get_baddr() self.infos[baddr] = info log_segload.info("loaded ami seglist: %s", info) return baddr else: log_segload.info("can't load ami seglist: %s", ami_bin_file) return 0 def unload_seglist(self, seglist_baddr): """unregister given seglist baddr and free seglist. return True if seglist was unloaded""" if seglist_baddr not in self.infos: log_segload.error("unknown seglist at @%06x", seglist_baddr) return False info = self.infos[seglist_baddr] log_segload.info("unload seglist: %s", info) del self.infos[seglist_baddr] info.seglist.free() return True def get_info(self, seglist_baddr): """return associated bin_img for given registered seglist baddr or None""" if seglist_baddr in self.infos: return self.infos[seglist_baddr] def register_seglist(self, baddr): """register custom seglist""" info = SegLoadInfo(SegList(self.alloc, baddr)) log_segload.info("register seglist: %s", info) self.infos[baddr] = info def unregister_seglist(self, baddr): """remove custom seglist""" info = self.infos[baddr] log_segload.info("unregister seglist: %s", info) del self.infos[baddr] def shutdown(self): """check orphan seglists on shutdown and return number of orphans""" log_segload.info("shutdown") for baddr in self.infos: info = self.infos[baddr] log_segload.warn("orphaned seglist: %s", info) # try to free list info.seglist.free() return len(self.infos) def int_load_ami_seglist(self, ami_bin_file, lock=None): """load seglist given by ami binary path and return SegLoadInfo""" if self.path_mgr is None: return None # try to map path sys_path = self.path_mgr.ami_to_sys_path( lock, ami_bin_file, mustExist=True) if sys_path: info = self.int_load_sys_seglist(sys_path) info.ami_file = ami_bin_file return info def int_load_sys_seglist(self, sys_bin_file): """load seglist given by sys binary path and return SegLoadInfo""" base_name = os.path.basename(sys_bin_file) # does file exist? if not os.path.isfile(sys_bin_file): return None # try to load bin image in supported format (e.g. HUNK or ELF) bin_img = self.binfmt.load_image(sys_bin_file) if bin_img is None: return None # create relocator relocator = Relocate(bin_img) # get info about segments to allocate sizes = relocator.get_sizes() names = bin_img.get_segment_names() bin_img_segs = bin_img.get_segments() # build label names if self.alloc.label_mgr: labels = [] for i in xrange(len(sizes)): name = "%s_%d:%s" % (base_name, i, names[i].lower()) labels.append(name) else: labels = None # allocate seg list seg_list = SegList.alloc(self.alloc, sizes, labels, bin_img_segs) # retrieve addr addrs = seg_list.get_all_addrs() # relocate to addresses and return data datas = relocator.relocate(addrs) # write contents to allocated memory for i in xrange(len(sizes)): # write data to segments self.mem.w_block(addrs[i], datas[i]) return SegLoadInfo(seg_list, bin_img, sys_bin_file)
if auto_init: offs += (34, 38, 42) # get relocs to myself (seg 0) relocs = seg.get_reloc(seg) if relocs is not None: raise ValueError("no relocations expected in BlizKick module") relocs = BinImage.Relocations(seg) seg.add_reloc(seg, relocs) # add relocs for o in offs: relocs.add_reloc(BinImage.Reloc(o)) # check if we can remove last data segment (contains only version info) if len(segs) == 2 and segs[1].get_type() == BinImage.SEGMENT_TYPE_DATA: data = segs[1].get_data() if data[:5] == '$VER:': self.bin_img.segments = [seg] # test if __name__ == '__main__': import sys from amitools.binfmt.BinFmt import BinFmt bf = BinFmt() for f in sys.argv[1:]: if bf.is_image(f): bin_img = bf.load_image(f) print(bin_img) bkm = BlizKickModule(bin_img) print(bkm.bk_type) bkm.fix_module()
def __init__(self, mem, alloc): self.mem = mem self.alloc = alloc self.error = None self.loaded_seg_lists = {} self.binfmt = BinFmt()