Hi Mark, jankratochvil/scnfindvma
On Wed, 13 Nov 2013 13:03:21 +0100, Mark Wielaard wrote: > There are other implementation of libelf and gelf and we should try to > keep them somewhat compatible. OK, I didn't realize that. OK this way? Thanks, Jan
Provide __libdwfl_scnfindvma libdwfl/ 2013-11-13 Jan Kratochvil <[email protected]> Provide __libdwfl_scnfindvma. * Makefile.am (libdwfl_a_SOURCES): Add scnfindvma.c. * dwfl_module_addrsym.c (dwfl_module_addrsym) (same_section): Call __libdwfl_scnfindvma where is the code from here moved out. * libdwflP.h (__libdwfl_scnfindvma): New declaration. * scnfindvma.c: New file. Signed-off-by: Jan Kratochvil <[email protected]> diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am index ce590da..a20d951 100644 --- a/libdwfl/Makefile.am +++ b/libdwfl/Makefile.am @@ -70,7 +70,8 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \ dwfl_segment_report_module.c \ link_map.c core-file.c open.c image-header.c \ dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \ - linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c + linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \ + scnfindvma.c if ZLIB libdwfl_a_SOURCES += gzip.c diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c index d9eb0a2..5e46608 100644 --- a/libdwfl/dwfl_module_addrsym.c +++ b/libdwfl/dwfl_module_addrsym.c @@ -53,21 +53,9 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, if (addr_shndx == SHN_UNDEF || addr_symfile != symfile) { GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symfile, addr); - Elf_Scn *scn = NULL; - addr_shndx = SHN_ABS; + Elf_Scn *scn = __libdwfl_scnfindvma (symfile->elf, mod_addr); + addr_shndx = scn == NULL ? SHN_ABS : elf_ndxscn (scn); addr_symfile = symfile; - while ((scn = elf_nextscn (symfile->elf, scn)) != NULL) - { - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - if (likely (shdr != NULL) - && mod_addr >= shdr->sh_addr - && mod_addr < shdr->sh_addr + shdr->sh_size) - { - addr_shndx = elf_ndxscn (scn); - break; - } - } } return shndx == addr_shndx && addr_symfile == symfile; diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 0c862b3..ffe5752 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -531,6 +531,10 @@ extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start) extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end) internal_function; +/* Get section containing VMA address. Return NULL otherwise. */ +extern Elf_Scn *__libdwfl_scnfindvma (Elf *elf, GElf_Addr vma) + internal_function; + /* Decompression wrappers: decompress whole file into memory. */ extern Dwfl_Error __libdw_gunzip (int fd, off64_t start_offset, void *mapped, size_t mapped_size, diff --git a/libdwfl/scnfindvma.c b/libdwfl/scnfindvma.c new file mode 100644 index 0000000..8db2e85 --- /dev/null +++ b/libdwfl/scnfindvma.c @@ -0,0 +1,47 @@ +/* Get section containing VMA address. Return NULL otherwise. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + Contributed by Ulrich Drepper <[email protected]>, 1998. + + 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/>. */ + +#include "libdwflP.h" + +Elf_Scn * +internal_function +__libdwfl_scnfindvma (Elf *elf, GElf_Addr vma) +{ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (likely (shdr != NULL) + && vma >= shdr->sh_addr + && vma < shdr->sh_addr + shdr->sh_size) + break; + } + return scn; +}
