Beispiel #1
0
 def remove_nobits(self):
     """If this section is nobits, change it to PROGBITS."""
     if self.type == SHT_NOBITS:
         # Note: Order is important here. self.get_size() is implemented
         # differently depending on NOBITS vs PROGBITS
         self._data = ByteArray('\0' * self.get_size())
         self.type = SHT_PROGBITS
Beispiel #2
0
 def test_get_data(self):
     data = ByteArray("pants")
     sect = UnpreparedElfSection("test", data=data)
     self.assertEquals(sect.get_data(), data)
     sect = UnpreparedElfSection("test", section_type=SHT_NOBITS)
     sect.set_size(10)
     self.assertEquals(sect.get_data(), ByteArray('\0' * 10))
Beispiel #3
0
    def _update_data(self):
        """Update the note data based on our changes."""

        if not (self.note_name is None or self.note_type is None or \
                self._desc_data is None):
            # Round the data up to a multiple of word size.
            desc_data = self._desc_data

            if (len(desc_data) % self.bytes_per_word) != 0:
                desc_data += ByteArray('\0' *
                                       (len(desc_data) % self.bytes_per_word))

            data = ByteArray(
                struct.pack(self.endianess + self._format_chr * 3,
                            len(self.note_name) + 1, len(desc_data),
                            self.note_type))

            data += ByteArray(
                struct.pack(
                    self.endianess +
                    str(align_up(len(self.note_name) + 1, self.bytes_per_word))
                    + 's', self.note_name + '\0'))

            data += desc_data
            self._data = 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 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 #6
0
    def todata(self, wordsize, endianess):
        """Initialise the data from object."""
        if wordsize == 32:
            format_str = "III"
        else:
            format_str = "QQQ"

        num_mappings = len(self._mappings)

        if num_mappings > self.RS_MAX_MAPS:
            raise MergeError, "Error: %d rootserver mappings " \
            "are being added to the kernel config but the maximum is %d." % \
            (num_mappings, self.RS_MAX_MAPS)

        data = ByteArray(
            struct.pack(endianess + format_str, self._entry, self._stack,
                        num_mappings))

        for i in range(num_mappings):
            data += self._mappings[i].todata(wordsize, endianess)

        # Pad unused fields with zeros.
        data += ByteArray('\0' * (Mapping.get_struct_size(wordsize) * \
                                  (self.RS_MAX_MAPS - num_mappings)))

        return ByteArray(data)
Beispiel #7
0
 def test_data_append(self):
     data = ByteArray("pants")
     sect = UnpreparedElfSection(None, "test", data = data)
     self.assertEquals(sect.get_data(), data)
     sect.append_data(ByteArray("foo"))
     self.assertEquals(sect.get_data(), ByteArray("pantsfoo"))
     sect = sect.prepare(0, 0, 0)
     self.assertEqual(hasattr(sect, "data_append"), False)
Beispiel #8
0
 def get_data(self, base, size):
     """Get some size bytes of data starting at base.
     base must be > 0."""
     assert 'b' in self.mode
     self.seek(base)
     data = ByteArray()
     data.fromfile(self, size)
     return data
Beispiel #9
0
 def get_data(self, base, size):
     """
     Get some size bytes of data starting at base.
     base must be > 0.
     """
     assert 'b' in self.mode
     self.seek(base)
     data = ByteArray()
     data.fromfile(self, size)
     return data
Beispiel #10
0
    def test_getmemsz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_memsz)
        data = ByteArray()
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_memsz(), 10)

        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_memsz)
Beispiel #11
0
    def test_getmemsz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_memsz)
        data = ByteArray()
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_memsz(), 10)

        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_memsz)
Beispiel #12
0
 def _encode(self, offset, val):
     """
     Encode the provided value at the offset in this section's data.
     """
     if val >= 0:
         self._data[offset:offset+4] = \
                 ByteArray(struct.pack(self.format_word, val))
     else:
         self._data[offset:offset+4] = \
                 ByteArray(struct.pack(self.format_signed_word, val))
