Esempio n. 1
0
def test_equality():

    # The sparse memory image we will be testing

    mem_image = SparseMemoryImage()

    # Create first bytearray with some data

    data_ints_a = [random.randint(0, 1000) for r in xrange(10)]
    data_bytes_a = bytearray()
    for data_int in data_ints_a:
        data_bytes_a.extend(struct.pack("<I", data_int))

    # Create a second section section and add it to the sparse memory image

    section_a = SparseMemoryImage.Section(".text", 0x1000, data_bytes_a)
    mem_image.add_section(section_a)

    # Create a second bytearray with some data

    data_ints_b = [random.randint(0, 1000) for r in xrange(10)]
    data_bytes_b = bytearray()
    for data_ints in data_ints_b:
        data_bytes_b.extend(struct.pack("<I", data_int))

    # Create a second section section and add it to the sparse memory image

    section_b = SparseMemoryImage.Section(".data", 0x2000, data_bytes_b)
    mem_image.add_section(section_b)

    # Create a copy

    mem_image_copy = copy.deepcopy(mem_image)

    # Check two images are equal

    assert mem_image == mem_image_copy

    # Add another section to the copy

    section_c = SparseMemoryImage.Section(".test", 0x3000,
                                          bytearray("\x01\x02"))
    mem_image_copy.add_section(section_c)

    # Check two images are no longer equal

    assert mem_image != mem_image_copy
Esempio n. 2
0
def test_sections():

    # The sparse memory image we will be testing

    mem_image = SparseMemoryImage()

    # Create first bytearray with some data

    data_ints_a = [random.randint(0, 1000) for r in xrange(10)]
    data_bytes_a = bytearray()
    for data_int in data_ints_a:
        data_bytes_a.extend(struct.pack("<I", data_int))

    # Create a second section section and add it to the sparse memory image

    section_a = SparseMemoryImage.Section(".text", 0x1000, data_bytes_a)
    mem_image.add_section(section_a)

    # Create a second bytearray with some data

    data_ints_b = [random.randint(0, 1000) for r in xrange(10)]
    data_bytes_b = bytearray()
    for data_ints in data_ints_b:
        data_bytes_b.extend(struct.pack("<I", data_int))

    # Create a second section section and add it to the sparse memory
    # image. Use the alternative syntax for adding a section.

    section_b = SparseMemoryImage.Section(".data", 0x2000, data_bytes_b)
    mem_image.add_section(".data", 0x2000, data_bytes_b)

    # Retrieve and check both sections

    section_a_test = mem_image.get_section(".text")
    assert section_a_test == section_a

    section_b_test = mem_image.get_section(".data")
    assert section_b_test == section_b

    # Retrieve sections as a list

    sections_test = mem_image.get_sections()
    assert sections_test == [section_a_test, section_b_test]
Esempio n. 3
0
def test_basic(tmpdir):

    # Create a sparse memory image

    mem_image = SparseMemoryImage()

    section_names = [".text", ".data"]

    for i in range(4):

        section = SparseMemoryImage.Section()
        section.name = section_names[random.randint(0, 1)]
        section.addr = i * 0x00000200

        data_ints = [random.randint(0, 1000) for r in range(10)]
        data_bytes = bytearray()
        for data_int in data_ints:
            data_bytes.extend(struct.pack("<I", data_int))

        section.data = data_bytes

        mem_image.add_section(section)

    # Write the sparse memory image to an ELF file

    with tmpdir.join("elf-test").open('wb') as file_obj:
        elf.elf_writer(mem_image, file_obj)

    # Read the ELF file back into a new sparse memory image

    mem_image_test = None
    with tmpdir.join("elf-test").open('rb') as file_obj:
        mem_image_test = elf.elf_reader(file_obj)

    # Check that the original and new sparse memory images are equal

    assert mem_image == mem_image_test
