Hi,
jankratochvil/compatversion-baseaddpvaddr
follow-up/repost of: [patch 1/4] unwinder: New base address based dwfl_report_elf_baseaddr https://lists.fedorahosted.org/pipermail/elfutils-devel/2013-March/002977.ht... Message-ID: 20130317160910.GA2731@host2.jankratochvil.net
Implemented the suggestions.
The only "dangerous" change is in linux-kernel-modules.c where the new parameter is passed incompatibly as 'false' which seems more logical to me. But it is ignored anyway as kernel modules are (unfortunately) never ET_DYN.
Thanks, Jan
commit 784b53a1a4b832e27c2e590bddb99393a61edff9 Author: Jan Kratochvil jan.kratochvil@redhat.com Date: Sun Apr 28 19:55:48 2013 +0200
Add parameter add_p_vaddr to dwfl_report_elf.
libdwfl/ * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. Set it to true for ET_EXEC and ET_CORE. Provide alternative setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add NEW_VERSION. (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with COMPAT_VERSION. * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for dwfl_report_elf. * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
tests/ * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
Signed-off-by: Jan Kratochvil jan.kratochvil@redhat.com
diff --git a/ChangeLog b/ChangeLog index 1fdcb58..bffe62d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * NEWS (Version 0.156): New. + 2013-04-26 Mark Wielaard mjw@redhat.com
* configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests. diff --git a/NEWS b/NEWS index e38e60c..a71a87c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 0.156 + +libdwfl: dwfl_report_elf has new parameter add_p_vaddr. + Version 0.155
libelf: elf*_xlatetomd now works for cross-endian ELF note data. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b4d9dc3..ef9b3ac 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * libdw.map (ELFUTILS_0.156): New. + 2013-04-24 Mark Wielaard mjw@redhat.com
* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. diff --git a/libdw/libdw.map b/libdw/libdw.map index 1f71d03..d38a8ef 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -254,3 +254,9 @@ ELFUTILS_0.149 {
dwfl_dwarf_line; } ELFUTILS_0.148; + +ELFUTILS_0.156 { + global: + # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr. + dwfl_report_elf; +} ELFUTILS_0.149; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index c1a42d8..912064e 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,5 +1,21 @@ 2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com
+ * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. + Set it to true for ET_EXEC and ET_CORE. Provide alternative + setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. + (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add + NEW_VERSION. + (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with + COMPAT_VERSION. + * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. + * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. + * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. + * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for + dwfl_report_elf. + * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf. + +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + * dwfl_module_build_id.c: Use COMPAT_VERSION_SAMEPROTO instead of COMPAT_VERSION.
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c index d706170..1881803 100644 --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@ -41,7 +41,8 @@ Dwfl_Module * internal_function __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, - int fd, Elf *elf, GElf_Addr base, bool sanity) + int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr, + bool sanity) { GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); if (ehdr == NULL) @@ -166,6 +167,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, case ET_CORE: /* An assigned base address is meaningless for these. */ base = 0; + add_p_vaddr = true;
case ET_DYN: default:; @@ -181,11 +183,19 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, { vaddr = ph->p_vaddr & -ph->p_align; address_sync = ph->p_vaddr + ph->p_memsz; - start = base + vaddr; break; } } - bias = base; + if (add_p_vaddr) + { + start = base + vaddr; + bias = base; + } + else + { + start = base; + bias = base - vaddr; + }
for (size_t i = phnum; i-- > 0;) { @@ -195,7 +205,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, if (ph->p_type == PT_LOAD && ph->p_vaddr + ph->p_memsz > 0) { - end = base + (ph->p_vaddr + ph->p_memsz); + end = bias + (ph->p_vaddr + ph->p_memsz); break; } } @@ -246,8 +256,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, }
Dwfl_Module * -dwfl_report_elf (Dwfl *dwfl, const char *name, - const char *file_name, int fd, GElf_Addr base) +dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, + GElf_Addr base, bool add_p_vaddr) { bool closefd = false; if (fd < 0) @@ -270,7 +280,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, }
Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, - fd, elf, base, true); + fd, elf, base, add_p_vaddr, true); if (mod == NULL) { elf_end (elf); @@ -281,3 +291,16 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, return mod; } INTDEF (dwfl_report_elf) +NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156) + +#ifdef SHARED +COMPAT_VERSION (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr) + +Dwfl_Module * +_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base) +{ + return dwfl_report_elf (dwfl, name, file_name, fd, base, true); +} +#endif diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 000d582..572520d 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -141,10 +141,14 @@ extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, program headers in the given file, plus BASE. For an ET_REL file, does a simple absolute section layout starting at BASE. FD may be -1 to open FILE_NAME. On success, FD is consumed by the - library, and the `find_elf' callback will not be used for this module. */ + library, and the `find_elf' callback will not be used for this module. + ADD_P_VADDR has meaning only for ET_DYN files. With ADD_P_VADDR true BASE + then specifies in-memory address with subtracted on-disk file prelinked base + address (such as the GNU C library l_addr field). With ADD_P_VADDR false + BASE is in-memory absolute address start for any relocatable ELF type. */ extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - GElf_Addr base); + GElf_Addr base, bool add_p_vaddr);
/* Similar, but report the module for offline use. All ET_EXEC files being reported must be reported before any relocatable objects. diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 5aaa778..37a9dff 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -382,7 +382,8 @@ extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; Consumes ELF on success, not on failure. */ extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - Elf *elf, GElf_Addr base, bool sanity) + Elf *elf, GElf_Addr base, + bool add_p_vaddr, bool sanity) internal_function;
/* Meat of dwfl_report_offline. */ diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index c6ec29c..9f1b867 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -384,7 +384,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
// XXX hook for sysroot mod = INTUSE(dwfl_report_elf) (dwfl, basename (name), - name, -1, l_addr); + name, -1, l_addr, true); }
if (mod != NULL) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 9bf5f25..dec1a59 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -217,7 +217,7 @@ report_kernel (Dwfl *dwfl, const char **release, if (report) { Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME, - fname, fd, 0); + fname, fd, 0, false); if (mod == NULL) result = -1; else diff --git a/libdwfl/offline.c b/libdwfl/offline.c index 26a6bd6..28d2782 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -127,7 +127,8 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, Elf *elf) { Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, - dwfl->offline_next_address, false); + dwfl->offline_next_address, true, + false); if (mod != NULL) { /* If this is an ET_EXEC file with fixed addresses, the address range diff --git a/tests/ChangeLog b/tests/ChangeLog index e6722da..495926d 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf. + 2013-04-27 Mark Wielaard mjw@redhat.com
* update1.c (main): Use unique tempfile name and unlink file. diff --git a/tests/dwfl-report-elf-align.c b/tests/dwfl-report-elf-align.c index 0e8bfe3..a4e97d3 100644 --- a/tests/dwfl-report-elf-align.c +++ b/tests/dwfl-report-elf-align.c @@ -53,7 +53,7 @@ main (int argc, char **argv) uintptr_t base = strtoull (argv[2], &endptr, 0); assert (endptr && !*endptr);
- Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base); + Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base, false); assert (mod != NULL);
uintptr_t funcaddr = strtoull (argv[3], &endptr, 0);
Hi,
jankratochvil/compatversion-baseaddpvaddr
patch rebase.
Jan
commit 2ecbc7f264d2956e5f93f49dba2b8aba482b989f Author: Jan Kratochvil jan.kratochvil@redhat.com Date: Tue Apr 30 14:27:16 2013 +0200
Add parameter add_p_vaddr to dwfl_report_elf.
libdwfl/ * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. Set it to true for ET_EXEC and ET_CORE. Provide alternative setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add NEW_VERSION. (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with COMPAT_VERSION. * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for dwfl_report_elf. * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
tests/ * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
Signed-off-by: Jan Kratochvil jan.kratochvil@redhat.com
diff --git a/ChangeLog b/ChangeLog index 1fdcb58..bffe62d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * NEWS (Version 0.156): New. + 2013-04-26 Mark Wielaard mjw@redhat.com
* configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests. diff --git a/NEWS b/NEWS index e38e60c..a71a87c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 0.156 + +libdwfl: dwfl_report_elf has new parameter add_p_vaddr. + Version 0.155
libelf: elf*_xlatetomd now works for cross-endian ELF note data. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b4d9dc3..ef9b3ac 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * libdw.map (ELFUTILS_0.156): New. + 2013-04-24 Mark Wielaard mjw@redhat.com
* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. diff --git a/libdw/libdw.map b/libdw/libdw.map index 1f71d03..d38a8ef 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -254,3 +254,9 @@ ELFUTILS_0.149 {
dwfl_dwarf_line; } ELFUTILS_0.148; + +ELFUTILS_0.156 { + global: + # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr. + dwfl_report_elf; +} ELFUTILS_0.149; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 42f720c..74ede01 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,19 @@ +2013-04-30 Jan Kratochvil jan.kratochvil@redhat.com + + * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. + Set it to true for ET_EXEC and ET_CORE. Provide alternative + setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. + (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add + NEW_VERSION. + (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with + COMPAT_VERSION. + * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. + * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. + * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. + * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for + dwfl_report_elf. + * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf. + 2013-04-27 Mark Wielaard mjw@redhat.com
* link_map.c: #include system.h. diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c index d706170..20d04da 100644 --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@ -41,7 +41,8 @@ Dwfl_Module * internal_function __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, - int fd, Elf *elf, GElf_Addr base, bool sanity) + int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr, + bool sanity) { GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); if (ehdr == NULL) @@ -166,6 +167,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, case ET_CORE: /* An assigned base address is meaningless for these. */ base = 0; + add_p_vaddr = true;
case ET_DYN: default:; @@ -181,11 +183,19 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, { vaddr = ph->p_vaddr & -ph->p_align; address_sync = ph->p_vaddr + ph->p_memsz; - start = base + vaddr; break; } } - bias = base; + if (add_p_vaddr) + { + start = base + vaddr; + bias = base; + } + else + { + start = base; + bias = base - vaddr; + }
for (size_t i = phnum; i-- > 0;) { @@ -195,7 +205,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, if (ph->p_type == PT_LOAD && ph->p_vaddr + ph->p_memsz > 0) { - end = base + (ph->p_vaddr + ph->p_memsz); + end = bias + (ph->p_vaddr + ph->p_memsz); break; } } @@ -246,8 +256,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, }
Dwfl_Module * -dwfl_report_elf (Dwfl *dwfl, const char *name, - const char *file_name, int fd, GElf_Addr base) +dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, + GElf_Addr base, bool add_p_vaddr) { bool closefd = false; if (fd < 0) @@ -270,7 +280,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, }
Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, - fd, elf, base, true); + fd, elf, base, add_p_vaddr, true); if (mod == NULL) { elf_end (elf); @@ -281,3 +291,20 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, return mod; } INTDEF (dwfl_report_elf) +NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156) + +#ifdef SHARED +Dwfl_Module * + _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base); +COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr) + +Dwfl_Module * +_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base) +{ + return dwfl_report_elf (dwfl, name, file_name, fd, base, true); +} +#endif diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 000d582..572520d 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -141,10 +141,14 @@ extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, program headers in the given file, plus BASE. For an ET_REL file, does a simple absolute section layout starting at BASE. FD may be -1 to open FILE_NAME. On success, FD is consumed by the - library, and the `find_elf' callback will not be used for this module. */ + library, and the `find_elf' callback will not be used for this module. + ADD_P_VADDR has meaning only for ET_DYN files. With ADD_P_VADDR true BASE + then specifies in-memory address with subtracted on-disk file prelinked base + address (such as the GNU C library l_addr field). With ADD_P_VADDR false + BASE is in-memory absolute address start for any relocatable ELF type. */ extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - GElf_Addr base); + GElf_Addr base, bool add_p_vaddr);
/* Similar, but report the module for offline use. All ET_EXEC files being reported must be reported before any relocatable objects. diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 5aaa778..37a9dff 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -382,7 +382,8 @@ extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; Consumes ELF on success, not on failure. */ extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - Elf *elf, GElf_Addr base, bool sanity) + Elf *elf, GElf_Addr base, + bool add_p_vaddr, bool sanity) internal_function;
/* Meat of dwfl_report_offline. */ diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index c6ec29c..9f1b867 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -384,7 +384,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
// XXX hook for sysroot mod = INTUSE(dwfl_report_elf) (dwfl, basename (name), - name, -1, l_addr); + name, -1, l_addr, true); }
if (mod != NULL) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 9bf5f25..dec1a59 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -217,7 +217,7 @@ report_kernel (Dwfl *dwfl, const char **release, if (report) { Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME, - fname, fd, 0); + fname, fd, 0, false); if (mod == NULL) result = -1; else diff --git a/libdwfl/offline.c b/libdwfl/offline.c index 26a6bd6..28d2782 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -127,7 +127,8 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, Elf *elf) { Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, - dwfl->offline_next_address, false); + dwfl->offline_next_address, true, + false); if (mod != NULL) { /* If this is an ET_EXEC file with fixed addresses, the address range diff --git a/tests/ChangeLog b/tests/ChangeLog index f6c004c..4003851 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2013-04-30 Jan Kratochvil jan.kratochvil@redhat.com + + * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf. + 2013-04-29 Mark Wielaard mjw@redhat.com
* test-subr.sh: Don't use pushd, just cd into test-dir. diff --git a/tests/dwfl-report-elf-align.c b/tests/dwfl-report-elf-align.c index 0e8bfe3..a4e97d3 100644 --- a/tests/dwfl-report-elf-align.c +++ b/tests/dwfl-report-elf-align.c @@ -53,7 +53,7 @@ main (int argc, char **argv) uintptr_t base = strtoull (argv[2], &endptr, 0); assert (endptr && !*endptr);
- Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base); + Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base, false); assert (mod != NULL);
uintptr_t funcaddr = strtoull (argv[3], &endptr, 0);
On Tue, 2013-04-30 at 14:38 +0200, Jan Kratochvil wrote:
jankratochvil/compatversion-baseaddpvaddr
commit 2ecbc7f264d2956e5f93f49dba2b8aba482b989f Author: Jan Kratochvil jan.kratochvil@redhat.com Date: Tue Apr 30 14:27:16 2013 +0200
Add parameter add_p_vaddr to dwfl_report_elf. libdwfl/ * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. Set it to true for ET_EXEC and ET_CORE. Provide alternative setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add NEW_VERSION. (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with COMPAT_VERSION. * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for dwfl_report_elf. * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf. tests/ * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf. Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
This looks good to me. One tiny comment on the new documentation:
- ADD_P_VADDR has meaning only for ET_DYN files. With ADD_P_VADDR true BASE
- then specifies in-memory address with subtracted on-disk file prelinked base
- address (such as the GNU C library l_addr field). With ADD_P_VADDR false
- BASE is in-memory absolute address start for any relocatable ELF type. */
extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
GElf_Addr base);
GElf_Addr base, bool add_p_vaddr);
I would reword it as follows:
"For ET_EXEC and ET_CORE files BASE and ADD_P_VADDR will be ignored. ADD_P_VADDR is only used for ET_DYN files. When ADD_P_VADDR is true the module start address is calculated by taking the ELF phdr p_vaddr into account (which might have been set when the shared library was prelinked). When ADD_P_VADDR is false the module start address will be equal to BASE for any relocatable ELF type."
But that is mostly because that seems to be what we actually do in the code. The reference to l_addr might be confusing since the comments in link.h were wrong till very recently (when you fixed them).
Feel free to ignore me though if you think your description is more accurate.
Thanks,
Mark
On Wed, 01 May 2013 16:32:50 +0200, Mark Wielaard wrote:
"For ET_EXEC and ET_CORE files BASE and ADD_P_VADDR will be ignored. ADD_P_VADDR is only used for ET_DYN files. When ADD_P_VADDR is true the module start address is calculated by taking the ELF phdr p_vaddr into account (which might have been set when the shared library was prelinked). When ADD_P_VADDR is false the module start address will be equal to BASE for any relocatable ELF type."
While your paragraph is definitely better it is all too complicated. What about:
ADD_P_VADDR BASE ET_EXEC ignored ignored ET_DYN false absolute address where to place the file true start address relative to ELF's phdr p_vaddr ET_REL ignored absolute address where to place the file ET_CORE ignored ignored
ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library has been prelinked by tool prelink(8).
The reference to l_addr might be confusing since the comments in link.h were wrong till very recently (when you fixed them).
True.
OK this way?
Thanks, Jan
On Thu, May 02, 2013 at 05:11:13PM +0200, Jan Kratochvil wrote:
While your paragraph is definitely better it is all too complicated. What about:
ADD_P_VADDR BASE
ET_EXEC ignored ignored ET_DYN false absolute address where to place the file true start address relative to ELF's phdr p_vaddr ET_REL ignored absolute address where to place the file ET_CORE ignored ignored
ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library has been prelinked by tool prelink(8).
Nice idea. A table is much clearer than trying to describe it all in "readable" English sentences.
OK this way?
Yes, I like it.
Thanks,
Mark
jankratochvil/compatversion-baseaddpvaddr
On Fri, 03 May 2013 09:43:14 +0200, Mark Wielaard wrote:
Nice idea. A table is much clearer than trying to describe it all in "readable" English sentences.
Sorry for not posting a real patch before, is this comment form OK?
Thanks, Jan
commit 904aec2c2f62b729a536c2259274fdd440b0d923 Author: Jan Kratochvil jan.kratochvil@redhat.com Date: Tue Apr 30 14:27:16 2013 +0200
Add parameter add_p_vaddr to dwfl_report_elf.
libdwfl/ * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. Set it to true for ET_EXEC and ET_CORE. Provide alternative setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add NEW_VERSION. (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with COMPAT_VERSION. * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for dwfl_report_elf. * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
tests/ * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
Signed-off-by: Jan Kratochvil jan.kratochvil@redhat.com
diff --git a/ChangeLog b/ChangeLog index 1fdcb58..bffe62d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * NEWS (Version 0.156): New. + 2013-04-26 Mark Wielaard mjw@redhat.com
* configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests. diff --git a/NEWS b/NEWS index e38e60c..a71a87c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 0.156 + +libdwfl: dwfl_report_elf has new parameter add_p_vaddr. + Version 0.155
libelf: elf*_xlatetomd now works for cross-endian ELF note data. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b4d9dc3..ef9b3ac 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Jan Kratochvil jan.kratochvil@redhat.com + + * libdw.map (ELFUTILS_0.156): New. + 2013-04-24 Mark Wielaard mjw@redhat.com
* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES. diff --git a/libdw/libdw.map b/libdw/libdw.map index 1f71d03..d38a8ef 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -254,3 +254,9 @@ ELFUTILS_0.149 {
dwfl_dwarf_line; } ELFUTILS_0.148; + +ELFUTILS_0.156 { + global: + # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr. + dwfl_report_elf; +} ELFUTILS_0.149; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 42f720c..74ede01 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,19 @@ +2013-04-30 Jan Kratochvil jan.kratochvil@redhat.com + + * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr. + Set it to true for ET_EXEC and ET_CORE. Provide alternative + setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE. + (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add + NEW_VERSION. + (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with + COMPAT_VERSION. + * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it. + * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr. + * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf. + * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for + dwfl_report_elf. + * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf. + 2013-04-27 Mark Wielaard mjw@redhat.com
* link_map.c: #include system.h. diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c index d706170..20d04da 100644 --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@ -41,7 +41,8 @@ Dwfl_Module * internal_function __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, - int fd, Elf *elf, GElf_Addr base, bool sanity) + int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr, + bool sanity) { GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem); if (ehdr == NULL) @@ -166,6 +167,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, case ET_CORE: /* An assigned base address is meaningless for these. */ base = 0; + add_p_vaddr = true;
case ET_DYN: default:; @@ -181,11 +183,19 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, { vaddr = ph->p_vaddr & -ph->p_align; address_sync = ph->p_vaddr + ph->p_memsz; - start = base + vaddr; break; } } - bias = base; + if (add_p_vaddr) + { + start = base + vaddr; + bias = base; + } + else + { + start = base; + bias = base - vaddr; + }
for (size_t i = phnum; i-- > 0;) { @@ -195,7 +205,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, if (ph->p_type == PT_LOAD && ph->p_vaddr + ph->p_memsz > 0) { - end = base + (ph->p_vaddr + ph->p_memsz); + end = bias + (ph->p_vaddr + ph->p_memsz); break; } } @@ -246,8 +256,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, }
Dwfl_Module * -dwfl_report_elf (Dwfl *dwfl, const char *name, - const char *file_name, int fd, GElf_Addr base) +dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, + GElf_Addr base, bool add_p_vaddr) { bool closefd = false; if (fd < 0) @@ -270,7 +280,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, }
Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, - fd, elf, base, true); + fd, elf, base, add_p_vaddr, true); if (mod == NULL) { elf_end (elf); @@ -281,3 +291,20 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, return mod; } INTDEF (dwfl_report_elf) +NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156) + +#ifdef SHARED +Dwfl_Module * + _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base); +COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr) + +Dwfl_Module * +_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base) +{ + return dwfl_report_elf (dwfl, name, file_name, fd, base, true); +} +#endif diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 000d582..2b70e28 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -137,14 +137,21 @@ extern int dwfl_report_segment (Dwfl *dwfl, int ndx, extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, Dwarf_Addr start, Dwarf_Addr end);
-/* Report a module with start and end addresses computed from the ELF - program headers in the given file, plus BASE. For an ET_REL file, - does a simple absolute section layout starting at BASE. +/* Report a module to address BASE with start and end addresses computed + from the ELF program headers in the given file - see the table below. FD may be -1 to open FILE_NAME. On success, FD is consumed by the - library, and the `find_elf' callback will not be used for this module. */ + library, and the `find_elf' callback will not be used for this module. + ADD_P_VADDR BASE + ET_EXEC ignored ignored + ET_DYN false absolute address where to place the file + true start address relative to ELF's phdr p_vaddr + ET_REL ignored absolute address where to place the file + ET_CORE ignored ignored + ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library + has been prelinked by tool prelink(8). */ extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - GElf_Addr base); + GElf_Addr base, bool add_p_vaddr);
/* Similar, but report the module for offline use. All ET_EXEC files being reported must be reported before any relocatable objects. diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 5aaa778..37a9dff 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -382,7 +382,8 @@ extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; Consumes ELF on success, not on failure. */ extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - Elf *elf, GElf_Addr base, bool sanity) + Elf *elf, GElf_Addr base, + bool add_p_vaddr, bool sanity) internal_function;
/* Meat of dwfl_report_offline. */ diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index c6ec29c..9f1b867 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -384,7 +384,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
// XXX hook for sysroot mod = INTUSE(dwfl_report_elf) (dwfl, basename (name), - name, -1, l_addr); + name, -1, l_addr, true); }
if (mod != NULL) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 9bf5f25..dec1a59 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -217,7 +217,7 @@ report_kernel (Dwfl *dwfl, const char **release, if (report) { Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME, - fname, fd, 0); + fname, fd, 0, false); if (mod == NULL) result = -1; else diff --git a/libdwfl/offline.c b/libdwfl/offline.c index 26a6bd6..28d2782 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -127,7 +127,8 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, Elf *elf) { Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, - dwfl->offline_next_address, false); + dwfl->offline_next_address, true, + false); if (mod != NULL) { /* If this is an ET_EXEC file with fixed addresses, the address range diff --git a/tests/ChangeLog b/tests/ChangeLog index f6c004c..4003851 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2013-04-30 Jan Kratochvil jan.kratochvil@redhat.com + + * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf. + 2013-04-29 Mark Wielaard mjw@redhat.com
* test-subr.sh: Don't use pushd, just cd into test-dir. diff --git a/tests/dwfl-report-elf-align.c b/tests/dwfl-report-elf-align.c index 0e8bfe3..a4e97d3 100644 --- a/tests/dwfl-report-elf-align.c +++ b/tests/dwfl-report-elf-align.c @@ -53,7 +53,7 @@ main (int argc, char **argv) uintptr_t base = strtoull (argv[2], &endptr, 0); assert (endptr && !*endptr);
- Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base); + Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base, false); assert (mod != NULL);
uintptr_t funcaddr = strtoull (argv[3], &endptr, 0);
On Sun, May 05, 2013 at 07:10:06PM +0200, Jan Kratochvil wrote:
jankratochvil/compatversion-baseaddpvaddr
On Fri, 03 May 2013 09:43:14 +0200, Mark Wielaard wrote:
Nice idea. A table is much clearer than trying to describe it all in "readable" English sentences.
Sorry for not posting a real patch before, is this comment form OK?
Yes.
Thanks,
Mark
elfutils-devel@lists.fedorahosted.org