From: Timm Bäder <tbae...@redhat.com> Signed-off-by: Timm Bäder <tbae...@redhat.com> --- libdwfl/dwfl_segment_report_module.c | 77 +++++++++++++++++----------- 1 file changed, 47 insertions(+), 30 deletions(-)
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index c55168ed..01adfe9e 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -242,6 +242,39 @@ finish_portion (Dwfl *dwfl, (*memory_callback) (dwfl, -1, data, data_size, 0, 0, memory_callback_arg); } + +static inline bool +read_portion (Dwfl *dwfl, + Dwfl_Memory_Callback *memory_callback, + void *memory_callback_arg, + void **data, size_t *data_size, + GElf_Addr vaddr, size_t filesz, + void *buffer, + size_t buffer_available, + GElf_Addr start, + size_t segment) +{ + /* Check whether we will have to read the segment data, or if it + can be returned from the existing buffer. */ + if (filesz > buffer_available + || vaddr - start > buffer_available - filesz + /* If we're in string mode, then don't consider the buffer we have + sufficient unless it contains the terminator of the string. */ + || (filesz == 0 && memchr (vaddr - start + buffer, '\0', + buffer_available - (vaddr - start)) == NULL)) + { + *data = NULL; + *data_size = filesz; + return ! (*memory_callback) (dwfl, addr_segndx (dwfl, segment, vaddr, false), + data, data_size, vaddr, filesz, memory_callback_arg); + } + + /* We already have this whole note segment from our initial read. */ + *data = vaddr - start + buffer; + *data_size = 0; + return false; +} + int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Memory_Callback *memory_callback, @@ -283,30 +316,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, || memcmp (buffer, ELFMAG, SELFMAG) != 0) goto out; - inline bool read_portion (void **data, size_t *data_size, - GElf_Addr vaddr, size_t filesz) - { - /* Check whether we will have to read the segment data, or if it - can be returned from the existing buffer. */ - if (filesz > buffer_available - || vaddr - start > buffer_available - filesz - /* If we're in string mode, then don't consider the buffer we have - sufficient unless it contains the terminator of the string. */ - || (filesz == 0 && memchr (vaddr - start + buffer, '\0', - buffer_available - (vaddr - start)) == NULL)) - { - *data = NULL; - *data_size = filesz; - return ! (*memory_callback) (dwfl, addr_segndx (dwfl, segment, vaddr, false), - data, data_size, vaddr, filesz, memory_callback_arg); - } - - /* We already have this whole note segment from our initial read. */ - *data = vaddr - start + buffer; - *data_size = 0; - return false; - } - /* Extract the information we need from the file header. */ const unsigned char *e_ident; unsigned char ei_class; @@ -387,8 +396,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, void *ph_buffer = NULL; size_t ph_buffer_size = 0; - if (read_portion (&ph_buffer, &ph_buffer_size, - start + phoff, xlatefrom.d_size)) + if (read_portion (dwfl, memory_callback, memory_callback_arg, + &ph_buffer, &ph_buffer_size, + start + phoff, xlatefrom.d_size, + buffer, buffer_available, start, segment)) goto out; /* ph_buffer_size will be zero if we got everything from the initial @@ -445,7 +456,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, void *data; size_t data_size; - if (read_portion (&data, &data_size, vaddr, filesz)) + if (read_portion (dwfl, memory_callback, memory_callback_arg, + &data, &data_size, vaddr, filesz, + buffer, buffer_available, start, segment)) return; /* data_size will be zero if we got everything from the initial @@ -766,7 +779,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, void *dyn_data = NULL; size_t dyn_data_size = 0; if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0 - && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz)) + && ! read_portion (dwfl, memory_callback, memory_callback_arg, + &dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz, + buffer, buffer_available, start, segment)) { /* dyn_data_size will be zero if we got everything from the initial buffer, otherwise it will be the size of the new buffer that @@ -834,8 +849,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, /* Try to get the DT_SONAME string. */ if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz - && ! read_portion (&soname, &soname_size, - dynstr_vaddr + soname_stroff, 0)) + && ! read_portion (dwfl, memory_callback, memory_callback_arg, + &soname, &soname_size, + dynstr_vaddr + soname_stroff, 0, + buffer, buffer_available, start, segment)) name = soname; } -- 2.26.2