Example #1
0
 def __init__(self, abi, source=None):
     from peachpy.formats.mscoff.section import StringTable
     self.abi = abi
     self.sections = []
     self.symbols = []
     self.string_table = StringTable()
Example #2
0
class Image:
    def __init__(self, abi, source=None):
        from peachpy.formats.mscoff.section import StringTable
        self.abi = abi
        self.sections = []
        self.symbols = []
        self.string_table = StringTable()

    def add_section(self, section, name):
        from peachpy.formats.mscoff.section import Section
        assert isinstance(section, Section)

        section.index = len(self.sections)
        self.sections.append(section)

        import codecs
        name_bytestring = codecs.encode(name, "utf8")
        if len(name_bytestring) > 8:
            section.header.name = self.string_table.add(name_bytestring)
        else:
            section.header.name = name

        return section.index

    def add_symbol(self, symbol, name):
        from peachpy.formats.mscoff.symbol import SymbolEntry
        assert isinstance(symbol, SymbolEntry)

        import codecs
        name_bytestring = codecs.encode(name, "utf8")
        if len(name_bytestring) > 8:
            symbol.name = self.string_table.add(name_bytestring)
        else:
            symbol.name = name
        self.symbols.append(symbol)

    @property
    def as_bytearray(self):
        from peachpy.formats.mscoff.file import FileHeader
        from peachpy.formats.mscoff.section import SectionHeader
        import operator

        file_header = FileHeader(self.abi)
        file_header.section_count = len(self.sections)
        file_header.symbol_count = len(self.symbols)
        file_header.symbol_table_offset = FileHeader.size + len(self.sections) * SectionHeader.size

        # Update section offsets
        data_offset = FileHeader.size + len(self.sections) * SectionHeader.size
        file_header.symbol_table_offset = data_offset

        data = file_header.as_bytearray

        # Update section offsets
        data_offset = file_header.symbol_table_offset + \
            sum(map(operator.attrgetter("size"), self.symbols)) + \
            self.string_table.size
        for section in self.sections:
            if section.header.alignment != 0:
                if data_offset % section.header.alignment != 0:
                    padding_length = section.header.alignment - data_offset % section.header.alignment
                    data_offset += padding_length
            section.header.content_offset = data_offset
            data_offset += section.header.content_size

        # Write section headers
        for section in self.sections:
            data += section.header.as_bytearray

        # Write symbol table and string table (immediately follows symbols table)
        for symbol in self.symbols:
            data += symbol.as_bytearray
        data += self.string_table.as_bytearray

        # Write section content
        for section in self.sections:
            if section.header.alignment != 0:
                if len(data) % section.header.alignment != 0:
                    padding_length = section.header.alignment - len(data) % section.header.alignment
                    padding_data = bytearray([0] * padding_length)
                    data += padding_data
            data += section.content

        return data
Example #3
0
 def __init__(self, abi, source=None):
     from peachpy.formats.mscoff.section import StringTable
     self.abi = abi
     self.sections = list()
     self.symbols = list()
     self.string_table = StringTable()
Example #4
0
class Image:
    file_header_size = 20

    def __init__(self, abi, source=None):
        from peachpy.formats.mscoff.section import StringTable
        self.abi = abi
        self.sections = list()
        self.symbols = list()
        self.string_table = StringTable()

    def add_section(self, section):
        from peachpy.formats.mscoff.section import Section
        assert isinstance(section, Section)

        self.sections.append(section)

    def add_symbol(self, symbol):
        from peachpy.formats.mscoff.symbol import Symbol
        assert isinstance(symbol, Symbol)

        self.symbols.append(symbol)

    def encode(self):
        from peachpy.encoder import Encoder
        encoder = Encoder(self.abi.endianness)

        # Collect names that need to be encoded in the string table
        import codecs
        for section in self.sections:
            if len(codecs.encode(section.name, "utf8")) > 8:
                self.string_table.add(section.name)
        for symbol in self.symbols:
            if len(codecs.encode(symbol.name, "utf8")) > 8:
                self.string_table.add(symbol.name)

        # Layout sections offsets
        from peachpy.formats.mscoff.section import Section

        section_offset_map = dict()
        symbol_table_offset = Image.file_header_size + len(
            self.sections) * Section.header_size
        data_offset = symbol_table_offset + self.string_table.size
        for symbol in self.symbols:
            data_offset += symbol.entry_size
        for section in self.sections:
            section_offset_map[section] = data_offset
            data_offset += section.content_size

        # Layout section relocations
        from peachpy.formats.mscoff.symbol import Relocation

        section_relocations_map = dict()
        for section in self.sections:
            if section.relocations:
                section_relocations_map[section] = data_offset
                data_offset += Relocation.entry_size * len(section.relocations)

        section_index_map = {
            section: index + 1
            for index, section in enumerate(self.sections)
        }
        symbol_index_map = {
            symbol: index
            for index, symbol in enumerate(self.symbols)
        }

        # Write file header
        timestamp = 0
        file_flags = 0
        data = encoder.uint16(self.abi.mscoff_machine_type) + \
            encoder.uint16(len(self.sections)) + \
            encoder.uint32(timestamp) + \
            encoder.uint32(symbol_table_offset) + \
            encoder.uint32(len(self.symbols)) + \
            encoder.uint16(0) + \
            encoder.uint16(file_flags)

        # Write section headers
        for section in self.sections:
            data += section.encode_header(encoder, self.string_table._strings,
                                          section_offset_map[section],
                                          section_relocations_map.get(section))

        # Write symbol table and string table (immediately follows symbols table)
        for symbol in self.symbols:
            data += symbol.encode_entry(encoder, self.string_table._strings,
                                        section_index_map)
        data += self.string_table.encode()

        # Write section content
        for section in self.sections:
            data += section.content

        # Write section relocations
        for section in self.sections:
            for relocation in section.relocations:
                data += relocation.encode_entry(encoder, symbol_index_map)

        return data