Beispiel #13
0
    def test_get_program_header(self):
        data = ByteArray()
        data.memsz = 0
        seg = DataElfSegment(None, data = data)
        self.assertRaises(Unprepared, seg.get_program_header, '<', 32)
        seg.prepare(0)
        self.assertRaises(InvalidArgument, seg.get_program_header, '<', 33)
        self.assertRaises(InvalidArgument, seg.get_program_header, 'ads', 32)

        ph = seg.get_program_header('<', 32)
        self.assertEquals(ph.todata(), Elf32ProgramHeader('<').todata())
Beispiel #14
0
    def test_get_program_header(self):
        data = ByteArray()
        data.memsz = 0
        seg = DataElfSegment(data=data)
        self.assertRaises(Unprepared, seg.get_program_header, "<", 32)
        seg.prepare(0)
        self.assertRaises(InvalidArgument, seg.get_program_header, "<", 33)
        self.assertRaises(InvalidArgument, seg.get_program_header, "ads", 32)

        ph = seg.get_program_header("<", 32)
        self.assertEquals(ph.todata(), Elf32ProgramHeader("<").todata())
Beispiel #15
0
    def test_getfilesz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_filesz)
        data = ByteArray("1234567890")
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_filesz(), 10)
        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_filesz)

        seg = SectionedElfSegment()
        self.assertEqual(seg.get_filesz(), 0)
Beispiel #16
0
    def test_getfilesz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_filesz)
        data = ByteArray("1234567890")
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_filesz(), 10)
        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_filesz)

        seg = SectionedElfSegment()
        self.assertEqual(seg.get_filesz(), 0)
Beispiel #17
0
    def get_thread_data(self, base_addr, live_threads, num_spare_threads):
        # Sort the threads into reverse priority order.
        live_threads.sort(lambda x, y: cmp(y[1], x[1]))

        # Setup empty scheduling queue data structures.
        priority_bitfield = 0L
        plist = [0 for i in range(self.MAX_PRIORITY + 1)]
        threads_at_priority = [[] for i in range(self.MAX_PRIORITY + 1)]

        # Iterate through and create scheduler priority list and bitmap.
        for i, thread in enumerate(live_threads):
            priority = thread[1]
            threads_at_priority[priority].append((i, priority))
            if plist[priority] == 0L:
                priority_bitfield |= (1 << priority)
                plist[priority] = self.thread_num_to_tcb_addr(base_addr, i)

        # For each thread, determine who is next on the scheduler queue.
        tcb_prev_next = {}
        for plevel in threads_at_priority:
            i = 0
            for entry in plevel:
                prev = plevel[(i - 1) % len(plevel)][0]
                next = plevel[(i + 1) % len(plevel)][0]
                tcb_prev_next[entry[0]] = (prev, next)
                i += 1

        # Iterate through and create the TCBs.
        thread_data = ByteArray()
        num_threads = 0
        for i, thread in enumerate(live_threads):
            prev, next = tcb_prev_next[i]
            thread_data += self.init_thread(i, thread, base_addr, prev, next)
            num_threads += 1

        # Pack scheduling data
        priority_table = ByteArray()
        for pdata in plist:
            priority_table += ByteArray(struct.pack(self.format_str, pdata))

        # Create the spare threads.
        first_spare_thread_num = num_threads
        for id in range(num_spare_threads):
            prev = first_spare_thread_num + ((id - 1) % num_spare_threads)
            next = first_spare_thread_num + ((id + 1) % num_spare_threads)
            thread_data += self.init_empty_thread(num_threads, base_addr, prev,
                                                  next)
            num_threads += 1
        first_spare_thread_addr = self.thread_num_to_tcb_addr(
            base_addr, first_spare_thread_num)

        return thread_data, priority_table, priority_bitfield, first_spare_thread_addr
Beispiel #18
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 #19
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 #20
0
 def remove_nobits(self):
     """If this section is nobits, change it to PROGBITS."""
     if self.type == SHT_NOBITS:
         # Note: Order is important here. self.get_size() is implemented
         # differently depending on NOBITS vs PROGBITS
         self._data = ByteArray('\0' * self.get_size())
         self.type = SHT_PROGBITS
