Exemplo n.º 1
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)
Exemplo n.º 2
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)
Exemplo n.º 3
0
 def test_prepare(self):
     ef = UnpreparedElfFile()
     segment = SectionedElfSegment(None, align=0x1)
     new_sect = UnpreparedElfSection(None, "pants")
     ef.add_section(new_sect)
     segment.add_section(new_sect)
     ef.add_segment(segment)
     ef.add_segment(HeaderElfSegment(None))
     ef = ef.prepare(32, '<')
Exemplo n.º 4
0
 def test_prepare(self):
     ef = UnpreparedElfFile()
     segment = SectionedElfSegment(align=0x1)
     new_sect = UnpreparedElfSection("pants")
     ef.add_section(new_sect)
     segment.add_section(new_sect)
     ef.add_segment(segment)
     ef.add_segment(HeaderElfSegment())
     ef = ef.prepare(32, "<")
Exemplo n.º 5
0
    def test_get_section(self):
        ef = SectionedElfSegment(sections=[])
        self.assertEquals(ef.get_sections(), [])

        data = ByteArray("pants")
        ef = DataElfSegment(data=data)
        self.assertRaises(InvalidArgument, ef.get_sections)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.get_sections)
Exemplo n.º 6
0
    def test_get_section(self):
        ef = SectionedElfSegment(sections=[])
        self.assertEquals(ef.get_sections(), [])

        data = ByteArray("pants")
        ef = DataElfSegment(data=data)
        self.assertRaises(InvalidArgument, ef.get_sections)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.get_sections)
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
0
    def test_has_sections(self):
        seg = DataElfSegment()
        self.assertEquals(seg.has_sections(), False)

        seg = SectionedElfSegment(sections=[])
        self.assertEquals(seg.has_sections(), True)

        seg = HeaderElfSegment()
        self.assertEquals(seg.has_sections(), False)
Exemplo n.º 10
0
    def test_remove_section(self):
        ef = UnpreparedElfFile()
        sect = UnpreparedElfSection(None)
        self.assertRaises(InvalidArgument, ef.remove_section, sect)
        ef.add_section(sect)
        self.assertEqual(sect in ef.sections, True)
        ef.remove_section(sect)
        self.assertEqual(sect in ef.sections, False)

        seg = SectionedElfSegment(None)
        ef.add_segment(seg)
        ef.add_section(sect)
        seg.add_section(sect)
        self.assertEqual(sect in ef.sections, True)
        self.assertEqual(sect in seg.sections, True)  
        ef.remove_section(sect)
        self.assertEqual(sect in ef.sections, False)
        self.assertEqual(sect in seg.sections, False)  
Exemplo n.º 11
0
    def test_remove_section(self):
        ef = UnpreparedElfFile()
        sect = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, ef.remove_section, sect)
        ef.add_section(sect)
        self.assertEqual(sect in ef.sections, True)
        ef.remove_section(sect)
        self.assertEqual(sect in ef.sections, False)

        seg = SectionedElfSegment()
        ef.add_segment(seg)
        ef.add_section(sect)
        seg.add_section(sect)
        self.assertEqual(sect in ef.sections, True)
        self.assertEqual(sect in seg.sections, True)
        ef.remove_section(sect)
        self.assertEqual(sect in ef.sections, False)
        self.assertEqual(sect in seg.sections, False)
Exemplo n.º 12
0
    def test_remove_section(self):
        seg = SectionedElfSegment()
        section = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, seg.remove_section, section)
        seg.add_section(section)
        self.assertEqual(section in seg.sections, True)
        seg.remove_section(section)
        self.assertEqual(section in seg.sections, False)

        self.assertRaises(InvalidArgument, seg.remove_section, section)

        seg = DataElfSegment()
        data = ByteArray("foo")
        seg.set_data(data)
        self.assertRaises(InvalidArgument, seg.remove_section, None)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.remove_section, None)
Exemplo n.º 13
0
    def test_replace_section(self):
        seg = SectionedElfSegment(sections=[UnpreparedElfSection("test")])
        old_section = seg.get_sections()[0]
        new_section = UnpreparedElfSection("new")
        seg.replace_section(old_section, new_section)
        self.assertEqual(seg.get_sections(), [new_section])
        new_seg = seg.copy()

        self.assertRaises(InvalidArgument, seg.replace_section, None,
                          new_section)
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def test_remove_section(self):
        seg = SectionedElfSegment()
        section = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, seg.remove_section, section)
        seg.add_section(section)
        self.assertEqual(section in seg.sections, True)
        seg.remove_section(section)
        self.assertEqual(section in seg.sections, False)

        self.assertRaises(InvalidArgument, seg.remove_section, section)

        seg = DataElfSegment()
        data = ByteArray("foo")
        seg.set_data(data)
        self.assertRaises(InvalidArgument, seg.remove_section, None)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.remove_section, None)
