Beispiel #1
0
    def todata(self):
        """Return a list of (array, offset) tuples"""
        data = [(0, self.get_elf_header().todata())]

        # Create any section headers
        if self.sections[1:]:
            sect_data = ByteArray()
            for header in self.get_section_headers():
                sect_data.extend(header.todata())
            data.append( (self._sh_offset, sect_data) )

        # Create any section headers
        if self.segments:
            ph_data = ByteArray()
            for segment in self.segments:
                ph_data.extend(
                    segment.get_program_header(self.endianess,
                                               self.wordsize).todata())
            data.append( (self._ph_offset, ph_data) )

        if self.sections[1:]:
            data += [(sec.offset, sec.get_file_data()) for sec in self.sections]
        elif self.segments:
            data += [(seg.offset, seg.get_file_data()) for seg in self.segments]

        return data
Beispiel #2
0
    def todata(self):
        """Return a list of (array, offset) tuples"""
        data = [(0, self.get_elf_header().todata())]

        # Create any section headers
        if self.sections and self.has_section_headers:
            sect_data = ByteArray()
            for sh in self.get_section_headers():
                sect_data.extend(sh.todata())
            data.append((self._sh_offset, sect_data))

        # Create any segment headers
        if self.segments:
            ph_data = ByteArray()
            for segment in self.segments:
                ph_data.extend(
                    segment.get_program_header(self.endianess,
                                               self.wordsize).todata())
            data.append((self._ph_offset, ph_data))

        if self.sections:
            data += [(sec.offset, sec.get_file_data())
                     for sec in self.sections]
        elif self.segments:
            data += [(seg.offset, seg.get_file_data())
                     for seg in self.segments]

        return data
Beispiel #3
0
 def get_file_data(self, clean=False):
     """Return an array of bytes representing the data."""
     #return ByteArray(chain(*(reloc.todata() for reloc in self.int_relocs)))
     data = ByteArray()
     for reloc in self.int_relocs:
         data.extend(reloc.todata())
     return data
Beispiel #4
0
 def get_file_data(self, clean=False):
     """Return an array of bytes representing the data."""
     #return ByteArray(chain(*(reloc.todata() for reloc in self.int_relocs)))
     data = ByteArray()
     for reloc in self.int_relocs:
         data.extend(reloc.todata())
     return data
Beispiel #5
0
    def add_memsection(self, attrs, machine, pools):
        """
        Create a memsection for inclusion in the image.

        If the data or file attributes of 'attr' are non-None, then a
        ELF segment will be created, otherwise the memsection will
        will be included in the address layout process, but will be
        created at runtime by Iguana server.
        """
        new_segment = None
        in_image = False

        if attrs.file is not None or attrs.data is not None:
            if attrs.file is not None:
                the_file = open(attrs.file, 'r')
                data = ByteArray(the_file.read())
                the_file.close()
            else:
                data = attrs.data
                
            if attrs.size is not None and len(data) < attrs.size:
                data.extend([0] * (attrs.size - len(data)))

            attrs.size = data.buffer_info()[1] * data.itemsize

            sect = UnpreparedElfSection(attrs.name, SHT_PROGBITS,
                                        attrs.virt_addr,
                                        data = data,
                                        flags = SHF_WRITE | SHF_ALLOC)
            self.elf.add_section(sect)
            new_segment = SectionedElfSegment(PT_LOAD, attrs.virt_addr,
                                              attrs.phys_addr, PF_R | PF_W,
                                              machine.min_page_size(),
                                              sections=[sect])
            self.elf.add_segment(new_segment)
            in_image = True
            
        obj = ImageMemsection(new_segment, attrs, pools)

        # If the memsection has data that goes into the image, then
        # put it at the front of the list so that it will be near the
        # code segments.
        if in_image:
            self.memsections = [obj] + self.memsections
        else:
            self.memsections.append(obj)

        return obj