Beispiel #21
0
 def get_data(self):
     """Return the data the will exist in memory. This may differ
     from what is copied into the file itself."""
     if self.type == SHT_NOBITS:
         return ByteArray('\0' * self.get_size())
     else:
         return self._data
Beispiel #22
0
    def test_get_file_data(self):
        ef = SectionedElfSegment(sections=[])
        self.assertRaises(InvalidArgument, ef.get_file_data)

        data = ByteArray("pants")
        ef = DataElfSegment(data=data)
        self.assertEqual(ef.get_file_data(), data)
Beispiel #23
0
 def get_file_data(self):
     """Return the data that should be copied into the file. The
     data is returned as a byte array."""
     if self.type == SHT_NOBITS:
         return ByteArray()
     else:
         return self._data
Beispiel #24
0
    def __init__(self, attrs, elf, _, pools, kernel_seg):
        ImageKernelHeap.__init__(self, attrs, pools)

        self.segment = None
        self.kernel_segment = kernel_seg

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

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

        section_name = "kernel.heap"
        sect = UnpreparedElfSection(elf,
                                    section_name,
                                    SHT_PROGBITS,
                                    self.attrs.virt_addr,
                                    data=data,
                                    flags=SHF_WRITE | SHF_ALLOC)
        elf.add_section(sect)
        self.segment = SectionedElfSegment(elf,
                                           PT_LOAD,
                                           self.attrs.virt_addr,
                                           self.attrs.phys_addr,
                                           PF_R | PF_W,
                                           self.attrs.align,
                                           sections=[sect])
        elf.add_segment(self.segment)
Beispiel #25
0
    def test_remove_nobits(self):
        for file_name in ["data/null_elf",
                          "data/arm_exec",
                          "data/arm_stripped_exec",
                          "data/arm_exec_nosect",
                          "data/arm_object",
                          "data/mips64_exec",
                          "data/mips32_exec",
                          "data/ia32_exec",
                          "data/amd64_exec",
                          "data/ia64_exec",
                          ]:
            ef = PreparedElfFile(filename=file_name)
            if ef.segments:
                seg_sizes = []
                for segment in ef.segments:
                    seg_sizes.append((segment.get_memsz(), segment.get_filesz()))
                ef.remove_nobits()
                for segment, seg_size in zip(ef.segments, seg_sizes):
                    self.assertEqual(segment.get_memsz(), segment.get_filesz())
                    self.assertEqual(segment.get_memsz(), seg_size[0])

        ef = UnpreparedElfFile()
        sec = UnpreparedElfSection(None, section_type=SHT_NOBITS, data=10)
        self.assertEqual(sec.get_size(), 10)
        ef.add_section(sec)
        ef.remove_nobits()
        sec = ef.sections[1]
        self.assertEqual(sec.type, SHT_PROGBITS)
        self.assertEqual(sec.get_size(), 10)
        self.assertEqual(sec.get_file_data(), ByteArray('\0' * 10))
Beispiel #26
0
 def todata(self):
     """Convert the ELF header to an array of bytes"""
     packed = struct.pack(self.endianess + self.layout, self.st_name,
                          self.st_info, self.st_other, self.st_shndx,
                          self.st_value, self.st_size)
     data = ByteArray(packed)
     return data
Beispiel #27
0
    def generate_dynamic_segments(self, cell, image, machine, pools):
        """
        Create a memsection for the environment based on the size
        of the contents.
        """
        attrs = image.new_attrs(
            cell.namespace.add_namespace("cell_environment"))
        attrs.attach = PF_R | PF_W
        attrs.pager = None
        attrs.data = ByteArray('\0')

        cell.space.register_mapping(attrs)

        self._add_entry(
            "SEGMENTS",
            CellEnvSegments(self.machine, self.image, self.mappings,
                            self.min_page_size))
        for mapping in self.mappings:
            self._add_entry(
                mapping[1],
                CellEnvSegmentEntry(self.machine, self.image, mapping))

        self.snap(cell)

        out = self.generate_data(machine, image)
        attrs.size = len(out.getvalue())

        self.memsect = image.add_memsection(attrs,
                                            machine,
                                            pools,
                                            section_prefix=cell.name)
