Esempio n. 1
0
    def _manage_address(self, absolute, zero_page, arg):

        address = self.parse_integer(arg)

        # numeric address ?
        if address is not None:
            # valid zero_page ?
            if zero_page is not None and is_zero_page(address):
                return pack_byte(zero_page, address)
            if absolute is None:
                raise AbsoluteAddressNotAllowed()
            return pack('<BH', absolute, address)

        # label management

        # check for already defined label (zero page optimization)
        address = self.get_label_absolute_address_by_name(arg)
        if address is None:
            if absolute is None:
                raise AbsoluteAddressNotAllowed()
            self.add_label_translation(label=arg, size=2)
            return pack('<BH', absolute, 0)

        if zero_page is not None and is_zero_page(address):
            return pack_byte(zero_page, address)

        # normal labeling (postpone to linking phase)
        if absolute is None:
            raise AbsoluteAddressNotAllowed()
        self.add_label_translation(label=arg, size=2)
        return pack('<BH', absolute, 0)
Esempio n. 2
0
 def _call(self, instr):
     arg = instr.tokens[1]
     value = self.parse_integer_or_label(arg,
                                         size=2,
                                         relative=True,
                                         start=self.current_org +
                                         self.org_counter + 3)
     return pack('<Bh', 0xE8, value)
Esempio n. 3
0
 def _manage_branching(self, instr, code):
     arg = instr.tokens[1]
     address = self.parse_integer_or_label(arg,
                                           size=1,
                                           relative=True,
                                           start=self.current_org +
                                           self.org_counter + 2)
     return pack('<Bb', code, address)
Esempio n. 4
0
 def __init__(self, bits, big_endian, e_type, machine, alignment=0):
     self.header = b'\x7fELF' + \
         pack('BBBB', 2 if bits == 64 else 1, 2 if big_endian else 1, 1, 0)
     self.bits = bits
     self.endianess_prefix = '>' if big_endian else '<'
     self.header += bytes(8)
     self.header += pack(self.endianess_prefix + 'HHI', e_type, machine, 1)
     self.entry_point = 0
     if self.bits == 32:
         self.section_pack_format = self.endianess_prefix + 'IIIIIIIIII'
         self.section_header_size = 40
         self.header_size = 52
     elif self.bits == 64:
         self.section_pack_format = self.endianess_prefix + 'IIQQQQIIQQ'
         self.section_header_size = 64
         self.header_size = 64
     self.alignment = alignment
     self.relocations = {}
Esempio n. 5
0
    def _build_section(self, section_data):
        sh_type = 0x01
        if section_data['size'] == 0:
            sh_type = 0x08
        sh_flags = 0
        if 'R' in section_data['permissions']:
            sh_flags |= 0x02
        if 'W' in section_data['permissions']:
            sh_flags |= 0x01
        if 'X' in section_data['permissions']:
            sh_flags |= 0x04
        if 'E' in section_data['permissions']:
            sh_flags |= 0x04

        return pack(self.section_pack_format,
                    section_data['elf_string_offset'], sh_type, sh_flags,
                    section_data['start'],
                    self.file_base + section_data['offset'],
                    section_data['size'], 0, 0, self.alignment, 0)
Esempio n. 6
0
 def _mem(self, arg):
     value = self.parse_integer_or_label(arg, size=2)
     return pack('<H', value)
Esempio n. 7
0
 def _imm16(self, op, reg, arg):
     value = self.parse_integer_or_label(arg, size=2)
     return pack('<BH', op + self.regs16.index(reg.upper()), value)
Esempio n. 8
0
    def link(self, assembler):

        # first prepare the .shstrtab section
        sh_string_table = b'\x00'
        for section_name, section_data in assembler.sections.items():
            section_data['elf_string_offset'] = len(sh_string_table)
            sh_string_table += section_name.encode() + b'\0'

        sh_string_table_name_offset = len(sh_string_table)

        sh_string_table += '.shstrtab'.encode() + b'\0'

        # then build the symbols names table
        string_table = b'\x00'
        for symbol_name, symbol_data in assembler.labels.items():
            if symbol_name not in assembler.exports:
                continue
            symbol_data['elf_string_offset'] = len(string_table)
            string_table += symbol_name.encode() + b'\0'

        string_table_name_offset = len(sh_string_table)
        sh_string_table += '.strtab'.encode() + b'\0'

        symtab_name_offset = len(sh_string_table)
        sh_string_table += '.symtab'.encode() + b'\0'

        self.file_base = self.header_size + \
            self.section_header_size * (len(assembler.sections) + 4)

        sections = b''
        sections += self._build_null_section()
        for section_index, section_data in enumerate(
                assembler.sections.values()):
            section_data['elf_section_index'] = section_index
            sections += self._build_section(section_data)

        symtab = b''
        for symbol_name, symbol_data in assembler.labels.items():
            if symbol_name not in assembler.exports:
                continue
            if self.bits == 32:
                symtab += pack(
                    self.endianess_prefix + 'IIIBBH',
                    symbol_data['elf_string_offset'], symbol_data['base'], 0,
                    0x10, 0, assembler.sections[
                        symbol_data['section']]['elf_section_index'] + 1)
            if self.bits == 64:
                symtab += pack(
                    self.endianess_prefix + 'IBBHQQ',
                    symbol_data['elf_string_offset'], 0x10, 0,
                    assembler.sections[symbol_data['section']]
                    ['elf_section_index'] + 1, symbol_data['base'], 0)

        code_size = len(assembler.assembled_bytes)

        sections += self._build_string_section(sh_string_table_name_offset,
                                               self.file_base + code_size,
                                               sh_string_table)

        sections += self._build_string_section(
            string_table_name_offset,
            self.file_base + code_size + len(sh_string_table), string_table)

        sections += self._build_symtab_section(
            symtab_name_offset, self.file_base + code_size +
            len(sh_string_table) + len(string_table), symtab,
            len(assembler.sections) + 2)

        if self.bits == 32:
            self.header += pack(self.endianess_prefix + 'IIIIHHHHHH',
                                self.entry_point, 0, self.header_size, 0,
                                self.header_size, 0, 0,
                                self.section_header_size,
                                len(assembler.sections) + 4,
                                len(assembler.sections) + 1)
        elif self.bits == 64:
            self.header += pack(self.endianess_prefix + 'QQQIHHHHHH',
                                self.entry_point, 0, self.header_size, 0,
                                self.header_size, 0, 0,
                                self.section_header_size,
                                len(assembler.sections) + 4,
                                len(assembler.sections) + 1)

        return self.header + sections + assembler.assembled_bytes + sh_string_table + string_table + symtab
Esempio n. 9
0
 def _build_symtab_section(self, name_offset, offset, data, link):
     return pack(self.section_pack_format, name_offset, 0x02, 0, 0, offset,
                 len(data), link, 0, 0, 16 if self.bits == 32 else 24)
Esempio n. 10
0
 def _build_string_section(self, name_offset, offset, data):
     return pack(self.section_pack_format, name_offset, 0x03, 0x20, 0,
                 offset, len(data), 0, 0, 0, 0)
Esempio n. 11
0
 def _build_null_section(self):
     return pack(self.section_pack_format, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)