Пример #1
0
def compile_dwarf(dies, little_endian=True, bits=64):
    if isinstance(dies, DwarfDie):
        dies = (dies, )
    assert all(isinstance(die, DwarfDie) for die in dies)
    cu_die = DwarfDie(DW_TAG.compile_unit, [
        DwarfAttrib(DW_AT.comp_dir, DW_FORM.string, '/usr/src'),
        DwarfAttrib(DW_AT.stmt_list, DW_FORM.sec_offset, 0),
    ], dies)

    return create_elf_file(ET.EXEC, [
        ElfSection(
            name='.debug_abbrev',
            sh_type=SHT.PROGBITS,
            data=_compile_debug_abbrev(cu_die),
        ),
        ElfSection(
            name='.debug_info',
            sh_type=SHT.PROGBITS,
            data=_compile_debug_info(cu_die, little_endian, bits),
        ),
        ElfSection(
            name='.debug_line',
            sh_type=SHT.PROGBITS,
            data=_compile_debug_line(cu_die, little_endian),
        ),
        ElfSection(
            name='.debug_str',
            sh_type=SHT.PROGBITS,
            data=b'\0',
        ),
    ],
                           little_endian=little_endian,
                           bits=bits)
Пример #2
0
def dwarf_sections(
    dies, little_endian=True, bits=64, *, lang=None, use_dw_form_indirect=False
):
    if isinstance(dies, DwarfDie):
        dies = (dies,)
    assert all(isinstance(die, DwarfDie) for die in dies)

    if dies and dies[0].tag in UNIT_HEADER_TYPES:
        unit_dies = dies
    else:
        unit_dies = (DwarfDie(DW_TAG.compile_unit, (), dies),)
    assert all(die.tag in UNIT_HEADER_TYPES for die in unit_dies)

    unit_attribs = [DwarfAttrib(DW_AT.stmt_list, DW_FORM.sec_offset, 0)]
    if lang is not None:
        unit_attribs.append(DwarfAttrib(DW_AT.language, DW_FORM.data1, lang))
    cu_attribs = unit_attribs + [
        DwarfAttrib(DW_AT.comp_dir, DW_FORM.string, "/usr/src")
    ]

    unit_dies = [
        DwarfDie(
            die.tag,
            list(die.attribs)
            + (cu_attribs if die.tag == DW_TAG.compile_unit else unit_attribs),
            die.children,
        )
        for die in unit_dies
    ]

    debug_info, debug_types = _compile_debug_info(
        unit_dies, little_endian, bits, use_dw_form_indirect
    )

    sections = [
        ElfSection(
            name=".debug_abbrev",
            sh_type=SHT.PROGBITS,
            data=_compile_debug_abbrev(unit_dies, use_dw_form_indirect),
        ),
        ElfSection(name=".debug_info", sh_type=SHT.PROGBITS, data=debug_info),
        ElfSection(
            name=".debug_line",
            sh_type=SHT.PROGBITS,
            data=_compile_debug_line(unit_dies, little_endian),
        ),
        ElfSection(name=".debug_str", sh_type=SHT.PROGBITS, data=b"\0"),
    ]
    if debug_types:
        sections.append(
            ElfSection(name=".debug_types", sh_type=SHT.PROGBITS, data=debug_types)
        )
    return sections