def assemble(asm_code):

    # If asm_code is a single string, then put it in a list to simplify the
    # rest of the logic.

    asm_code_list = asm_code
    if isinstance(asm_code, str):
        asm_code_list = [asm_code]

    # Create a single list of lines

    asm_list = []
    for asm_seq in asm_code_list:
        asm_list.extend(asm_seq.splitlines())

    # First pass to create symbol table. This is obviously very simplistic.
    # We can maybe make it more robust in the future.

    addr = 0x00000200
    sym = {}
    for line in asm_list:
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".data"):
            pass

        else:
            (label, sep, rest) = line.partition(':')
            if sep != "":
                sym[label.strip()] = addr
            else:
                addr += 4

    # Second pass to assemble text section

    asm_list_idx = 0
    addr = 0x00000200
    text_bytes = bytearray()
    mngr2proc_bytes = bytearray()
    proc2mngr_bytes = bytearray()

    # Shunning: the way I handle multiple manager is as follows.
    #
    # At the beginning the single_core sign is true and all "> 1" "< 2"
    # values are dumped into the above mngr2proc_bytes and mngr2proc_bytes.
    # So, for single core testing the assembler works as usual.
    #
    # For multicore testing, I assume that all lists wrapped by curly braces
    # have the same width, and I will use the first ever length as the number
    # of cores. For example, when I see "> {1,2,3,4}", it means there are 4
    # cores. It will then set single_core=False and num_cores=4.
    # Later if I see "> {1,2,3}" I will throw out assertion error.
    #
    # Also, Upon the first occurence of the mentioned curly braces, I will
    # just duplicate mngr2proc_bytes for #core times, and put the duplicates
    # into mngrs2procs.  Later, when I see a "> 1", I will check the
    # single_core flag. If it's False, it will dump the check message into
    # all the duplicated bytearrays.
    #
    # The problem of co-existence if we keep mngr2proc and mngrs2procs, is
    # that unless we record the exact order we receive the csr instructions,
    # we cannot arbitrarily interleave the values in mngr2proc and mngrs2procs.

    mngrs2procs_bytes = []
    procs2mngrs_bytes = []
    single_core = True
    num_cores = 1

    def duplicate():

        # duplicate the bytes and no more mngr2proc/proc2mngr

        for i in xrange(num_cores):
            mngrs2procs_bytes.append(bytearray())
            mngrs2procs_bytes[i][:] = mngr2proc_bytes

            procs2mngrs_bytes.append(bytearray())
            procs2mngrs_bytes[i][:] = proc2mngr_bytes

    for line in asm_list:
        asm_list_idx += 1
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".data"):
            break

        else:
            if ':' not in line:

                inst_str = line

                # First see if we have either a < or a >

                if '<' in line:
                    (temp, sep, value) = line.partition('<')

                    value = value.lstrip(' ')
                    if value.startswith('{'):
                        values = map(lambda x: int(x, 0),
                                     value[1:-1].split(','))

                        if not single_core and len(values) != num_cores:
                            raise Exception(
                                "Previous curly brace pair has {} elements in between, but this one \"{}\" has {}."
                                .format(num_cores, line, len(values)))

                        if single_core:
                            single_core = False
                            num_cores = len(values)
                            duplicate()

                        for i in xrange(num_cores):
                            mngrs2procs_bytes[i].extend(
                                struct.pack("<I", Bits(32, values[i])))

                    else:
                        bits = Bits(32, int(value, 0))

                        if single_core:
                            mngr2proc_bytes.extend(struct.pack("<I", bits))
                        else:
                            for x in mngrs2procs_bytes:
                                x.extend(struct.pack("<I", bits))

                    inst_str = temp

                elif '>' in line:
                    (temp, sep, value) = line.partition('>')

                    value = value.lstrip(' ')
                    if value.startswith('{'):
                        values = map(lambda x: int(x, 0),
                                     value[1:-1].split(','))

                        if not single_core and len(values) != num_cores:
                            raise Exception(
                                "Previous curly brace pair has {} elements in between, but this one \"{}\" has {}."
                                .format(num_cores, line, len(values)))

                        if single_core:
                            single_core = False
                            num_cores = len(values)
                            duplicate()

                        for i in xrange(num_cores):
                            procs2mngrs_bytes[i].extend(
                                struct.pack("<I", Bits(32, values[i])))

                    else:
                        bits = Bits(32, int(value, 0))

                        if single_core:
                            proc2mngr_bytes.extend(struct.pack("<I", bits))
                        else:
                            for x in procs2mngrs_bytes:
                                x.extend(struct.pack("<I", bits))

                    inst_str = temp

                bits = assemble_inst(sym, addr, inst_str)
                text_bytes.extend(struct.pack("<I", bits.uint()))
                addr += 4

    # Assemble data section

    data_bytes = bytearray()
    for line in asm_list[asm_list_idx:]:
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".word"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<I", int(value, 0)))
            addr += 4

        elif line.startswith(".hword"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<H", int(value, 0)))
            addr += 2

        elif line.startswith(".byte"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<B", int(value, 0)))
            addr += 1

    # Construct the corresponding section objects

    text_section = \
      SparseMemoryImage.Section( ".text", 0x0200, text_bytes )

    data_section = SparseMemoryImage.Section(".data", 0x2000, data_bytes)

    # Build a sparse memory image

    mem_image = SparseMemoryImage()
    mem_image.add_section(text_section)

    if len(data_section.data) > 0:
        mem_image.add_section(data_section)

    if single_core:

        mngr2proc_section = \
          SparseMemoryImage.Section( ".mngr2proc", 0x13000, mngr2proc_bytes )

        if len(mngr2proc_section.data) > 0:
            mem_image.add_section(mngr2proc_section)

        proc2mngr_section = \
          SparseMemoryImage.Section( ".proc2mngr", 0x14000, proc2mngr_bytes )

        if len(proc2mngr_section.data) > 0:
            mem_image.add_section(proc2mngr_section)

    else:

        for i in xrange(len(mngrs2procs_bytes)):
            img = SparseMemoryImage.Section(".mngr{}_2proc".format(i),
                                            0x15000 + 0x1000 * i,
                                            mngrs2procs_bytes[i])

            if len(img.data) > 0:
                mem_image.add_section(img)

        for i in xrange(len(procs2mngrs_bytes)):
            img = SparseMemoryImage.Section(".proc{}_2mngr".format(i),
                                            0x16000 + 0x2000 * i,
                                            procs2mngrs_bytes[i])
            if len(img.data) > 0:
                mem_image.add_section(img)

    return mem_image
Esempio n. 5
0
def assemble(asm_code):

    # If asm_code is a single string, then put it in a list to simplify the
    # rest of the logic.

    asm_code_list = asm_code
    if isinstance(asm_code, str):
        asm_code_list = [asm_code]

    # Create a single list of lines

    asm_list = []
    for asm_seq in asm_code_list:
        asm_list.extend(asm_seq.splitlines())

    # First pass to create symbol table. This is obviously very simplistic.
    # We can maybe make it more robust in the future.

    addr = 0x00000400
    sym = {}
    for line in asm_list:
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".data"):
            pass

        else:
            (label, sep, rest) = line.partition(':')
            if sep != "":
                sym[label.strip()] = addr
            else:
                addr += 4

    # Second pass to assemble text section

    asm_list_idx = 0
    addr = 0x00000400
    text_bytes = bytearray()
    mngr2proc_bytes = bytearray()
    proc2mngr_bytes = bytearray()

    for line in asm_list:
        asm_list_idx += 1
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".data"):
            break

        else:
            if ':' not in line:
                inst_str = line

                # First see if we have either a < or a >

                if '<' in line:
                    (temp, sep, value) = line.partition('<')
                    bits = Bits(32, int(value, 0))
                    mngr2proc_bytes.extend(struct.pack("<I", bits))
                    inst_str = temp

                elif '>' in line:
                    (temp, sep, value) = line.partition('>')
                    bits = Bits(32, int(value, 0))
                    proc2mngr_bytes.extend(struct.pack("<I", bits))
                    inst_str = temp

                bits = assemble_inst(sym, addr, inst_str)
                text_bytes.extend(struct.pack("<I", bits.uint()))
                addr += 4

    # Assemble data section

    data_bytes = bytearray()
    for line in asm_list[asm_list_idx:]:
        line = line.partition('#')[0]
        line = line.strip()

        if line == "":
            continue

        if line.startswith(".offset"):
            (cmd, sep, addr_str) = line.partition(' ')
            addr = int(addr_str, 0)

        elif line.startswith(".word"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<I", int(value, 0)))
            addr += 4

        elif line.startswith(".hword"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<H", int(value, 0)))
            addr += 2

        elif line.startswith(".byte"):
            (cmd, sep, value) = line.partition(' ')
            data_bytes.extend(struct.pack("<B", int(value, 0)))
            addr += 1

    # Construct the corresponding section objects

    text_section = \
      SparseMemoryImage.Section( ".text", 0x0400, text_bytes )

    data_section = SparseMemoryImage.Section(".data", 0x2000, data_bytes)

    mngr2proc_section = \
      SparseMemoryImage.Section( ".mngr2proc", 0x3000, mngr2proc_bytes )

    proc2mngr_section = \
      SparseMemoryImage.Section( ".proc2mngr", 0x4000, proc2mngr_bytes )

    # Build a sparse memory image

    mem_image = SparseMemoryImage()
    mem_image.add_section(text_section)

    if len(data_section.data) > 0:
        mem_image.add_section(data_section)

    if len(mngr2proc_section.data) > 0:
        mem_image.add_section(mngr2proc_section)

    if len(proc2mngr_section.data) > 0:
        mem_image.add_section(proc2mngr_section)

    return mem_image
Esempio n. 6
0
def elf_reader(file_obj):

    # Read the data for the ELF header

    ehdr_data = file_obj.read(ElfHeader.NBYTES)

    # Construct an ELF header object

    ehdr = ElfHeader(ehdr_data)

    # Verify if its a known format and realy an ELF file

    if ehdr.ident[0:4] != '\x7fELF':
        raise ValueError("Not a valid ELF file")

    # We need to find the section string table so we can figure out the
    # name of each section. We know that the section header for the section
    # string table is entry shstrndx, so we first get the data for this
    # section header.

    file_obj.seek(ehdr.shoff + ehdr.shstrndx * ehdr.shentsize)
    shdr_data = file_obj.read(ehdr.shentsize)

    # Construct a section header object for the section string table

    shdr = ElfSectionHeader(shdr_data)

    # Read the data for the section header table

    file_obj.seek(shdr.offset)
    shstrtab_data = file_obj.read(shdr.size)

    # Load sections

    symtab_data = None
    strtab_data = None

    mem_image = SparseMemoryImage()

    for section_idx in range(ehdr.shnum):

        # Read the data for the section header

        file_obj.seek(ehdr.shoff + section_idx * ehdr.shentsize)
        shdr_data = file_obj.read(ehdr.shentsize)

        # Pad the returned string in case the section header is not long
        # enough (otherwise the unpack function would not work)

        shdr_data = shdr_data.ljust(ElfSectionHeader.NBYTES, '\0')

        # Construct a section header object

        shdr = ElfSectionHeader(shdr_data)

        # Find the section name

        start = shstrtab_data[shdr.name:]
        section_name = start.partition('\0')[0]

        # Only sections marked as alloc should be written to memory

        if not (shdr.flags & ElfSectionHeader.FLAGS_ALLOC):
            continue

        # Read the section data if it exists

        if section_name not in ['.sbss', '.bss']:
            file_obj.seek(shdr.offset)
            data = file_obj.read(shdr.size)

        # NOTE: the .bss and .sbss sections don't actually contain any
        # data in the ELF.  These sections should be initialized to zero.
        # For more information see:
        #
        # - http://stackoverflow.com/questions/610682/bss-section-in-elf-file

        else:
            data = '\0' * shdr.size

        # Save the data holding the symbol string table

        if shdr.type == ElfSectionHeader.TYPE_STRTAB:
            strtab_data = data

        # Save the data holding the symbol table

        elif shdr.type == ElfSectionHeader.TYPE_SYMTAB:
            symtab_data = data

        # Otherwise create section and append it to our list of sections

        else:
            section = SparseMemoryImage.Section(section_name, shdr.addr, data)
            mem_image.add_section(section)

    # Load symbols. We skip the first symbol since it both "designates the
    # first entry in the table and serves as the undefined symbol index".
    # For now, I have commented this out, since we are not really using it.

    # num_symbols = len(symtab_data) / ElfSymTabEntry.NBYTES
    # for sym_idx in xrange(1,num_symbols):
    #
    #   # Read the data for a symbol table entry
    #
    #   start = sym_idx * ElfSymTabEntry.NBYTES
    #   sym_data = symtab_data[start:start+ElfSymTabEntry.NBYTES]
    #
    #   # Construct a symbol table entry
    #
    #   sym = ElfSymTabEntry( sym_data )
    #
    #   # Get the symbol type
    #
    #   sym_type  = sym.info & 0xf
    #
    #   # Check to see if symbol is one of the three types we want to load
    #
    #   valid_sym_types = \
    #   [
    #     ElfSymTabEntry.TYPE_NOTYPE,
    #     ElfSymTabEntry.TYPE_OBJECT,
    #     ElfSymTabEntry.TYPE_FUNC,
    #   ]
    #
    #   # Check to see if symbol is one of the three types we want to load
    #
    #   if sym_type not in valid_sym_types:
    #     continue
    #
    #   # Get the symbol name from the string table
    #
    #   start = strtab_data[sym.name:]
    #   name = start.partition('\0')[0]
    #
    #   # Add symbol to the sparse memory image
    #
    #   mem_image.add_symbol( name, sym.value )

    return mem_image
Esempio n. 7
0
File: elf.py Progetto: jl2255/pymtl
def elf_reader(file_obj):

    # Read the data for the ELF header

    ehdr_data = file_obj.read(ElfHeader.NBYTES)

    # Construct an ELF header object

    ehdr = ElfHeader(ehdr_data)

    # Verify if its a known format and realy an ELF file

    if ehdr.ident[0:4] != '\x7fELF':
        raise ValueError("Not a valid ELF file")

    # We need to find the section string table so we can figure out the
    # name of each section. We know that the section header for the section
    # string table is entry shstrndx, so we first get the data for this
    # section header.

    file_obj.seek(ehdr.shoff + ehdr.shstrndx * ehdr.shentsize)
    shdr_data = file_obj.read(ehdr.shentsize)

    # Construct a section header object for the section string table

    shdr = ElfSectionHeader(shdr_data)

    # Read the data for the section header table

    file_obj.seek(shdr.offset)
    shstrtab_data = file_obj.read(shdr.size)

    # Load sections

    symtab_data = None
    strtab_data = None

    mem_image = SparseMemoryImage()

    for section_idx in range(ehdr.shnum):

        # Read the data for the section header

        file_obj.seek(ehdr.shoff + section_idx * ehdr.shentsize)
        shdr_data = file_obj.read(ehdr.shentsize)

        # Pad the returned string in case the section header is not long
        # enough (otherwise the unpack function would not work)

        shdr_data = shdr_data.ljust(ElfSectionHeader.NBYTES, '\0')

        # Construct a section header object

        shdr = ElfSectionHeader(shdr_data)

        # Find the section name

        start = shstrtab_data[shdr.name:]
        section_name = start.partition('\0')[0]

        # This is the list of sections that we currently want to load.

        valid_section_names = \
        [
          ".text",
          ".data",
          ".sdata",
          ".xcpthandler",
          ".init",
          ".fini",
          ".ctors",
          ".dtors",
          ".eh_frame",
          ".jcr",
          ".sbss",
          ".bss",
          ".rodata",
          ".strtab",
          ".symtab",
        ]

        # Check to see if section is one of ones we want to load

        if section_name not in valid_section_names:
            continue

        # Read the section data

        file_obj.seek(shdr.offset)
        data = file_obj.read(shdr.size)

        # Save the data holding the symbol string table

        if shdr.type == ElfSectionHeader.TYPE_STRTAB:
            strtab_data = data

        # Save the data holding the symbol table

        elif shdr.type == ElfSectionHeader.TYPE_SYMTAB:
            symtab_data = data

        # Otherwise create section and append it to our list of sections

        else:
            section = SparseMemoryImage.Section(section_name, shdr.addr, data)
            mem_image.add_section(section)

    # Load symbols. We skip the first symbol since it both "designates the
    # first entry in the table and serves as the undefined symbol index".
    # For now, I have commented this out, since we are not really using it.

    # num_symbols = len(symtab_data) / ElfSymTabEntry.NBYTES
    # for sym_idx in xrange(1,num_symbols):
    #
    #   # Read the data for a symbol table entry
    #
    #   start = sym_idx * ElfSymTabEntry.NBYTES
    #   sym_data = symtab_data[start:start+ElfSymTabEntry.NBYTES]
    #
    #   # Construct a symbol table entry
    #
    #   sym = ElfSymTabEntry( sym_data )
    #
    #   # Get the symbol type
    #
    #   sym_type  = sym.info & 0xf
    #
    #   # Check to see if symbol is one of the three types we want to load
    #
    #   valid_sym_types = \
    #   [
    #     ElfSymTabEntry.TYPE_NOTYPE,
    #     ElfSymTabEntry.TYPE_OBJECT,
    #     ElfSymTabEntry.TYPE_FUNC,
    #   ]
    #
    #   # Check to see if symbol is one of the three types we want to load
    #
    #   if sym_type not in valid_sym_types:
    #     continue
    #
    #   # Get the symbol name from the string table
    #
    #   start = strtab_data[sym.name:]
    #   name = start.partition('\0')[0]
    #
    #   # Add symbol to the sparse memory image
    #
    #   mem_image.add_symbol( name, sym.value )

    return mem_image
Esempio n. 8
0
def mk_section(name, addr, words):
    data = bytearray()
    for word in words:
        data.extend(struct.pack("<I", word))

    return SparseMemoryImage.Section(name, addr, data)