Beispiel #28
0
    def __init__(self, elffile, name=None, section_type=SHT_NULL, address=0,
                 data=None, flags=0, addralign=0, info=None, link=None,
                 entsize=None):
        self.elffile = elffile
        self.address = address
        self.type = section_type
        self._name = name
        self.flags = flags
        self.addralign = addralign
        self.entsize = entsize
        self.info = info
        self.link = link
        self._backlinks = [] # keeps track of sections which link to us.
        self._in_segment_offset = None
        self.in_segment = False

        if self.address is None:
            self.address = 0

        # If the section is a 'NOBITS' section, then it just has size, and
        # no real data. So _data, may be an integer or a ByteArray depending
        # on the different circumstance
        if data is None:
            if section_type == SHT_NOBITS:
                self._data = 0
            else:
                self._data = ByteArray()
        else:
            self._data = data
        if section_type == SHT_NOBITS:
            assert is_integer(self._data)
        else:
            assert self._data.__class__ == ByteArray
Beispiel #29
0
    def _get_segments(self):
        elf_file = UnpreparedElfFile()
        sections = [UnpreparedElfSection(elf_file, "test1", data=ByteArray("test1 data")),
                    UnpreparedElfSection(elf_file, "test2", data=ByteArray("test2 data"))]

        empty_sec_seg = SectionedElfSegment(None)
        full_sec_seg = SectionedElfSegment(elf_file, sections=sections)
        
        head_seg = HeaderElfSegment(None)
        prep_head_seg = HeaderElfSegment(None)
        prep_head_seg.prepare(37, PROG_HEADER_SIZE)
        
        data = ByteArray("pants")
        full_data_seg = DataElfSegment(None, vaddr=DATA_BASE, paddr=PHYS_BASE, data=data)
        nobits_data_seg = DataElfSegment(None, vaddr=DATA_BASE, paddr=PHYS_BASE, data=data, memsz=10)

        return empty_sec_seg, full_sec_seg, head_seg, prep_head_seg, full_data_seg, nobits_data_seg
Beispiel #30
0
    def test_setdata(self):
        ef = DataElfSegment()
        data = ByteArray("foo")
        ef.set_data(data)
        self.assertEqual(ef.get_file_data(), data)

        ef = SectionedElfSegment(sections=[])
        self.assertRaises(InvalidArgument, ef.set_data, data)
Beispiel #31
0
 def todata(self):
     """Convert the ELF header to an array of bytes"""
     packed = struct.pack(self.endianess + self.layout, self.sh_name,
                          self.sh_type, self.sh_flags, self.sh_addr,
                          self.sh_offset, self.sh_size, self.sh_link,
                          self.sh_info, self.sh_addralign, self.sh_entsize)
     data = ByteArray(packed)
     return data
Beispiel #32
0
    def generate_init_script(self, kernel, elf, image, machine):
        f = self.create_ops(kernel, image, machine)

        dlen = len(f.getvalue())
        assert (dlen <= self.init_ms.get_attrs().size)

        self.init_ms.segment.sections[0]._data[:dlen] = ByteArray(f.getvalue())
        f.close()
Beispiel #33
0
 def todata(self):
     """Convert the ELF header to an array of bytes"""
     packed = struct.pack(self.endianess + self.layout, self.p_type,
                          self.p_flags, self.p_offset, self.p_vaddr,
                          self.p_paddr, self.p_filesz, self.p_memsz,
                          self.p_align)
     data = ByteArray(packed)
     return data
Beispiel #34
0
    def _update_data(self):
        """Update the note data based on our changes."""

        if not (self.note_name is None or self.note_type is None or \
                self._desc_data is None):
            data = ByteArray(
                struct.pack(self._endianess + self._format_chr * 3,
                            len(self.note_name) + 1, len(self._desc_data),
                            self.note_type))

            data += ByteArray(
                struct.pack(
                    self._endianess +
                    str(align_up(len(self.note_name) + 1,
                                 self.bytes_per_word)) + 's', self.note_name))

            data += self._desc_data
            self._data = data
