[PATCH] libdwfl: Move nested function in dwfl_segment_report_module.c

Yunlian Jiang via elfutils-devel elfutils-devel@sourceware.org
Fri Jul 28 16:36:00 GMT 2017


This moves part of nested functions in dwfl_segment_report_module.c to file
scope.
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
    * Move nested function 'segment_read' to file scope to compile with clang.
    * Move nested function 'release_buffer' to file scope to compile with clang.
    * Move nested function 'read_portion' to file scope to compile with clang.
    * Move nested function 'finish_portion' to file scope to compile with clang.

>From 47a9587f4c8aa10b155b054e892109b57c6e0ad4 Mon Sep 17 00:00:00 2001
From: Yunlian Jiang <yunlian@google.com>
Date: Fri, 28 Jul 2017 09:27:20 -0700
Subject: [PATCH] libdwfl: move nested function in dwfl_segment_report_module.c

* Move nested function 'segment_read' to file scope to compile with clang.
* Move nested function 'release_buffer' to file scope to compile with clang.
* Move nested function 'read_portion' to file scope to compile with clang.
* Move nested function 'finish_portion' to file scope to compile with clang.

Signed-off-by: Yunlian Jiang <yunlian@google.com>
---
 libdwfl/dwfl_segment_report_module.c | 198 +++++++++++++++++++++--------------
 1 file changed, 120 insertions(+), 78 deletions(-)

diff --git a/libdwfl/dwfl_segment_report_module.c
b/libdwfl/dwfl_segment_report_module.c
index 207a2573..462cb7d5 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -232,6 +232,85 @@ invalid_elf (Elf *elf, bool disk_file_has_build_id,
   return false;
 }

+static inline bool
+segment_read (int segndx, void **buffer, size_t *buffer_available,
+      GElf_Addr addr, size_t minread, Dwfl *dwfl,
+      Dwfl_Memory_Callback *memory_callback,
+      void *memory_callback_arg)
+{
+  return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
+               addr, minread, memory_callback_arg);
+}
+
+static inline void
+release_buffer (void **buffer, size_t *buffer_available,
+ Dwfl *dwfl,
+ Dwfl_Memory_Callback *memory_callback,
+ void *memory_callback_arg)
+{
+  if (*buffer != NULL)
+    (void) segment_read (-1, buffer, buffer_available, 0, 0, dwfl,
+         memory_callback, memory_callback_arg);
+}
+
+static inline int
+finish(void *phdrsp, void *buffer, size_t buffer_available,
+       Elf *elf, int fd, int ndx, Dwfl *dwfl,
+       Dwfl_Memory_Callback *memory_callback,
+       void *memory_callback_arg)
+
+{
+  free (phdrsp);
+  release_buffer (&buffer, &buffer_available, dwfl, memory_callback,
+  memory_callback_arg);
+  if (elf != NULL)
+    elf_end (elf);
+  if (fd != -1)
+    close (fd);
+  return ndx;
+}
+
+#define DO_REAL_FINISH finish(phdrsp, buffer, buffer_available, elf, fd, ndx, \
+ dwfl, memory_callback, memory_callback_arg)
+
+static  inline bool
+read_portion (void **data, size_t *data_size,
+      GElf_Addr vaddr, size_t filesz,
+      GElf_Addr start, size_t segment,
+      void *buffer, size_t buffer_available,
+      Dwfl *dwfl,
+      Dwfl_Memory_Callback *memory_callback,
+      void *memory_callback_arg
+      )
+{
+  if (vaddr - start + filesz > buffer_available
+      /* 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 (addr_segndx (dwfl, segment, vaddr, false),
+   data, data_size, vaddr, filesz,
+   dwfl, memory_callback, memory_callback_arg);
+    }
+
+    /* We already have this whole note segment from our initial read.  */
+  *data = vaddr - start + buffer;
+  *data_size = 0;
+  return false;
+}
+
+static inline void
+finish_portion (void **data, size_t *data_size, Dwfl *dwfl,
+ Dwfl_Memory_Callback *memory_callback,
+ void *memory_callback_arg)
+{
+  if (*data_size != 0)
+    release_buffer (data, data_size, dwfl, memory_callback,
memory_callback_arg);
+}
+
 int
 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
     Dwfl_Memory_Callback *memory_callback,
@@ -257,20 +336,6 @@ 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);
-  }
-
   /* First read in the file header and check its sanity.  */

   void *buffer = NULL;
@@ -282,48 +347,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 (ndx, &buffer, &buffer_available,
-    start, sizeof (Elf64_Ehdr))
+    start, sizeof (Elf64_Ehdr),
+    dwfl, memory_callback, memory_callback_arg)
       || memcmp (buffer, ELFMAG, SELFMAG) != 0)
