def Pack(self, offset): """Figure out how to pack the entry into the section Most of the time the entries are not fully specified. There may be an alignment but no size. In that case we take the size from the contents of the entry. If an entry has no hard-coded offset, it will be placed at @offset. Once this function is complete, both the offset and size of the entry will be know. Args: Current section offset pointer Returns: New section offset pointer (after this entry) """ self.Detail( 'Packing: offset=%s, size=%s, content_size=%x' % (to_hex(self.offset), to_hex(self.size), self.contents_size)) if self.offset is None: if self.offset_unset: self.Raise('No offset set with offset-unset: should another ' 'entry provide this correct offset?') self.offset = tools.align(offset, self.align) needed = self.pad_before + self.contents_size + self.pad_after needed = tools.align(needed, self.align_size) size = self.size if not size: size = needed new_offset = self.offset + size aligned_offset = tools.align(new_offset, self.align_end) if aligned_offset != new_offset: size = aligned_offset - self.offset new_offset = aligned_offset if not self.size: self.size = size if self.size < needed: self.Raise("Entry contents size is %#x (%d) but entry size is " "%#x (%d)" % (needed, needed, self.size, self.size)) # Check that the alignment is correct. It could be wrong if the # and offset or size values were provided (i.e. not calculated), but # conflict with the provided alignment values if self.size != tools.align(self.size, self.align_size): self.Raise( "Size %#x (%d) does not match align-size %#x (%d)" % (self.size, self.size, self.align_size, self.align_size)) if self.offset != tools.align(self.offset, self.align): self.Raise("Offset %#x (%d) does not match align %#x (%d)" % (self.offset, self.offset, self.align, self.align)) self.Detail( ' - packed: offset=%#x, size=%#x, content_size=%#x, next_offset=%x' % (self.offset, self.size, self.contents_size, new_offset)) return new_offset
def get_data(self): """Obtain the full contents of the FIP Thhis builds the FIP with headers and all required FIP entries. Returns: bytes: data resulting from building the FIP """ buf = io.BytesIO() hdr = struct.pack(HEADER_FORMAT, HEADER_MAGIC, HEADER_SERIAL, self._flags) buf.write(hdr) # Calculate the position fo the first entry offset = len(hdr) offset += len(self._fip_entries) * ENTRY_SIZE offset += ENTRY_SIZE # terminating entry for fent in self._fip_entries: offset = tools.align(offset, self._align) fent.offset = offset offset += fent.size # Write out the TOC for fent in self._fip_entries: hdr = struct.pack(ENTRY_FORMAT, fent.uuid, fent.offset, fent.size, fent.flags) buf.write(hdr) # Write out the entries for fent in self._fip_entries: buf.seek(fent.offset) buf.write(fent.data) return buf.getvalue()
def CheckSize(self): contents_size = len(self.data) size = self.size if not size: data = self.GetPaddedData(self.data) size = len(data) size = tools.align(size, self.align_size) if self.size and contents_size > self.size: self._Raise( "contents size %#x (%d) exceeds section size %#x (%d)" % (contents_size, contents_size, self.size, self.size)) if not self.size: self.size = size if self.size != tools.align(self.size, self.align_size): self._Raise( "Size %#x (%d) does not match align-size %#x (%d)" % (self.size, self.size, self.align_size, self.align_size)) return size