Beispiel #6
0
    def to_data(self, phys_addr):
        # Map a 1M section
        def set_section(array, index, pfn, rwx, cache):
            entry = (pfn << 20) | (rwx << 10) | (cache << 2) | 0x12
            #print "set  1M entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
            assert array.get_data(index*4, 4, '<') == 0
            array.set_data(index*4, entry, 4, '<')

        # Map a 4K page
        def set_page(array, offset, index, pfn, rwx, cache):
            entry = (pfn << 12) | (rwx << 10) | (rwx << 8) | (rwx << 6) | \
                    (rwx << 4) | (cache << 2) | 0x2
            #print "set  4K entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
            assert array.get_data(offset+index*4, 4, '<') == 0
            array.set_data(offset+index*4, entry, 4, '<')

        # Map a 64K page
        def set_large_page(array, offset, index, pfn, rwx, cache):
            entry = (pfn << 12) | (rwx << 10) | (rwx << 8) | (rwx << 6) | \
                    (rwx << 4) | (cache << 2) | 0x1
            for i in range(index, index+16):
                #print "set 64K entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
                assert array.get_data(offset+i*4, 4, '<') == 0
                array.set_data(offset+i*4, entry, 4, '<')

        # Create a subtree to support 4k pages
        # will extend pagetable array as neccesary, returns an offset into pagetable array
        # which is start of 2nd level pagetable
        # will return old subtree if one already exists here
        def create_subtree(array, index, phys_addr):
            existing = array.get_data(index*4, 4, '<')
            # if we have already created a subtree here
            if existing & 0x3 == 1:
                return (existing & 0xfffffc00) - phys_addr
            assert (existing & 0x3 == 0)
            start = len(pagetable)
            array.extend(1024*[0])
            entry = ((phys_addr + start) & ~0x3ff) | 0x11
            #print "create subtree %x = %x (%x)" % (index, entry, phys_addr + start)
            array.set_data(index*4, entry, 4, '<')
            return start

        pagetable = ByteArray(16*1024*"\0")
        # Sort by virtual
        self._mappings.sort(key=lambda x: x[0])

        for virt, phys, pgsize, npages, rwx, cache in self._mappings:
            if virt == 0:
                #print "Warning mapping at 0 - reserving 1K of space which may not be needed"
                pagetable.extend(1024*[0])
                continue
            #print "map %x -> %x (%x bytes)" % (virt, phys, pgsize*npages)
            section_index = virt / 1024 / 1024
            num_sections = ((npages*pgsize - 1) / 1024 / 1024) + 1
            for section in range(section_index, section_index+num_sections):
                if pgsize == 0x00100000: # 1MB
                    set_section(pagetable, section,
                                phys / 1024 / 1024 + section-section_index,
                                rwx, cache)
                elif pgsize == 0x00010000: # 64KB
                    subtree = create_subtree(pagetable, section, phys_addr)
                    page_index = (virt - (section * 1024 * 1024)) / 4096
                    for page in range(page_index, page_index + npages):
                        set_large_page(pagetable, subtree, page,
                                 phys / 4096 + page - page_index, rwx, cache)
                else: # 4KB
                    subtree = create_subtree(pagetable, section, phys_addr)
                    page_index = (virt - (section * 1024 * 1024)) / 4096
                    for page in range(page_index, page_index + npages):
                        set_page(pagetable, subtree, page,
                                 phys / 4096 + page - page_index, rwx, cache)

        return pagetable
Beispiel #7
0
 def get_file_data(self):
     """Return an array of bytes representing the data."""
     data = ByteArray()
     for sym in self.int_syms:
         data.extend(sym.todata())
     return data
Beispiel #8
0
 def get_file_data(self):
     """Return an array of bytes representing the data."""
     data = ByteArray()
     for s in self.strings:
         data.extend(ByteArray(s))
     return data
Beispiel #9
0
    def add_memsection(self, attrs, machine, pools, section_prefix=None):
        """
        Create a memsection for inclusion in the image.

        If the data or file attributes of 'attr' are non-None, then a
        ELF segment will be created, otherwise the memsection will
        will be included in the address layout process, but will be
        created at runtime by Iguana server.
        """
        new_segment = None
        in_image = False

        if attrs.file is not None or attrs.data is not None:
            if attrs.file is not None:
                the_file = open(attrs.file, 'r')
                data = ByteArray(the_file.read())
                the_file.close()
            else:
                data = attrs.data

            if attrs.size is not None and len(data) < attrs.size:
                data.extend([0] * (attrs.size - len(data)))

            attrs.size = data.buffer_info()[1] * data.itemsize

            if section_prefix:
                section_name = "%s.%s" % (section_prefix, attrs.ns_node.name)
            else:
                section_name = attrs.ns_node.name
            sect = UnpreparedElfSection(self.elf,
                                        section_name,
                                        SHT_PROGBITS,
                                        attrs.virt_addr,
                                        data=data,
                                        flags=SHF_WRITE | SHF_ALLOC)
            self.elf.add_section(sect)
            new_segment = SectionedElfSegment(self.elf,
                                              PT_LOAD,
                                              attrs.virt_addr,
                                              attrs.phys_addr,
                                              PF_R | PF_W,
                                              machine.min_page_size(),
                                              sections=[sect])
            self.elf.add_segment(new_segment)
            in_image = True
