Signed-off-by: Florian Weimer <[email protected]> --- libdw/ChangeLog | 12 +++++++++ libdw/Makefile.am | 3 ++- libdw/dwarf_begin_elf.c | 36 +++++++++++++-------------- libdw/dwarf_debugaltlink.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ libdw/libdw.h | 8 +++++- libdw/libdw.map | 5 ++++ libdw/libdwP.h | 4 ++- 7 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 libdw/dwarf_debugaltlink.c
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 1d9b9a3..581fc52 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,15 @@ +2014-04-10 Florian Weimer <[email protected]> + + * libdw.h (dwarf_debugaltlink): New function. + * libdwP.h (IDX_debug_info): Add IDX_gnu_debugaltlink. + (dwarf_debugaltlink): Internal declaration. + * Makefile.am (libdw_a_SOURCES): Add dwarf_debugaltlink.c. + * libdw.map (ELFUTILS_0.159): Export dwarf_debugaltlink. + * dwarf_debugaltlink.c: New file. + * dwarf_begin_elf.c (dwarf_scnnames): Add IDX_gnu_debugaltlink + element. + (check_section): Call open_debugaltlink. + 2014-03-03 Jan Kratochvil <[email protected]> Fix abort() on missing section headers. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index cd9e314..c40410d 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -87,7 +87,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_cfi_addrframe.c \ dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \ - dwarf_getlocation_die.c dwarf_getlocation_attr.c + dwarf_getlocation_die.c dwarf_getlocation_attr.c \ + dwarf_debugaltlink.c if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index 79daeac..a2bf245 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -1,5 +1,5 @@ /* Create descriptor from ELF descriptor for processing file. - Copyright (C) 2002-2011 Red Hat, Inc. + Copyright (C) 2002-2011, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <[email protected]>, 2002. @@ -54,7 +54,7 @@ /* Section names. */ -static const char dwarf_scnnames[IDX_last][17] = +static const char dwarf_scnnames[IDX_last][18] = { [IDX_debug_info] = ".debug_info", [IDX_debug_types] = ".debug_types", @@ -67,7 +67,8 @@ static const char dwarf_scnnames[IDX_last][17] = [IDX_debug_str] = ".debug_str", [IDX_debug_macinfo] = ".debug_macinfo", [IDX_debug_macro] = ".debug_macro", - [IDX_debug_ranges] = ".debug_ranges" + [IDX_debug_ranges] = ".debug_ranges", + [IDX_gnu_debugaltlink] = ".gnu_debugaltlink" }; #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0])) @@ -223,22 +224,6 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp) return NULL; } -#ifdef ENABLE_DWZ - /* For dwz multifile support, ignore if it looks wrong. */ - if (strcmp (scnname, ".gnu_debugaltlink") == 0) - { - Elf_Data *data = elf_getdata (scn, NULL); - if (data != NULL && data->d_size != 0) - { - const char *alt_name = data->d_buf; - const void *build_id = memchr (data->d_buf, '\0', data->d_size); - const int id_len = data->d_size - (build_id - data->d_buf + 1); - if (alt_name && build_id && id_len > 0) - return open_debugaltlink (result, alt_name, build_id + 1, id_len); - } - } -#endif /* ENABLE_DWZ */ - /* Recognize the various sections. Most names start with .debug_. */ size_t cnt; for (cnt = 0; cnt < ndwarf_scnnames; ++cnt) @@ -328,6 +313,19 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp) } #endif +#ifdef ENABLE_DWZ + /* For dwz multifile support, ignore if it looks wrong. */ + if (result->sectiondata[IDX_gnu_debugaltlink] != NULL) + { + const char *alt_name; + const void *build_id; + size_t id_len; + if (INTUSE (dwarf_debugaltlink) (result, &alt_name, &build_id, &id_len) + == 0) + return open_debugaltlink (result, alt_name, build_id, id_len); + } +#endif /* ENABLE_DWZ */ + return result; } diff --git a/libdw/dwarf_debugaltlink.c b/libdw/dwarf_debugaltlink.c new file mode 100644 index 0000000..2d0b68c --- /dev/null +++ b/libdw/dwarf_debugaltlink.c @@ -0,0 +1,61 @@ +/* Create descriptor from ELF descriptor for processing file. + Copyright (C) 2012, 2014 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> + +#include "libdwP.h" + +int dwarf_debugaltlink (Dwarf *dwarf, + const char **alt_name, + const void **build_id, + size_t *build_id_len) +{ + Elf_Data *data = dwarf->sectiondata[IDX_gnu_debugaltlink]; + if (data == NULL) + { + __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK); + return -1; + } + + const void *ptr = memchr (data->d_buf, '\0', data->d_size); + if (ptr == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_ELF); + return -1; + } + *alt_name = data->d_buf; + *build_id = ptr + 1; + *build_id_len = data->d_size - (ptr - data->d_buf + 1); + return 0; +} + +INTDEF (dwarf_debugaltlink) diff --git a/libdw/libdw.h b/libdw/libdw.h index 0d94c52..2682989 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -1,5 +1,5 @@ /* Interfaces for libdw. - Copyright (C) 2002-2010, 2013 Red Hat, Inc. + Copyright (C) 2002-2010, 2013, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -267,6 +267,12 @@ extern int dwarf_end (Dwarf *dwarf); /* Get the data block for the .debug_info section. */ extern Elf_Data *dwarf_getscn_info (Dwarf *dwarf); +/* Get the data from the .gnu_debugaltlink section. */ +extern int dwarf_debugaltlink (Dwarf *dwarf, + const char **alt_name, + const void **build_id, + size_t *build_id_len); + /* Read the header for the DWARF CU. */ extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, size_t *header_sizep, Dwarf_Off *abbrev_offsetp, diff --git a/libdw/libdw.map b/libdw/libdw.map index d0e4731..92605d0 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -292,3 +292,8 @@ ELFUTILS_0.158 { dwfl_core_file_attach; dwfl_linux_proc_attach; } ELFUTILS_0.157; + +ELFUTILS_0.159 { + global: + dwarf_debugaltlink; +} ELFUTILS_0.158; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 4939200..28d6260 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -1,5 +1,5 @@ /* Internal definitions for libdwarf. - Copyright (C) 2002-2011, 2013 Red Hat, Inc. + Copyright (C) 2002-2011, 2013, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <[email protected]>, 2002. @@ -74,6 +74,7 @@ enum IDX_debug_macinfo, IDX_debug_macro, IDX_debug_ranges, + IDX_gnu_debugaltlink, IDX_last }; @@ -676,6 +677,7 @@ INTDECL (dwarf_begin_elf) INTDECL (dwarf_child) INTDECL (dwarf_dieoffset) INTDECL (dwarf_diename) +INTDECL (dwarf_debugaltlink) INTDECL (dwarf_end) INTDECL (dwarf_entrypc) INTDECL (dwarf_errmsg) -- 1.9.0
