Beispiel #1
0
def signed( value, nbits ):
  mask = 0x1 << (nbits - 1)
  value = trim( value, nbits )
  if value & mask:
    twos_complement = ~value + 1
    return -intmask( trim( twos_complement, nbits ) )
  return intmask( value )
Beispiel #2
0
def signed(value, nbits):
    mask = 0x1 << (nbits - 1)
    value = trim(value, nbits)
    if value & mask:
        twos_complement = ~value + 1
        return -intmask(trim(twos_complement, nbits))
    return intmask(value)
Beispiel #3
0
def load_program( fp, mem, alignment=0, is_64bit=False ):

  mem_image  = elf.elf_reader( fp, is_64bit=is_64bit )
  sections   = mem_image.get_sections()
  entrypoint = -1

  for section in sections:
    start_addr = section.addr
    for i, data in enumerate( section.data ):
      mem.write( start_addr+i, 1, ord( data ) )

    # TODO: HACK should really have elf_reader return the entry point
    #       address in the elf header!
    if section.name == '.text':
      entrypoint = intmask( section.addr )
    if section.name == '.data':
      mem.data_section = section.addr

  assert entrypoint >= 0

  last_sec   = sections[-1]
  breakpoint = last_sec.addr + len( last_sec.data )

  if alignment > 0:
    def round_up( val, alignment ):
      return (val + alignment - 1) & ~(alignment - 1)
    breakpoint = round_up( breakpoint, alignment )

  return entrypoint, breakpoint
Beispiel #4
0
def do_syscall(s):
    syscall_number = s.rf[v4]
    arg0 = intmask(s.rf[a1])
    arg1 = intmask(s.rf[a2])
    arg2 = intmask(s.rf[a3])

    if syscall_number not in syscall_funcs:
        print "WARNING: syscall not implemented: %d" % syscall_number
        # TODO: return an error?
    else:
        syscall_handler = syscall_funcs[syscall_number]

        # call the syscall handler and get the return and error values
        retval, errno = syscall_handler(s, arg0, arg1, arg2)

        if s.debug.enabled("syscalls"):
            print " retval=%x errno=%x" % (retval, errno)

        s.rf[a1] = trim_32(retval)
Beispiel #5
0
def do_syscall( s ):
  syscall_number = s.rf[ v4 ]
  arg0 = intmask( s.rf[ a1 ] )
  arg1 = intmask( s.rf[ a2 ] )
  arg2 = intmask( s.rf[ a3 ] )

  if syscall_number not in syscall_funcs:
    print "WARNING: syscall not implemented: %d" % syscall_number
    # TODO: return an error?
  else:
    syscall_handler = syscall_funcs[ syscall_number ]

    # call the syscall handler and get the return and error values
    retval, errno = syscall_handler( s, arg0, arg1, arg2 )

    if s.debug.enabled( "syscalls" ):
      print " retval=%x errno=%x" % ( retval, errno )

    s.rf[ a1 ] = trim_32( retval )
Beispiel #6
0
def syscall_brk( s, arg0, arg1, arg2 ):

  new_brk = arg0

  if s.debug.enabled( "syscalls" ):
    print "syscall_brk( addr=%x )" % new_brk,

  if new_brk != 0:
    s.breakpoint = r_uint( new_brk )

  return intmask( s.breakpoint ), 0