Exemplo n.º 16
0
    def test_replace_section(self):
        elf_from = UnpreparedElfFile()
        elf_to = UnpreparedElfFile()

        seg = SectionedElfSegment(elf_from, sections=[UnpreparedElfSection(elf_from, "test")])
        old_section = seg.get_sections()[0]
        new_section = UnpreparedElfSection(elf_to, "new")
        seg.replace_section(old_section, new_section)
        self.assertEqual(seg.get_sections(), [new_section])
        new_seg = seg.copy_into(elf_to)

        self.assertRaises(InvalidArgument, seg.replace_section, None, new_section)
Exemplo n.º 17
0
    def test_replace_section(self):
        seg = SectionedElfSegment(sections=[UnpreparedElfSection("test")])
        old_section = seg.get_sections()[0]
        new_section = UnpreparedElfSection("new")
        seg.replace_section(old_section, new_section)
        self.assertEqual(seg.get_sections(), [new_section])
        new_seg = seg.copy()

        self.assertRaises(InvalidArgument, seg.replace_section, None, new_section)
Exemplo n.º 18
0
    def test_copy(self):
        seg = DataElfSegment()
        new_seg = seg.copy()

        seg = SectionedElfSegment()
        seg.sections = [UnpreparedElfSection("test")]
        new_seg = seg.copy()

        seg = DataElfSegment()
        seg._data = ByteArray()
        new_seg = seg.copy()

        seg = DataElfSegment()
        seg.prepare(34)
        new_seg = seg.copy()

        seg = HeaderElfSegment()
        new_Seg = seg.copy()
Exemplo n.º 19
0
    def test_copy_into(self):
        elf_from = UnpreparedElfFile()
        elf_to = UnpreparedElfFile()
        seg = DataElfSegment(elf_from, ByteArray("pants"))
        new_seg = seg.copy_into(elf_to)

        seg = SectionedElfSegment(elf_from)
        seg.sections = [UnpreparedElfSection(elf_from, "test")]
        new_seg = seg.copy_into(elf_to)

        seg = DataElfSegment(elf_from, ByteArray("pants"))
        seg._data = ByteArray()
        new_seg = seg.copy_into(elf_to)

        seg = DataElfSegment(elf_from, ByteArray("pants"))
        seg.prepare(34)
        new_seg = seg.copy_into(elf_to)

        seg = HeaderElfSegment(elf_from)
        new_seg = seg.copy_into(elf_to)
