Pure-python library for parsing ELF and DWARF
What's structure of a dsym file generated when build the app. I know it contain DWARF debug info, but what's a dsym file. I want to read the DWARF info in it.
Is it just a Mach-O binary file that contain only debug sections? How do I pass it to a DWARF parse tool like pyelftool
, which read the DWARF info in a ELF file's debug sections.
I use objdump -h
to print the sections of a dsym file ( a .dsym file is a package, I just refer the binary file in the package )
/Users/luna/Desktop/EarList.app.dSYM/Contents/Resources/DWARF/EarList: file format mach-o-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00001738 000026e0 000026e0 00000000 2**4
ALLOC, LOAD, CODE
1 .symbol_stub 00000054 00003e18 00003e18 00000000 2**1
ALLOC, LOAD, CODE
2 __TEXT.__stub_helper 00000098 00003e6c 00003e6c 00000000 2**2
ALLOC, LOAD, READONLY, CODE
3 .const 00000010 00003f08 00003f08 00000000 2**3
ALLOC, LOAD, READONLY, DATA
4 __TEXT.__objc_methname 000007db 00003f18 00003f18 00000000 2**0
ALLOC, LOAD, READONLY, CODE
5 .cstring 000001a9 000046f3 000046f3 00000000 2**0
ALLOC, LOAD, READONLY, DATA
6 __TEXT.__objc_classname 0000003c 0000489c 0000489c 00000000 2**0
ALLOC, LOAD, READONLY, CODE
7 __TEXT.__objc_methtype 0000049d 000048d8 000048d8 00000000 2**0
ALLOC, LOAD, READONLY, CODE
8 __TEXT.__unwind_info 0000007c 00004d75 00004d75 00000000 2**0
ALLOC, LOAD, READONLY, CODE
9 .eh_frame 00000204 00004df8 00004df8 00000000 2**3
ALLOC, LOAD, READONLY, DATA
10 __DATA.__program_vars 00000014 00005000 00005000 00000000 2**2
ALLOC, LOAD, DATA
11 .non_lazy_symbol_pointer 00000008 00005014 00005014 00000000 2**2
ALLOC, LOAD, DATA
12 .lazy_symbol_pointer 00000038 0000501c 0000501c 00000000 2**2
ALLOC, LOAD, DATA
13 __DATA.__objc_classlist 00000008 00005054 00005054 00000000 2**2
ALLOC, LOAD, DATA
14 __DATA.__objc_protolist 00000008 0000505c 0000505c 00000000 2**2
ALLOC, LOAD, DATA
15 __DATA.__objc_imageinfo 00000008 00005064 00005064 00000000 2**2
ALLOC, LOAD, DATA
16 __DATA.__objc_const 00000518 00005070 00005070 00000000 2**3
ALLOC, LOAD, DATA
17 __DATA.__objc_selrefs 00000054 00005588 00005588 00000000 2**2
ALLOC, LOAD, DATA
18 __DATA.__objc_classrefs 00000010 000055dc 000055dc 00000000 2**2
ALLOC, LOAD, DATA
19 __DATA.__objc_superrefs 00000004 000055ec 000055ec 00000000 2**2
ALLOC, LOAD, DATA
20 __DATA.__objc_data 00000050 000055f0 000055f0 00000000 2**2
ALLOC, LOAD, DATA
21 .cfstring 00000290 00005640 00005640 00000000 2**2
ALLOC, LOAD, DATA
22 __DATA.__objc_ivar 00000004 000058d0 000058d0 00000000 2**2
ALLOC, LOAD, DATA
23 .data 00000058 000058d4 000058d4 00000000 2**2
ALLOC, LOAD, DATA
24 __DATA.__common 00000010 0000592c 0000592c 00000000 2**2
ALLOC
25 .debug_abbrev 0000028a 00008000 00008000 00002000 2**0
CONTENTS, DEBUGGING
26 .debug_aranges 000000c0 0000828a 0000828a 0000228a 2**0
CONTENTS, DEBUGGING
27 .debug_info 0000813c 0000834a 0000834a 0000234a 2**0
CONTENTS, DEBUGGING
28 __DWARF.__debug_inlined 00000038 00010486 00010486 0000a486 2**0
CONTENTS, ALLOC, LOAD, DATA
29 .debug_line 00001205 000104be 000104be 0000a4be 2**0
CONTENTS, DEBUGGING
30 .debug_pubnames 0000028e 000116c3 000116c3 0000b6c3 2**0
CONTENTS, DEBUGGING
31 .debug_pubtypes 0000159f 00011951 00011951 0000b951 2**0
CONTENTS, DEBUGGING
32 .debug_str 00005e4f 00012ef0 00012ef0 0000cef0 2**0
CONTENTS, DEBUGGING
33 __DWARF.__apple_names 0000033c 00018d3f 00018d3f 00012d3f 2**0
CONTENTS, ALLOC, LOAD, DATA
34 __DWARF.__apple_types 000016a3 0001907b 0001907b 0001307b 2**0
CONTENTS, ALLOC, LOAD, DATA
35 __DWARF.__apple_namespac 00000024 0001a71e 0001a71e 0001471e 2**0
CONTENTS, ALLOC, LOAD, DATA
36 __DWARF.__apple_objc 00000088 0001a742 0001a742 00014742 2**0
CONTENTS, ALLOC, LOAD, DATA
Source: (StackOverflow)
I need a method for accessing DIE's directly using their offset. So far, I have found that there is a method for the Computation Unit (CU) object in which you can access a DIE from its offset.
I.e. :
cu._get_DIE(die.attributes['DW_AT_type'].value)
However if you try to access a DIE that is outside of the current CU, you are out of bounds because that DIE isn't indexed under that CU.
The best way I can think of to accomplish this is to loop through the CU's and create a comprehensive list of DIE's using the offset as an index.
It seems like there should be a method for the DWARFInfo
class that you can access any DIE as long as you have it's offset.
The reason that I need to do this is because I am looping through all of the CU's to generate a list of my globals, and I need to reference DIE's in different CU's to retrieve the type information as I go.
Source: (StackOverflow)
I am creating my own bootloader for an ATXmega128A4U. To use the bootloader I want to transform the ELF-file of the firmware into a memory map used in the the ATXmega.
For that I use python and the modul "pyelftools". The documentation of it is poor and so I run into a problem: I do not know what information I can use to get the address, offset etc. from the data at the sections.
My goal is to create a bytearray, copy the data/code into it and transfer it to the bootlaoder. Below is my code:
import sys
# If pyelftools is not installed, the example can also run from the root or
# examples/ dir of the source distribution.
sys.path[0:0] = ['.', '..']
from elftools.common.py3compat import bytes2str
from elftools.elf.elffile import ELFFile
# 128k flash for the ATXmega128a4u
flashsize = 128 * 1024
def process_file(filename):
with open(filename, 'rb') as f:
# get the data
elffile = ELFFile(f)
dataSec = elffile.get_section_by_name(b'.data')
textSec = elffile.get_section_by_name(b'.text')
# prepare the memory
flashMemory = bytearray(flashsize)
# the data section
startAddr = dataSec.header.sh_offset
am = dataSec.header.sh_size
i = 0
while i < am:
val = dataSec.stream.read(1)
flashMemory[startAddr] = val[0]
startAddr += 1
i += 1
# the text section
startAddr = textSec.header.sh_offset
am = textSec.header.sh_size
i = 0
while i < am:
print(str(startAddr) + ' : ' + str(i))
val = textSec.stream.read(1)
flashMemory[startAddr] = val[0]
startAddr += 1
i += 1
print('finished')
if __name__ == '__main__':
process_file('firmware.elf')
Hope someone can tell me how to solve this problem.
Source: (StackOverflow)