def _set(self, val, off, size, lazy, le): # TODO: le ignored here base = off // 8 off %= 8 val = bytearray(val) if len(val) == 0: return if lazy == False or not self.lazy: nx = (off + size + 7) // 8 if le: val = val[:nx] else: val = val[len(val) - nx:] val = Format(val).shiftl(off).v mask0 = BitOps.mask(off) maskn1 = BitOps.imask( BitOps.mod1(off + size, 8), modpw=8) # we dont want imask(0) (imask(8) needed) b0 = self.buf.read(base) mask_b0 = mask0 if nx == 1: b0 |= maskn1 else: if maskn1 != 0: val[-1] |= self.buf.read(base + nx - 1) & maskn1 if mask_b0 != 0: val[0] |= b0 & mask_b0 self.buf.write(base, val) else: assert False
def add(self, pos, data): for i, v in enumerate(data): atom = (pos + i) // self.atom_bitsize in_atom = (pos + i) % self.atom_bitsize self.lrufifo.touch(atom) self.atom_data[atom][0] &= BitOps.ibit(in_atom) self.atom_data[atom][1] = (self.atom_data[atom][1] & BitOps.ibit(in_atom)) | v << in_atom
def decode_data(x): tmp = struct.unpack('>I', x)[0] sgn = tmp >> 31 val = (tmp >> 18) & BitOps.mask(13) if sgn == 1: val = (1 << 13) - val fault = tmp >> 16 & 1 val = val * BitOps.bit2sign(sgn) ref_junc = tmp >> 4 & BitOps.mask(11) if tmp >> 15 & 1: ref_junc = (1 << 11) - ref_junc; ref_junc /= 2**4 return val / 4, ref_junc
def __init__(self, typ, off=0, backend=None, parent=None, fieldname='', default_backend=True, force_array_size=None, child_backend=None, byteoff=None): super().__init__(handler=self.item_handler, repr_blacklist_keys=['parent']) self._typ = typ self._base_typ = typ.get_base_typ() self._children = OrderedDict() if byteoff is not None: off = byteoff * 8 self._off = off # in bits self.parent = parent self._fieldname = fieldname self._bytesize = None self._fields = OrderedDict() self._force_array_size = force_array_size if backend is None and default_backend: backend = StructBackend(BufAccessor(self.byte_size)) self._backend = backend if child_backend is None: child_backend = backend self._child_backend = child_backend if self._base_typ != self._typ: self._base_size = self._base_typ.size self._base_align = self._base_typ.align if self.is_array: pos = 0 self.stride = BitOps.align(self._base_size, self._base_align * 8) assert self.stride != 0 #for i in range(typ.array_size): # self.add_child(self._base_typ, pos) # pos += self._base_size # pos = BitOps.align(pos, self._base_align) else: self._pointee = None else: if typ.is_primitive(): pass elif typ.is_union: self._selected = 0 for field in typ.ordered_fields: self.add_field(field) else: pos = 0 for field in typ.ordered_fields: self.add_field(field) #self._mem = Memory(reader=self.get_buf, writer=self.set_buf, minv=0, maxv=self.bytesize) self._init_accessors()
def build(self): for i, section in enumerate(self.sections): section.new_id = i for i, prog in enumerate(self.progs): prog.new_id = i res = io.BytesIO(bytearray()) self.elf.header.e_shnum = len(self.sections) align_v = 1 ehdr = self.elf.header ehdr.e_shnum = len(self.sections) ehdr.e_phnum = len(self.progs) ehdr.e_shstrndx = self.shstrtab_section.new_id ehdr_size = self.elf.structs.Elf_Ehdr.sizeof() shdr_size = ehdr.e_shentsize * ehdr.e_shnum phdr_size = ehdr.e_phentsize * ehdr.e_phnum self.write_phdr(ehdr, res) pos = BitOps.align(ehdr.e_phoff + phdr_size, align_v) self.prepare_sections(pos) pos = BitOps.align(pos, align_v) pos = self.write_sections_content(res) pos = BitOps.align(pos, align_v) ehdr.e_shoff = pos #for prog in self.progs: # if prog.raw.header.p_type != 'PT_PHDR': continue # prog.raw.header.p_offset = ehdr.e_phoff # prog.raw.header.p_filesz = phdr_size # prog.raw.header.p_memsz = phdr_size self.write_sections(ehdr, res) res.seek(0) res.write(self.elf.structs.Elf_Ehdr.build(ehdr)) print(ehdr_size, shdr_size, phdr_size, ehdr.e_shentsize) return res.getvalue()
def resize_bits(self, n): assert isinstance(self.v, bytearray) nx = len(self.v) * 8 - n if nx // 8 != 0: del self.v[-(nx // 8):] if nx > 0: nx &= 7 self.v[-1] &= BitOps.mask(8 - (nx & 7)) return self
def set_section_at(self, section, pos): if section.done: return pos section.done = True shdr = section.raw.header pos = BitOps.align(pos, shdr.sh_addralign) shdr.sh_size = len(section.data) shdr.sh_offset = pos section.new_offset = pos pos += len(section.data) return pos
def __init__(self, atom_bitsize, reader=None, writer=None): self.atom_bitsize = atom_bitsize self.reader = reader self.writer = writer self.atom_data = defaultdict(lambda: [BitOps.mask(atom_bitsize), 0]) self.lrufifo = LRUFifo()
def unwhiten(self, whitened_data): res = BitOps.xorlist(whitened_data, self.get_white_seq(len(whitened_data))) return Format.ToBytes(res)