From: Eli Bendersky Date: Wed, 28 Dec 2011 07:21:14 +0000 (+0200) Subject: a bit of refactoring in the test/ dir + completed dwarf_location_lists example X-Git-Tag: v0.10~3 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=26e41c4b59ed72ac7bb74006bf077b2438a6acfb;p=pyelftools.git a bit of refactoring in the test/ dir + completed dwarf_location_lists example --- diff --git a/examples/dwarf_location_lists.py b/examples/dwarf_location_lists.py index 266bceb..a9f22bb 100644 --- a/examples/dwarf_location_lists.py +++ b/examples/dwarf_location_lists.py @@ -18,6 +18,9 @@ except ImportError: sys.path.extend(['.', '..']) from elftools.elf.elffile import ELFFile +from elftools.dwarf.descriptions import ( + describe_DWARF_expr, set_global_machine_arch) +from elftools.dwarf.locationlists import LocationEntry def process_file(filename): @@ -37,6 +40,10 @@ def process_file(filename): # section, and returned here as a LocationLists object. location_lists = dwarfinfo.location_lists() + # This is required for the descriptions module to correctly decode + # register names contained in DWARF expressions. + set_global_machine_arch(elffile.get_machine_arch()) + for CU in dwarfinfo.iter_CUs(): # DWARFInfo allows to iterate over the compile units contained in # the .debug_info section. CU is a CompileUnit object, with some @@ -52,17 +59,45 @@ def process_file(filename): # AttributeValue object (from elftools.dwarf.die), which we # can examine. for attr in DIE.attributes.itervalues(): - if ( attr.name == 'DW_AT_location' and - attr.form in ('DW_FORM_data4', 'DW_FORM_data8')): + if attribute_has_location_list(attr): # This is a location list. Its value is an offset into # the .debug_loc section, so we can use the location # lists object to decode it. loclist = location_lists.get_location_list_at_offset( attr.value) - print(' DIE %s. attr %s.\n %s' % ( + + print(' DIE %s. attr %s.\n%s' % ( DIE.tag, attr.name, - loclist)) + show_loclist(loclist, dwarfinfo, indent=' '))) + +def show_loclist(loclist, dwarfinfo, indent): + """ Display a location list nicely, decoding the DWARF expressions + contained within. + """ + d = [] + for loc_entity in loclist: + if isinstance(loc_entity, LocationEntry): + d.append('%s <<%s>>' % ( + loc_entity, + describe_DWARF_expr(loc_entity.loc_expr, dwarfinfo.structs))) + else: + d.append(str(loc_entity)) + return '\n'.join(indent + s for s in d) + + +def attribute_has_location_list(attr): + """ Only some attributes can have location list values, if they have the + required DW_FORM (loclistptr "class" in DWARF spec v3) + """ + if (attr.name in ( 'DW_AT_location', 'DW_AT_string_length', + 'DW_AT_const_value', 'DW_AT_return_addr', + 'DW_AT_data_member_location', 'DW_AT_frame_base', + 'DW_AT_segment', 'DW_AT_static_link', + 'DW_AT_use_location', 'DW_AT_vtable_elem_location')): + if attr.form in ('DW_FORM_data4', 'DW_FORM_data8'): + return True + return False if __name__ == '__main__': diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/external_tools/Makefile b/test/external_tools/Makefile new file mode 100644 index 0000000..fd44b8e --- /dev/null +++ b/test/external_tools/Makefile @@ -0,0 +1,18 @@ +CFLAGS = -Wall --std=c99 +# This is where `make install` from libelf places its stuff +LIBELF_HEADERS = /usr/local/include/libelf/ +LIBELF_LIBS = /usr/local/lib/ + +all: elf_creator + +elf_creator: elf_creator.c + gcc $(CFLAGS) -o elf_creator elf_creator.c \ + -I$(LIBELF_HEADERS) -L$(LIBELF_LIBS) -Wl,-rpath,$(LIBELF_LIBS) -lelf + +clean: + rm -f *.o + rm -f *.so + rm -f *.a + rm -f elf_creator + + diff --git a/test/external_tools/README.txt b/test/external_tools/README.txt new file mode 100644 index 0000000..a6c496a --- /dev/null +++ b/test/external_tools/README.txt @@ -0,0 +1,2 @@ +Some utilities that use libelf to create synthetic ELF files + diff --git a/test/external_tools/elf_creator.c b/test/external_tools/elf_creator.c new file mode 100644 index 0000000..1fd1b56 --- /dev/null +++ b/test/external_tools/elf_creator.c @@ -0,0 +1,204 @@ +/* Loosely based on the code in a Knol by Roberto Garcia Lopez: +** +** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3# +** +** Note: This file is released under the terms of the LGPL2 license. +*/ +#include +#include +#include +#include +#include +#include +#include + + +const char* OUTFILE = "generated.o"; + +// Definition of the default string table section ".shstrtab" +const char defaultStrTable[] = +{ + /* offset 00 */ '\0', // The NULL section + /* offset 01 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0', + /* offset 11 */ '.', 's', 't', 'r', 't', 'a', 'b', '\0', + /* offset 19 */ '.', 's', 'y', 'm', 't', 'a', 'b', '\0', + /* offset 27 */ '.', 'c', 'o', 'm', 'm', 'e', 'n', 't', '\0', + /* offset 36 */ '.', 'b', 's', 's', '\0', + /* offset 41 */ '.', 'd', 'a', 't', 'a', '\0', + /* offset 47 */ '.', 'r', 'e', 'l', '.', 't', 'e', 'x', 't', '\0', + /* offset 57 */ '.', 't', 'e', 'x', 't', '\0' +}; + +const char defaultStrTableLen = sizeof(defaultStrTable); + +// Offsets of section names in the string table +const char _shstrtab_offset = 1; +const char _strtab_offset = 11; +const char _symtab_offset = 19; +const char _text_offset = 57; + +// Position of sections within the object file +const char _shstrtab = 1; +const char _strtab = 2; +const char _symtab = 3; +const char _text = 4; + +const char TEXT_CONTENTS[] = {0x91, 0x92, 0x93, 0x94}; + + +//---------------------------------------------------------------------------- + +int main() +{ + int FileDes; + Elf *pElf; + Elf32_Ehdr *pEhdr; + Elf32_Shdr *pShdr; + Elf_Scn *pScn; + Elf_Data *pData; + + // Create the ELF header + if (elf_version(EV_CURRENT) == EV_NONE) // It must appear before "elf_begin()" + errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1)); + + if ((FileDes = open(OUTFILE, O_CREAT | O_WRONLY | O_TRUNC, 0777)) < 0) + errx(EX_OSERR, "open \"%s\" failed", "compiled.o"); + + if ((pElf = elf_begin(FileDes, ELF_C_WRITE, NULL)) == NULL) // 3rd argument is ignored for "ELF_C_WRITE" + errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1)); + + if ((pEhdr = elf32_newehdr(pElf)) == NULL) + errx(EX_SOFTWARE, "elf32_newehdr() failed: %s", elf_errmsg(-1)); + + pEhdr->e_ident[EI_CLASS] = ELFCLASS32; // Defined by Intel architecture + pEhdr->e_ident[EI_DATA] = ELFDATA2LSB; // Defined by Intel architecture + pEhdr->e_machine = EM_386; // Intel architecture + pEhdr->e_type = ET_REL; // Relocatable file (object file) + pEhdr->e_shstrndx = _shstrtab; // Point to the shstrtab section + + // Create the section "default section header string table (.shstrtab)" + if ((pScn = elf_newscn(pElf)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + if ((pData = elf_newdata(pScn)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + + pData->d_align = 1; + pData->d_buf = (void *) defaultStrTable; + pData->d_type = ELF_T_BYTE; + pData->d_size = defaultStrTableLen; + + if ((pShdr = elf32_getshdr(pScn)) == NULL) + errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); + + pShdr->sh_name = _shstrtab_offset; // Point to the name of the section + pShdr->sh_type = SHT_STRTAB; + pShdr->sh_flags = 0; + + // Create the section ".strtab" + if ((pScn = elf_newscn(pElf)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + if ((pData = elf_newdata(pScn)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + + const char strtab[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0}; + + pData->d_align = 1; + pData->d_buf = (void *) strtab; + pData->d_type = ELF_T_BYTE; + pData->d_size = sizeof(strtab); + + if ((pShdr = elf32_getshdr(pScn)) == NULL) + errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); + + pShdr->sh_name = _strtab_offset; + pShdr->sh_type = SHT_STRTAB; + pShdr->sh_flags = 0; + + // Create the section ".symtab" + if ((pScn = elf_newscn(pElf)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + if ((pData = elf_newdata(pScn)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + + Elf32_Sym x[4]; + + // Definition of the undefined section (this must be the first item by the definition of TIS ELF) + x[0].st_name = 0; + x[0].st_value = 0; + x[0].st_size = 0; + x[0].st_info = 0; + x[0].st_other = 0; + x[0].st_shndx = SHN_UNDEF; + + // Definition of the name of the source file (this must be the second item by the definition in TIS ELF) + x[1].st_name = 1; + x[1].st_value = 0; + x[1].st_size = 0; + x[1].st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE); // This is the value that st_info must have (because of TIS ELF) + x[1].st_other = 0; + x[1].st_shndx = SHN_ABS; // The section where the symbol is + + // Definition of the ".text" section as a section in the ".symtab" section + x[2].st_name = 0; + x[2].st_value = 0; + x[2].st_size = 0; + x[2].st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION); + x[2].st_other = 0; + x[2].st_shndx = _text; // The section where the symbol is + + // Definition of the "_start" symbol + x[3].st_name = 13; // Offset in the "strtab" section where the name start + x[3].st_value = 0; + x[3].st_size = 0; + x[3].st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE); + x[3].st_other = 0; + x[3].st_shndx = _text; // The section where the symbol is + + pData->d_align = 4; + pData->d_buf = (void *) x; + pData->d_type = ELF_T_BYTE; + pData->d_size = sizeof(x); + + if ((pShdr = elf32_getshdr(pScn)) == NULL) + errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); + + pShdr->sh_name = _symtab_offset; // Point to the name of the section + pShdr->sh_type = SHT_SYMTAB; + pShdr->sh_flags = 0; + pShdr->sh_link = _strtab; // point to the section .strtab (the section that contain the strings) + pShdr->sh_info = ELF32_ST_INFO(STB_LOCAL, 3); // the second argument is beause of TIS ELF (One greater than the symbol table index of the last local symbol (binding STB_LOCAL)) + + // Create many sections named .text + for (int i = 0; i < 70000; ++i) { + if ((pScn = elf_newscn(pElf)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + if ((pData = elf_newdata(pScn)) == NULL) + errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); + + pData->d_align = 4; + pData->d_buf = (void *)TEXT_CONTENTS; + pData->d_type = ELF_T_BYTE; + pData->d_size = sizeof(TEXT_CONTENTS); + + if ((pShdr = elf32_getshdr(pScn)) == NULL) + errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); + + pShdr->sh_name = _text_offset; + pShdr->sh_type = SHT_PROGBITS; + pShdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR; + } + + // Update the sections internally + if (elf_update(pElf, ELF_C_NULL) < 0) + errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); + // Write the object file + if (elf_update(pElf, ELF_C_WRITE) < 0) + errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1)); + // Close all handles + elf_end(pElf); + close(FileDes); + printf("Generated file: %s\n", OUTFILE); + + return 0; +} + diff --git a/test/run_readelf_tests.py b/test/run_readelf_tests.py index 5effd5f..9ffa519 100755 --- a/test/run_readelf_tests.py +++ b/test/run_readelf_tests.py @@ -12,9 +12,9 @@ import re from difflib import SequenceMatcher from optparse import OptionParser import logging -import subprocess import tempfile import platform +from test.utils import run_exe, is_in_rootdir # Create a global logger object @@ -33,19 +33,6 @@ def discover_testfiles(rootdir): yield os.path.join(rootdir, filename) -def run_exe(exe_path, args): - """ Runs the given executable as a subprocess, given the - list of arguments. Captures its return code (rc) and stdout and - returns a pair: rc, stdout_str - """ - popen_cmd = [exe_path] + args - if os.path.splitext(exe_path)[1] == '.py': - popen_cmd.insert(0, 'python') - proc = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE) - proc_stdout = proc.communicate()[0] - return proc.returncode, proc_stdout - - def run_test_on_file(filename, verbose=False): """ Runs a test on the given input filename. Return True if all test runs succeeded. @@ -173,21 +160,10 @@ def dump_output_to_temp_files(*args): testlog.info('@@ Output #%s dumped to file: %s' % (i + 1, path)) -def die(msg): - testlog.error('Error: %s' % msg) - sys.exit(1) - - -def is_in_rootdir(): - """ Check whether the current dir is the root dir of pyelftools - """ - dirstuff = os.listdir('.') - return 'test' in dirstuff and 'elftools' in dirstuff - - def main(): if not is_in_rootdir(): - die('Please run me from the root dir of pyelftools!') + testlog.error('Error: Please run me from the root dir of pyelftools!') + return 1 optparser = OptionParser( usage='usage: %prog [options] [file] [file] ...', diff --git a/test/utils.py b/test/utils.py new file mode 100644 index 0000000..e09521c --- /dev/null +++ b/test/utils.py @@ -0,0 +1,22 @@ +import os, subprocess + + +def run_exe(exe_path, args): + """ Runs the given executable as a subprocess, given the + list of arguments. Captures its return code (rc) and stdout and + returns a pair: rc, stdout_str + """ + popen_cmd = [exe_path] + args + if os.path.splitext(exe_path)[1] == '.py': + popen_cmd.insert(0, 'python') + proc = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE) + proc_stdout = proc.communicate()[0] + return proc.returncode, proc_stdout + + +def is_in_rootdir(): + """ Check whether the current dir is the root dir of pyelftools + """ + dirstuff = os.listdir('.') + return 'test' in dirstuff and 'elftools' in dirstuff + diff --git a/test/utils/Makefile b/test/utils/Makefile deleted file mode 100644 index fd44b8e..0000000 --- a/test/utils/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CFLAGS = -Wall --std=c99 -# This is where `make install` from libelf places its stuff -LIBELF_HEADERS = /usr/local/include/libelf/ -LIBELF_LIBS = /usr/local/lib/ - -all: elf_creator - -elf_creator: elf_creator.c - gcc $(CFLAGS) -o elf_creator elf_creator.c \ - -I$(LIBELF_HEADERS) -L$(LIBELF_LIBS) -Wl,-rpath,$(LIBELF_LIBS) -lelf - -clean: - rm -f *.o - rm -f *.so - rm -f *.a - rm -f elf_creator - - diff --git a/test/utils/README.txt b/test/utils/README.txt deleted file mode 100644 index a6c496a..0000000 --- a/test/utils/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -Some utilities that use libelf to create synthetic ELF files - diff --git a/test/utils/elf_creator.c b/test/utils/elf_creator.c deleted file mode 100644 index 1fd1b56..0000000 --- a/test/utils/elf_creator.c +++ /dev/null @@ -1,204 +0,0 @@ -/* Loosely based on the code in a Knol by Roberto Garcia Lopez: -** -** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3# -** -** Note: This file is released under the terms of the LGPL2 license. -*/ -#include -#include -#include -#include -#include -#include -#include - - -const char* OUTFILE = "generated.o"; - -// Definition of the default string table section ".shstrtab" -const char defaultStrTable[] = -{ - /* offset 00 */ '\0', // The NULL section - /* offset 01 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0', - /* offset 11 */ '.', 's', 't', 'r', 't', 'a', 'b', '\0', - /* offset 19 */ '.', 's', 'y', 'm', 't', 'a', 'b', '\0', - /* offset 27 */ '.', 'c', 'o', 'm', 'm', 'e', 'n', 't', '\0', - /* offset 36 */ '.', 'b', 's', 's', '\0', - /* offset 41 */ '.', 'd', 'a', 't', 'a', '\0', - /* offset 47 */ '.', 'r', 'e', 'l', '.', 't', 'e', 'x', 't', '\0', - /* offset 57 */ '.', 't', 'e', 'x', 't', '\0' -}; - -const char defaultStrTableLen = sizeof(defaultStrTable); - -// Offsets of section names in the string table -const char _shstrtab_offset = 1; -const char _strtab_offset = 11; -const char _symtab_offset = 19; -const char _text_offset = 57; - -// Position of sections within the object file -const char _shstrtab = 1; -const char _strtab = 2; -const char _symtab = 3; -const char _text = 4; - -const char TEXT_CONTENTS[] = {0x91, 0x92, 0x93, 0x94}; - - -//---------------------------------------------------------------------------- - -int main() -{ - int FileDes; - Elf *pElf; - Elf32_Ehdr *pEhdr; - Elf32_Shdr *pShdr; - Elf_Scn *pScn; - Elf_Data *pData; - - // Create the ELF header - if (elf_version(EV_CURRENT) == EV_NONE) // It must appear before "elf_begin()" - errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1)); - - if ((FileDes = open(OUTFILE, O_CREAT | O_WRONLY | O_TRUNC, 0777)) < 0) - errx(EX_OSERR, "open \"%s\" failed", "compiled.o"); - - if ((pElf = elf_begin(FileDes, ELF_C_WRITE, NULL)) == NULL) // 3rd argument is ignored for "ELF_C_WRITE" - errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1)); - - if ((pEhdr = elf32_newehdr(pElf)) == NULL) - errx(EX_SOFTWARE, "elf32_newehdr() failed: %s", elf_errmsg(-1)); - - pEhdr->e_ident[EI_CLASS] = ELFCLASS32; // Defined by Intel architecture - pEhdr->e_ident[EI_DATA] = ELFDATA2LSB; // Defined by Intel architecture - pEhdr->e_machine = EM_386; // Intel architecture - pEhdr->e_type = ET_REL; // Relocatable file (object file) - pEhdr->e_shstrndx = _shstrtab; // Point to the shstrtab section - - // Create the section "default section header string table (.shstrtab)" - if ((pScn = elf_newscn(pElf)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - if ((pData = elf_newdata(pScn)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - - pData->d_align = 1; - pData->d_buf = (void *) defaultStrTable; - pData->d_type = ELF_T_BYTE; - pData->d_size = defaultStrTableLen; - - if ((pShdr = elf32_getshdr(pScn)) == NULL) - errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); - - pShdr->sh_name = _shstrtab_offset; // Point to the name of the section - pShdr->sh_type = SHT_STRTAB; - pShdr->sh_flags = 0; - - // Create the section ".strtab" - if ((pScn = elf_newscn(pElf)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - if ((pData = elf_newdata(pScn)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - - const char strtab[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0}; - - pData->d_align = 1; - pData->d_buf = (void *) strtab; - pData->d_type = ELF_T_BYTE; - pData->d_size = sizeof(strtab); - - if ((pShdr = elf32_getshdr(pScn)) == NULL) - errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); - - pShdr->sh_name = _strtab_offset; - pShdr->sh_type = SHT_STRTAB; - pShdr->sh_flags = 0; - - // Create the section ".symtab" - if ((pScn = elf_newscn(pElf)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - if ((pData = elf_newdata(pScn)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - - Elf32_Sym x[4]; - - // Definition of the undefined section (this must be the first item by the definition of TIS ELF) - x[0].st_name = 0; - x[0].st_value = 0; - x[0].st_size = 0; - x[0].st_info = 0; - x[0].st_other = 0; - x[0].st_shndx = SHN_UNDEF; - - // Definition of the name of the source file (this must be the second item by the definition in TIS ELF) - x[1].st_name = 1; - x[1].st_value = 0; - x[1].st_size = 0; - x[1].st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE); // This is the value that st_info must have (because of TIS ELF) - x[1].st_other = 0; - x[1].st_shndx = SHN_ABS; // The section where the symbol is - - // Definition of the ".text" section as a section in the ".symtab" section - x[2].st_name = 0; - x[2].st_value = 0; - x[2].st_size = 0; - x[2].st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION); - x[2].st_other = 0; - x[2].st_shndx = _text; // The section where the symbol is - - // Definition of the "_start" symbol - x[3].st_name = 13; // Offset in the "strtab" section where the name start - x[3].st_value = 0; - x[3].st_size = 0; - x[3].st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE); - x[3].st_other = 0; - x[3].st_shndx = _text; // The section where the symbol is - - pData->d_align = 4; - pData->d_buf = (void *) x; - pData->d_type = ELF_T_BYTE; - pData->d_size = sizeof(x); - - if ((pShdr = elf32_getshdr(pScn)) == NULL) - errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); - - pShdr->sh_name = _symtab_offset; // Point to the name of the section - pShdr->sh_type = SHT_SYMTAB; - pShdr->sh_flags = 0; - pShdr->sh_link = _strtab; // point to the section .strtab (the section that contain the strings) - pShdr->sh_info = ELF32_ST_INFO(STB_LOCAL, 3); // the second argument is beause of TIS ELF (One greater than the symbol table index of the last local symbol (binding STB_LOCAL)) - - // Create many sections named .text - for (int i = 0; i < 70000; ++i) { - if ((pScn = elf_newscn(pElf)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - if ((pData = elf_newdata(pScn)) == NULL) - errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); - - pData->d_align = 4; - pData->d_buf = (void *)TEXT_CONTENTS; - pData->d_type = ELF_T_BYTE; - pData->d_size = sizeof(TEXT_CONTENTS); - - if ((pShdr = elf32_getshdr(pScn)) == NULL) - errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1)); - - pShdr->sh_name = _text_offset; - pShdr->sh_type = SHT_PROGBITS; - pShdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR; - } - - // Update the sections internally - if (elf_update(pElf, ELF_C_NULL) < 0) - errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); - // Write the object file - if (elf_update(pElf, ELF_C_WRITE) < 0) - errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1)); - // Close all handles - elf_end(pElf); - close(FileDes); - printf("Generated file: %s\n", OUTFILE); - - return 0; -} - diff --git a/z.py b/z.py index f04c4cd..02d4f3f 100644 --- a/z.py +++ b/z.py @@ -21,8 +21,10 @@ dinfo = efile.get_dwarf_info() from elftools.dwarf.locationlists import LocationLists from elftools.dwarf.descriptions import describe_DWARF_expr llists = LocationLists(dinfo.debug_loc_sec.stream, dinfo.structs) -for li in llists.get_location_list_at_offset(0): - print li - print describe_DWARF_expr(li.loc_expr, dinfo.structs) +for loclist in llists.iter_location_lists(): + print '----> loclist!' + for li in loclist: + print li + print describe_DWARF_expr(li.loc_expr, dinfo.structs)