Beispiel #35
0
 def test_init(self):
     ElfSegment()
     ElfSegment(PT_LOAD)
     ElfSegment(program_header_type=PT_LOAD)
     sections = [UnpreparedElfSection("foo")]
     self.assertRaises(TypeError,
                       ElfSegment,
                       data=ByteArray("pants"),
                       sections=sections)
Beispiel #36
0
    def generate_init(self, machine, _, pools, image):
        """Create the environment section."""
        out = self.generate_data(machine, image)

        dlen = len(out.getvalue())
        assert (self.memsect.attrs.size == dlen)

        self.memsect.segment.sections[0]._data[:dlen] = \
                                                      ByteArray(out.getvalue())
Beispiel #37
0
 def todata(self):
     """Convert the ELF header to an array of bytes"""
     data = self.ident.todata()
     packed = struct.pack(self.ident.endianess + self.layout, self.e_type,
                          self.e_machine, self.e_version, self.e_entry,
                          self.e_phoff, self.e_shoff, self.e_flags,
                          self.e_ehsize, self.e_phentsize, self.e_phnum,
                          self.e_shentsize, self.e_shnum, self.e_shstrndx)
     data.extend(ByteArray(packed))
     return data
Beispiel #38
0
 def _todata(self, as_bytearray, args):
     """
     A helper method which subclass.todata() should call to pack the
     data and return it in the correct wrapping object.
     """
     packed = pack(self.endianess + self.layout, *args)
     if as_bytearray:
         return ByteArray(packed)
     else:
         return packed