Пример #3
0
def compile_dwarf(dies, little_endian=True, bits=64, *, lang=None):
    if isinstance(dies, DwarfDie):
        dies = (dies, )
    assert all(isinstance(die, DwarfDie) for die in dies)
    cu_attribs = [
        DwarfAttrib(DW_AT.comp_dir, DW_FORM.string, "/usr/src"),
        DwarfAttrib(DW_AT.stmt_list, DW_FORM.sec_offset, 0),
    ]
    if lang is not None:
        cu_attribs.append(DwarfAttrib(DW_AT.language, DW_FORM.data1, lang))
    cu_die = DwarfDie(DW_TAG.compile_unit, cu_attribs, dies)

    return create_elf_file(
        ET.EXEC,
        [
            ElfSection(
                p_type=PT.LOAD,
                vaddr=0xFFFF0000,
                data=b"",
            ),
            ElfSection(
                name=".debug_abbrev",
                sh_type=SHT.PROGBITS,
                data=_compile_debug_abbrev(cu_die),
            ),
            ElfSection(
                name=".debug_info",
                sh_type=SHT.PROGBITS,
                data=_compile_debug_info(cu_die, little_endian, bits),
            ),
            ElfSection(
                name=".debug_line",
                sh_type=SHT.PROGBITS,
                data=_compile_debug_line(cu_die, little_endian),
            ),
            ElfSection(
                name=".debug_str",
                sh_type=SHT.PROGBITS,
                data=b"\0",
            ),
        ],
        little_endian=little_endian,
        bits=bits,
    )
Пример #4
0
 def test_simple(self):
     data = b"hello, world"
     prog = Program()
     with tempfile.NamedTemporaryFile() as f:
         f.write(
             create_elf_file(
                 ET.CORE,
                 [ElfSection(p_type=PT.LOAD, vaddr=0xFFFF0000, data=data)]))
         f.flush()
         prog.set_core_dump(f.name)
     self.assertEqual(prog.read(0xFFFF0000, len(data)), data)
     self.assertRaises(FaultError, prog.read, 0x0, len(data), physical=True)
Пример #5
0
 def test_zero_fill(self):
     data = b'hello, world'
     prog = Program()
     with tempfile.NamedTemporaryFile() as f:
         f.write(
             create_elf_file(ET.CORE, [
                 ElfSection(
                     p_type=PT.LOAD,
                     vaddr=0xffff0000,
                     data=data,
                     memsz=len(data) + 4,
                 ),
             ]))
         f.flush()
         prog.set_core_dump(f.name)
     self.assertEqual(prog.read(0xffff0000, len(data) + 4), data + bytes(4))
Пример #6
0
 def test_physical(self):
     data = b'hello, world'
     prog = Program()
     with tempfile.NamedTemporaryFile() as f:
         f.write(
             create_elf_file(ET.CORE, [
                 ElfSection(
                     p_type=PT.LOAD,
                     vaddr=0xffff0000,
                     paddr=0xa0,
                     data=data,
                 ),
             ]))
         f.flush()
         prog.set_core_dump(f.name)
     self.assertEqual(prog.read(0xffff0000, len(data)), data)
     self.assertEqual(prog.read(0xa0, len(data), physical=True), data)
Пример #7
0
def create_elf_symbol_file(symbols):
    # We need some DWARF data so that libdwfl will load the file.
    sections = dwarf_sections(())
    # Create a section for the symbols to reference and the corresponding
    # segment for address lookups.
    min_address = min(symbol.value for symbol in symbols)
    max_address = max(symbol.value + symbol.size for symbol in symbols)
    sections.append(
        ElfSection(
            name=".foo",
            sh_type=SHT.NOBITS,
            p_type=PT.LOAD,
            vaddr=min_address,
            memsz=max_address - min_address,
        ))
    symbols = [
        symbol._replace(shindex=len(sections)
                        if symbol.shindex is None else symbol.shindex)
        for symbol in symbols
    ]
    return create_elf_file(ET.EXEC, sections, symbols)
Пример #8
0
 def test_unsaved(self):
     data = b"hello, world"
     prog = Program()
     with tempfile.NamedTemporaryFile() as f:
         f.write(
             create_elf_file(
                 ET.CORE,
                 [
                     ElfSection(
                         p_type=PT.LOAD,
                         vaddr=0xFFFF0000,
                         data=data,
                         memsz=len(data) + 4,
                     ),
                 ],
             )
         )
         f.flush()
         prog.set_core_dump(f.name)
     with self.assertRaisesRegex(FaultError, "memory not saved in core dump") as cm:
         prog.read(0xFFFF0000, len(data) + 4)
     self.assertEqual(cm.exception.address, 0xFFFF000C)