# This check should be added, but currently fails with iguana.
#         elif attrs.size is None:
#             raise MergeError, \
#                   'No size attribute given for memsection \"%s\".' % attrs.abs_name()

        obj = ImageMemsection(new_segment, attrs, pools)

        # If the memsection has data that goes into the image, then
        # put it at the front of the list so that it will be near the
        # code segments.
        if in_image:
            self.memsections = [obj] + self.memsections
        else:
            self.memsections.append(obj)

        return obj
Beispiel #10
0
 def get_file_data(self):
     """Return an array of bytes representing the data."""
     data = ByteArray()
     for sym in self.int_syms:
         data.extend(sym.todata())
     return data
Beispiel #11
0
 def get_file_data(self):
     """Return an array of bytes representing the data."""
     data = ByteArray()
     for s in self.strings:
         data.extend(ByteArray(s))
     return data
Beispiel #12
0
    def to_data(self, phys_addr):
        # Map a 1M section
        def set_section(array, index, pfn, rwx, cache):
            entry = (pfn << 20) | (rwx << 10) | (cache << 2) | 0x12
            #print "set  1M entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
            assert array.get_data(index * 4, 4, '<') == 0
            array.set_data(index * 4, entry, 4, '<')

        # Map a 4K page
        def set_page(array, offset, index, pfn, rwx, cache):
            entry = (pfn << 12) | (rwx << 10) | (rwx << 8) | (rwx << 6) | \
                    (rwx << 4) | (cache << 2) | 0x2
            #print "set  4K entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
            assert array.get_data(offset + index * 4, 4, '<') == 0
            array.set_data(offset + index * 4, entry, 4, '<')

        # Map a 64K page
        def set_large_page(array, offset, index, pfn, rwx, cache):
            entry = (pfn << 12) | (rwx << 10) | (rwx << 8) | (rwx << 6) | \
                    (rwx << 4) | (cache << 2) | 0x1
            for i in range(index, index + 16):
                #print "set 64K entry %x = %x (%x, %x, %x)" % (index, entry, pfn, rwx, cache)
                assert array.get_data(offset + i * 4, 4, '<') == 0
                array.set_data(offset + i * 4, entry, 4, '<')

        # Create a subtree to support 4k pages
        # will extend pagetable array as neccesary, returns an offset into pagetable array
        # which is start of 2nd level pagetable
        # will return old subtree if one already exists here
        def create_subtree(array, index, phys_addr):
            existing = array.get_data(index * 4, 4, '<')
            # if we have already created a subtree here
            if existing & 0x3 == 1:
                return (existing & 0xfffffc00) - phys_addr
            assert (existing & 0x3 == 0)
            start = len(pagetable)
            array.extend(1024 * [0])
            entry = ((phys_addr + start) & ~0x3ff) | 0x11
            #print "create subtree %x = %x (%x)" % (index, entry, phys_addr + start)
            array.set_data(index * 4, entry, 4, '<')
            return start

        pagetable = ByteArray(16 * 1024 * "\0")
        # Sort by virtual
        self._mappings.sort(key=lambda x: x[0])

        for virt, phys, pgsize, npages, rwx, cache in self._mappings:
            if virt == 0:
                #print "Warning mapping at 0 - reserving 1K of space which may not be needed"
                pagetable.extend(1024 * [0])
                continue
            #print "map %x -> %x (%x bytes)" % (virt, phys, pgsize*npages)
            section_index = virt / 1024 / 1024
            num_sections = ((npages * pgsize - 1) / 1024 / 1024) + 1
            for section in range(section_index, section_index + num_sections):
                if pgsize == 0x00100000:  # 1MB
                    set_section(pagetable, section,
                                phys / 1024 / 1024 + section - section_index,
                                rwx, cache)
                elif pgsize == 0x00010000:  # 64KB
                    subtree = create_subtree(pagetable, section, phys_addr)
                    page_index = (virt - (section * 1024 * 1024)) / 4096
                    for page in range(page_index, page_index + npages):
                        set_large_page(pagetable, subtree, page,
                                       phys / 4096 + page - page_index, rwx,
                                       cache)
                else:  # 4KB
                    subtree = create_subtree(pagetable, section, phys_addr)
                    page_index = (virt - (section * 1024 * 1024)) / 4096
                    for page in range(page_index, page_index + npages):
                        set_page(pagetable, subtree, page,
                                 phys / 4096 + page - page_index, rwx, cache)

        return pagetable