Example #5
0
class Image:
    file_header_size = 20

    def __init__(self, abi, source=None):
        from peachpy.formats.mscoff.section import StringTable
        self.abi = abi
        self.sections = list()
        self.symbols = list()
        self.string_table = StringTable()

    def add_section(self, section):
        from peachpy.formats.mscoff.section import Section
        assert isinstance(section, Section)

        self.sections.append(section)

    def add_symbol(self, symbol):
        from peachpy.formats.mscoff.symbol import Symbol
        assert isinstance(symbol, Symbol)

        self.symbols.append(symbol)

    def encode(self):
        from peachpy.encoder import Encoder
        encoder = Encoder(self.abi.endianness)

        # Collect names that need to be encoded in the string table
        import codecs
        for section in self.sections:
            if len(codecs.encode(section.name, "utf8")) > 8:
                self.string_table.add(section.name)
        for symbol in self.symbols:
            if len(codecs.encode(symbol.name, "utf8")) > 8:
                self.string_table.add(symbol.name)

        # Layout sections offsets
        from peachpy.formats.mscoff.section import Section

        section_offset_map = dict()
        symbol_table_offset = Image.file_header_size + len(self.sections) * Section.header_size
        data_offset = symbol_table_offset + self.string_table.size
        for symbol in self.symbols:
            data_offset += symbol.entry_size
        for section in self.sections:
            section_offset_map[section] = data_offset
            data_offset += section.content_size

        # Layout section relocations
        from peachpy.formats.mscoff.symbol import Relocation

        section_relocations_map = dict()
        for section in self.sections:
            if section.relocations:
                section_relocations_map[section] = data_offset
                data_offset += Relocation.entry_size * len(section.relocations)

        section_index_map = {section: index + 1 for index, section in enumerate(self.sections)}
        symbol_index_map = {symbol: index for index, symbol in enumerate(self.symbols)}

        # Write file header
        timestamp = 0
        file_flags = 0
        data = encoder.uint16(self.abi.mscoff_machine_type) + \
            encoder.uint16(len(self.sections)) + \
            encoder.uint32(timestamp) + \
            encoder.uint32(symbol_table_offset) + \
            encoder.uint32(len(self.symbols)) + \
            encoder.uint16(0) + \
            encoder.uint16(file_flags)

        # Write section headers
        for section in self.sections:
            data += section.encode_header(encoder, self.string_table._strings,
                                          section_offset_map[section],
                                          section_relocations_map.get(section))

        # Write symbol table and string table (immediately follows symbols table)
        for symbol in self.symbols:
            data += symbol.encode_entry(encoder, self.string_table._strings, section_index_map)
        data += self.string_table.encode()

        # Write section content
        for section in self.sections:
            data += section.content

        # Write section relocations
        for section in self.sections:
            for relocation in section.relocations:
                data += relocation.encode_entry(encoder, symbol_index_map)

        return data
Example #6
0
class Image:
    def __init__(self, abi, source=None):
        from peachpy.formats.mscoff.section import StringTable
        self.abi = abi
        self.sections = []
        self.symbols = []
        self.string_table = StringTable()

    def add_section(self, section, name):
        from peachpy.formats.mscoff.section import Section
        assert isinstance(section, Section)

        section.index = len(self.sections)
        self.sections.append(section)

        import codecs
        name_bytestring = codecs.encode(name, "utf8")
        if len(name_bytestring) > 8:
            section.header.name = self.string_table.add(name_bytestring)
        else:
            section.header.name = name

        return section.index

    def add_symbol(self, symbol, name):
        from peachpy.formats.mscoff.symbol import SymbolEntry
        assert isinstance(symbol, SymbolEntry)

        import codecs
        name_bytestring = codecs.encode(name, "utf8")
        if len(name_bytestring) > 8:
            symbol.name = self.string_table.add(name_bytestring)
        else:
            symbol.name = name
        self.symbols.append(symbol)

    @property
    def as_bytearray(self):
        from peachpy.formats.mscoff.file import FileHeader
        from peachpy.formats.mscoff.section import SectionHeader
        import operator

        file_header = FileHeader(self.abi)
        file_header.section_count = len(self.sections)
        file_header.symbol_count = len(self.symbols)
        file_header.symbol_table_offset = FileHeader.size + len(
            self.sections) * SectionHeader.size

        # Update section offsets
        data_offset = FileHeader.size + len(self.sections) * SectionHeader.size
        file_header.symbol_table_offset = data_offset

        data = file_header.as_bytearray

        # Update section offsets
        data_offset = file_header.symbol_table_offset + \
            sum(map(operator.attrgetter("size"), self.symbols)) + \
            self.string_table.size
        for section in self.sections:
            if section.header.alignment != 0:
                if data_offset % section.header.alignment != 0:
                    padding_length = section.header.alignment - data_offset % section.header.alignment
                    data_offset += padding_length
            section.header.content_offset = data_offset
            data_offset += section.header.content_size

        # Write section headers
        for section in self.sections:
            data += section.header.as_bytearray

        # Write symbol table and string table (immediately follows symbols table)
        for symbol in self.symbols:
            data += symbol.as_bytearray
        data += self.string_table.as_bytearray

        # Write section content
        for section in self.sections:
            if section.header.alignment != 0:
                if len(data) % section.header.alignment != 0:
                    padding_length = section.header.alignment - len(
                        data) % section.header.alignment
                    padding_data = bytearray([0] * padding_length)
                    data += padding_data
            data += section.content

        return data