Re: Openwrt porting
On 2023-12-24 07:12, taehee Park wrote: I think elfutils is very useful in debugging. But i cant use this in openwrt package. Because only library is built and utility like eu-stack or eu-readelf not built Could someone help thus? I don't know anything about openwrt, but quickly looking at the source code, it has a patch to suppress building the binaries which does this: package/libs/elfutils/patches/005-build_only_libs.patch: SUBDIRS = config lib libelf libcpu backends libebl libdwelf libdwfl libdw \ - libasm debuginfod src po doc tests + libasm You could try removing that patch, and then updating the install stanza to also include the binaries: https://github.com/openwrt/openwrt/blob/3e738781a9712eaa81d5af0ecc8b55cbfe480c68/package/libs/elfutils/Makefile#L95
dwfl_link_map_report() on a core file with sysroot? Opens the wrong solibs?
I'm trying to get callstacks out of a core file using libdwfl where the ELF files live in a sysroot (and are from a different architecture, ARM). I'm possibly doing something stupid as I find that dwfl_link_map_report() opens /lib/libpthread.so on the *host* rather than the libpthread.so from my sysroot. It obviously doesn't then get very far. I called elf_begin(), dwfl_begin() and then dwfl_core_file_report(), passing in the path to the executable (in the sysroot). There's a comment in link_map.c around line 390 which says: // XXX hook for sysroot So inspired by this, I hacked in some code to open files relative to my sysroot and it all started working. Am I just missing some obvious setup, or is this just missing sysroot support? Thanks! Luke
Re: dwfl_link_map_report() on a core file with sysroot? Opens the wrong solibs?
On Thu, 13 Dec 2018 at 22:37, Roland McGrath wrote: > > I think it's just missing. The hardest part is just deciding how the > configuration should work. Thanks. My current attempt adds a new function call, dwfl_set_sysroot(), which works, but feels a bit clunky. I might see if I can just use the find_elf callback instead. > > On Thu, Dec 13, 2018, 12:27 Luke Diamand > >> I'm trying to get callstacks out of a core file using libdwfl where >> the ELF files live in a sysroot (and are from a different >> architecture, ARM). >> >> I'm possibly doing something stupid as I find that >> dwfl_link_map_report() opens /lib/libpthread.so on the *host* rather >> than the libpthread.so from my sysroot. It obviously doesn't then get >> very far. >> >> I called elf_begin(), dwfl_begin() and then dwfl_core_file_report(), >> passing in the path to the executable (in the sysroot). >> >> There's a comment in link_map.c around line 390 which says: >> >> // XXX hook for sysroot >> >> So inspired by this, I hacked in some code to open files relative to >> my sysroot and it all started working. >> >> Am I just missing some obvious setup, or is this just missing sysroot >> support? >> >> Thanks! >> Luke >> > -- > > > Thanks, > Roland
Re: dwfl_link_map_report() on a core file with sysroot? Opens the wrong solibs?
On Sun, 6 Jan 2019 at 21:04, Mark Wielaard wrote: > > On Fri, Dec 14, 2018 at 01:44:17PM +, Luke Diamand wrote: > > On Thu, 13 Dec 2018 at 22:37, Roland McGrath wrote: > > > > > > I think it's just missing. The hardest part is just deciding how the > > > configuration should work. > > > > Thanks. My current attempt adds a new function call, > > dwfl_set_sysroot(), which works, but feels a bit clunky. I might see > > if I can just use the find_elf callback instead. > > If you got this working please let us know. > It might help others and/or deciding how to add a proper > interface/config/hook for it. > I have a fix which I think does the right thing - I've been playing around with core files from a Raspberry Pi and analysing them on a Linux x86 PC using eu-stack. Christmas and New Year intervened but I hope to submit something once I've recovered from that. Thanks! Luke
[PATCHv1 1/2] libdwfl: specify optional sysroot to search for shared libraries
When searching the list of modules in a core file, if the core was generated on a different system to the current one, we need to look in a sysroot for the various shared objects. For example, we might be looking at a core file from an ARM system using elfutils running on an x86 host. This change adds a new function, dwfl_set_sysroot(), which then gets used when searching for libraries. Signed-off-by: Luke Diamand --- libdw/libdw.map| 7 ++- libdwfl/libdwfl.h | 5 + libdwfl/libdwflP.h | 1 + libdwfl/link_map.c | 25 +++-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/libdw/libdw.map b/libdw/libdw.map index 55482d58..43a9de2e 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -360,4 +360,9 @@ ELFUTILS_0.173 { ELFUTILS_0.175 { global: dwelf_elf_begin; -} ELFUTILS_0.173; \ No newline at end of file +} ELFUTILS_0.173; + +ELFUTILS_0.176 { + global: +dwfl_set_sysroot; +} ELFUTILS_0.175; diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index a0c1d357..c11e2f24 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -807,6 +807,11 @@ int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid, bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation) __nonnull_attribute__ (1, 2); +/* Set the sysroot to use when searching for shared libraries. If not + specified, search in the system root. */ +void dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot) + __nonnull_attribute__ (1); + #ifdef __cplusplus } #endif diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 941a8b66..993a0e7c 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -138,6 +138,7 @@ struct Dwfl int lookup_tail_ndx; struct Dwfl_User_Core *user_core; + const char *sysroot; /* sysroot, or NULL to search standard system paths */ }; #define OFFLINE_REDZONE0x1 diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 29307c74..0fae680d 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -388,8 +388,21 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, if (name != NULL) { /* This code is mostly inlined dwfl_report_elf. */ - // XXX hook for sysroot - int fd = open (name, O_RDONLY); + char *path_name; + const char *sysroot = dwfl->sysroot; + int rc; + + /* don't look in the sysroot if the path is already inside the sysroot */ + bool name_in_sysroot = strncmp(name, sysroot, strlen(sysroot)) == 0; + + if (!name_in_sysroot && sysroot) + rc = asprintf(&path_name, "%s/%s", sysroot, name); + else + rc = asprintf(&path_name, "%s", name); + if (unlikely(rc == -1)) + return release_buffer(-1); + + int fd = open (path_name, O_RDONLY); if (fd >= 0) { Elf *elf; @@ -471,6 +484,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, close (fd); } } + free(path_name); } if (mod != NULL) @@ -1037,3 +1051,10 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, &integrated_memory_callback, &mcb, r_debug_info); } INTDEF (dwfl_link_map_report) + +void +dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot) +{ + dwfl->sysroot = sysroot; +} +INTDEF (dwfl_set_sysroot) -- 2.20.1
[PATCHv1 2/2] eu-stack: add support for sysroot option
Use the dwfl_set_sysroot() function to set the sysroot to be used when analysing a core: e.g. $ eu-stack --core core --sysroot /path/to/sysroot -e crashing_prog Signed-off-by: Luke Diamand --- src/stack.c | 9 + 1 file changed, 9 insertions(+) diff --git a/src/stack.c b/src/stack.c index c5f347e1..5a58cc1b 100644 --- a/src/stack.c +++ b/src/stack.c @@ -73,6 +73,7 @@ static int core_fd = -1; static Elf *core = NULL; static const char *exec = NULL; static char *debuginfo_path = NULL; +static const char *sysroot = NULL; static const Dwfl_Callbacks proc_callbacks = { @@ -554,6 +555,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_modules = true; break; +case 'S': + sysroot = arg; + break; + case ARGP_KEY_END: if (core == NULL && exec != NULL) argp_error (state, @@ -587,6 +592,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)), dwfl = dwfl_begin (&core_callbacks); if (dwfl == NULL) error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + if (sysroot) +dwfl_set_sysroot(dwfl, sysroot); if (dwfl_core_file_report (dwfl, core, exec) < 0) error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1)); } @@ -670,6 +677,8 @@ main (int argc, char **argv) N_("Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"), 0 }, { "list-modules", 'l', NULL, 0, N_("Show module memory map with build-id, elf and debug files detected"), 0 }, + { "sysroot", 'S', "sysroot", 0, + N_("Set the sysroot to search for libraries referenced from the core file"), 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; -- 2.20.1
[PATCHv1 0/2] specify a sysroot to search when examining a core file
Following on from this discussion: https://sourceware.org/ml/elfutils-devel/2018-q4/msg00224.html This patch adds a new API to specify a sysroot, and extends eu-stack to use it with a new command line option. I have been experimenting with this on various ARM-based platforms, currently using a virt-qemu platform built from buildroot. Luke Diamand (2): libdwfl: specify optional sysroot to search for shared libraries eu-stack: add support for sysroot option libdw/libdw.map| 7 ++- libdwfl/libdwfl.h | 5 + libdwfl/libdwflP.h | 1 + libdwfl/link_map.c | 25 +++-- src/stack.c| 9 + 5 files changed, 44 insertions(+), 3 deletions(-) -- 2.20.1
MIPS Elfutils support?
Hi! I was hoping to use elfutils on some MIPS core files. So I was wondering what the status is? There is a patch in Debian (apparently originally from RedHat?) here: https://sources.debian.org/src/elfutils/0.175-2/debian/patches/mips_backend.diff/ That's not in the mainline code though, and also lacks unwind support (?). I also have a small patch needed to pick up the shared library process map - instead of using DT_DEBUG, MIPS targets use DT_MIPS_RLD_MAP in core files. Thanks Luke
[PATCHv2 0/2] specify a sysroot to search when examining a core file
This updates my patch to check for a NULL sysroot, as pointed out by Dmitry, and to canonicalize sysroot. https://sourceware.org/ml/elfutils-devel/2019-q1/msg00071.html Luke Diamand (2): libdwfl: specify optional sysroot to search for shared libraries eu-stack: add support for sysroot option libdw/libdw.map| 7 ++- libdwfl/dwfl_end.c | 1 + libdwfl/libdwfl.h | 5 + libdwfl/libdwflP.h | 1 + libdwfl/link_map.c | 26 -- src/stack.c| 9 + 6 files changed, 46 insertions(+), 3 deletions(-) -- 2.20.1
[PATCHv2 1/2] libdwfl: specify optional sysroot to search for shared libraries
When searching the list of modules in a core file, if the core was generated on a different system to the current one, we need to look in a sysroot for the various shared objects. For example, we might be looking at a core file from an ARM system using elfutils running on an x86 host. This change adds a new function, dwfl_set_sysroot(), which then gets used when searching for libraries. Signed-off-by: Luke Diamand --- libdw/libdw.map| 7 ++- libdwfl/dwfl_end.c | 1 + libdwfl/libdwfl.h | 5 + libdwfl/libdwflP.h | 1 + libdwfl/link_map.c | 26 -- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/libdw/libdw.map b/libdw/libdw.map index 55482d58..43a9de2e 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -360,4 +360,9 @@ ELFUTILS_0.173 { ELFUTILS_0.175 { global: dwelf_elf_begin; -} ELFUTILS_0.173; \ No newline at end of file +} ELFUTILS_0.173; + +ELFUTILS_0.176 { + global: +dwfl_set_sysroot; +} ELFUTILS_0.175; diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c index 74ee9e07..345d9947 100644 --- a/libdwfl/dwfl_end.c +++ b/libdwfl/dwfl_end.c @@ -45,6 +45,7 @@ dwfl_end (Dwfl *dwfl) free (dwfl->lookup_addr); free (dwfl->lookup_module); free (dwfl->lookup_segndx); + free (dwfl->sysroot); Dwfl_Module *next = dwfl->modulelist; while (next != NULL) diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index a0c1d357..c11e2f24 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -807,6 +807,11 @@ int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid, bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation) __nonnull_attribute__ (1, 2); +/* Set the sysroot to use when searching for shared libraries. If not + specified, search in the system root. */ +void dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot) + __nonnull_attribute__ (1); + #ifdef __cplusplus } #endif diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 941a8b66..db16ab57 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -138,6 +138,7 @@ struct Dwfl int lookup_tail_ndx; struct Dwfl_User_Core *user_core; + char *sysroot; /* sysroot, or NULL to search standard system paths */ }; #define OFFLINE_REDZONE0x1 diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 29307c74..cf18c0a2 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -34,6 +34,7 @@ #include #include #include +#include /* This element is always provided and always has a constant value. This makes it an easy thing to scan for to discern the format. */ @@ -388,8 +389,21 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, if (name != NULL) { /* This code is mostly inlined dwfl_report_elf. */ - // XXX hook for sysroot - int fd = open (name, O_RDONLY); + char *path_name; + int rc; + const char *sysroot = dwfl->sysroot; + + /* don't look in the sysroot if the path is already inside the sysroot */ + bool name_in_sysroot = sysroot && (strncmp(name, sysroot, strlen(sysroot)) == 0); + + if (!name_in_sysroot && sysroot) + rc = asprintf(&path_name, "%s/%s", sysroot, name); + else + rc = asprintf(&path_name, "%s", name); + if (unlikely(rc == -1)) + return release_buffer(-1); + + int fd = open (path_name, O_RDONLY); if (fd >= 0) { Elf *elf; @@ -471,6 +485,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, close (fd); } } + free(path_name); } if (mod != NULL) @@ -1037,3 +1052,10 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, &integrated_memory_callback, &mcb, r_debug_info); } INTDEF (dwfl_link_map_report) + +void +dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot) +{ + dwfl->sysroot = realpath(sysroot, NULL); +} +INTDEF (dwfl_set_sysroot) -- 2.20.1
[PATCHv2 2/2] eu-stack: add support for sysroot option
Use the dwfl_set_sysroot() function to set the sysroot to be used when analysing a core: e.g. $ eu-stack --core core --sysroot /path/to/sysroot -e crashing_prog Signed-off-by: Luke Diamand --- src/stack.c | 9 + 1 file changed, 9 insertions(+) diff --git a/src/stack.c b/src/stack.c index c5f347e1..5a58cc1b 100644 --- a/src/stack.c +++ b/src/stack.c @@ -73,6 +73,7 @@ static int core_fd = -1; static Elf *core = NULL; static const char *exec = NULL; static char *debuginfo_path = NULL; +static const char *sysroot = NULL; static const Dwfl_Callbacks proc_callbacks = { @@ -554,6 +555,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_modules = true; break; +case 'S': + sysroot = arg; + break; + case ARGP_KEY_END: if (core == NULL && exec != NULL) argp_error (state, @@ -587,6 +592,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)), dwfl = dwfl_begin (&core_callbacks); if (dwfl == NULL) error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); + if (sysroot) +dwfl_set_sysroot(dwfl, sysroot); if (dwfl_core_file_report (dwfl, core, exec) < 0) error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1)); } @@ -670,6 +677,8 @@ main (int argc, char **argv) N_("Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"), 0 }, { "list-modules", 'l', NULL, 0, N_("Show module memory map with build-id, elf and debug files detected"), 0 }, + { "sysroot", 'S', "sysroot", 0, + N_("Set the sysroot to search for libraries referenced from the core file"), 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; -- 2.20.1
Hitting g dwfl->lookup_elts limit in report_r_debug, so not all modules show up and backtracing fails
I've got a few cores where report_r_debug() in link_map.c fails to find all of the modules - for example I had libc.so missing. This obviously meant that elfutils could not backtrace my core. It seems to be related to this code: /* There can't be more elements in the link_map list than there are segments. DWFL->lookup_elts is probably twice that number, so it is certainly above the upper bound. If we iterate too many times, there must be a loop in the pointers due to link_map clobberation. */ size_t iterations = 0; while (next != 0 && ++iterations < dwfl->lookup_elts) I've changed this to just keep going until it reaches dwfl->lookup_elts*5, which seems to "fix" it, but I feel there must be a better fix! The most recent core I saw with this had lookup_elts=36, and hit 109 iterations of the loop and then backtraced just fine. Thanks! Luke
[RFC PATCH 0/1] In report_r_debug, iterate more segments
Further to: https://sourceware.org/pipermail/elfutils-devel/2023q2/006149.html This is a draft patch to increase the number of iterations looking for segments to load. This lets eu-stack backtrace cores that would otherwise fail. I have not included any unit tests as so far I have been unable to reproduce the problem in a suitably small example. Luke Diamand (1): report_r_debug: handle `-z separate-code' and find more modules libdwfl/link_map.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) -- 2.39.1
[RFC PATCH 1/1] report_r_debug: handle `-z separate-code' and find more modules
Looking at some cores in eu-stack, I found that they were not being backtraced. This was because elfutils had not found some modules (e.g. libc-2.22.so) in report_r_debug. That is because it has a limit on the number of link map entries it will look at, to avoid loops in corrupted core files. The example I found had: - 36 elements - 109 iterations I have increased the limit, and this seems to solve the problem. Florian Weimer suggested that the problem is caused by use of `-z separate-code' although I have not yet managed to confirm this. See also: https://sourceware.org/pipermail/elfutils-devel/2023q2/006149.html Signed-off-by: Luke Diamand --- libdwfl/link_map.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 06d85eb6..975910a9 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -330,12 +330,13 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, Dwfl_Module **lastmodp = &dwfl->modulelist; int result = 0; - /* There can't be more elements in the link_map list than there are - segments. DWFL->lookup_elts is probably twice that number, so it - is certainly above the upper bound. If we iterate too many times, - there must be a loop in the pointers due to link_map clobberation. */ + /* Keep an upper bound on the number of iterations - if we iterate + * too many times, there must be a loop in the pointers due to link_map + * clobberation. + */ size_t iterations = 0; - while (next != 0 && ++iterations < dwfl->lookup_elts) + + while (next != 0 && ++iterations < dwfl->lookup_elts * 5) { if (read_addrs (&memory_closure, elfclass, elfdata, &buffer, &buffer_available, next, &read_vaddr, -- 2.39.1
Re: [EXTERNAL] Re: Hitting g dwfl->lookup_elts limit in report_r_debug, so not all modules show up and backtracing fails
On 08/05/2023 17:35, Mark Wielaard wrote: Hi Florian, Hi Luke, On Tue, 2023-05-02 at 09:57 +0200, Florian Weimer via Elfutils-devel wrote: * Luke Diamand via Elfutils-devel: I've got a few cores where report_r_debug() in link_map.c fails to find all of the modules - for example I had libc.so missing. This obviously meant that elfutils could not backtrace my core. It seems to be related to this code: /* There can't be more elements in the link_map list than there are segments. DWFL->lookup_elts is probably twice that number, so it is certainly above the upper bound. If we iterate too many times, there must be a loop in the pointers due to link_map clobberation. */ size_t iterations = 0; while (next != 0 && ++iterations < dwfl->lookup_elts) I've changed this to just keep going until it reaches dwfl->lookup_elts*5, which seems to "fix" it, but I feel there must be a better fix! The most recent core I saw with this had lookup_elts=36, and hit 109 iterations of the loop and then backtraced just fine. It's probably another fallout from -z separate-code, which tends to create four LOAD segments. The magic number 5 sounds about right, as gold also has -z text-unlikely-segment, which might result in creating that number of load segments (but I haven't tried). Wow, that had never occurred to me. Thanks. Luke does the binary/libraries from which your core file was generated contain multiple PT_LOAD segments? We could add something like: diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 06d85eb6..76f23354 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -331,11 +331,17 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, int result = 0; /* There can't be more elements in the link_map list than there are - segments. DWFL->lookup_elts is probably twice that number, so it - is certainly above the upper bound. If we iterate too many times, - there must be a loop in the pointers due to link_map clobberation. */ + segments. A segment is created for each PT_LOAD and there can be + up to 5 per module (-z separate-code, tends to create four LOAD + segments, gold has -z text-unlikely-segment, which might result + in creating that number of load segments) DWFL->lookup_elts is + probably twice the number of modules, so that multiplied by max + PT_LOADs is certainly above the upper bound. If we iterate too + many times, there must be a loop in the pointers due to link_map + clobberation. */ +#define MAX_PT_LOAD 5 size_t iterations = 0; - while (next != 0 && ++iterations < dwfl->lookup_elts) + while (next != 0 && ++iterations < dwfl->lookup_elts * MAX_PT_LOAD) { if (read_addrs (&memory_closure, elfclass, elfdata, &buffer, &buffer_available, next, &read_vaddr, Does that sound reasonable? Sorry - I did not see this until just after sending in my patch! Let me try it with this change and I will re-roll it. Luke
[PATCHv2 0/1] In report_r_debug, iterate more segments
Further to: https://sourceware.org/pipermail/elfutils-devel/2023q2/006149.html This is a patch to increase the number of iterations looking for segments to load. This lets eu-stack backtrace cores that would otherwise fail. Florian Weimer and Mark Wielaard suggested both the explanation and the fix. Luke Diamand (1): report_r_debug: handle `-z separate-code' and find more modules libdwfl/link_map.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) -- 2.40.1
[PATCHv2 1/1] report_r_debug: handle `-z separate-code' and find more modules
Looking at some cores in eu-stack, I found that they were not being backtraced. This was because elfutils had not found some modules (e.g. libc-2.22.so) in report_r_debug. That is because it has a limit on the number of link map entries it will look at, to avoid loops in corrupted core files. The example I found had: - 36 elements - 109 iterations See also discussion here: https://sourceware.org/pipermail/elfutils-devel/2023q2/006149.html Signed-off-by: Luke Diamand --- libdwfl/link_map.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 06d85eb6..76f23354 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -331,11 +331,17 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, int result = 0; /* There can't be more elements in the link_map list than there are - segments. DWFL->lookup_elts is probably twice that number, so it - is certainly above the upper bound. If we iterate too many times, - there must be a loop in the pointers due to link_map clobberation. */ + segments. A segment is created for each PT_LOAD and there can be + up to 5 per module (-z separate-code, tends to create four LOAD + segments, gold has -z text-unlikely-segment, which might result + in creating that number of load segments) DWFL->lookup_elts is + probably twice the number of modules, so that multiplied by max + PT_LOADs is certainly above the upper bound. If we iterate too + many times, there must be a loop in the pointers due to link_map + clobberation. */ +#define MAX_PT_LOAD 5 size_t iterations = 0; - while (next != 0 && ++iterations < dwfl->lookup_elts) + while (next != 0 && ++iterations < dwfl->lookup_elts * MAX_PT_LOAD) { if (read_addrs (&memory_closure, elfclass, elfdata, &buffer, &buffer_available, next, &read_vaddr, -- 2.40.1
Re: [EXTERNAL] Re: [PATCH 1/5] strip: Adapt src/strip -o -f on mips
On 09/05/2023 16:15, Mark Wielaard wrote: Hi, On Tue, 2023-04-11 at 16:12 +0800, Ying Huang wrote: From: Ying Huang In mips64 little-endian, r_info consists of four byte fields(contains three reloc types) and a 32-bit symbol index. In order to adapt GELF_R_SYM and GELF_R_TYPE, need convert raw data to get correct symbol index and type. Is there a spec that describes this? I see you adjusted elf.h to include: +#define ELF64_MIPS_R_TYPE(i) ((i) & 0xff) +#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff) +#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff) Is this patch intended to support 32 bit MIPS (and MIPSEL) ? For me it did not work but I could see if I can add that in. (From a very long time ago, I have some patches based on the debian MIPS support but I never managed to find time to upstream them, so this is great to finally see!) Luke