[PATCH 02/14] segment_report_module: Pull segment_read into file scope
In preparation of getting rid of nested functions Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 30 +--- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index dd3fdb9e..9f06672a 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -232,6 +232,16 @@ invalid_elf (Elf *elf, bool disk_file_has_build_id, return false; } +static inline bool +segment_read (Dwfl *dwfl, + Dwfl_Memory_Callback *memory_callback, void *memory_callback_arg, + int segndx, void **buffer, size_t *buffer_available, + GElf_Addr addr, size_t minread) +{ + return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available, + addr, minread, memory_callback_arg); +} + int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Memory_Callback *memory_callback, @@ -257,18 +267,11 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Addr start = dwfl->lookup_addr[segment]; - inline bool segment_read (int segndx, - void **buffer, size_t *buffer_available, - GElf_Addr addr, size_t minread) - { -return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available, -addr, minread, memory_callback_arg); - } - inline void release_buffer (void **buffer, size_t *buffer_available) { if (*buffer != NULL) - (void) segment_read (-1, buffer, buffer_available, 0, 0); + (void) segment_read (dwfl, memory_callback, memory_callback_arg, + -1, buffer, buffer_available, 0, 0); } /* First read in the file header and check its sanity. */ @@ -293,7 +296,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, return ndx; } - if (segment_read (ndx, &buffer, &buffer_available, + if (segment_read (dwfl, memory_callback, memory_callback_arg, +ndx, &buffer, &buffer_available, start, sizeof (Elf64_Ehdr)) || memcmp (buffer, ELFMAG, SELFMAG) != 0) return finish (); @@ -312,7 +316,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, { *data = NULL; *data_size = filesz; - return segment_read (addr_segndx (dwfl, segment, vaddr, false), + return segment_read (dwfl, memory_callback, memory_callback_arg, + addr_segndx (dwfl, segment, vaddr, false), data, data_size, vaddr, filesz); } @@ -919,7 +924,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, { void *into = contents + offset; size_t read_size = size; - (void) segment_read (addr_segndx (dwfl, segment, vaddr, false), + (void) segment_read (dwfl, memory_callback, memory_callback_arg, + addr_segndx (dwfl, segment, vaddr, false), &into, &read_size, vaddr, size); } -- 2.26.2
[PATCH 06/14] segment_report_module: Pull read_portion() into file scope
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 79 +--- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 751a96f1..00455aa4 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -254,6 +254,40 @@ finish_portion (Dwfl *dwfl, -1, data, data_size, 0, 0); } + +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 segment_read (dwfl, memory_callback, memory_callback_arg, + addr_segndx (dwfl, segment, vaddr, false), + data, data_size, vaddr, filesz); +} + + /* 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, @@ -296,31 +330,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 segment_read (dwfl, memory_callback, memory_callback_arg, - addr_segndx (dwfl, segment, vaddr, false), -data, data_size, vaddr, filesz); - } - -/* 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; @@ -401,8 +410,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 @@ -459,7 +470,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 @@ -780,7 +793,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 @@ -848,8 +863,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int n
[PATCH 07/14] segment_report_module: Use a struct for build id information
Keep the three build id fields in a struct. This will be an important clean up later. Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 54 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 00455aa4..44743fab 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -54,6 +54,13 @@ # define MY_ELFDATAELFDATA2MSB #endif +struct elf_build_id +{ + void *memory; + size_t len; + GElf_Addr vaddr; +}; + /* Return user segment index closest to ADDR but not above it. If NEXT, return the closest to ADDR but not below it. */ @@ -206,16 +213,16 @@ handle_file_note (GElf_Addr module_start, GElf_Addr module_end, static bool invalid_elf (Elf *elf, bool disk_file_has_build_id, -const void *build_id, size_t build_id_len) + struct elf_build_id *build_id) { - if (! disk_file_has_build_id && build_id_len > 0) + if (! disk_file_has_build_id && build_id->len > 0) { /* Module found in segments with build-id is more reliable than a module found via DT_DEBUG on disk without any build-id. */ return true; } - if (disk_file_has_build_id && build_id_len > 0) + if (disk_file_has_build_id && build_id->len > 0) { const void *elf_build_id; ssize_t elf_build_id_len; @@ -224,8 +231,8 @@ invalid_elf (Elf *elf, bool disk_file_has_build_id, elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id); if (elf_build_id_len > 0) { - if (build_id_len != (size_t) elf_build_id_len - || memcmp (build_id, elf_build_id, build_id_len) != 0) + if (build_id->len != (size_t) elf_build_id_len + || memcmp (build_id->memory, elf_build_id, build_id->len) != 0) return true; } } @@ -456,16 +463,17 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Xword dyn_filesz = 0; /* Collect the build ID bits here. */ - void *build_id = NULL; - size_t build_id_len = 0; - GElf_Addr build_id_vaddr = 0; + struct elf_build_id build_id; + build_id.memory = NULL; + build_id.len = 0; + build_id.vaddr =0; /* Consider a PT_NOTE we've found in the image. */ inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz, GElf_Xword align) { /* If we have already seen a build ID, we don't care any more. */ -if (build_id != NULL || filesz == 0) +if (build_id.memory != NULL || filesz == 0) return; void *data; @@ -524,11 +532,11 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, && nh->n_namesz == sizeof "GNU" && !memcmp (note_name, "GNU", sizeof "GNU")) { - build_id_vaddr = note_desc - (const void *) notes + vaddr; - build_id_len = nh->n_descsz; - build_id = malloc (nh->n_descsz); - if (likely (build_id != NULL)) - memcpy (build_id, note_desc, build_id_len); +build_id.vaddr = note_desc - (const void *) notes + vaddr; +build_id.len = nh->n_descsz; +build_id.memory = malloc (build_id.len); +if (likely (build_id.memory != NULL)) + memcpy (build_id.memory, note_desc, build_id.len); break; } @@ -643,7 +651,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, header we read at START was not produced by these program headers. */ if (unlikely (!found_bias)) { - free (build_id); + free (build_id.memory); goto out; } @@ -698,7 +706,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, { if (module->elf != NULL && invalid_elf (module->elf, module->disk_file_has_build_id, - build_id, build_id_len)) +&build_id)) { elf_end (module->elf); close (module->fd); @@ -714,7 +722,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, } if (skip_this_module) { - free (build_id); + free (build_id.memory); goto out; } } @@ -733,7 +741,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false); if (error == DWFL_E_NOERROR) invalid = invalid_elf (elf, true /* disk_file_has_build_id */, - build_id, build_id_len); + &build_id); } if (invalid) { @@ -881,11 +889,11 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC)) mod->is_executable = true; - i
[PATCH 05/14] segment_report_module: Pull finish_portion() info file scope
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index ba11b60a..751a96f1 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -242,6 +242,18 @@ segment_read (Dwfl *dwfl, addr, minread, memory_callback_arg); } + +static inline void +finish_portion (Dwfl *dwfl, +Dwfl_Memory_Callback *memory_callback, +void *memory_callback_arg, +void **data, size_t *data_size) +{ + if (*data_size != 0 && *data != NULL) +(void) segment_read (dwfl, memory_callback, memory_callback_arg, + -1, data, data_size, 0, 0); +} + int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Memory_Callback *memory_callback, @@ -309,13 +321,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, return false; } - inline void finish_portion (void **data, size_t *data_size) - { -if (*data_size != 0 && *data != NULL) - (void) segment_read (dwfl, memory_callback, memory_callback_arg, - -1, data, data_size, 0, 0); - } - /* Extract the information we need from the file header. */ const unsigned char *e_ident; unsigned char ei_class; @@ -522,7 +527,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, done: if (notes != data) free (notes); -finish_portion (&data, &data_size); +finish_portion (dwfl, memory_callback, memory_callback_arg, &data, &data_size); } /* Consider each of the program headers we've read from the image. */ @@ -619,7 +624,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, p64[i].p_align); } - finish_portion (&ph_buffer, &ph_buffer_size); + finish_portion (dwfl, memory_callback, memory_callback_arg, &ph_buffer, &ph_buffer_size); /* We must have seen the segment covering offset 0, or else the ELF header we read at START was not produced by these program headers. */ @@ -811,7 +816,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, } free (dyns); } - finish_portion (&dyn_data, &dyn_data_size); + finish_portion (dwfl, memory_callback, memory_callback_arg, &dyn_data, &dyn_data_size); /* We'll use the name passed in or a stupid default if not DT_SONAME. */ if (name == NULL) @@ -872,7 +877,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, /* At this point we do not need BUILD_ID or NAME any more. They have been copied. */ free (build_id); - finish_portion (&soname, &soname_size); + finish_portion (dwfl, memory_callback, memory_callback_arg, &soname, &soname_size); if (unlikely (mod == NULL)) { -- 2.26.2
[PATCH 14/14] segment_report_module: Inline consider_phdr() into only caller
Get rid of the nested function this way Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 142 +-- 1 file changed, 66 insertions(+), 76 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 0679453e..f93c60e2 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -475,7 +475,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, /* NOTE if the number of sections is > 0xff00 then e_shnum is zero and the actual number would come from the section zero sh_size field. We ignore this here because getting shdrs -is just a nice bonus (see below in consider_phdr PT_LOAD +is just a nice bonus (see below in the type == PT_LOAD case where we trim the last segment). */ shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize; break; @@ -561,80 +561,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, build_id.len = 0; build_id.vaddr =0; - /* Consider each of the program headers we've read from the image. */ - inline void consider_phdr (GElf_Word type, -GElf_Addr vaddr, GElf_Xword memsz, -GElf_Off offset, GElf_Xword filesz, -GElf_Xword align) - { -switch (type) - { - case PT_DYNAMIC: - dyn_vaddr = vaddr; - dyn_filesz = filesz; - break; - - case PT_NOTE: - /* We calculate from the p_offset of the note segment, - because we don't yet know the bias for its p_vaddr. */ - consider_notes (dwfl, memory_callback, memory_callback_arg, - start + offset, filesz, align, - buffer, buffer_available, start, segment, - ei_data, &build_id, - &xlatefrom, &xlateto, - ehdr.e32.e_ident[EI_DATA]); - break; - - case PT_LOAD: - align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1; - - GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align; - GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end; - GElf_Off filesz_offset = filesz_vaddr - vaddr + offset; - - if (file_trimmed_end < offset + filesz) - { - file_trimmed_end = offset + filesz; - - /* Trim the last segment so we don't bother with zeros - in the last page that are off the end of the file. - However, if the extra bit in that page includes the - section headers, keep them. */ - if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end) - { - filesz += shdrs_end - file_trimmed_end; - file_trimmed_end = shdrs_end; - } - } - - total_filesz += filesz; - - if (file_end < filesz_offset) - { - file_end = filesz_offset; - if (filesz_vaddr - start == filesz_offset) - contiguous = file_end; - } - - if (!found_bias && (offset & -align) == 0 - && likely (filesz_offset >= phoff + phnum * phentsize)) - { - bias = start - vaddr; - found_bias = true; - } - - if ((vaddr & -align) < module_start) - { - module_start = vaddr & -align; - module_address_sync = vaddr + memsz; - } - - if (module_end < vaddr_end) - module_end = vaddr_end; - break; - } - } - Elf32_Phdr *p32 = phdrsp; Elf64_Phdr *p64 = phdrsp; if ((ei_class == ELFCLASS32 && @@ -646,6 +572,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, } else { + /* Consider each of the program headers we've read from the image. */ for (uint_fast16_t i = 0; i < phnum; ++i) { bool is32 = (ei_class == ELFCLASS32); @@ -656,7 +583,70 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; GElf_Xword align = is32 ? p32[i].p_align : p64[i].p_align; - consider_phdr (type, vaddr, memsz, offset, filesz, align); + if (type == PT_DYNAMIC) +{ + dyn_vaddr = vaddr; + dyn_filesz = filesz; +} + else if (type == PT_NOTE) +{ + /* We calculate from the p_offset of the note segment, + because we don't yet know the bias for its p_vaddr. */ + consider_notes (dwfl, memory_callback, memory_callback_arg, + start + offset, filesz, align, + buffer, buffer_available, start, segment, + ei_data, &build_id, + &xlatefrom, &xlateto, +
[PATCH 13/14] segment_report_module: Inline consider_dyn() into only caller
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 40 +--- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 7c97784f..0679453e 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -784,33 +784,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Addr dynstr_vaddr = 0; GElf_Xword dynstrsz = 0; bool execlike = false; - inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val) - { -switch (tag) - { - default: - return false; - - case DT_DEBUG: - execlike = true; - break; - - case DT_SONAME: - soname_stroff = val; - break; - - case DT_STRTAB: - dynstr_vaddr = val; - break; - - case DT_STRSZ: - dynstrsz = val; - break; - } - -return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0; - } - const size_t dyn_entsize = (ei_class == ELFCLASS32 ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn)); void *dyn_data = NULL; @@ -848,7 +821,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Sxword tag = is32 ? d32[i].d_tag : d64[i].d_tag; GElf_Xword val = is32 ? d32[i].d_un.d_val : d64[i].d_un.d_val; - if (consider_dyn (tag, val)) + if (tag == DT_DEBUG) +execlike = true; + else if (tag == DT_SONAME) +soname_stroff = val; + else if (tag == DT_STRTAB) +dynstr_vaddr = val; + else if (tag == DT_STRSZ) +dynstrsz = val; + else +continue; + + if (soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0) break; } } -- 2.26.2
[PATCH 04/14] segment_report_module: Remove nested release_buffer() function
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 16 ++-- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index d06d0ba0..ba11b60a 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -267,13 +267,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Addr start = dwfl->lookup_addr[segment]; - inline void release_buffer (void **buffer, size_t *buffer_available) - { -if (*buffer != NULL) - (void) segment_read (dwfl, memory_callback, memory_callback_arg, - -1, buffer, buffer_available, 0, 0); - } - /* First read in the file header and check its sanity. */ void *buffer = NULL; @@ -318,8 +311,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, inline void finish_portion (void **data, size_t *data_size) { -if (*data_size != 0) - release_buffer (data, data_size); +if (*data_size != 0 && *data != NULL) + (void) segment_read (dwfl, memory_callback, memory_callback_arg, + -1, data, data_size, 0, 0); } /* Extract the information we need from the file header. */ @@ -972,7 +966,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, out: free (phdrsp); - release_buffer (&buffer, &buffer_available); + if (buffer != NULL) +(void) segment_read (dwfl, memory_callback, memory_callback_arg, + -1, &buffer, &buffer_available, 0, 0); if (elf != NULL) elf_end (elf); if (fd != -1) -- 2.26.2
[PATCH 08/14] segment_report_module: Pull consider_notes() into file scope
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 187 +++ 1 file changed, 101 insertions(+), 86 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 44743fab..76686a72 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -295,6 +295,99 @@ read_portion (Dwfl *dwfl, return false; } + +/* Consider a PT_NOTE we've found in the image. */ +static inline void +consider_notes (Dwfl *dwfl, +Dwfl_Memory_Callback *memory_callback, void *memory_callback_arg, +GElf_Addr vaddr, GElf_Xword filesz, +GElf_Xword align, +void *buffer, size_t buffer_available, +GElf_Addr start, +size_t segment, +unsigned char ei_data, +struct elf_build_id *build_id, +Elf_Data *xlatefrom, +Elf_Data *xlateto, +unsigned int xencoding) +{ + if (build_id->memory != NULL || filesz == 0) +return; + + void *data; + size_t data_size; + 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 + buffer, otherwise it will be the size of the new buffer that + could be read. */ + if (data_size != 0) +filesz = data_size; + + assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); + + void *notes; + if (ei_data == MY_ELFDATA) +notes = data; + else +{ + notes = malloc (filesz); + if (unlikely (notes == NULL)) +return; + xlatefrom->d_type = xlateto->d_type = (align == 8 + ? ELF_T_NHDR8 : ELF_T_NHDR); + xlatefrom->d_buf = (void *) data; + xlatefrom->d_size = filesz; + xlateto->d_buf = notes; + xlateto->d_size = filesz; + if (elf32_xlatetom (xlateto, xlatefrom, xencoding) == NULL) +goto done; +} + + const GElf_Nhdr *nh = notes; + size_t len = 0; + while (filesz > len + sizeof (*nh)) +{ + const void *note_name; + const void *note_desc; + + len += sizeof (*nh); + note_name = notes + len; + + len += nh->n_namesz; + len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); + note_desc = notes + len; + + if (unlikely (filesz < len + nh->n_descsz)) +break; + + if (nh->n_type == NT_GNU_BUILD_ID + && nh->n_descsz > 0 + && nh->n_namesz == sizeof "GNU" + && !memcmp (note_name, "GNU", sizeof "GNU")) +{ + build_id->vaddr = note_desc - (const void *) notes + vaddr; + build_id->len = nh->n_descsz; + build_id->memory = malloc (build_id->len); + if (likely (build_id->memory != NULL)) +memcpy (build_id->memory, note_desc, build_id->len); + break; +} + + len += nh->n_descsz; + len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len); + nh = (void *) notes + len; +} + +done: + if (notes != data) +free (notes); + finish_portion (dwfl, memory_callback, memory_callback_arg, &data, &data_size); +} + int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Memory_Callback *memory_callback, @@ -468,89 +561,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, build_id.len = 0; build_id.vaddr =0; - /* Consider a PT_NOTE we've found in the image. */ - inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz, - GElf_Xword align) - { -/* If we have already seen a build ID, we don't care any more. */ -if (build_id.memory != NULL || filesz == 0) - return; - -void *data; -size_t data_size; -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 - buffer, otherwise it will be the size of the new buffer that - could be read. */ -if (data_size != 0) - filesz = data_size; - -assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); - -void *notes; -if (ei_data == MY_ELFDATA) - notes = data; -else - { - notes = malloc (filesz); - if (unlikely (notes == NULL)) - return; - xlatefrom.d_type = xlateto.d_type = (align == 8 -? ELF_T_NHDR8 : ELF_T_NHDR); - xlatefrom.d_buf = (void *) data; - xlatefrom.d_size = filesz; - xlateto.d_buf = notes; - xlateto.d_size = filesz; - if (elf32_xlatetom (&xlateto, &xlatefrom, - ehdr.e32.e_ident[EI_DATA]) == NULL) -
[PATCH 01/14] segment_report_module: Get rid of variable-length arrays
This prevents a jump which is needed in a later patch. Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 430e13d5..dd3fdb9e 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -606,18 +606,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, } } - Elf32_Phdr (*p32)[phnum] = phdrsp; - Elf64_Phdr (*p64)[phnum] = phdrsp; + Elf32_Phdr *p32 = phdrsp; + Elf64_Phdr *p64 = phdrsp; if (ei_class == ELFCLASS32) { if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) found_bias = false; /* Trigger error check. */ else for (uint_fast16_t i = 0; i < phnum; ++i) - consider_phdr ((*p32)[i].p_type, -(*p32)[i].p_vaddr, (*p32)[i].p_memsz, -(*p32)[i].p_offset, (*p32)[i].p_filesz, -(*p32)[i].p_align); + consider_phdr (p32[i].p_type, +p32[i].p_vaddr, p32[i].p_memsz, +p32[i].p_offset, p32[i].p_filesz, +p32[i].p_align); } else { @@ -625,10 +625,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, found_bias = false; /* Trigger error check. */ else for (uint_fast16_t i = 0; i < phnum; ++i) - consider_phdr ((*p64)[i].p_type, -(*p64)[i].p_vaddr, (*p64)[i].p_memsz, -(*p64)[i].p_offset, (*p64)[i].p_filesz, -(*p64)[i].p_align); + consider_phdr (p64[i].p_type, +p64[i].p_vaddr, p64[i].p_memsz, +p64[i].p_offset, p64[i].p_filesz, +p64[i].p_align); } finish_portion (&ph_buffer, &ph_buffer_size); @@ -796,8 +796,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, dyn_filesz = dyn_data_size; void *dyns = malloc (dyn_filesz); - Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns; - Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns; + Elf32_Dyn *d32 = dyns; + Elf64_Dyn *d64 = dyns; if (unlikely (dyns == NULL)) return finish (); @@ -811,14 +811,14 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, { if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i) - if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val)) + if (consider_dyn (d32[i].d_tag, d32[i].d_un.d_val)) break; } else { if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i) - if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val)) + if (consider_dyn (d64[i].d_tag, d64[i].d_un.d_val)) break; } free (dyns); @@ -937,12 +937,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (ei_class == ELFCLASS32) for (uint_fast16_t i = 0; i < phnum; ++i) - read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr, -(*p32)[i].p_offset, (*p32)[i].p_filesz); + read_phdr (p32[i].p_type, p32[i].p_vaddr, +p32[i].p_offset, p32[i].p_filesz); else for (uint_fast16_t i = 0; i < phnum; ++i) - read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr, -(*p64)[i].p_offset, (*p64)[i].p_filesz); + read_phdr (p64[i].p_type, p64[i].p_vaddr, +p64[i].p_offset, p64[i].p_filesz); } else { -- 2.26.2
[PATCH 10/14] segment_report_module: Use one loop for p32/p64 arrays
Do one loop check for 32/64 bit inside the loop, instead of outside. This way we have only one call site for the function called in the loop body. Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 52 +++- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 80f97cfd..2535f9e3 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -637,27 +637,27 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Elf32_Phdr *p32 = phdrsp; Elf64_Phdr *p64 = phdrsp; - if (ei_class == ELFCLASS32) + if ((ei_class == ELFCLASS32 && + elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) || + (ei_class == ELFCLASS64 && + elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)) { - if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) - found_bias = false; /* Trigger error check. */ - else - for (uint_fast16_t i = 0; i < phnum; ++i) - consider_phdr (p32[i].p_type, -p32[i].p_vaddr, p32[i].p_memsz, -p32[i].p_offset, p32[i].p_filesz, -p32[i].p_align); + found_bias = false; /* Trigger error check */ } else { - if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) - found_bias = false; /* Trigger error check. */ - else - for (uint_fast16_t i = 0; i < phnum; ++i) - consider_phdr (p64[i].p_type, -p64[i].p_vaddr, p64[i].p_memsz, -p64[i].p_offset, p64[i].p_filesz, -p64[i].p_align); + for (uint_fast16_t i = 0; i < phnum; ++i) +{ + bool is32 = (ei_class == ELFCLASS32); + GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type; + GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr; + GElf_Xword memsz = is32 ? p32[i].p_memsz : p64[i].p_memsz; + GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset; + GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; + GElf_Xword align = is32 ? p32[i].p_align : p64[i].p_align; + + consider_phdr (type, vaddr, memsz, offset, filesz, align); +} } finish_portion (dwfl, memory_callback, memory_callback_arg, &ph_buffer, &ph_buffer_size); @@ -967,14 +967,16 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, } } - if (ei_class == ELFCLASS32) - for (uint_fast16_t i = 0; i < phnum; ++i) - read_phdr (p32[i].p_type, p32[i].p_vaddr, -p32[i].p_offset, p32[i].p_filesz); - else - for (uint_fast16_t i = 0; i < phnum; ++i) - read_phdr (p64[i].p_type, p64[i].p_vaddr, -p64[i].p_offset, p64[i].p_filesz); + for (uint_fast16_t i = 0; i < phnum; ++i) +{ + bool is32 = (ei_class == ELFCLASS32); + GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type; + GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr; + GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset; + GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; + + read_phdr (type, vaddr, offset, filesz); +} } else { -- 2.26.2
Removing gnu99 constructs from elfutils
Hi, I'm looking into removing both the nested functions as well as variable-length arrays in the elfutils source code, so it can be built using clang. This is a continuation of https://sourceware.org/bugzilla/show_bug.cgi?id=24964 basically. I did try to incorporate some cleanup commits as well so the result does not get too ugly. Some of the nested functions have quite a few hidden dependencies on the surrounding code. I started with libdwfl/dwfl_segment_report_module.c but am planning on converting everything else as well of course. What do you think? Thanks, Timm
[PATCH 09/14] segment_report_module: Get rid of nested final_read() function
Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 76686a72..80f97cfd 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -948,15 +948,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (unlikely (contents == NULL)) goto out; - inline void final_read (size_t offset, GElf_Addr vaddr, size_t size) - { - void *into = contents + offset; - size_t read_size = size; - (void) segment_read (dwfl, memory_callback, memory_callback_arg, - addr_segndx (dwfl, segment, vaddr, false), -&into, &read_size, vaddr, size); - } - if (contiguous < file_trimmed_end) { /* We can't use the memory image verbatim as the file image. @@ -966,7 +957,14 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, GElf_Off offset, GElf_Xword filesz) { if (type == PT_LOAD) - final_read (offset, vaddr + bias, filesz); + { +void *into = contents + offset; +size_t read_size = filesz; +(void)segment_read (dwfl, memory_callback, memory_callback_arg, +addr_segndx (dwfl, segment, vaddr + bias, false), +&into, &read_size, vaddr + bias, read_size); + + } } if (ei_class == ELFCLASS32) @@ -987,7 +985,13 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, memcpy (contents, buffer, have); if (have < file_trimmed_end) - final_read (have, start + have, file_trimmed_end - have); +{ + void *into = contents + have; + size_t read_size = file_trimmed_end - have; + (void)segment_read (dwfl, memory_callback, memory_callback_arg, + addr_segndx (dwfl, segment, start + have, false), + &into, &read_size, start + have, read_size); +} } elf = elf_memory (contents, file_trimmed_end); -- 2.26.2
[PATCH 03/14] segment_report_module: Remove nested finish() function
This works just as well with a goto-out style label. Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 50 +--- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 9f06672a..d06d0ba0 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -285,22 +285,11 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, here so we can always safely free it. */ void *phdrsp = NULL; - inline int finish (void) - { -free (phdrsp); -release_buffer (&buffer, &buffer_available); -if (elf != NULL) - elf_end (elf); -if (fd != -1) - close (fd); -return ndx; - } - if (segment_read (dwfl, memory_callback, memory_callback_arg, ndx, &buffer, &buffer_available, start, sizeof (Elf64_Ehdr)) || memcmp (buffer, ELFMAG, SELFMAG) != 0) -return finish (); +goto out; inline bool read_portion (void **data, size_t *data_size, GElf_Addr vaddr, size_t filesz) @@ -368,13 +357,13 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, case ELFCLASS32: xlatefrom.d_size = sizeof (Elf32_Ehdr); if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) - return finish (); + goto out; e_type = ehdr.e32.e_type; phoff = ehdr.e32.e_phoff; phnum = ehdr.e32.e_phnum; phentsize = ehdr.e32.e_phentsize; if (phentsize != sizeof (Elf32_Phdr)) - return finish (); + goto out; /* NOTE if the number of sections is > 0xff00 then e_shnum is zero and the actual number would come from the section zero sh_size field. We ignore this here because getting shdrs @@ -386,19 +375,19 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, case ELFCLASS64: xlatefrom.d_size = sizeof (Elf64_Ehdr); if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) - return finish (); + goto out; e_type = ehdr.e64.e_type; phoff = ehdr.e64.e_phoff; phnum = ehdr.e64.e_phnum; phentsize = ehdr.e64.e_phentsize; if (phentsize != sizeof (Elf64_Phdr)) - return finish (); + goto out; /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */ shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize; break; default: - return finish (); + goto out; } /* The file header tells where to find the program headers. @@ -406,7 +395,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Without them, we don't have a module to report. */ if (phnum == 0) -return finish (); +goto out; xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR; xlatefrom.d_size = phnum * phentsize; @@ -415,7 +404,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, size_t ph_buffer_size = 0; if (read_portion (&ph_buffer, &ph_buffer_size, start + phoff, xlatefrom.d_size)) -return finish (); +goto out; /* ph_buffer_size will be zero if we got everything from the initial buffer, otherwise it will be the size of the new buffer that @@ -428,11 +417,11 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, bool class32 = ei_class == ELFCLASS32; size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); if (unlikely (phnum > SIZE_MAX / phdr_size)) -return finish (); +goto out; const size_t phdrsp_bytes = phnum * phdr_size; phdrsp = malloc (phdrsp_bytes); if (unlikely (phdrsp == NULL)) -return finish (); +goto out; xlateto.d_buf = phdrsp; xlateto.d_size = phdrsp_bytes; @@ -643,7 +632,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (unlikely (!found_bias)) { free (build_id); - return finish (); + goto out; } /* Now we know enough to report a module for sure: its bounds. */ @@ -714,7 +703,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (skip_this_module) { free (build_id); - return finish (); + goto out; } } @@ -804,7 +793,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Elf32_Dyn *d32 = dyns; Elf64_Dyn *d64 = dyns; if (unlikely (dyns == NULL)) - return finish (); + goto out; xlatefrom.d_type = xlateto.d_type = ELF_T_DYN; xlatefrom.d_buf = (void *) dyn_data; @@ -894,7 +883,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, if (unlikely (mod == NULL)) { ndx = -1; - return finish (); + goto out; } /* We have reported the module. Now let the caller decide whether we @@ -918,7 +907,7 @@ dwfl_segment_repor
[PATCH 11/14] segment_report_module: Inline read_phdr() into only caller
There is now only one caller for this nested function, so get rid of it by just inlining it there. Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 25 + 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 2535f9e3..bcf69fe7 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -952,30 +952,23 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, { /* We can't use the memory image verbatim as the file image. So we'll be reading into a local image of the virtual file. */ - - inline void read_phdr (GElf_Word type, GElf_Addr vaddr, -GElf_Off offset, GElf_Xword filesz) - { - if (type == PT_LOAD) - { -void *into = contents + offset; -size_t read_size = filesz; -(void)segment_read (dwfl, memory_callback, memory_callback_arg, -addr_segndx (dwfl, segment, vaddr + bias, false), -&into, &read_size, vaddr + bias, read_size); - - } - } - for (uint_fast16_t i = 0; i < phnum; ++i) { bool is32 = (ei_class == ELFCLASS32); GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type; + + if (type != PT_LOAD) +continue; + GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr; GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset; GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz; - read_phdr (type, vaddr, offset, filesz); + void *into = contents + offset; + size_t read_size = filesz; + (void)segment_read (dwfl, memory_callback, memory_callback_arg, + addr_segndx (dwfl, segment, vaddr + bias, false), + &into, &read_size, vaddr + bias, read_size); } } else -- 2.26.2
[PATCH 12/14] segment_report_module: Unify d32/d64 loops
Just like we did before, use only one loop here and check for 32/64 bit in the loop body. This way we only have one call site for consider_dyn Signed-off-by: Timm Bäder --- libdwfl/dwfl_segment_report_module.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index bcf69fe7..7c97784f 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -838,20 +838,20 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, xlateto.d_buf = dyns; xlateto.d_size = dyn_filesz; - if (ei_class == ELFCLASS32) - { - if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) - for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i) - if (consider_dyn (d32[i].d_tag, d32[i].d_un.d_val)) - break; - } - else - { - if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) - for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i) - if (consider_dyn (d64[i].d_tag, d64[i].d_un.d_val)) - break; - } + bool is32 = (ei_class == ELFCLASS32); + if ((is32 && elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL) + || (!is32 && elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)) +{ + size_t n = is32 ? (dyn_filesz / sizeof (Elf32_Dyn)) : (dyn_filesz / sizeof (Elf64_Dyn)); + for (size_t i = 0; i < n; ++i) +{ + GElf_Sxword tag = is32 ? d32[i].d_tag : d64[i].d_tag; + GElf_Xword val = is32 ? d32[i].d_un.d_val : d64[i].d_un.d_val; + + if (consider_dyn (tag, val)) +break; +} +} free (dyns); } finish_portion (dwfl, memory_callback, memory_callback_arg, &dyn_data, &dyn_data_size); -- 2.26.2
[Bug libdw/22252] Parallel parsing of CU's DIEs from libdw
https://sourceware.org/bugzilla/show_bug.cgi?id=22252 Ben Woodard changed: What|Removed |Added Status|WAITING |RESOLVED Resolution|--- |FIXED --- Comment #2 from Ben Woodard --- Yea done. -- You are receiving this mail because: You are on the CC list for the bug.
Re: [PATCH 14/14] segment_report_module: Inline consider_phdr() into only caller
On 12/11/2020 17:52, Navin P wrote: Hi, I already have a patch that makes elfutils compile with clang. Since you are working this will be of use to you. I've attached the patch since it is big. Here are some of the changes 1. All functions at file scope have static qualifier so that no collison with other files. 2. Non global variables declared in the outer function should be passed as pointer variable in the new outer file scope function whenever they are assigned in the nested function. The argument addition in new functions are at the end. 3. With the applied patch above , gcc passes all 220 tests where clang fails 3 tests which is due to llvm_addrsig (change in libelf/elf.h ) and other 2 tests are error related to .rela.eh_frame. Thanks, Navin. Has this been proposed for inclusion in elfutils? What's the status on that? Or are you just keeping this locally? Looking at the patch, I'm not really a fan of a few of those changes, from a code point of view. consider_phdr() takes 35 arguments now for example. Do you have more information on the test failures? Are they caused by LLVM/clang bugs? Thanks, Timm