public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* Remove remaining nested functions from libdwfl
@ 2020-11-26 14:10 tbaeder
  2020-11-26 14:10 ` [PATCH 1/3] segment_report_module: Pull finish_portion() into file scope tbaeder
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: tbaeder @ 2020-11-26 14:10 UTC (permalink / raw)
  To: elfutils-devel

Here are the three patches to remove the three remaining nested
functions from libdwfl/dwfl_segment_report_module.c.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] segment_report_module: Pull finish_portion() into file scope
  2020-11-26 14:10 Remove remaining nested functions from libdwfl tbaeder
@ 2020-11-26 14:10 ` tbaeder
  2020-11-26 14:10 ` [PATCH 2/3] segment_report_module: Pull read_portion() " tbaeder
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: tbaeder @ 2020-11-26 14:10 UTC (permalink / raw)
  To: elfutils-devel

From: Timm Bäder <tbaeder@redhat.com>

Use a read_state struct here to minimize the amount of parameters we
pass.
---
 libdwfl/dwfl_segment_report_module.c | 38 ++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index 7e747184..391fd761 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -61,6 +61,14 @@ struct elf_build_id
   GElf_Addr vaddr;
 };
 
+struct read_state
+{
+  Dwfl *dwfl;
+  Dwfl_Memory_Callback *memory_callback;
+  void *memory_callback_arg;
+  void **buffer;
+  size_t *buffer_available;
+};
 
 /* Return user segment index closest to ADDR but not above it.
    If NEXT, return the closest to ADDR but not below it.  */
@@ -239,6 +247,15 @@ invalid_elf (Elf *elf, bool disk_file_has_build_id,
   return false;
 }
 
+static void
+finish_portion (struct read_state *read_state,
+		void **data, size_t *data_size)
+{
+  if (*data_size != 0 && *data != NULL)
+    (*read_state->memory_callback) (read_state->dwfl, -1, data, data_size,
+				    0, 0, read_state->memory_callback_arg);
+}
+
 int
 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
 			    Dwfl_Memory_Callback *memory_callback,
@@ -249,6 +266,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
 			    const struct r_debug_info *r_debug_info)
 {
   size_t segment = ndx;
+  struct read_state read_state;
 
   if (segment >= dwfl->lookup_elts)
     segment = dwfl->lookup_elts - 1;
@@ -271,6 +289,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
   Elf *elf = NULL;
   int fd = -1;
 
+  read_state.dwfl = dwfl;
+  read_state.memory_callback = memory_callback;
+  read_state.memory_callback_arg = memory_callback_arg;
+  read_state.buffer = &buffer;
+  read_state.buffer_available = &buffer_available;
+
   /* We might have to reserve some memory for the phdrs.  Set to NULL
      here so we can always safely free it.  */
   void *phdrsp = NULL;
@@ -306,12 +330,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)
-      (*memory_callback) (dwfl, -1, data, data_size, 0, 0, memory_callback_arg);
-  }
-
   /* Extract the information we need from the file header.  */
   const unsigned char *e_ident;
   unsigned char ei_class;
@@ -519,7 +537,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 (&read_state, &data, &data_size);
   }
 
   Elf32_Phdr *p32 = phdrsp;
@@ -609,7 +627,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
         }
     }
 
-  finish_portion (&ph_buffer, &ph_buffer_size);
+  finish_portion (&read_state, &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.  */
@@ -787,7 +805,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
         }
       free (dyns);
     }
-  finish_portion (&dyn_data, &dyn_data_size);
+  finish_portion (&read_state, &dyn_data, &dyn_data_size);
 
   /* We'll use the name passed in or a stupid default if not DT_SONAME.  */
   if (name == NULL)
@@ -848,7 +866,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.memory);
-  finish_portion (&soname, &soname_size);
+  finish_portion (&read_state, &soname, &soname_size);
 
   if (unlikely (mod == NULL))
     {
-- 
2.26.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/3] segment_report_module: Pull read_portion() into file scope
  2020-11-26 14:10 Remove remaining nested functions from libdwfl tbaeder
  2020-11-26 14:10 ` [PATCH 1/3] segment_report_module: Pull finish_portion() into file scope tbaeder