-    return finish ();
-
-  inline bool read_portion (void **data, size_t *data_size,
-    GElf_Addr vaddr, size_t filesz)
-  {
-    if (vaddr - start + filesz > buffer_available
- /* 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 (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;
-  }
-
-  inline void finish_portion (void **data, size_t *data_size)
-  {
-    if (*data_size != 0)
-      release_buffer (data, data_size);
-  }
+    return DO_REAL_FINISH;

   /* Extract the information we need from the file header.  */
   const unsigned char *e_ident;
@@ -360,31 +388,31 @@ 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 ();
+ return DO_REAL_FINISH;
       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 ();
+ return DO_REAL_FINISH;
       shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
       break;

     case ELFCLASS64:
       xlatefrom.d_size = sizeof (Elf64_Ehdr);
       if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
- return finish ();
+ return DO_REAL_FINISH;
       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 ();
+ return DO_REAL_FINISH;
       shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
       break;

     default:
-      return finish ();
+      return DO_REAL_FINISH;
     }

   /* The file header tells where to find the program headers.
@@ -392,7 +420,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 ();
+    return DO_REAL_FINISH;

   xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
   xlatefrom.d_size = phnum * phentsize;
@@ -400,19 +428,21 @@ 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))
-    return finish ();
+    start + phoff, xlatefrom.d_size,
+    start, segment, buffer, buffer_available,
+    dwfl, memory_callback, memory_callback_arg))
+    return DO_REAL_FINISH;

   xlatefrom.d_buf = ph_buffer;

   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 ();
+    return DO_REAL_FINISH;
   const size_t phdrsp_bytes = phnum * phdr_size;
   phdrsp = malloc (phdrsp_bytes);
   if (unlikely (phdrsp == NULL))
-    return finish ();
+    return DO_REAL_FINISH;

   xlateto.d_buf = phdrsp;
   xlateto.d_size = phdrsp_bytes;
@@ -450,7 +480,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 (&data, &data_size, vaddr, filesz,
+      start, segment, buffer, buffer_available,
+      dwfl, memory_callback, memory_callback_arg))
       return;

     assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
@@ -501,7 +533,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,
   done:
     if (notes != data)
       free (notes);
-    finish_portion (&data, &data_size);
+    finish_portion (&data, &data_size,
+    dwfl, memory_callback, memory_callback_arg);
   }

   /* Consider each of the program headers we've read from the image.  */
@@ -598,14 +631,15 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,
  (*p64)[i].p_align);
     }

-  finish_portion (&ph_buffer, &ph_buffer_size);
+  finish_portion (&ph_buffer, &ph_buffer_size,
+  dwfl, memory_callback, memory_callback_arg);

   /* 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.  */
   if (unlikely (!found_bias))
     {
       free (build_id);
-      return finish ();
+      return DO_REAL_FINISH;
     }

   /* Now we know enough to report a module for sure: its bounds.  */
@@ -676,7 +710,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,
       if (skip_this_module)
  {
   free (build_id);
-  return finish ();
+  return DO_REAL_FINISH;
  }
     }

@@ -754,13 +788,15 @@ 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 (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz,
+         start, segment, buffer, buffer_available,
+     dwfl, memory_callback, memory_callback_arg))
     {
       void *dyns = malloc (dyn_filesz);
       Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
       Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
       if (unlikely (dyns == NULL))
- return finish ();
+ return DO_REAL_FINISH;

       xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
       xlatefrom.d_buf = (void *) dyn_data;
@@ -784,7 +820,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,
  }
       free (dyns);
     }
-  finish_portion (&dyn_data, &dyn_data_size);
+  finish_portion (&dyn_data, &dyn_data_size,
+  dwfl, memory_callback, memory_callback_arg);

   /* We'll use the name passed in or a stupid default if not DT_SONAME.  */
   if (name == NULL)
@@ -817,7 +854,9 @@ 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))
+     dynstr_vaddr + soname_stroff, 0,
+     start, segment, buffer, buffer_available,
+     dwfl, memory_callback, memory_callback_arg))
  name = soname;
     }

@@ -845,12 +884,13 @@ 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 (&soname, &soname_size,
+  dwfl, memory_callback, memory_callback_arg);

   if (unlikely (mod == NULL))
     {
       ndx = -1;
-      return finish ();
+      return DO_REAL_FINISH;
     }

   /* We have reported the module.  Now let the caller decide whether we
@@ -874,14 +914,15 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,

       void *contents = calloc (1, file_trimmed_end);
       if (unlikely (contents == NULL))
- return finish ();
+ return DO_REAL_FINISH;

       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 (addr_segndx (dwfl, segment, vaddr, false),
-     &into, &read_size, vaddr, size);
+     &into, &read_size, vaddr, size,
+     dwfl, memory_callback, memory_callback_arg);
       }

       if (contiguous < file_trimmed_end)
@@ -935,5 +976,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx,
const char *name,
       mod->main_bias = bias;
     }

-  return finish ();
+  return DO_REAL_FINISH;
 }
+#undef DO_REAL_FINISH
-- 
2.14.0.rc0.400.g1c36432dff-goog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-libdwfl-move-nested-function-in-dwfl_segment_report_.patch
Type: text/x-patch
Size: 13027 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/elfutils-devel/attachments/20170728/6d582720/attachment.bin>


More information about the Elfutils-devel mailing list