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 <jan.kratochvil(a)redhat.com>
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 <jan.kratochvil(a)redhat.com>
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 <drepper(a)redhat.com>, 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;
+}