Exemplo n.º 20
0
    def _initialise_segments(self, hdr, f, prepare):
        """Initialise instance from program headers."""
        # Now load all the program headers
        #
        # "The time has come," the developer said, "to talk of many
        # things: Of section to segment mapping and scatter load, of
        # cabbages and kings, and why the RVCT linker is on drugs and
        # whether pigs have wings."
        #
        # There are two ways of determining which sections belong in a
        # segment:
        #
        # 1) In most cases a section is in a segment if its virtual
        #    address range falls in the virtual address range of the
        #    segment.  These segments tend to contain multiple
        #    PROGBITS sections and may end with a NOBITS section.
        #
        # 2) In the case of segments build with RVCT's scatter load
        #    support the virtual address of the included sections can
        #    be anywhere in memory.  In this case a section is in the
        #    segment if its data file offset falls in the offset range
        #    of the segment.  These segments can contain multiple
        #    PROGBITS and NOBITS sections in any order.  The file size
        #    of the segment is the filesize of all of the PROGBITS
        #    sections.  The memory size of the segment is the sum of
        #    the size of all of the sections, not the difference
        #    between the lowest and highest virtual addresses.
        #
        # Some other things about ELF files that you need to know:
        #
        # a) Segments can overlap, and sections can appear in multiple
        #    segments.
        #
        # b) Some sections do not appear in any segments.  These tend
        #    to be the symbol table and other debugging data.
        #
        # c) The offsets of NOBITS sections tend to be the same as the
        #    offset for the next PROGBITS section, even if it is in
        #    the next segment.  However, sometimes NOBITS sections
        #    appear at the beginning of a segment.
        #
        # d) The address offset from the start of a segment and the
        #    file offset from the start of the segment are not
        #    necessarily the same.
        #
        # Therefore, to map sections to segments involves two passes:
        #
        # 1) Find all of the sections that fall in the segment virtual
        #    address range.
        #
        # 2) Find all of the remaining sections that fall in the file
        #    offset range.  If any are found then mark the segment as
        #    a scatter-load segment.
        #
        # The file size and memory size of a segment depends on
        # whether or not it is a scatter load segment.  For scatter
        # load files, the section that has the latest offset from the
        # beginning of the section is used, while for non-scatter-load
        # segments, the section with the largest virtual address is
        # used.
        #
        # File offsets cannot be used for both types of segments
        # because broken linkers can produce sections with
        # inconsistant virtual address to file offset mappings and
        # this will make elfweaver produce segments with incorrect
        # file sizes or memory sizes.
        #
        # "O Readers," said the developer, "You've had a pleasant run!
        # Shall we start the code again?" But answer came there none--
        # And this was scarcely odd, because no-one would read this far
        # for fun.

        phoff = hdr.e_phoff
        self._ph_offset = phoff
        self.segments = []

        # Short circuit the return.
        if hdr.e_phoff == 0:
            return

        ph_list = self._get_headers(hdr, f, ELF_PH_CLASSES, hdr.e_phoff,
                                    hdr.e_phentsize, hdr.e_phnum)
        phentsize = hdr.e_phentsize

        sheaders = self._get_section_headers(hdr, f)
        for ph in ph_list:
            # Map segments to sections, pass 1.
            if ph.p_type != PT_PHDR:
                sects = []
                for (section, sh) in zip(self.sections, sheaders):
                    # See if the section's virtual address range falls within
                    # the virtual address range of the segment.
                    low = ph.p_vaddr
                    high = low + ph.p_memsz
                    addr = section.address
                    if low <= addr < high and addr + section.get_size() <= high:
                        section.set_in_segment_offset(sh.sh_offset -
                                                      ph.p_offset)
                        sects.append(section)

                if sects == []:
                    data = f.get_data(ph.p_offset, ph.p_filesz)
                    data.memsz = ph.p_memsz
                    es = DataElfSegment(ph=ph, data=data)
                else:
                    es = SectionedElfSegment(ph=ph, sections=sects)
            else:
                es = HeaderElfSegment(ph=ph)
            self.segments.append(es)

        # Map segments to sections, pass 2
        for ph, es in zip(ph_list, self.segments):
            if ph.p_type != PT_PHDR:
                for (section, sh) in zip(self.sections, sheaders):
                    # Scatter-load sections do not appear in
                    # multiple segments, so skip sections that
                    # are already in some segment.
                    if section.is_in_segment():
                        continue
                    # See if the section's file offset range
                    # falls within the file offset range of
                    # the segment.  Remember that the trailing
                    # BSS section can have the offset of the
                    # next section
                    if ph.p_offset <= sh.sh_offset <= ph.p_offset + ph.p_filesz and \
                           ((section.type == SHT_NOBITS and sh.sh_offset != ph.p_offset) or \
                            (section.type != SHT_NOBITS and section.get_size() > 0 and \
                             sh.sh_offset + section.get_size() <= ph.p_offset + ph.p_filesz)):
                        section.set_in_segment_offset(sh.sh_offset -
                                                      ph.p_offset)
                        es.add_section(section)
                        es.set_scatter_load()
                prog_header_size = None
            else:
                prog_header_size = phentsize * hdr.e_phnum

            # Now mark the segment as prepared.
            if prepare:
                es.prepare(ph.p_offset, prog_header_size)