Beispiel #39
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 #40
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 #41
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 #42
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 #43
0
class BaseElfSection(object):
    """
    ElfSection instances represent sections in an ELF file. Note that this
    differs from ElfSectionheader, which just describes the header, not the
    data itself.

    ElfSection objects can exist in two states: prepared and unprepared. The
    subclasses UnpreparedElfSection and PreparedElfSection represent these two
    states.

    In the prepared state the section is ready to be written out to a file, but
    can not be modified (unless the changes maintain certain invariants).

    In the unprepared state the section can be modified, but must be prepared
    for writing before it can actually be written out.

    A section can be intialised from into either the prepared or unprepared
    state. Once in the prepared state, it is not possible to revert to the
    unprepared state.

    An unprepared section has a method .prepare which will return a prepared
    version of the section.

    Two important properties of the section, the wordsize and endianess, are
    only available in the prepared state.

    This class is written with the expectation that it will be sub-classed. To
    create a subclass (e.g. to implement a particular type of section) you need
    to create subclasses following the inheritance pattern below (this pattern
    is a little complicated, but would look much saner in 3D).

                           BaseElfSection
                                 |
             |-------------------------------------------|
             |                      |                    |
    UnpreparedElfSection     PreparedElfSection       BaseSubClass
             |                      |                 |  |
             |                      |-----------------|  |
             |                      |                    |
             |              PreparedSubClass             |
             |                                           |
             |-------------------------------------------|
             |
     UnpreparedSubClass

     class BaseSubClass(BaseElfSection): pass
     class UnpreparedSubClass(UnpreparedElfSection, BaseSubClass): pass
     class PreparedSubClass(PreparedElfSection, BaseSubClass): pass

     In this example, BaseSubClass would provide any class specific methods and
     also override any methods of BaseElfSection. When overriding methods of
     BaseElfSection, it is important to pass these overrides to subclasses.

     For example, if BaseSubClass defines get_size() (overriding
     BaseElfSection.get_size), then each of its subclasses would require a line

     get_size = BaseSubClass.get_size

     This is because python resolves multiple inheritance depth first, left to
     right, so BaseElfSection.get_size would be the first method resolved unless
     the explicit override is given.
    """

    def __init__(self, elffile, name=None, section_type=SHT_NULL, address=0,
                 data=None, flags=0, addralign=0, info=None, link=None,
                 entsize=None):
        self.elffile = elffile
        self.address = address
        self.type = section_type
        self._name = name
        self.flags = flags
        self.addralign = addralign
        self.entsize = entsize
        self.info = info
        self.link = link
        self._backlinks = [] # keeps track of sections which link to us.
        self._in_segment_offset = None
        self.in_segment = False

        if self.address is None:
            self.address = 0

        # If the section is a 'NOBITS' section, then it just has size, and
        # no real data. So _data, may be an integer or a ByteArray depending
        # on the different circumstance
        if data is None:
            if section_type == SHT_NOBITS:
                self._data = 0
            else:
                self._data = ByteArray()
        else:
            self._data = data
        if section_type == SHT_NOBITS:
            assert is_integer(self._data)
        else:
            assert self._data.__class__ == ByteArray

    def __repr__(self):
        return "<%s %s %s>" % (self.__class__.__name__, self.type, self.name)

    def get_size(self):
        """Return the size of the section in bytes."""
        if self.type == SHT_NOBITS:
            return self._data
        else:
            return len(self._data)

    def _get_name(self):
        """Return the name of this segment."""
        return self._name
    name = property(_get_name)

    def _set_link(self, link):
        """Set a related section."""
        if link is not None:
            if not issubclass(link.__class__, BaseElfSection):
                raise InvalidArgument, "Link must be an ElfSection. %s" % \
                      str(link.__class__)
            link._backlinks.append(self)
        self._link = link

    def _get_link(self):
        """Return the related ElfSection."""
        return self._link
    link = property(_get_link, _set_link)

    def get_data(self):
        """
        Return the data the will exist in memory. This may differ
        from what is copied into the file itself.
        """
        if self.type == SHT_NOBITS:
            return ByteArray('\0' * self.get_size())
        else:
            return self._data

    def get_file_data(self, clean=False):
        """
        Return the data that should be copied into the file. The
        data is returned as a byte array.
        """
        if self.type == SHT_NOBITS:
            return ByteArray()
        else:
            if clean:
                return self._data.copy()
            else:
                return self._data

    def remove_nobits(self):
        """If this section is nobits, change it to PROGBITS."""
        if self.type == SHT_NOBITS:
            # Note: Order is important here. self.get_size() is implemented
            # differently depending on NOBITS vs PROGBITS
            self._data = ByteArray('\0' * self.get_size())
            self.type = SHT_PROGBITS

    def get_num_entries(self):
        """Return number of entries in the section."""
        if self.entsize is None:
            raise InvalidArgument, "This section does not use entries"
        return self.get_size() / self.entsize

    def get_entry(self, index):
        """Return the data for a given entry"""
        if self.entsize is None:
            raise InvalidArgument, "This section does not use entries"
        size = self.entsize
        return self._data[index*size:(index+1)*size]

    def get_entries(self):
        """Return a generator of all entries."""
        if self.entsize is None:
            raise InvalidArgument, "This section does not use entries"
        for i in range(self.get_num_entries()):
            yield self.get_entry(i)

    def set_in_segment_offset(self, offset):
        self._in_segment_offset = offset

    def calc_in_segment_offset(self, segment):
        """
        Return the offset into the given segment.
        """
        offset = self._in_segment_offset
        if not segment.is_scatter_load() or offset is None or \
               self.name.startswith('kernel_') or self.name.startswith('ER_'):
            return self.address - segment.vaddr
        else:
            return offset

    def data_trim(self, frm, to):
        """Trim the data so it is just [frm:to]"""
        self._data = self._data[frm:to]

    def info_is_section(self):
        """ Do we expect the .link for this section to be a section itself? """
        return self.type in (SHT_REL, SHT_RELA)

    def _get_wordsize(self):
        """ Wordsize is proxied to the elf file. """
        return self.elffile.wordsize
    wordsize = property(_get_wordsize)

    def _get_endianess(self):
        """ Endianess is proxied to the elf file. """
        return self.elffile.endianess
    endianess = property(_get_endianess)