@ 2020-11-26 14:10 ` tbaeder
  2020-11-26 14:10 ` [PATCH 3/3] segment_report_module: Inline consider_notes() into only caller tbaeder
  2020-11-28  1:02 ` Remove remaining nested functions from libdwfl Mark Wielaard
  3 siblings, 0 replies; 5+ messages in thread
From: tbaeder @ 2020-11-26 14:10 UTC (permalink / raw)
  To: elfutils-devel

From: Timm Bäder <tbaeder@redhat.com>

---
 libdwfl/dwfl_segment_report_module.c | 65 +++++++++++++++-------------
 1 file changed, 35 insertions(+), 30 deletions(-)

diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index 391fd761..a082886a 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -256,6 +256,35 @@ finish_portion (struct read_state *read_state,
 				    0, 0, read_state->memory_callback_arg);
 }
 
+static inline bool
+read_portion (struct read_state *read_state,
+	      void **data, size_t *data_size,
+	      GElf_Addr start, size_t segment,
+	      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 > *read_state->buffer_available
+      || vaddr - start > *read_state->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 + *read_state->buffer, '\0',
+				 *read_state->buffer_available - (vaddr - start)) == NULL))
+    {
+      *data = NULL;
+      *data_size = filesz;
+      return ! (*read_state->memory_callback) (read_state->dwfl,
+					       addr_segndx (read_state->dwfl, segment, vaddr, false),
+					       data, data_size, vaddr, filesz,
+					       read_state->memory_callback_arg);
+    }
+
+  /* We already have this whole note segment from our initial read.  */
+  *data = vaddr - start + (*read_state->buffer);
+  *data_size = 0;
+  return false;
+}
+
 int
 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
 			    Dwfl_Memory_Callback *memory_callback,
@@ -304,32 +333,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;
@@ -410,7 +413,8 @@ 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,
+  if (read_portion (&read_state, &ph_buffer, &ph_buffer_size,
+		    start, segment,
 		    start + phoff, xlatefrom.d_size))
     goto out;
 
@@ -469,7 +473,7 @@ 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 (&read_state, &data, &data_size, start, segment, vaddr, filesz))
       return;
 
     /* data_size will be zero if we got everything from the initial
@@ -756,7 +760,7 @@ 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 (&read_state, &dyn_data, &dyn_data_size, start, segment, dyn_vaddr, dyn_filesz))
     {
       /* 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
@@ -837,7 +841,8 @@ 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,
+	  && ! read_portion (&read_state, &soname, &soname_size,
+			     start, segment,
 			     dynstr_vaddr + soname_stroff, 0))
 	name = soname;
     }
-- 
2.26.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/3] segment_report_module: Inline consider_notes() into only caller
  2020-11-26 14:10 Remove remaining nested functions from libdwfl tbaeder
  2020-11-26 14:10 ` [PATCH 1/3] segment_report_module: Pull finish_portion() into file scope tbaeder
  2020-11-26 14:10 ` [PATCH 2/3] segment_report_module: Pull read_portion() " tbaeder
@ 2020-11-26 14:10 ` tbaeder
  2020-11-28  1:02 ` Remove remaining nested functions from libdwfl Mark Wielaard
  3 siblings, 0 replies; 5+ messages in thread
From: tbaeder @ 2020-11-26 14:10 UTC (permalink / raw)
  To: elfutils-devel

From: Timm Bäder <tbaeder@redhat.com>

Get rid of a nested function this way.
---
 libdwfl/dwfl_segment_report_module.c | 162 +++++++++++++--------------
 1 file changed, 80 insertions(+), 82 deletions(-)

diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index a082886a..c48d9ab7 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -463,87 +463,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 (&read_state, &data, &data_size, start, segment, vaddr, filesz))
-      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)
-	  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 (&read_state, &data, &data_size);
-  }
-
   Elf32_Phdr *p32 = phdrsp;
   Elf64_Phdr *p64 = phdrsp;
   if ((ei_class == ELFCLASS32
@@ -573,9 +492,88 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
             }
           else if (type == PT_NOTE)
             {
+              /* If we have already seen a build ID, we don't care any more.  */
+              if (build_id.memory != NULL || filesz == 0)
+                continue; /* Next header */
+
               /* We calculate from the p_offset of the note segment,
                because we don't yet know the bias for its p_vaddr.  */
-              consider_notes ( start + offset, filesz, align);
+              const size_t note_vaddr = start + offset;
+              void *data;
+              size_t data_size;
+              if (read_portion (&read_state, &data, &data_size, start, segment, note_vaddr, filesz))
+                continue; /* Next header */
+
+              /* 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
+                {
+                  const unsigned int xencoding = ehdr.e32.e_ident[EI_DATA];
+
+                  notes = malloc (filesz);
+                  if (unlikely (notes == NULL))
+                    continue; /* Next header */
+                  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)
+                    {
+                      free (notes);
+                      finish_portion (&read_state, &data, &data_size);
+                      continue;
+                    }
+                }
+
+              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 + note_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;
+                }
+
+              if (notes != data)
+                free (notes);
+              finish_portion (&read_state, &data, &data_size);
             }
           else if (type == PT_LOAD)
             {
-- 
2.26.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Remove remaining nested functions from libdwfl
  2020-11-26 14:10 Remove remaining nested functions from libdwfl tbaeder
                   ` (2 preceding siblings ...)
  2020-11-26 14:10 ` [PATCH 3/3] segment_report_module: Inline consider_notes() into only caller tbaeder
@ 2020-11-28  1:02 ` Mark Wielaard
  3 siblings, 0 replies; 5+ messages in thread
From: Mark Wielaard @ 2020-11-28  1:02 UTC (permalink / raw)
  To: tbaeder, elfutils-devel

On Thu, 2020-11-26 at 15:10 +0100, Timm Bäder via Elfutils-devel wrote:
> Here are the three patches to remove the three remaining nested
> functions from libdwfl/dwfl_segment_report_module.c.

Thanks those look good. Pushed.

I did add ChangeLog entries and made sure all lines were < 80 chars.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-28  1:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-26 14:10 Remove remaining nested functions from libdwfl tbaeder
2020-11-26 14:10 ` [PATCH 1/3] segment_report_module: Pull finish_portion() into file scope tbaeder
2020-11-26 14:10 ` [PATCH 2/3] segment_report_module: Pull read_portion() " tbaeder
2020-11-26 14:10 ` [PATCH 3/3] segment_report_module: Inline consider_notes() into only caller tbaeder
2020-11-28  1:02 ` Remove remaining nested functions from libdwfl Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).