Exemplo n.º 21
0
Arquivo: core.py Projeto: BruceYi/okl4
    def _initialise_segments(self, hdr, file_, prepare):
        """Initialise instance from program headers."""
        # Now load all the program headers
        #
        # "The time has come," the developer said, "to talk of many
        # things: Of section to segment mapping and scatter load, of
        # cabbages and kings, and why the RVCT linker is on drugs and
        # whether pigs have wings."
        #
        # There are two ways of determining which sections belong in a
        # segment:
        #
        # 1) In most cases a section is in a segment if its virtual
        #    address range falls in the virtual address range of the
        #    segment.  These segments tend to contain multiple
        #    PROGBITS sections and may end with a NOBITS section.
        #
        # 2) In the case of segments build with RVCT's scatter load
        #    support the virtual address of the included sections can
        #    be anywhere in memory.  In this case a section is in the
        #    segment if its data file offset falls in the offset range
        #    of the segment.  These segments can contain multiple
        #    PROGBITS and NOBITS sections in any order.  The file size
        #    of the segment is the filesize of all of the PROGBITS
        #    sections.  The memory size of the segment is the sum of
        #    the size of all of the sections, not the difference
        #    between the lowest and highest virtual addresses.
        #
        # Some other things about ELF files that you need to know:
        #
        # a) Segments can overlap, and sections can appear in multiple
        #    segments.
        #
        # b) Some sections do not appear in any segments.  These tend
        #    to be the symbol table and other debugging data.
        #
        # c) The offsets of NOBITS sections tend to be the same as the
        #    offset for the next PROGBITS section, even if it is in
        #    the next segment.  However, sometimes NOBITS sections
        #    appear at the beginning of a segment.
        #
        # d) The address offset from the start of a segment and the
        #    file offset from the start of the segment are not
        #    necessarily the same.
        #
        # Therefore, to map sections to segments involves two passes:
        #
        # 1) Find all of the sections that fall in the segment virtual
        #    address range.
        #
        # 2) Find all of the remaining sections that fall in the file
        #    offset range.  If any are found then mark the segment as
        #    a scatter-load segment.
        #
        # The file size and memory size of a segment depends on
        # whether or not it is a scatter load segment.  For scatter
        # load files, the section that has the latest offset from the
        # beginning of the section is used, while for non-scatter-load
        # segments, the section with the largest virtual address is
        # used.
        #
        # File offsets cannot be used for both types of segments
        # because broken linkers can produce sections with
        # inconsistant virtual address to file offset mappings and
        # this will make elfweaver produce segments with incorrect
        # file sizes or memory sizes.
        #
        # "O Readers," said the developer, "You've had a pleasant run!
        # Shall we start the code again?" But answer came there none--
        # And this was scarcely odd, because no-one would read this far
        # for fun.

        self._ph_offset = hdr.e_phoff
        self.segments = []

        # Short circuit the return.
        if hdr.e_phoff == 0:
            return

        ph_list = self._get_headers(hdr, file_, ELF_PH_CLASSES, hdr.e_phoff,
                                    hdr.e_phentsize, hdr.e_phnum)

        # Map segments to sections, pass 1.
        for ph in ph_list:
            if ph.p_type != PT_PHDR:
                low = ph.p_vaddr
                high = low + ph.p_memsz
                sects = []
                for section in self.sections:
                    # See if the section's virtual address range falls within
                    # the virtual address range of the segment.
                    addr = section.address
                    if low <= addr < high and addr + section.get_size() <= high:
                        sects.append(section)

                if sects:
                    seg = SectionedElfSegment(self, prog_header=ph,
                                              sections=sects)
                else:
                    data = file_.get_data(ph.p_offset, ph.p_filesz)
                    seg = DataElfSegment(self, prog_header=ph, data=data,
                                         memsz=ph.p_memsz)
            else:
                seg = HeaderElfSegment(self, prog_header=ph)
            self.segments.append(seg)

        # Map segments to sections, pass 2
        sheaders = self._get_section_headers(hdr, file_)
        sect_offsets = [header.sh_offset for header in sheaders]
        for ph, seg in zip(ph_list, self.segments):
            if seg.has_sections():
                low = ph.p_offset
                high = low + ph.p_filesz
                for (section, offset) in zip(self.sections, sect_offsets):
                    # Scatter-load sections do not appear in multiple segments,
                    # so skip sections that are already in some segment.
                    if section.in_segment:
                        continue
                    # See if the section's file offset range falls within the
                    # file offset range of the segment.  Remember that the
                    # trailing BSS section can have the offset of the next
                    # section
                    if low <= offset <= high and \
                           ((section.type == SHT_NOBITS and offset != low) or \
                            (section.type != SHT_NOBITS and section.get_size() > 0 and \
                             offset + section.get_size() <= high)):
                        seg.add_section(section)
                        seg.set_scatter_load()

                # If we're a scatter-load segment we need to work out in segment
                # offsets for our sections
                if seg.is_scatter_load():
                    for section in seg.sections:
                        idx = self.sections.index(section)
                        offset = sect_offsets[idx]
                        section.set_in_segment_offset(offset - ph.p_offset)

        # If need be, we now prepare the segments
        if prepare:
            for ph, seg in zip(ph_list, self.segments):
                if ph.p_type == PT_PHDR:
                    prog_header_size = hdr.e_phentsize * hdr.e_phnum
                else:
                    prog_header_size = None
                seg.prepare(ph.p_offset, prog_header_size)