Beispiel #7
0
def execute_cmp(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = intmask(a - b)

        s.N = (result >> 31) & 1
        s.Z = trim_32(result) == 0
        s.C = not_borrow_from(result)
        s.V = overflow_from_sub(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Beispiel #8
0
def do_syscall( s ):
  syscall_number = s.rf[17]
  arg0 = intmask( s.rf[10] )
  arg1 = intmask( s.rf[11] )
  arg2 = intmask( s.rf[12] )
  # TODO: riscv supports 6 syscall args, disabling higher args for the time
  # being
  #arg3 = s.rf[13]
  #arg4 = s.rf[14]
  #arg5 = s.rf[15]

  if syscall_number not in syscall_funcs:
    print "WARNING: syscall not implemented: %d" % syscall_number
  else:
    syscall_handler = syscall_funcs[ syscall_number ]

    retval, errno = syscall_handler( s, arg0, arg1, arg2 )

    if s.debug.enabled( "syscalls" ):
      print " retval=%x errno=%x" % ( retval, errno )

    s.rf[ 10 ] = retval
Beispiel #9
0
def do_syscall(s):
    syscall_number = s.rf[17]
    arg0 = intmask(s.rf[10])
    arg1 = intmask(s.rf[11])
    arg2 = intmask(s.rf[12])
    # TODO: riscv supports 6 syscall args, disabling higher args for the time
    # being
    #arg3 = s.rf[13]
    #arg4 = s.rf[14]
    #arg5 = s.rf[15]

    if syscall_number not in syscall_funcs:
        print "WARNING: syscall not implemented: %d" % syscall_number
    else:
        syscall_handler = syscall_funcs[syscall_number]

        retval, errno = syscall_handler(s, arg0, arg1, arg2)

        if s.debug.enabled("syscalls"):
            print " retval=%x errno=%x" % (retval, errno)

        s.rf[10] = retval
Beispiel #10
0
def execute_cmp( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result = intmask( a - b )

    s.N = (result >> 31)&1
    s.Z = trim_32( result ) == 0
    s.C = not_borrow_from( result )
    s.V = overflow_from_sub( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Beispiel #11
0
def execute_sbc(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = intmask(a - b - (not s.C))
        s.rf[inst.rd] = trim_32(result)

        if inst.S:
            if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = not_borrow_from(result)
            s.V = overflow_from_sub(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Beispiel #12
0
def execute_sbc( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result  = intmask( a - b - (not s.C) )
    s.rf[ inst.rd ] = trim_32( result )

    if inst.S:
      if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = not_borrow_from( result )
      s.V = overflow_from_sub( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Beispiel #13
0
def load_program(elf, mem, coreids, alignment=0, ext_base=0x8e000000,
                 ext_size=32):
    """Copy the contents of an ELF file into individual cores.
    The 'elf' argument should be the result of a call to
    pydgin.elf.elf_reader().
    """
    sections   = elf.get_sections()
    code_blocks = []
    for coreid in coreids:
        coreid_mask = coreid << 20
        for section in sections:
            if is_local_address(section.addr):
                start_addr = coreid_mask | section.addr
            else:
                start_addr = section.addr
            for index, data in enumerate(section.data):
                mem.write(start_addr + index, 1, ord(data), quiet=True)
            if section.name == '.text' or section.name == 'NEW_LIB_RO':
                entry_point = intmask(start_addr)
                end_point = entry_point + len(section.data)
                code_blocks.append((entry_point, end_point))
            if section.name == '.data':
                mem.data_section = section.addr
    return code_blocks
Beispiel #14
0
def elf_reader(file_obj, is_64bit=False):

    # Read the data for the ELF header

    ehdr_data = file_obj.read(
        ElfHeader.NBYTES64 if is_64bit else ElfHeader.NBYTES)

    # Construct an ELF header object

    ehdr = ElfHeader(ehdr_data, is_64bit=is_64bit)

    # 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(intmask(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, is_64bit=is_64bit)

    # Read the data for the section header table

    file_obj.seek(intmask(shdr.offset))
    shstrtab_data = file_obj.read(intmask(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(intmask(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' )
        shdr_nbytes = ElfSectionHeader.NBYTES64 if is_64bit else \
                      ElfSectionHeader.NBYTES
        fill = '\0' * (shdr_nbytes - len(shdr_data))
        shdr_data = shdr_data + fill

        # Construct a section header object

        shdr = ElfSectionHeader(shdr_data, is_64bit=is_64bit)

        # Find the section name

        #start = shstrtab_data[shdr.name:]
        idx = shdr.name
        assert idx >= 0
        start = shstrtab_data[idx:]

        #section_name = start.partition('\0')[0]
        section_name = start.split('\0', 1)[0]

        # only sections marked as lloc 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(intmask(shdr.offset))
            data = file_obj.read(intmask(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
Beispiel #15
0
def elf_reader( file_obj, is_64bit=False ):

  # Read the data for the ELF header

  ehdr_data = file_obj.read( ElfHeader.NBYTES64 if is_64bit
                        else ElfHeader.NBYTES )

  # Construct an ELF header object

  ehdr = ElfHeader( ehdr_data, is_64bit=is_64bit )

  # 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( intmask( 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, is_64bit=is_64bit )

  # Read the data for the section header table

  file_obj.seek( intmask( shdr.offset ) )
  shstrtab_data = file_obj.read( intmask( 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( intmask( 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' )
    shdr_nbytes = ElfSectionHeader.NBYTES64 if is_64bit else \
                  ElfSectionHeader.NBYTES
    fill      = '\0'*( shdr_nbytes - len(shdr_data) )
    shdr_data = shdr_data + fill

    # Construct a section header object

    shdr = ElfSectionHeader( shdr_data, is_64bit=is_64bit )

    # Find the section name

    #start = shstrtab_data[shdr.name:]
    idx = shdr.name
    assert idx >= 0
    start = shstrtab_data[idx:]

    #section_name = start.partition('\0')[0]
    section_name = start.split('\0', 1)[0]

    # only sections marked as lloc 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( intmask( shdr.offset ) )
      data = file_obj.read( intmask( 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