Re: dwarf_begin_elf() won't create handle without .debug_* sections
On Wed, 2018-05-30 at 17:32 +, Sasha Da Rocha Pinheiro wrote: > I just fixed something interesting in Dyninst. We were assuming that > the FDEs were following the CIE in the eh_frame section, but this is > not correct. I found them mixed in an ARM binary and this caused > wrong parsing. > So we I did dwarf_next_cfi() in the loop to go through the FDE's, and > I had to use it again in the loop to get the corresponding CIE. I > don't think it's a problem, just kinda not intuitive, for who wants > to understand after me. dwarf_next_cfi () is a very low level interface. Other cfi related interfaces that work with a Dwarf_CFI handle (dwarf_getcfi () and dwarf_getcfi_elf ()) and don't make any assumptions about the order. But they do build up a cache of all entries. In return for some extra memory usage you can use them without caring about the order in which they appear with dwarf_cfi_addrframe () by just giving an address you are interested in and using dwarf_frame_info (), dwarf_frame_cfa () and dwarf_frame_register () to extract the information (which might be less/different than what you would get from the "raw" Dwarf_CFI_Entry). Cheers, Mark
Re: [PATCH] tests: Run run-low_high_pc.sh testcase on split dwarf files.
On Thu, 2018-05-31 at 14:16 +0200, Mark Wielaard wrote: > Test that the low high pc attributes can be properly resolved also > in split dwarf setups. Pushed to master.
Re: [PATCH] tests: Split self_test_files into an exe, lib and obj list.
On Thu, 2018-05-31 at 14:40 +0200, Mark Wielaard wrote: > Introduce testrun_on_self_exe and testrun_on_self_lib. > Some tests cannot handle (unrelocated) ET_REL object files. > run-get-units-split.sh and run-unit-info.sh only handle executables > and shared libraries. This allows running the whole testsuite on an > elfutils build done with CFLAGS="-gdwarf-4 -gsplit-dwarf -O2". Pushed to master.
[PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file.
We would give up if one of them failed. With this fixed a self-test with make check succeeds when building elfutils itself with CFLAGS set to "-gdwarf-4 -gdwarf-split -O2". Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 7 +++ libdw/libdw_find_split_unit.c | 114 +- src/ChangeLog | 5 ++ src/readelf.c | 13 - 4 files changed, 92 insertions(+), 47 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index d8433eb..17acb90 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2018-05-31 Mark Wielaard + + * libdw_find_split_unit.c (try_split_file): New function extracted + from... + (__libdw_find_split_unit): ... here. Try both the relative and + absolute paths to find a .dwo file. + 2018-05-30 Mark Wielaard * libdw/dwarf_getsrclines.c (read_srclines): Change ndir and diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c index dc62e0d..da039e5 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -42,6 +42,49 @@ #include #include +void +try_split_file (Dwarf_CU *cu, const char *dwo_path) +{ + int split_fd = open (dwo_path, O_RDONLY); + if (split_fd != -1) +{ + Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ); + if (split_dwarf != NULL) + { + Dwarf_CU *split = NULL; + while (dwarf_get_units (split_dwarf, split, &split, + NULL, NULL, NULL, NULL) == 0) + { + if (split->unit_type == DW_UT_split_compile + && cu->unit_id8 == split->unit_id8) + { + if (tsearch (split->dbg, &cu->dbg->split_tree, + __libdw_finddbg_cb) == NULL) + { + /* Something went wrong. Don't link. */ + __libdw_seterrno (DWARF_E_NOMEM); + break; + } + + /* Link skeleton and split compile units. */ + __libdw_link_skel_split (cu, split); + + /* We have everything we need from this ELF +file. And we are going to close the fd to +not run out of file descriptors. */ + elf_cntl (split_dwarf->elf, ELF_C_FDDONE); + break; + } + } + if (cu->split == (Dwarf_CU *) -1) + dwarf_end (split_dwarf); + } + /* Always close, because we don't want to run out of file +descriptors. See also the elf_fcntl ELF_C_FDDONE call +above. */ + close (split_fd); +} +} Dwarf_CU * internal_function @@ -57,63 +100,42 @@ __libdw_find_split_unit (Dwarf_CU *cu) if (cu->unit_type == DW_UT_skeleton) { Dwarf_Die cudie = CUDIE (cu); - Dwarf_Attribute compdir, dwo_name; - /* It is fine if compdir doesn't exists, but then dwo_name needs -to be an absolute path. Also try relative path first. */ - dwarf_attr (&cudie, DW_AT_comp_dir, &compdir); - if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL - || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL) + Dwarf_Attribute dwo_name; + /* It is fine if dwo_dir doesn't exists, but then dwo_name needs +to be an absolute path. */ + if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL + || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL) { - const char *comp_dir = dwarf_formstring (&compdir); + /* First try the dwo file name in the same directory +as we found the skeleton file. */ const char *dwo_file = dwarf_formstring (&dwo_name); const char *debugdir = cu->dbg->debugdir; char *dwo_path = __libdw_filepath (debugdir, NULL, dwo_file); - if (dwo_path == NULL && comp_dir != NULL) - dwo_path = __libdw_filepath (debugdir, comp_dir, dwo_file); if (dwo_path != NULL) { - int split_fd = open (dwo_path, O_RDONLY); - if (split_fd != -1) + try_split_file (cu, dwo_path); + free (dwo_path); + } + + if (cu->split == (Dwarf_CU *) -1) + { + /* Try compdir plus dwo_name. */ + Dwarf_Attribute compdir; + dwarf_attr (&cudie, DW_AT_comp_dir, &compdir); + const char *dwo_dir = dwarf_formstring (&compdir); + if (dwo_dir != NULL) { - Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ); - if (split_dwarf != NULL) + dwo_path = __libdw_filepath (debugdir, dwo_dir, dwo_file); + if (dwo_path != NULL) { - Dwarf_CU *split = NULL; - while (dwarf_get_units (split_dwarf, split, &split, -
Re: [PATCH] readelf: Deal with combined normal and split dwarf DebugFission .debug_loc.
On Fri, 2018-06-01 at 02:51 +0200, Mark Wielaard wrote: > Normal and split dwarf from GNU DebugFission look the same, but should > be treated competely separtely. When having a file with both skeletons > and real compile units only note the secoffsets into the real .debug_loc > in readelf. Otherwise or known_locslistptr will get confused. > > Add a testfile that combines an normal -gdwarf-4 object with a > -gsplit-dwarf object. libdw already got this right, but add a > run-varlocs.sh test to make sure. Pushed to master.
Re: [PATCH] readelf: Fix .debug_types printing with implicit section_info.
On Fri, 2018-06-01 at 04:11 +0200, Mark Wielaard wrote: > Commit 314e9d7d "readelf: Handle .debug_info first if any other debug > section needs it" disabled section_info printing if it was already > handled. But section_types was an alias for section_info. So unless > section_info was explicitly printed, .debug_types wasn't. > > Make section_types its own thing to print .debug_types and make > section_info imply section_types. Add a testcase to make sure > .debug_types is now printed. Pushed to master.
Re: [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file.
On Fri, 2018-06-01 at 13:23 +0200, Mark Wielaard wrote: > We would give up if one of them failed. With this fixed a self-test with > make check succeeds when building elfutils itself with CFLAGS set to > "-gdwarf-4 -gdwarf-split -O2". Pushed to master.
elfutils 0.171 released
ELFUTILS 0.171 - http://elfutils.org/ A new release of elfutils is available at: ftp://sourceware.org/pub/elfutils/0.171/ or https://sourceware.org/elfutils/ftp/0.171/ * NEWS * DWARF5 and split dwarf, including GNU DebugFission, are supported now. Data can be read from the new DWARF sections .debug_addr, .debug_line_str, .debug_loclists, .debug_str_offsets and .debug_rnglists. Plus the new DWARF5 and GNU DebugFission encodings of the existing .debug sections. Also in split DWARF .dwo (DWARF object) files. This support is mostly handled by existing functions (dwarf_getlocation*, dwarf_getsrclines, dwarf_ranges, dwarf_form*, etc.) now returning the data from the new sections and data formats. But some new functions have been added to more easily get information about skeleton and split compile units (dwarf_get_units and dwarf_cu_info), handle new attribute data (dwarf_getabbrevattr_data) and to keep references to Dwarf_Dies that might come from different sections or files (dwarf_die_addr_die). Not yet supported are .dwp (Dwarf Package) and .sup (Dwarf Supplementary) files, the .debug_names index, the .debug_cu_index and .debug_tu_index sections. Only a single .debug_info (and .debug_types) section are currently handled. readelf: Handle all new DWARF5 sections. --debug-dump=info+ will show split unit DIEs when found. --dwarf-skeleton can be used when inspecting a .dwo file. Recognizes GNU locviews with --debug-dump=loc. libdw: New functions dwarf_die_addr_die, dwarf_get_units, dwarf_getabbrevattr_data and dwarf_cu_info. libdw will now try to resolve the alt file on first use of an alt attribute FORM when not set yet with dwarf_set_alt. dwarf_aggregate_size() now works with multi-dimensional arrays. libdwfl: Use process_vm_readv when available instead of ptrace. backends: Add a RISC-V backend. There were various improvements to build on Windows. The sha1 and md5 implementations have been removed, they weren't used. * GIT SHORTLOG * Andreas Schwab (3): libelf: Sync elf.h from glibc Add support for RISC-V backends: add checks for _GLOBAL_OFFSET_TABLE_ and __global_pointer$ on riscv Dima Kogan (1): libdw: dwarf_aggregate_size() works with multi-dimensional arrays Dmitry V. Levin (2): tests: robustify run-strip-nothing.sh against unstripped libc_nonshared.a elflint: fix typo in error diagnostics Joshua Watt (1): Use fallthrough attribute. Mark Wielaard (115): libelf: Sync elf.h from glibc. Internationalized messages should not contain the '\v' escape sequence. README: Add basic build instructions. ar: Check whether ar header values fit. libdw: Define LIBDW_CIE_ID and use it in dwarf_cfi_cie_p. libelf: Add ELF_E_INVALID_ELF error value. libelf: Don't error out when sanity checking e_shoff if scncnt is zero. libdwfl: When the kernel is found, but not the modules warn, don't fail. lib: Remove md5 and sha1 implementations. backends: Ignore GCC8 -Wpacked-not-aligned for m68k_corenote.c. config: files under /usr/lib/sysctl.d (_sysctldir) aren't %config. readelf: Handle DW_OP_GNU_variable_value. libdw: Update acceptable forms and attributes for dwarf_getlocation. libdw: Handle DW_OP_GNU_variable_value. tests: Add varlocs-self and exprlocs-self tests. tests: Fix cfi_debug => cfi_debug_bias typo in varlocs assert. readelf: Print DIE offset in attribute reading error messages. readelf: Print attribute name and form in error message. libdwfl: Don't dereference possibly unaligned auxv entry pointer from core. readelf: Adjust print_ops formatting. readelf: Print abbrev code for DIE with --debug-dump=info. readelf: Print actual file for decl_file and call_file attributes. readelf: Print CU, base address and unresolved .debug_range entries. readelf: Print CU, base address and unresolved .debug_loc entries. readelf: Hook up -g, --section-groups to display the section groups. readelf: Handle DW_OP_call2 and DW_OP_call4 correctly. libdw: dwarf_aggregate_size should not peel the given DIE. readelf: Try to continue after encountering bogus ELF Note data. libdw: Add explicit section index to struct Dwarf_CU. libdw: Check there is .debug_info/types section data in __libdw_offdie. readelf: Format offset as DIE index (hex). tests: Try to use coredumpctl to extract core files. readelf: Use dwarf_form_name for printing (unknown) forms. libdw: New get_uleb128_unchecked to use with already checked Dwarf_Abbrev. libdw: Reduce size of struct Dwarf_Abbrev. readelf: Fix crash on reading loc data or range data with bad/no CUs. tests: Check symtabshdr instead of symtabndx in elfstrmerge.c. libdw: Resolve alt file on first use. libdw: Add dwarf_die_addr_die function. Include sys/ptrace.h as early as possible. tests: Accept any core if no core with the "correct" pid can be found. libelf: Sync elf.h from glibc. libdw: Parse new DWARF5 units and CU DIEs. libdw: Add new dwarf_get_