[PATCH] Move nested functions in dwarf_entry_breakpoints.c to file scope.
by Chih-Hung Hsieh
No nested functions to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdw/ChangeLog | 5 ++
libdw/dwarf_entry_breakpoints.c | 110 +++++++++++++++++++++-------------------
2 files changed, 64 insertions(+), 51 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 39c49aa..b91c8c7 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-14 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Move recursive
+ functions 'add_bkpt', 'entrypc_bkpt', and 'search_range' to file scope.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
diff --git a/libdw/dwarf_entry_breakpoints.c b/libdw/dwarf_entry_breakpoints.c
index abfee73..c3c0f39 100644
--- a/libdw/dwarf_entry_breakpoints.c
+++ b/libdw/dwarf_entry_breakpoints.c
@@ -34,54 +34,40 @@
#include <stdlib.h>
-int
-dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
+/* Add one breakpoint location to the result vector. */
+static inline int
+add_bkpt (Dwarf_Addr pc, Dwarf_Addr **bkpts, int *pnbkpts)
{
- int nbkpts = 0;
- *bkpts = NULL;
-
- /* Add one breakpoint location to the result vector. */
- inline int add_bkpt (Dwarf_Addr pc)
- {
- Dwarf_Addr *newlist = realloc (*bkpts, ++nbkpts * sizeof newlist[0]);
- if (newlist == NULL)
- {
- free (*bkpts);
- *bkpts = NULL;
- __libdw_seterrno (DWARF_E_NOMEM);
- return -1;
- }
- newlist[nbkpts - 1] = pc;
- *bkpts = newlist;
- return nbkpts;
- }
-
- /* Fallback result, break at the entrypc/lowpc value. */
- inline int entrypc_bkpt (void)
+ Dwarf_Addr *newlist = realloc (*bkpts, ++(*pnbkpts) * sizeof newlist[0]);
+ if (newlist == NULL)
{
- Dwarf_Addr pc;
- return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc);
- }
-
- /* Fetch the CU's line records to look for this DIE's addresses. */
- Dwarf_Die cudie = CUDIE (die->cu);
- Dwarf_Lines *lines;
- size_t nlines;
- if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0)
- {
- int error = INTUSE (dwarf_errno) ();
- if (error == 0) /* CU has no DW_AT_stmt_list. */
- return entrypc_bkpt ();
- __libdw_seterrno (error);
+ free (*bkpts);
+ *bkpts = NULL;
+ __libdw_seterrno (DWARF_E_NOMEM);
return -1;
}
+ newlist[*pnbkpts - 1] = pc;
+ *bkpts = newlist;
+ return *pnbkpts;
+}
- /* Search a contiguous PC range for prologue-end markers.
- If DWARF, look for proper markers.
- Failing that, if ADHOC, look for the ad hoc convention. */
- inline int search_range (Dwarf_Addr low, Dwarf_Addr high,
- bool dwarf, bool adhoc)
- {
+/* Fallback result, break at the entrypc/lowpc value. */
+static inline int
+entrypc_bkpt (Dwarf_Die *die, Dwarf_Addr **bkpts, int *pnbkpts)
+{
+ Dwarf_Addr pc;
+ return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc, bkpts, pnbkpts);
+}
+
+/* Search a contiguous PC range for prologue-end markers.
+ If DWARF, look for proper markers.
+ Failing that, if ADHOC, look for the ad hoc convention. */
+static inline int
+search_range (Dwarf_Addr low, Dwarf_Addr high,
+ bool dwarf, bool adhoc,
+ Dwarf_Lines *lines, size_t nlines,
+ Dwarf_Addr **bkpts, int *pnbkpts)
+{
size_t l = 0, u = nlines;
while (l < u)
{
@@ -103,16 +89,35 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
if (dwarf)
for (size_t i = l; i < u && lines->info[i].addr < high; ++i)
if (lines->info[i].prologue_end
- && add_bkpt (lines->info[i].addr) < 0)
+ && add_bkpt (lines->info[i].addr, bkpts, pnbkpts) < 0)
return -1;
- if (adhoc && nbkpts == 0)
+ if (adhoc && *pnbkpts == 0)
while (++l < nlines && lines->info[l].addr < high)
if (!lines->info[l].end_sequence)
- return add_bkpt (lines->info[l].addr);
- return nbkpts;
+ return add_bkpt (lines->info[l].addr, bkpts, pnbkpts);
+ return *pnbkpts;
}
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return -1;
+}
+
+int
+dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
+{
+ int nbkpts = 0;
+ *bkpts = NULL;
+
+ /* Fetch the CU's line records to look for this DIE's addresses. */
+ Dwarf_Die cudie = CUDIE (die->cu);
+ Dwarf_Lines *lines;
+ size_t nlines;
+ if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0)
+ {
+ int error = INTUSE (dwarf_errno) ();
+ if (error == 0) /* CU has no DW_AT_stmt_list. */
+ return entrypc_bkpt (die, bkpts, &nbkpts);
+ __libdw_seterrno (error);
+ return -1;
}
/* Search each contiguous address range for DWARF prologue_end markers. */
@@ -126,14 +131,16 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
/* Most often there is a single contiguous PC range for the DIE. */
if (offset == 1)
- return search_range (begin, end, true, true) ?: entrypc_bkpt ();
+ return search_range (begin, end, true, true, lines, nlines, bkpts, &nbkpts)
+ ?: entrypc_bkpt (die, bkpts, &nbkpts);
Dwarf_Addr lowpc = (Dwarf_Addr) -1l;
Dwarf_Addr highpc = (Dwarf_Addr) -1l;
while (offset > 0)
{
/* We have an address range entry. */
- if (search_range (begin, end, true, false) < 0)
+ if (search_range (begin, end, true, false,
+ lines, nlines, bkpts, &nbkpts) < 0)
return -1;
if (begin < lowpc)
@@ -150,6 +157,7 @@ dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
fall back to just using the entrypc value. */
return (nbkpts
?: (lowpc == (Dwarf_Addr) -1l ? 0
- : search_range (lowpc, highpc, false, true))
- ?: entrypc_bkpt ());
+ : search_range (lowpc, highpc, false, true,
+ lines, nlines, bkpts, &nbkpts))
+ ?: entrypc_bkpt (die, bkpts, &nbkpts));
}
--
2.6.0.rc2.230.g3dd15c0
7 years, 11 months
[PATCH] Move nested functions in libdw_visit_scopes.c to file scope.
by Chih-Hung Hsieh
* No nested functions to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdw/ChangeLog | 5 ++
libdw/libdw_visit_scopes.c | 163 +++++++++++++++++++++++++--------------------
2 files changed, 95 insertions(+), 73 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 39c49aa..56ee808 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-14 Chih-Hung Hsieh <chh(a)google.com>
+
+ * libdw_visit_scopes.c (__libdw_visit_scopes): Move recursive nested
+ function 'walk_children' to file scope; inline 'recurse' at its call site.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
diff --git a/libdw/libdw_visit_scopes.c b/libdw/libdw_visit_scopes.c
index 5e5c26f..9cd5bad 100644
--- a/libdw/libdw_visit_scopes.c
+++ b/libdw/libdw_visit_scopes.c
@@ -64,6 +64,22 @@ may_have_scopes (Dwarf_Die *die)
return false;
}
+struct walk_children_state {
+ /* Parameters of __libdw_visit_scopes. */
+ unsigned int depth;
+ struct Dwarf_Die_Chain *imports;
+ int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+ void *arg;
+ /* Return value of recursive walker. */
+ int ret;
+ /* Extra local variables for the walker. */
+ struct Dwarf_Die_Chain child;
+};
+
+static inline int
+walk_children (struct walk_children_state *state);
+
int
internal_function
__libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root,
@@ -76,95 +92,96 @@ __libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root,
void *),
void *arg)
{
- struct Dwarf_Die_Chain child;
- int ret;
-
- child.parent = root;
- if ((ret = INTUSE(dwarf_child) (&root->die, &child.die)) != 0)
- return ret < 0 ? -1 : 0; // Having zero children is legal.
-
- inline int recurse (void)
+ struct walk_children_state state =
{
- return __libdw_visit_scopes (depth + 1, &child, imports,
- previsit, postvisit, arg);
- }
-
- /* Checks the given DIE hasn't been imported yet to prevent cycles. */
- inline bool imports_contains (Dwarf_Die *die)
- {
- for (struct Dwarf_Die_Chain *import = imports; import != NULL;
- import = import->parent)
- if (import->die.addr == die->addr)
- return true;
-
- return false;
- }
+ .depth = depth,
+ .imports = imports,
+ .previsit = previsit,
+ .postvisit = postvisit,
+ .arg = arg
+ };
+
+ state.child.parent = root;
+ if ((state.ret = INTUSE(dwarf_child) (&root->die, &state.child.die)) != 0)
+ return state.ret < 0 ? -1 : 0; // Having zero children is legal.
+
+ return walk_children (&state);
+}
- inline int walk_children (void)
+static inline int
+walk_children (struct walk_children_state *state)
{
- do
- {
- /* For an imported unit, it is logically as if the children of
- that unit are siblings of the other children. So don't do
- a full recursion into the imported unit, but just walk the
- children in place before moving to the next real child. */
- while (INTUSE(dwarf_tag) (&child.die) == DW_TAG_imported_unit)
- {
- Dwarf_Die orig_child_die = child.die;
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child.die,
- DW_AT_import,
- &attr_mem);
- if (INTUSE(dwarf_formref_die) (attr, &child.die) != NULL
- && INTUSE(dwarf_child) (&child.die, &child.die) == 0)
- {
- if (imports_contains (&orig_child_die))
- {
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
- }
- struct Dwarf_Die_Chain *orig_imports = imports;
- struct Dwarf_Die_Chain import = { .die = orig_child_die,
- .parent = orig_imports };
- imports = &import;
- int result = walk_children ();
- imports = orig_imports;
- if (result != DWARF_CB_OK)
- return result;
- }
-
- /* Any "real" children left? */
- if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die,
- &child.die)) != 0)
- return ret < 0 ? -1 : 0;
- };
-
- child.prune = false;
+ do
+ {
+ /* For an imported unit, it is logically as if the children of
+ that unit are siblings of the other children. So don't do
+ a full recursion into the imported unit, but just walk the
+ children in place before moving to the next real child. */
+ while (INTUSE(dwarf_tag) (&state->child.die) == DW_TAG_imported_unit)
+ {
+ Dwarf_Die orig_child_die = state->child.die;
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&state->child.die,
+ DW_AT_import,
+ &attr_mem);
+ if (INTUSE(dwarf_formref_die) (attr, &state->child.die) != NULL
+ && INTUSE(dwarf_child) (&state->child.die, &state->child.die) == 0)
+ {
+ /* Checks the given DIE hasn't been imported yet
+ to prevent cycles. */
+ bool imported = false;
+ for (struct Dwarf_Die_Chain *import = state->imports; import != NULL;
+ import = import->parent)
+ if (import->die.addr == orig_child_die.addr)
+ {
+ imported = true;
+ break;
+ }
+ if (imported)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+ struct Dwarf_Die_Chain *orig_imports = state->imports;
+ struct Dwarf_Die_Chain import = { .die = orig_child_die,
+ .parent = orig_imports };
+ state->imports = &import;
+ int result = walk_children (state);
+ state->imports = orig_imports;
+ if (result != DWARF_CB_OK)
+ return result;
+ }
+
+ /* Any "real" children left? */
+ if ((state->ret = INTUSE(dwarf_siblingof) (&orig_child_die,
+ &state->child.die)) != 0)
+ return state->ret < 0 ? -1 : 0;
+ };
+
+ state->child.prune = false;
/* previsit is declared NN */
- int result = (*previsit) (depth + 1, &child, arg);
+ int result = (*state->previsit) (state->depth + 1, &state->child, state->arg);
if (result != DWARF_CB_OK)
return result;
- if (!child.prune && may_have_scopes (&child.die)
- && INTUSE(dwarf_haschildren) (&child.die))
+ if (!state->child.prune && may_have_scopes (&state->child.die)
+ && INTUSE(dwarf_haschildren) (&state->child.die))
{
- result = recurse ();
+ result = __libdw_visit_scopes (state->depth + 1, &state->child, state->imports,
+ state->previsit, state->postvisit, state->arg);
if (result != DWARF_CB_OK)
return result;
}
- if (postvisit != NULL)
+ if (state->postvisit != NULL)
{
- result = (*postvisit) (depth + 1, &child, arg);
+ result = (*state->postvisit) (state->depth + 1, &state->child, state->arg);
if (result != DWARF_CB_OK)
return result;
}
- }
- while ((ret = INTUSE(dwarf_siblingof) (&child.die, &child.die)) == 0);
-
- return ret < 0 ? -1 : 0;
- }
+ }
+ while ((state->ret = INTUSE(dwarf_siblingof) (&state->child.die, &state->child.die)) == 0);
- return walk_children ();
+ return state->ret < 0 ? -1 : 0;
}
--
2.6.0.rc2.230.g3dd15c0
7 years, 11 months
[PATCH] Move nested functions in gzip.c to file scope.
by Chih-Hung Hsieh
* libdwfl/gzip.c should now compile with clang.
All local variables used by nested functions are
passed in an unzip_state structure.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdwfl/ChangeLog | 4 +
libdwfl/gzip.c | 269 ++++++++++++++++++++++++++++++------------------------
2 files changed, 152 insertions(+), 121 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5cae434..926c010 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2015-10-21 Chih-Hung Hsieh <chh(a)google.com>
+
+ * gzip.c (unzip): Move nested functions to file scope.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* core-file.c (elf_begin_rand): Replace loff_t with off_t.
diff --git a/libdwfl/gzip.c b/libdwfl/gzip.c
index c81e52e..283c74a 100644
--- a/libdwfl/gzip.c
+++ b/libdwfl/gzip.c
@@ -67,6 +67,95 @@
#define READ_SIZE (1 << 20)
+struct unzip_state {
+ int fd;
+ off_t start_offset;
+ size_t mapped_size;
+ void **whole;
+ void *buffer;
+ size_t size;
+ void *input_buffer;
+ off_t input_pos;
+ gzFile zf;
+};
+
+static inline bool
+bigger_buffer (struct unzip_state *state, size_t start)
+{
+ size_t more = state->size ? state->size * 2 : start;
+ char *b = realloc (state->buffer, more);
+ while (unlikely (b == NULL) && more >= state->size + 1024)
+ b = realloc (state->buffer, more -= 1024);
+ if (unlikely (b == NULL))
+ return false;
+ state->buffer = b;
+ state->size = more;
+ return true;
+}
+
+static inline void
+smaller_buffer (struct unzip_state *state, size_t end)
+{
+ state->buffer =
+ realloc (state->buffer, end) ?: end == 0 ? NULL : state->buffer;
+ state->size = end;
+}
+
+static inline Dwfl_Error
+fail (struct unzip_state *state, Dwfl_Error failure)
+{
+ if (state->input_pos == (off_t) state->mapped_size)
+ *state->whole = state->input_buffer;
+ else
+ {
+ free (state->input_buffer);
+ *state->whole = NULL;
+ }
+ free (state->buffer);
+ return failure;
+}
+
+static inline Dwfl_Error
+zlib_fail (struct unzip_state *state, int result)
+{
+ switch (result)
+ {
+ case Z (MEM_ERROR):
+ return fail (state, DWFL_E_NOMEM);
+ case Z (ERRNO):
+ return fail (state, DWFL_E_ERRNO);
+ default:
+ return fail (state, DWFL_E_ZLIB);
+ }
+}
+
+static Dwfl_Error
+open_stream (struct unzip_state *state)
+{
+ int d = dup (state->fd);
+ if (unlikely (d < 0))
+ return DWFL_E_BADELF;
+ if (state->start_offset != 0)
+ {
+ off_t off = lseek (d, state->start_offset, SEEK_SET);
+ if (off != state->start_offset)
+ {
+ close (d);
+ return DWFL_E_BADELF;
+ }
+ }
+ state->zf = gzdopen (d, "r");
+ if (unlikely (state->zf == NULL))
+ {
+ close (d);
+ return zlib_fail (state, Z (MEM_ERROR));
+ }
+
+ /* From here on, zlib will close D. */
+
+ return DWFL_E_NOERROR;
+}
+
/* If this is not a compressed image, return DWFL_E_BADELF.
If we uncompressed it into *WHOLE, *WHOLE_SIZE, return DWFL_E_NOERROR.
Otherwise return an error for bad compressed data or I/O failure.
@@ -75,84 +164,49 @@
is not null on entry, we'll use it in lieu of repeating a read. */
Dwfl_Error internal_function
-unzip (int fd, off_t start_offset,
- void *mapped, size_t mapped_size,
- void **whole, size_t *whole_size)
+unzip (int _fd, off_t _start_offset,
+ void *mapped, size_t _mapped_size,
+ void **_whole, size_t *whole_size)
{
- void *buffer = NULL;
- size_t size = 0;
- inline bool bigger_buffer (size_t start)
- {
- size_t more = size ? size * 2 : start;
- char *b = realloc (buffer, more);
- while (unlikely (b == NULL) && more >= size + 1024)
- b = realloc (buffer, more -= 1024);
- if (unlikely (b == NULL))
- return false;
- buffer = b;
- size = more;
- return true;
- }
- inline void smaller_buffer (size_t end)
- {
- buffer = realloc (buffer, end) ?: end == 0 ? NULL : buffer;
- size = end;
- }
-
- void *input_buffer = NULL;
- off_t input_pos = 0;
-
- inline Dwfl_Error fail (Dwfl_Error failure)
- {
- if (input_pos == (off_t) mapped_size)
- *whole = input_buffer;
- else
- {
- free (input_buffer);
- *whole = NULL;
- }
- free (buffer);
- return failure;
- }
-
- inline Dwfl_Error zlib_fail (int result)
- {
- switch (result)
- {
- case Z (MEM_ERROR):
- return fail (DWFL_E_NOMEM);
- case Z (ERRNO):
- return fail (DWFL_E_ERRNO);
- default:
- return fail (DWFL_E_ZLIB);
- }
- }
+ struct unzip_state state =
+ {
+ .fd = _fd,
+ .start_offset = _start_offset,
+ .mapped_size = _mapped_size,
+ .whole = _whole,
+ .buffer = NULL,
+ .size = 0,
+ .input_buffer = NULL,
+ .input_pos = 0,
+ .zf = NULL
+ };
if (mapped == NULL)
{
- if (*whole == NULL)
+ if (*state.whole == NULL)
{
- input_buffer = malloc (READ_SIZE);
- if (unlikely (input_buffer == NULL))
+ state.input_buffer = malloc (READ_SIZE);
+ if (unlikely (state.input_buffer == NULL))
return DWFL_E_NOMEM;
- ssize_t n = pread_retry (fd, input_buffer, READ_SIZE, start_offset);
+ ssize_t n = pread_retry (state.fd, state.input_buffer, READ_SIZE, state.start_offset);
if (unlikely (n < 0))
- return zlib_fail (Z (ERRNO));
+ return zlib_fail (&state, Z (ERRNO));
- input_pos = n;
- mapped = input_buffer;
- mapped_size = n;
+ state.input_pos = n;
+ mapped = state.input_buffer;
+ state.mapped_size = n;
}
else
{
- input_buffer = *whole;
- input_pos = mapped_size = *whole_size;
+ state.input_buffer = *state.whole;
+ state.input_pos = state.mapped_size = *whole_size;
}
}
#define NOMAGIC(magic) \
- (mapped_size <= sizeof magic || memcmp (mapped, magic, sizeof magic - 1))
+ (state.mapped_size <= sizeof magic || \
+ memcmp (mapped, magic, sizeof magic - 1))
/* First, look at the header. */
if (NOMAGIC (MAGIC)
@@ -169,39 +223,39 @@ unzip (int fd, off_t start_offset,
The stupid zlib interface has nothing to grok the
gzip file headers except the slow gzFile interface. */
- z_stream z = { .next_in = mapped, .avail_in = mapped_size };
+ z_stream z = { .next_in = mapped, .avail_in = state.mapped_size };
int result = inflateInit (&z);
if (result != Z (OK))
{
inflateEnd (&z);
- return zlib_fail (result);
+ return zlib_fail (&state, result);
}
do
{
- if (z.avail_in == 0 && input_buffer != NULL)
+ if (z.avail_in == 0 && state.input_buffer != NULL)
{
- ssize_t n = pread_retry (fd, input_buffer, READ_SIZE,
- start_offset + input_pos);
+ ssize_t n = pread_retry (state.fd, state.input_buffer, READ_SIZE,
+ state.start_offset + state.input_pos);
if (unlikely (n < 0))
{
inflateEnd (&z);
- return zlib_fail (Z (ERRNO));
+ return zlib_fail (&state, Z (ERRNO));
}
- z.next_in = input_buffer;
+ z.next_in = state.input_buffer;
z.avail_in = n;
- input_pos += n;
+ state.input_pos += n;
}
if (z.avail_out == 0)
{
- ptrdiff_t pos = (void *) z.next_out - buffer;
- if (!bigger_buffer (z.avail_in))
+ ptrdiff_t pos = (void *) z.next_out - state.buffer;
+ if (!bigger_buffer (&state, z.avail_in))
{
result = Z (MEM_ERROR);
break;
}
- z.next_out = buffer + pos;
- z.avail_out = size - pos;
+ z.next_out = state.buffer + pos;
+ z.avail_out = state.size - pos;
}
}
while ((result = do_inflate (&z)) == Z (OK));
@@ -209,87 +263,60 @@ unzip (int fd, off_t start_offset,
#ifdef BZLIB
uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
| z.total_out_lo32);
- smaller_buffer (total_out);
+ smaller_buffer (&state, total_out);
#else
- smaller_buffer (z.total_out);
+ smaller_buffer (&state, z.total_out);
#endif
inflateEnd (&z);
if (result != Z (STREAM_END))
- return zlib_fail (result);
+ return zlib_fail (&state, result);
#else /* gzip only. */
/* Let the decompression library read the file directly. */
- gzFile zf;
- Dwfl_Error open_stream (void)
- {
- int d = dup (fd);
- if (unlikely (d < 0))
- return DWFL_E_BADELF;
- if (start_offset != 0)
- {
- off_t off = lseek (d, start_offset, SEEK_SET);
- if (off != start_offset)
- {
- close (d);
- return DWFL_E_BADELF;
- }
- }
- zf = gzdopen (d, "r");
- if (unlikely (zf == NULL))
- {
- close (d);
- return zlib_fail (Z (MEM_ERROR));
- }
-
- /* From here on, zlib will close D. */
-
- return DWFL_E_NOERROR;
- }
-
- Dwfl_Error result = open_stream ();
+ Dwfl_Error result = open_stream (&state);
- if (result == DWFL_E_NOERROR && gzdirect (zf))
+ if (result == DWFL_E_NOERROR && gzdirect (state.zf))
{
- gzclose (zf);
- return fail (DWFL_E_BADELF);
+ gzclose (state.zf);
+ return fail (&state, DWFL_E_BADELF);
}
if (result != DWFL_E_NOERROR)
- return fail (result);
+ return fail (&state, result);
ptrdiff_t pos = 0;
while (1)
{
- if (!bigger_buffer (1024))
+ if (!bigger_buffer (&state, 1024))
{
- gzclose (zf);
- return zlib_fail (Z (MEM_ERROR));
+ gzclose (state.zf);
+ return zlib_fail (&state, Z (MEM_ERROR));
}
- int n = gzread (zf, buffer + pos, size - pos);
+ int n = gzread (state.zf, state.buffer + pos, state.size - pos);
if (n < 0)
{
int code;
- gzerror (zf, &code);
- gzclose (zf);
- return zlib_fail (code);
+ gzerror (state.zf, &code);
+ gzclose (state.zf);
+ return zlib_fail (&state, code);
}
if (n == 0)
break;
pos += n;
}
- gzclose (zf);
- smaller_buffer (pos);
+ gzclose (state.zf);
+ smaller_buffer (&state, pos);
#endif
- free (input_buffer);
+ free (state.input_buffer);
- *whole = buffer;
- *whole_size = size;
+ *state.whole = state.buffer;
+ *whole_size = state.size;
return DWFL_E_NOERROR;
}
--
2.6.0.rc2.230.g3dd15c0
8 years
[PATCH] No nested functions in dwarf_get{srclines,scopevar}
by Chih-Hung Hsieh
Move nested functions in libdw/dwarf_get{scopevar,srclines}.c
to file scope to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdw/ChangeLog | 8 ++
libdw/dwarf_getscopevar.c | 38 ++++----
libdw/dwarf_getsrclines.c | 241 ++++++++++++++++++++++++++--------------------
3 files changed, 165 insertions(+), 122 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 39c49aa..837ccdf 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-13 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwarf_getscopevar.c (dwarf_getscopevar): Move nested
+ function 'file_matches' to file scope.
+ * dwarf_getsrclines.c (read_srclines): Move nested functions
+ 'advance_pc' and 'add_new_line' to file scope and keep many
+ local state variables within one structure.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
diff --git a/libdw/dwarf_getscopevar.c b/libdw/dwarf_getscopevar.c
index eb50c0a..e59dccd 100644
--- a/libdw/dwarf_getscopevar.c
+++ b/libdw/dwarf_getscopevar.c
@@ -52,6 +52,25 @@ getattr (Dwarf_Die *die, int search_name, Dwarf_Word *value)
&attr_mem), value);
}
+inline static int
+file_matches (Dwarf_Files * files, size_t idx,
+ const char *lastfile, size_t match_file_len,
+ const char *match_file, bool *lastfile_matches)
+{
+ if (idx >= files->nfiles)
+ return false;
+ const char *file = files->info[idx].name;
+ if (file != lastfile)
+ {
+ size_t len = strlen (file);
+ *lastfile_matches = (len >= match_file_len
+ && !memcmp (match_file, file, match_file_len)
+ && (len == match_file_len
+ || file[len - match_file_len - 1] == '/'));
+ }
+ return *lastfile_matches;
+}
+
/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
Ignore the first SKIP_SHADOWS scopes that match the name.
If MATCH_FILE is not null, accept only declaration in that source file;
@@ -72,22 +91,6 @@ dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
size_t match_file_len = match_file == NULL ? 0 : strlen (match_file);
bool lastfile_matches = false;
const char *lastfile = NULL;
- inline bool file_matches (Dwarf_Files *files, size_t idx)
- {
- if (idx >= files->nfiles)
- return false;
-
- const char *file = files->info[idx].name;
- if (file != lastfile)
- {
- size_t len = strlen (file);
- lastfile_matches = (len >= match_file_len
- && !memcmp (match_file, file, match_file_len)
- && (len == match_file_len
- || file[len - match_file_len - 1] == '/'));
- }
- return lastfile_matches;
- }
/* Start with the innermost scope and move out. */
for (int out = 0; out < nscopes; ++out)
@@ -130,7 +133,8 @@ dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
|| getfiles (&scopes[out], &files) != 0)
break;
- if (!file_matches (files, i))
+ if (!file_matches (files, i, lastfile, match_file_len,
+ match_file, &lastfile_matches))
break;
if (match_lineno > 0
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 389c824..a8b57e1 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -78,6 +78,73 @@ compare_lines (const void *a, const void *b)
: 0;
}
+struct line_state {
+ Dwarf_Word addr;
+ unsigned int op_index;
+ unsigned int file;
+ int64_t line;
+ unsigned int column;
+ uint_fast8_t is_stmt;
+ bool basic_block;
+ bool prologue_end;
+ bool epilogue_begin;
+ unsigned int isa;
+ unsigned int discriminator;
+ struct linelist *linelist;
+ size_t nlinelist;
+ unsigned int end_sequence;
+};
+
+static inline void
+run_advance_pc (struct line_state *state, unsigned int op_advance,
+ uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr)
+{
+ state->addr += minimum_instr_len * ((state->op_index + op_advance)
+ / max_ops_per_instr);
+ state->op_index = (state->op_index + op_advance) % max_ops_per_instr;
+}
+
+static inline bool
+add_new_line (struct line_state *state, struct linelist *new_line)
+{
+ /* Set the line information. For some fields we use bitfields,
+ so we would lose information if the encoded values are too large.
+ Check just for paranoia, and call the data "invalid" if it
+ violates our assumptions on reasonable limits for the values. */
+ new_line->next = state->linelist;
+ new_line->sequence = state->nlinelist;
+ state->linelist = new_line;
+ ++(state->nlinelist);
+
+ /* Set the line information. For some fields we use bitfields,
+ so we would lose information if the encoded values are too large.
+ Check just for paranoia, and call the data "invalid" if it
+ violates our assumptions on reasonable limits for the values. */
+#define SET(field) \
+ do { \
+ new_line->line.field = state->field; \
+ if (unlikely (new_line->line.field != state->field)) \
+ return true; \
+ } while (0)
+
+ SET (addr);
+ SET (op_index);
+ SET (file);
+ SET (line);
+ SET (column);
+ SET (is_stmt);
+ SET (basic_block);
+ SET (end_sequence);
+ SET (prologue_end);
+ SET (epilogue_begin);
+ SET (isa);
+ SET (discriminator);
+
+#undef SET
+
+ return false;
+}
+
static int
read_srclines (Dwarf *dbg,
const unsigned char *linep, const unsigned char *lineendp,
@@ -86,8 +153,6 @@ read_srclines (Dwarf *dbg,
{
int res = -1;
- struct linelist *linelist = NULL;
- size_t nlinelist = 0;
size_t nfilelist = 0;
unsigned int ndirlist = 0;
@@ -323,27 +388,28 @@ read_srclines (Dwarf *dbg,
/* We are about to process the statement program. Initialize the
state machine registers (see 6.2.2 in the v2.1 specification). */
- Dwarf_Word addr = 0;
- unsigned int op_index = 0;
- unsigned int file = 1;
- /* We only store an int, but want to check for overflow (see SET below). */
- int64_t line = 1;
- unsigned int column = 0;
- uint_fast8_t is_stmt = default_is_stmt;
- bool basic_block = false;
- bool prologue_end = false;
- bool epilogue_begin = false;
- unsigned int isa = 0;
- unsigned int discriminator = 0;
+ struct line_state state =
+ {
+ .linelist = NULL,
+ .nlinelist = 0,
+ .addr = 0,
+ .op_index = 0,
+ .file = 1,
+ /* We only store an int, but want to check for overflow (see SET below). */
+ .line = 1,
+ .column = 0,
+ .is_stmt = default_is_stmt,
+ .basic_block = false,
+ .prologue_end = false,
+ .epilogue_begin = false,
+ .isa = 0,
+ .discriminator = 0
+ };
/* Apply the "operation advance" from a special opcode or
DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
- inline void advance_pc (unsigned int op_advance)
- {
- addr += minimum_instr_len * ((op_index + op_advance)
- / max_ops_per_instr);
- op_index = (op_index + op_advance) % max_ops_per_instr;
- }
+#define advance_pc(op_advance) \
+ run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr)
/* Process the instructions. */
@@ -352,51 +418,16 @@ read_srclines (Dwarf *dbg,
struct linelist llstack[MAX_STACK_LINES];
#define NEW_LINE(end_seq) \
do { \
- struct linelist *ll = (nlinelist < MAX_STACK_LINES \
- ? &llstack[nlinelist] \
+ struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \
+ ? &llstack[state.nlinelist] \
: malloc (sizeof (struct linelist))); \
if (unlikely (ll == NULL)) \
goto no_mem; \
- if (unlikely (add_new_line (ll, end_seq))) \
+ state.end_sequence = end_seq; \
+ if (unlikely (add_new_line (&state, ll))) \
goto invalid_data; \
} while (0)
- inline bool add_new_line (struct linelist *new_line, bool end_sequence)
- {
- new_line->next = linelist;
- new_line->sequence = nlinelist;
- linelist = new_line;
- ++nlinelist;
-
- /* Set the line information. For some fields we use bitfields,
- so we would lose information if the encoded values are too large.
- Check just for paranoia, and call the data "invalid" if it
- violates our assumptions on reasonable limits for the values. */
-#define SET(field) \
- do { \
- new_line->line.field = field; \
- if (unlikely (new_line->line.field != field)) \
- return true; \
- } while (0)
-
- SET (addr);
- SET (op_index);
- SET (file);
- SET (line);
- SET (column);
- SET (is_stmt);
- SET (basic_block);
- SET (end_sequence);
- SET (prologue_end);
- SET (epilogue_begin);
- SET (isa);
- SET (discriminator);
-
-#undef SET
-
- return false;
- }
-
while (linep < lineendp)
{
unsigned int opcode;
@@ -422,17 +453,17 @@ read_srclines (Dwarf *dbg,
+ (opcode - opcode_base) % line_range);
/* Perform the increments. */
- line += line_increment;
+ state.line += line_increment;
advance_pc ((opcode - opcode_base) / line_range);
/* Add a new line with the current state machine values. */
NEW_LINE (0);
/* Reset the flags. */
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
- discriminator = 0;
+ state.basic_block = false;
+ state.prologue_end = false;
+ state.epilogue_begin = false;
+ state.discriminator = 0;
}
else if (opcode == 0)
{
@@ -457,28 +488,28 @@ read_srclines (Dwarf *dbg,
NEW_LINE (1);
/* Reset the registers. */
- addr = 0;
- op_index = 0;
- file = 1;
- line = 1;
- column = 0;
- is_stmt = default_is_stmt;
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
- discriminator = 0;
+ state.addr = 0;
+ state.op_index = 0;
+ state.file = 1;
+ state.line = 1;
+ state.column = 0;
+ state.is_stmt = default_is_stmt;
+ state.basic_block = false;
+ state.prologue_end = false;
+ state.epilogue_begin = false;
+ state.isa = 0;
+ state.discriminator = 0;
break;
case DW_LNE_set_address:
/* The value is an address. The size is defined as
apporiate for the target machine. We use the
address size field from the CU header. */
- op_index = 0;
+ state.op_index = 0;
if (unlikely (lineendp - linep < (uint8_t) address_size))
goto invalid_data;
if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
- address_size, &addr))
+ address_size, &state.addr))
goto out;
break;
@@ -542,7 +573,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (linep >= lineendp))
goto invalid_data;
- get_uleb128 (discriminator, linep, lineendp);
+ get_uleb128 (state.discriminator, linep, lineendp);
break;
default:
@@ -567,10 +598,10 @@ read_srclines (Dwarf *dbg,
NEW_LINE (0);
/* Reset the flags. */
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
- discriminator = 0;
+ state.basic_block = false;
+ state.prologue_end = false;
+ state.epilogue_begin = false;
+ state.discriminator = 0;
break;
case DW_LNS_advance_pc:
@@ -594,7 +625,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (linep >= lineendp))
goto invalid_data;
get_sleb128 (s128, linep, lineendp);
- line += s128;
+ state.line += s128;
break;
case DW_LNS_set_file:
@@ -605,7 +636,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (linep >= lineendp))
goto invalid_data;
get_uleb128 (u128, linep, lineendp);
- file = u128;
+ state.file = u128;
break;
case DW_LNS_set_column:
@@ -616,7 +647,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (linep >= lineendp))
goto invalid_data;
get_uleb128 (u128, linep, lineendp);
- column = u128;
+ state.column = u128;
break;
case DW_LNS_negate_stmt:
@@ -624,7 +655,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
- is_stmt = 1 - is_stmt;
+ state.is_stmt = 1 - state.is_stmt;
break;
case DW_LNS_set_basic_block:
@@ -632,7 +663,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
- basic_block = true;
+ state.basic_block = true;
break;
case DW_LNS_const_add_pc:
@@ -653,8 +684,8 @@ read_srclines (Dwarf *dbg,
|| unlikely (lineendp - linep < 2))
goto invalid_data;
- addr += read_2ubyte_unaligned_inc (dbg, linep);
- op_index = 0;
+ state.addr += read_2ubyte_unaligned_inc (dbg, linep);
+ state.op_index = 0;
break;
case DW_LNS_set_prologue_end:
@@ -662,7 +693,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
- prologue_end = true;
+ state.prologue_end = true;
break;
case DW_LNS_set_epilogue_begin:
@@ -670,7 +701,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
- epilogue_begin = true;
+ state.epilogue_begin = true;
break;
case DW_LNS_set_isa:
@@ -680,7 +711,7 @@ read_srclines (Dwarf *dbg,
if (unlikely (linep >= lineendp))
goto invalid_data;
- get_uleb128 (isa, linep, lineendp);
+ get_uleb128 (state.isa, linep, lineendp);
break;
}
}
@@ -728,7 +759,7 @@ read_srclines (Dwarf *dbg,
if (filesp != NULL)
*filesp = files;
- size_t buf_size = (sizeof (Dwarf_Lines) + (sizeof (Dwarf_Line) * nlinelist));
+ size_t buf_size = (sizeof (Dwarf_Lines) + (sizeof (Dwarf_Line) * state.nlinelist));
void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
/* First use the buffer for the pointers, and sort the entries.
@@ -736,13 +767,13 @@ read_srclines (Dwarf *dbg,
copy into the buffer from the beginning so the overlap works. */
assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
struct linelist **sortlines = (buf + buf_size
- - sizeof (struct linelist **) * nlinelist);
+ - sizeof (struct linelist **) * state.nlinelist);
/* The list is in LIFO order and usually they come in clumps with
ascending addresses. So fill from the back to probably start with
runs already in order before we sort. */
- struct linelist *lineslist = linelist;
- for (size_t i = nlinelist; i-- > 0; )
+ struct linelist *lineslist = state.linelist;
+ for (size_t i = state.nlinelist; i-- > 0; )
{
sortlines[i] = lineslist;
lineslist = lineslist->next;
@@ -750,14 +781,14 @@ read_srclines (Dwarf *dbg,
assert (lineslist == NULL);
/* Sort by ascending address. */
- qsort (sortlines, nlinelist, sizeof sortlines[0], &compare_lines);
+ qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines);
/* Now that they are sorted, put them in the final array.
The buffers overlap, so we've clobbered the early elements
of SORTLINES by the time we're reading the later ones. */
Dwarf_Lines *lines = buf;
- lines->nlines = nlinelist;
- for (size_t i = 0; i < nlinelist; ++i)
+ lines->nlines = state.nlinelist;
+ for (size_t i = 0; i < state.nlinelist; ++i)
{
lines->info[i] = sortlines[i]->line;
lines->info[i].files = files;
@@ -766,8 +797,8 @@ read_srclines (Dwarf *dbg,
/* Make sure the highest address for the CU is marked as end_sequence.
This is required by the DWARF spec, but some compilers forget and
dwfl_module_getsrc depends on it. */
- if (nlinelist > 0)
- lines->info[nlinelist - 1].end_sequence = 1;
+ if (state.nlinelist > 0)
+ lines->info[state.nlinelist - 1].end_sequence = 1;
/* Pass the line structure back to the caller. */
if (linesp != NULL)
@@ -778,11 +809,11 @@ read_srclines (Dwarf *dbg,
out:
/* Free malloced line records, if any. */
- for (size_t i = MAX_STACK_LINES; i < nlinelist; i++)
+ for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
{
- struct linelist *ll = linelist->next;
- free (linelist);
- linelist = ll;
+ struct linelist *ll = state.linelist->next;
+ free (state.linelist);
+ state.linelist = ll;
}
if (ndirlist >= MAX_STACK_DIRS)
free (dirarray);
--
2.6.0.rc2.230.g3dd15c0
8 years
[PATCH] Move nested functions in dwfl_module.c and dwfl_module_getsrc_file.c.
by Chih-Hung Hsieh
* Nested functions in these two files are moved to file scope
to compile with clang. Extra parameters are added to pass
local variables.
Signed-off-by: Chih-Hung Hsieh
---
libdwfl/ChangeLog | 7 +++++++
libdwfl/dwfl_module.c | 33 +++++++++++++++++----------------
libdwfl/dwfl_module_getsrc_file.c | 31 ++++++++++++++++++-------------
3 files changed, 42 insertions(+), 29 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5cae434..0374e5a 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2015-10-21 Chih-Hung Hsieh <chh(a)google.com>
+
+ * dwfl_module.c (dwfl_report_module): Move nested function 'use' to file
+ scope.
+ * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Move nested functions
+ 'dwarf_line_file', 'dwfl_line', and 'dwfl_line_file' to file scope.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* core-file.c (elf_begin_rand): Replace loff_t with off_t.
diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c
index 8efcfaa..76d45a8 100644
--- a/libdwfl/dwfl_module.c
+++ b/libdwfl/dwfl_module.c
@@ -125,6 +125,21 @@ dwfl_report_begin (Dwfl *dwfl)
}
INTDEF (dwfl_report_begin)
+static inline Dwfl_Module *
+use (Dwfl_Module *mod, Dwfl_Module **tailp, Dwfl *dwfl)
+{
+ mod->next = *tailp;
+ *tailp = mod;
+
+ if (unlikely (dwfl->lookup_module != NULL))
+ {
+ free (dwfl->lookup_module);
+ dwfl->lookup_module = NULL;
+ }
+
+ return mod;
+}
+
/* Report that a module called NAME spans addresses [START, END).
Returns the module handle, either existing or newly allocated,
or returns a null pointer for an allocation error. */
@@ -134,20 +149,6 @@ dwfl_report_module (Dwfl *dwfl, const char *name,
{
Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
- inline Dwfl_Module *use (Dwfl_Module *mod)
- {
- mod->next = *tailp;
- *tailp = mod;
-
- if (unlikely (dwfl->lookup_module != NULL))
- {
- free (dwfl->lookup_module);
- dwfl->lookup_module = NULL;
- }
-
- return mod;
- }
-
for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
{
if (m->low_addr == start && m->high_addr == end
@@ -157,7 +158,7 @@ dwfl_report_module (Dwfl *dwfl, const char *name,
after the last module already reported. */
*prevp = m->next;
m->gc = false;
- return use (m);
+ return use (m, tailp, dwfl);
}
if (! m->gc)
@@ -181,7 +182,7 @@ dwfl_report_module (Dwfl *dwfl, const char *name,
mod->high_addr = end;
mod->dwfl = dwfl;
- return use (mod);
+ return use (mod, tailp, dwfl);
}
INTDEF (dwfl_report_module)
diff --git a/libdwfl/dwfl_module_getsrc_file.c b/libdwfl/dwfl_module_getsrc_file.c
index 20aa8a5..75ba68e 100644
--- a/libdwfl/dwfl_module_getsrc_file.c
+++ b/libdwfl/dwfl_module_getsrc_file.c
@@ -30,6 +30,24 @@
#include "../libdw/libdwP.h"
+static inline const char *
+INTUSE(dwarf_line_file) (const Dwarf_Line *line)
+{
+ return line->files->info[line->file].name;
+}
+
+static inline Dwarf_Line *
+dwfl_line (const Dwfl_Line *line)
+{
+ return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
+}
+
+static inline const char *
+dwfl_line_file (const Dwfl_Line *line)
+{
+ return INTUSE(dwarf_line_file) (dwfl_line (line));
+}
+
int
dwfl_module_getsrc_file (Dwfl_Module *mod,
const char *fname, int lineno, int column,
@@ -58,19 +76,6 @@ dwfl_module_getsrc_file (Dwfl_Module *mod,
&& cu != NULL
&& (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR)
{
- inline const char *INTUSE(dwarf_line_file) (const Dwarf_Line *line)
- {
- return line->files->info[line->file].name;
- }
- inline Dwarf_Line *dwfl_line (const Dwfl_Line *line)
- {
- return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
- }
- inline const char *dwfl_line_file (const Dwfl_Line *line)
- {
- return INTUSE(dwarf_line_file) (dwfl_line (line));
- }
-
/* Search through all the line number records for a matching
file and line/column number. If any of the numbers is zero,
no match is performed. */
--
2.6.0.rc2.230.g3dd15c0
8 years, 1 month
[PATCH] Move nested functions in frame_unwind.c.
by Chih-Hung Hsieh
* Nested functions 'pop' and 'push' in libdwfl/frame_unwind.c
are moved to file scope. Used local variables are passed in
struct eval_stack.
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdwfl/ChangeLog | 5 ++
libdwfl/frame_unwind.c | 161 +++++++++++++++++++++++++++----------------------
2 files changed, 93 insertions(+), 73 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5cae434..96ea068 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-21 Chih-Hung Hsieh <chh(a)google.com>
+
+ * frame_unwind.c (expr_eval): Move nested function 'push' and 'pop'
+ to file scope. Pass used local variables in struct eval_stack.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* core-file.c (elf_begin_rand): Replace loff_t with off_t.
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index bd100b8..68b3d92 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -101,6 +101,47 @@ bra_compar (const void *key_voidp, const void *elem_voidp)
return (offset > op->offset) - (offset < op->offset);
}
+struct eval_stack {
+ Dwarf_Addr *addrs;
+ size_t used;
+ size_t allocated;
+};
+
+static bool
+do_push (struct eval_stack *stack, Dwarf_Addr val)
+{
+ if (stack->used >= DWARF_EXPR_STACK_MAX)
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (stack->used == stack->allocated)
+ {
+ stack->allocated = MAX (stack->allocated * 2, 32);
+ Dwarf_Addr *new_addrs = realloc (stack->addrs, stack->allocated * sizeof (*stack->addrs));
+ if (new_addrs == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return false;
+ }
+ stack->addrs = new_addrs;
+ }
+ stack->addrs[stack->used++] = val;
+ return true;
+}
+
+static bool
+do_pop (struct eval_stack *stack, Dwarf_Addr *val)
+{
+ if (stack->used == 0)
+ {
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ *val = stack->addrs[--stack->used];
+ return true;
+}
+
/* If FRAME is NULL is are computing CFI frame base. In such case another
DW_OP_call_frame_cfa is no longer permitted. */
@@ -114,43 +155,15 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
- Dwarf_Addr *stack = NULL;
- size_t stack_used = 0, stack_allocated = 0;
+ struct eval_stack stack =
+ {
+ .addrs = NULL,
+ .used = 0,
+ .allocated = 0
+ };
- bool
- push (Dwarf_Addr val)
- {
- if (stack_used >= DWARF_EXPR_STACK_MAX)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (stack_used == stack_allocated)
- {
- stack_allocated = MAX (stack_allocated * 2, 32);
- Dwarf_Addr *stack_new = realloc (stack, stack_allocated * sizeof (*stack));
- if (stack_new == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return false;
- }
- stack = stack_new;
- }
- stack[stack_used++] = val;
- return true;
- }
-
- bool
- pop (Dwarf_Addr *val)
- {
- if (stack_used == 0)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- *val = stack[--stack_used];
- return true;
- }
+#define pop(x) do_pop(&stack, x)
+#define push(x) do_push(&stack, x)
Dwarf_Addr val1, val2;
bool is_location = false;
@@ -168,14 +181,14 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_lit0 ... DW_OP_lit31:
if (! push (op->atom - DW_OP_lit0))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_addr:
if (! push (op->number + bias))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -195,7 +208,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_consts:
if (! push (op->number))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -203,67 +216,67 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
|| ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_regx:
if (! state_get_reg (state, op->number, &val1) || ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_breg0 ... DW_OP_breg31:
if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
val1 += op->number;
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_bregx:
if (! state_get_reg (state, op->number, &val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
val1 += op->number2;
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_dup:
if (! pop (&val1) || ! push (val1) || ! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_drop:
if (! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_pick:
- if (stack_used <= op->number)
+ if (stack.used <= op->number)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
- if (! push (stack[stack_used - 1 - op->number]))
+ if (! push (stack.addrs[stack.used - 1 - op->number]))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -271,14 +284,14 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val1) || ! pop (&val2)
|| ! push (val2) || ! push (val1) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
case DW_OP_swap:
if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -288,7 +301,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
|| ! push (val1) || ! push (val3) || ! push (val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
}
@@ -297,7 +310,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_deref_size:
if (process->callbacks->memory_read == NULL)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
return false;
}
@@ -305,7 +318,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
|| ! process->callbacks->memory_read (process->dwfl, val1, &val1,
process->callbacks_arg))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (op->atom == DW_OP_deref_size)
@@ -314,7 +327,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
if (op->number > addr_bytes)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
@@ -330,7 +343,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
}
if (! push (val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -338,7 +351,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case atom: \
if (! pop (&val1) || ! push (expr)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -349,7 +362,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_plus_uconst:
if (! pop (&val1) || ! push (val1 + op->number))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -357,7 +370,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case atom: \
if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -366,7 +379,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
if (! pop (&val2) || ! pop (&val1) \
|| ! push ((int64_t) val1 op (int64_t) val2)) \
{ \
- free (stack); \
+ free (stack.addrs); \
return false; \
} \
break;
@@ -374,18 +387,18 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_div:
if (! pop (&val2) || ! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val2 == 0)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
if (! push ((int64_t) val1 / (int64_t) val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -393,18 +406,18 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_mod:
if (! pop (&val2) || ! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val2 == 0)
{
- free (stack);
+ free (stack.addrs);
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
}
if (! push (val1 % val2))
{
- free (stack);
+ free (stack.addrs);
return false;
}
break;
@@ -426,7 +439,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
case DW_OP_bra:
if (! pop (&val1))
{
- free (stack);
+ free (stack.addrs);
return false;
}
if (val1 == 0)
@@ -438,7 +451,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
sizeof (*ops), bra_compar);
if (found == NULL)
{
- free (stack);
+ free (stack.addrs);
/* PPC32 vDSO has such invalid operations. */
__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
return false;
@@ -460,7 +473,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
|| ! push (cfa))
{
__libdwfl_seterrno (DWFL_E_LIBDW);
- free (stack);
+ free (stack.addrs);
return false;
}
is_location = true;
@@ -476,10 +489,10 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
}
if (! pop (result))
{
- free (stack);
+ free (stack.addrs);
return false;
}
- free (stack);
+ free (stack.addrs);
if (is_location)
{
if (process->callbacks->memory_read == NULL)
@@ -492,6 +505,8 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
return false;
}
return true;
+#undef push
+#undef pop
}
static void
--
2.6.0.rc2.230.g3dd15c0
8 years, 1 month
[PATCH] Move nested functions in backends to file scope.
by Chih-Hung Hsieh
* backends/aarch64_regs.c and backends/ia64_retval.c
should now compile with clang.
Signed-off-by: Chih-Hung Hsieh
---
backends/ChangeLog | 6 ++++++
backends/aarch64_regs.c | 38 ++++++++++++++++++++++----------------
backends/ia64_retval.c | 20 +++++++++++---------
3 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 6ea3dc4..7f0d1c0 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-21 Chih-Hung Hsieh <chh(a)google.com>
+
+ * ia64_retval.c (hfa_type): Move nested function 'hfa' to file scope.
+ * aarch64_regs.c (aarch64_register_info): Move nested function 'regtype'
+ to file scope.
+
2015-10-16 Mark Wielaard <mjw(a)redhat.com>
* ppc_symbol.c (ppc_check_special_symbol): Also allow _SDA_BASE_
diff --git a/backends/aarch64_regs.c b/backends/aarch64_regs.c
index 7a8a678..23014bf 100644
--- a/backends/aarch64_regs.c
+++ b/backends/aarch64_regs.c
@@ -38,6 +38,25 @@
#define BACKEND aarch64_
#include "libebl_CPU.h"
+__attribute__ ((format (printf, 7, 8)))
+static ssize_t
+do_regtype (const char *setname, int type,
+ const char **setnamep, int *typep,
+ char *name, size_t namelen, const char *fmt, ...)
+{
+ *setnamep = setname;
+ *typep = type;
+
+ va_list ap;
+ va_start (ap, fmt);
+ int s = vsnprintf (name, namelen, fmt, ap);
+ va_end(ap);
+
+ if (s < 0 || (unsigned) s >= namelen)
+ return -1;
+ return s + 1;
+}
+
ssize_t
aarch64_register_info (Ebl *ebl __attribute__ ((unused)),
int regno, char *name, size_t namelen,
@@ -47,26 +66,13 @@ aarch64_register_info (Ebl *ebl __attribute__ ((unused)),
if (name == NULL)
return 128;
- __attribute__ ((format (printf, 3, 4)))
- ssize_t
- regtype (const char *setname, int type, const char *fmt, ...)
- {
- *setnamep = setname;
- *typep = type;
-
- va_list ap;
- va_start (ap, fmt);
- int s = vsnprintf (name, namelen, fmt, ap);
- va_end(ap);
-
- if (s < 0 || (unsigned) s >= namelen)
- return -1;
- return s + 1;
- }
*prefix = "";
*bits = 64;
+#define regtype(setname, type, ...) \
+ do_regtype(setname, type, setnamep, typep, name, namelen, __VA_ARGS__)
+
switch (regno)
{
case 0 ... 30:
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index b5928c5..0bb280c 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -89,6 +89,16 @@ static const Dwarf_Op loc_aggregate[] =
#define nloc_aggregate 1
+static inline int
+compute_hfa (const Dwarf_Op *loc, int nregs, int fpregs_used, const Dwarf_Op **locp)
+{
+ if (fpregs_used == 0)
+ *locp = loc;
+ else if (*locp != loc)
+ return 9;
+ return fpregs_used + nregs;
+}
+
/* If this type is an HFA small enough to be returned in FP registers,
return the number of registers to use. Otherwise 9, or -1 for errors. */
static int
@@ -100,15 +110,6 @@ hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
If we find a datum that's not the same FP type as the first datum, punt.
If we count more than eight total homogeneous FP data, punt. */
- inline int hfa (const Dwarf_Op *loc, int nregs)
- {
- if (fpregs_used == 0)
- *locp = loc;
- else if (*locp != loc)
- return 9;
- return fpregs_used + nregs;
- }
-
int tag = DWARF_TAG_OR_RETURN (typedie);
switch (tag)
{
@@ -123,6 +124,7 @@ hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
&attr_mem), &encoding) != 0)
return -1;
+#define hfa(loc, nregs) compute_hfa(loc, nregs, fpregs_used, locp)
switch (encoding)
{
case DW_ATE_float:
--
2.6.0.rc2.230.g3dd15c0
8 years, 1 month
Compressed section support for libelf prototype.
by Mark Wielaard
Hi,
The following patch series introduces compressed ELF sections in libelf.
It is a prototype. We want to match the interface that other libelf
implementations will use if possible. This version is slightly different
from the one proposed by the Solaris hackers. I also wrote a different
prototype that was based on the elf_[raw]data/new_data interface (which I
lost that one is a freak fight with git...) That one gave the user a bit
more control mixing compressed/decompressed data. But the current interface
is much simpler. I will post about this on the Generic System V Application
Binary Interface mailinglist where also other proposals have been discussed.
If you have comments on the interface please join the discussion there.
https://groups.google.com/forum/#!forum/generic-abi
Comments on the implementation very welcome here of course.
The main thing that is missing is converting between memory and file
representation before compressing if necessary. Which shouldn't be hard.
There is a XXX comment. Also actually writing the compressed or decompressed
data to the file isn't tested at all. I like to add a new program that lets
you [un]compress sections and/or convert between different compression types
next. That would also be a good testcase for the implementation.
Cheers,
Mark
8 years, 1 month
[PATCH] Do without union of variable length arrays.
by Chih-Hung Hsieh
Prepare to compile without gnu99 extension.
A union like
{ T32 a32[n]; T64 a64[n]; } u;
is expanded to
void *data = malloc (...);
T32 *a32 = data;
T64 *a64 = data;
Signed-off-by: Chih-Hung Hsieh <chh(a)google.com>
---
libdwfl/dwfl_module_getdwarf.c | 46 +++++++++++---------
libdwfl/dwfl_segment_report_module.c | 60 +++++++++++++-------------
libdwfl/elf-from-memory.c | 41 +++++++++---------
libdwfl/link_map.c | 81 +++++++++++++-----------------------
libelf/elf_getarsym.c | 12 ++----
src/readelf.c | 30 +++++++------
src/unstrip.c | 22 ++++++----
7 files changed, 138 insertions(+), 154 deletions(-)
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index dba9d66..5f1b9b1 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -370,14 +370,17 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
{
typedef union
{
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdr;
- phdr *phdrs = malloc (sizeof (phdr));
+ Elf32_Phdr p32;
+ Elf64_Phdr p64;
+ } phdr_u;
+ /* phnum elements of phdr_u */
+ void *phdrs = malloc (phnum * sizeof (phdr_u));
+ Elf32_Phdr *p32 = phdrs;
+ Elf64_Phdr *p64 = phdrs;
if (unlikely (phdrs == NULL))
return DWFL_E_NOMEM;
dst.d_buf = phdrs;
- dst.d_size = sizeof (phdr);
+ dst.d_size = phnum * sizeof (phdr_u);
if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
ehdr.e32.e_ident[EI_DATA]) == NULL))
{
@@ -387,18 +390,18 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
{
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_INTERP)
+ if (p32[i].p_type == PT_INTERP)
{
- undo_interp = phdrs->p32[i].p_vaddr;
+ undo_interp = p32[i].p_vaddr;
break;
}
}
else
{
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_INTERP)
+ if (p64[i].p_type == PT_INTERP)
{
- undo_interp = phdrs->p64[i].p_vaddr;
+ undo_interp = p64[i].p_vaddr;
break;
}
}
@@ -414,14 +417,17 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
typedef union
{
- Elf32_Shdr s32[shnum - 1];
- Elf64_Shdr s64[shnum - 1];
- } shdr;
- shdr *shdrs = malloc (sizeof (shdr));
+ Elf32_Shdr s32;
+ Elf64_Shdr s64;
+ } shdr_u;
+ /* (shnum - 1) elements of shdr_u */
+ void *shdrs = malloc ((shnum - 1) * sizeof (shdr_u));
+ Elf32_Shdr *s32 = shdrs;
+ Elf64_Shdr *s64 = shdrs;
if (unlikely (shdrs == NULL))
return DWFL_E_NOMEM;
dst.d_buf = shdrs;
- dst.d_size = sizeof (shdr);
+ dst.d_size = (shnum - 1) * sizeof (shdr_u);
if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
ehdr.e32.e_ident[EI_DATA]) == NULL))
{
@@ -484,14 +490,14 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
highest = 0;
if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdrs->s32[i].sh_type,
- shdrs->s32[i].sh_flags, shdrs->s32[i].sh_addr,
- shdrs->s32[i].sh_size);
+ consider_shdr (undo_interp, s32[i].sh_type,
+ s32[i].sh_flags, s32[i].sh_addr,
+ s32[i].sh_size);
else
for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdrs->s64[i].sh_type,
- shdrs->s64[i].sh_flags, shdrs->s64[i].sh_addr,
- shdrs->s64[i].sh_size);
+ consider_shdr (undo_interp, s64[i].sh_type,
+ s64[i].sh_flags, s64[i].sh_addr,
+ s64[i].sh_size);
if (highest > file->vaddr)
file->address_sync = highest;
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index a0f07ad..b5c45f3 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -406,17 +406,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
typedef union
{
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrsn;
+ Elf32_Phdr p32;
+ Elf64_Phdr p64;
+ } phdr_u;
- phdrsp = malloc (sizeof (phdrsn));
+ phdrsp = malloc (phnum * sizeof (phdr_u));
+ Elf32_Phdr *p32 = phdrsp;
+ Elf64_Phdr *p64 = phdrsp;
if (unlikely (phdrsp == NULL))
return finish ();
- phdrsn *phdrs = (phdrsn *) phdrsp;
- xlateto.d_buf = phdrs;
- xlateto.d_size = sizeof (phdrsn);
+ xlateto.d_buf = phdrsp;
+ xlateto.d_size = phnum * sizeof (phdr_u);
/* Track the bounds of the file visible in memory. */
GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
@@ -579,10 +580,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 (phdrs->p32[i].p_type,
- phdrs->p32[i].p_vaddr, phdrs->p32[i].p_memsz,
- phdrs->p32[i].p_offset, phdrs->p32[i].p_filesz,
- phdrs->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
{
@@ -590,10 +591,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 (phdrs->p64[i].p_type,
- phdrs->p64[i].p_vaddr, phdrs->p64[i].p_memsz,
- phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz,
- phdrs->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);
@@ -749,44 +750,39 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
const size_t dyn_entsize = (ei_class == ELFCLASS32
? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
- void *dyns = NULL;
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))
{
- typedef union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } dynn;
- dyns = malloc (sizeof (dynn));
+ void *dyns = malloc (dyn_filesz);
+ Elf32_Dyn *d32 = dyns;
+ Elf64_Dyn *d64 = dyns;
if (unlikely (dyns == NULL))
return finish ();
- dynn *dyn = (dynn *) dyns;
xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
xlatefrom.d_buf = (void *) dyn_data;
xlatefrom.d_size = dyn_filesz;
- xlateto.d_buf = dyn;
- xlateto.d_size = sizeof (dynn);
+ 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 (dyn->d32[i].d_tag, dyn->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 (dyn->d64[i].d_tag, dyn->d64[i].d_un.d_val))
+ if (consider_dyn (d64[i].d_tag, d64[i].d_un.d_val))
break;
}
+ free (dyns);
}
- free (dyns);
finish_portion (&dyn_data, &dyn_data_size);
/* We'll use the name passed in or a stupid default if not DT_SONAME. */
@@ -901,12 +897,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 (phdrs->p32[i].p_type, phdrs->p32[i].p_vaddr,
- phdrs->p32[i].p_offset, phdrs->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 (phdrs->p64[i].p_type, phdrs->p64[i].p_vaddr,
- phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz);
+ read_phdr (p64[i].p_type, p64[i].p_vaddr,
+ p64[i].p_offset, p64[i].p_filesz);
}
else
{
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index ed8f6e9..ee37cfd 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -193,20 +193,21 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
typedef union
{
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrsn;
+ Elf32_Phdr p32;
+ Elf64_Phdr p64;
+ } phdr_u;
- phdrsp = malloc (sizeof (phdrsn));
+ phdrsp = malloc (phnum * sizeof (phdr_u));
+ Elf32_Phdr *p32 = phdrsp;
+ Elf64_Phdr *p64 = phdrsp;
if (unlikely (phdrsp == NULL))
{
free (buffer);
goto no_memory;
}
- phdrsn *phdrs = (phdrsn *) phdrsp;
- xlateto.d_buf = phdrs;
- xlateto.d_size = sizeof (phdrsn);
+ xlateto.d_buf = phdrsp;
+ xlateto.d_size = phnum * sizeof (phdr_u);
/* Scan for PT_LOAD segments to find the total size of the file image. */
size_t contents_size = 0;
@@ -249,9 +250,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e32.e_ident[EI_DATA]) == NULL)
goto libelf_error;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p32[i].p_vaddr, phdrs->p32[i].p_offset,
- phdrs->p32[i].p_filesz, phdrs->p32[i].p_memsz))
+ if (p32[i].p_type == PT_LOAD)
+ if (handle_segment (p32[i].p_vaddr, p32[i].p_offset,
+ p32[i].p_filesz, p32[i].p_memsz))
goto bad_elf;
break;
@@ -260,9 +261,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e64.e_ident[EI_DATA]) == NULL)
goto libelf_error;
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p64[i].p_vaddr, phdrs->p64[i].p_offset,
- phdrs->p64[i].p_filesz, phdrs->p64[i].p_memsz))
+ if (p64[i].p_type == PT_LOAD)
+ if (handle_segment (p64[i].p_vaddr, p64[i].p_offset,
+ p64[i].p_filesz, p64[i].p_memsz))
goto bad_elf;
break;
@@ -315,9 +316,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS32:
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p32[i].p_vaddr, phdrs->p32[i].p_offset,
- phdrs->p32[i].p_filesz))
+ if (p32[i].p_type == PT_LOAD)
+ if (handle_segment (p32[i].p_vaddr, p32[i].p_offset,
+ p32[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -342,9 +343,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS64:
for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs->p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs->p64[i].p_vaddr, phdrs->p64[i].p_offset,
- phdrs->p64[i].p_filesz))
+ if (p64[i].p_type == PT_LOAD)
+ if (handle_segment (p64[i].p_vaddr, p64[i].p_offset,
+ p64[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -373,7 +374,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
}
free (phdrsp);
- phdrs = phdrsp = NULL;
+ phdrsp = NULL;
/* Now we have the image. Open libelf on it. */
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 030c600..a756e43 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -48,20 +48,16 @@ static bool
auxv_format_probe (const void *auxv, size_t size,
uint_fast8_t *elfclass, uint_fast8_t *elfdata)
{
- const union
- {
- char buf[size];
- Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
- Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
- } *u = auxv;
+ const Elf32_auxv_t *a32 = auxv;
+ const Elf64_auxv_t *a64 = auxv;
inline bool check64 (size_t i)
{
/* The AUXV pointer might not even be naturally aligned for 64-bit
data, because note payloads in a core file are not aligned. */
- uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
- uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);
+ uint64_t type = read_8ubyte_unaligned_noncvt (&a64[i].a_type);
+ uint64_t val = read_8ubyte_unaligned_noncvt (&a64[i].a_un.a_val);
if (type == BE64 (PROBE_TYPE)
&& val == BE64 (PROBE_VAL64))
@@ -85,8 +81,8 @@ auxv_format_probe (const void *auxv, size_t size,
/* The AUXV pointer might not even be naturally aligned for 32-bit
data, because note payloads in a core file are not aligned. */
- uint32_t type = read_4ubyte_unaligned_noncvt (&u->a32[i].a_type);
- uint32_t val = read_4ubyte_unaligned_noncvt (&u->a32[i].a_un.a_val);
+ uint32_t type = read_4ubyte_unaligned_noncvt (&a32[i].a_type);
+ uint32_t val = read_4ubyte_unaligned_noncvt (&a32[i].a_un.a_val);
if (type == BE32 (PROBE_TYPE)
&& val == BE32 (PROBE_VAL32))
@@ -280,29 +276,26 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
return true;
}
- const union
- {
- Elf32_Addr a32[n];
- Elf64_Addr a64[n];
- } *in = vaddr - read_vaddr + buffer;
+ Elf32_Addr *a32 = vaddr - read_vaddr + buffer;
+ Elf64_Addr *a64 = (void *) a32;
if (elfclass == ELFCLASS32)
{
if (elfdata == ELFDATA2MSB)
for (size_t i = 0; i < n; ++i)
- addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&in->a32[i]));
+ addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&a32[i]));
else
for (size_t i = 0; i < n; ++i)
- addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&in->a32[i]));
+ addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&a32[i]));
}
else
{
if (elfdata == ELFDATA2MSB)
for (size_t i = 0; i < n; ++i)
- addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&in->a64[i]));
+ addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&a64[i]));
else
for (size_t i = 0; i < n; ++i)
- addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&in->a64[i]));
+ addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&a64[i]));
}
return false;
@@ -861,13 +854,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
}
if (in_ok)
{
- typedef union
- {
- Elf32_Phdr p32;
- Elf64_Phdr p64;
- char data[phnum * phent];
- } data_buf;
- data_buf *buf = malloc (sizeof (data_buf));
+ void *buf = malloc (phnum * phent);
+ Elf32_Phdr *p32 = buf;
+ Elf64_Phdr *p64 = buf;
if (unlikely (buf == NULL))
{
__libdwfl_seterrno (DWFL_E_NOMEM);
@@ -886,25 +875,20 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
(&out, &in, elfdata) != NULL))
{
/* We are looking for PT_DYNAMIC. */
- const union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } *u = (void *) buf;
if (elfclass == ELFCLASS32)
{
for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p32[i].p_type,
- u->p32[i].p_vaddr,
- u->p32[i].p_filesz))
+ if (consider_phdr (p32[i].p_type,
+ p32[i].p_vaddr,
+ p32[i].p_filesz))
break;
}
else
{
for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p64[i].p_type,
- u->p64[i].p_vaddr,
- u->p64[i].p_filesz))
+ if (consider_phdr (p64[i].p_type,
+ p64[i].p_vaddr,
+ p64[i].p_filesz))
break;
}
}
@@ -955,13 +939,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
dyn_vaddr, dyn_filesz, memory_callback_arg))
{
- typedef union
- {
- Elf32_Dyn d32;
- Elf64_Dyn d64;
- char data[dyn_filesz];
- } data_buf;
- data_buf *buf = malloc (sizeof (data_buf));
+ void *buf = malloc (dyn_filesz);
+ Elf32_Dyn *d32 = buf;
+ Elf64_Dyn *d64 = buf;
if (unlikely (buf == NULL))
{
__libdwfl_seterrno (DWFL_E_NOMEM);
@@ -980,18 +960,13 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
(&out, &in, elfdata) != NULL))
{
/* We are looking for DT_DEBUG. */
- const union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } *u = (void *) buf;
if (elfclass == ELFCLASS32)
{
size_t n = dyn_filesz / sizeof (Elf32_Dyn);
for (size_t i = 0; i < n; ++i)
- if (u->d32[i].d_tag == DT_DEBUG)
+ if (d32[i].d_tag == DT_DEBUG)
{
- r_debug_vaddr = u->d32[i].d_un.d_val;
+ r_debug_vaddr = d32[i].d_un.d_val;
break;
}
}
@@ -999,9 +974,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
{
size_t n = dyn_filesz / sizeof (Elf64_Dyn);
for (size_t i = 0; i < n; ++i)
- if (u->d64[i].d_tag == DT_DEBUG)
+ if (d64[i].d_tag == DT_DEBUG)
{
- r_debug_vaddr = u->d64[i].d_un.d_val;
+ r_debug_vaddr = d64[i].d_un.d_val;
break;
}
}
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
index 8324244..6f7bfab 100644
--- a/libelf/elf_getarsym.c
+++ b/libelf/elf_getarsym.c
@@ -203,11 +203,7 @@ elf_getarsym (elf, ptr)
elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
if (elf->state.ar.ar_sym != NULL)
{
- union
- {
- uint32_t u32[n];
- uint64_t u64[n];
- } *file_data;
+ void *file_data; /* unit32_t[n] or uint64_t[n] */
char *str_data;
size_t sz = n * w;
@@ -274,7 +270,7 @@ elf_getarsym (elf, ptr)
arsym[cnt].as_name = str_data;
if (index64_p)
{
- uint64_t tmp = file_data->u64[cnt];
+ uint64_t tmp = ((uint64_t *) file_data)[cnt];
if (__BYTE_ORDER == __LITTLE_ENDIAN)
tmp = bswap_64 (tmp);
@@ -296,9 +292,9 @@ elf_getarsym (elf, ptr)
}
}
else if (__BYTE_ORDER == __LITTLE_ENDIAN)
- arsym[cnt].as_off = bswap_32 (file_data->u32[cnt]);
+ arsym[cnt].as_off = bswap_32 (((uint32_t *) file_data)[cnt]);
else
- arsym[cnt].as_off = file_data->u32[cnt];
+ arsym[cnt].as_off = ((uint32_t *) file_data)[cnt];
arsym[cnt].as_hash = _dl_elf_hash (str_data);
str_data = rawmemchr (str_data, '\0') + 1;
diff --git a/src/readelf.c b/src/readelf.c
index 8e64400..6011ad7 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4943,7 +4943,7 @@ print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
unsigned int version, unsigned int ptr_size,
Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
{
- char regnamebuf[REGNAMESZ];
+ char *regnamebuf = alloca (REGNAMESZ);
const char *regname (unsigned int regno)
{
register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
@@ -8378,11 +8378,16 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
-#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count]
- union { TYPES; } value;
+#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
+ typedef union { TYPES; } value_t;
+ void *data = alloca (count * sizeof (value_t));
+#undef DO_TYPE
+
+#define DO_TYPE(NAME, Name, hex, dec) \
+ GElf_##Name *value_##Name __attribute__((unused)) = data
+ TYPES;
#undef DO_TYPE
- void *data = &value;
size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
size_t convsize = size;
if (repeated_size != NULL)
@@ -8413,7 +8418,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
colno = print_core_item (colno, ',', WRAP_COLUMN, \
- 0, item->name, dec, value.Name[0]); \
+ 0, item->name, dec, value_##Name[0]); \
break
TYPES;
#undef DO_TYPE
@@ -8429,7 +8434,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
colno = print_core_item (colno, ',', WRAP_COLUMN, \
- 0, item->name, hex, value.Name[0]); \
+ 0, item->name, hex, value_##Name[0]); \
break
TYPES;
#undef DO_TYPE
@@ -8519,8 +8524,8 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
{
#define DO_TYPE(NAME, Name, hex, dec) \
case ELF_T_##NAME: \
- sec = value.Name[0]; \
- usec = value.Name[1]; \
+ sec = value_##Name[0]; \
+ usec = value_##Name[1]; \
break
TYPES;
#undef DO_TYPE
@@ -8550,12 +8555,12 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
case 'c':
assert (count == 1);
colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
- "%c", value.Byte[0]);
+ "%c", value_Byte[0]);
break;
case 's':
colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
- "%.*s", (int) count, value.Byte);
+ "%.*s", (int) count, value_Byte);
break;
case '\n':
@@ -8899,8 +8904,9 @@ handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
assert (maxnreg > 0);
}
- struct register_info regs[maxnreg];
- memset (regs, 0, sizeof regs);
+ const int sizeof_regs = sizeof (struct register_info) * maxnreg;
+ struct register_info *regs = alloca (sizeof_regs);
+ memset (regs, 0, sizeof_regs);
/* Sort to collect the sets together. */
int maxreg = 0;
diff --git a/src/unstrip.c b/src/unstrip.c
index 82bcdd8..7507eef 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1013,13 +1013,16 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
".gnu.prelink_undo");
- union
+ typedef union
{
- Elf32_Shdr s32[shnum - 1];
- Elf64_Shdr s64[shnum - 1];
- } shdr;
- dst.d_buf = &shdr;
- dst.d_size = sizeof shdr;
+ Elf32_Shdr s32;
+ Elf64_Shdr s64;
+ } shdr_u;
+ void *shdr = alloca ((shnum - 1) * sizeof (shdr_u));
+ Elf32_Shdr *s32 = shdr;
+ Elf64_Shdr *s64 = shdr;
+ dst.d_buf = shdr;
+ dst.d_size = (shnum - 1) * sizeof (shdr_u);
ELF_CHECK (gelf_xlatetom (main, &dst, &src,
main_ehdr->e_ident[EI_DATA]) != NULL,
_("cannot read '.gnu.prelink_undo' section: %s"));
@@ -1030,7 +1033,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
struct section *sec = &undo_sections[undo_nalloc];
if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
{
-#define COPY(field) sec->shdr.field = shdr.s32[i].field
+#define COPY(field) sec->shdr.field = s32[i].field
COPY (sh_name);
COPY (sh_type);
COPY (sh_flags);
@@ -1044,7 +1047,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
#undef COPY
}
else
- sec->shdr = shdr.s64[i];
+ sec->shdr = s64[i];
if (sec->shdr.sh_flags & SHF_ALLOC)
{
sec->shdr.sh_addr += bias;
@@ -1260,7 +1263,8 @@ copy_elided_sections (Elf *unstripped, Elf *stripped,
more sections in stripped file than debug file -- arguments reversed?"));
/* Cache the stripped file's section details. */
- struct section sections[stripped_shnum - 1];
+ struct section *sections =
+ alloca (sizeof (struct section) * (stripped_shnum - 1));
Elf_Scn *scn = NULL;
while ((scn = elf_nextscn (stripped, scn)) != NULL)
{
--
2.5.0.457.gab17608
8 years, 1 month
[PATCH] libelf: use the right size when preading in[0].sh_size
by Jose E. Marchesi
This fixes a small thinko, that was making get_shnum to return
(size_t) -1 for all elf-64 files with e_shnum == 0.
commit 9430a51d8d7809842c651112ad30a6b56876cd89
Author: Jose E. Marchesi <jose.marchesi(a)oracle.com>
Date: Tue Oct 20 16:20:39 2015 +0200
libelf: use the right size when preading in [0].sh_size
Signed-off-by: Jose E. Marchesi <jose.marchesi(a)oracle.com>
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index d8651d7..63c7277 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-20 Jose E. Marchesi <jose.marchesi(a)oracle.com>
+
+ * elf_begin.c (get_shnum): Elf64_Shdr.sh_size is an Elf64_Xword.
+ Fix the size argument to pread_retry.
+
2015-10-09 Josh Stone <jistone(a)redhat.com>
* libelf.h: Replace loff_t with int64_t throughout.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 213b5c0..11e2203 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -216,7 +216,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
+ offset))->sh_size,
sizeof (Elf64_Xword));
else
- if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Word),
+ if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Xword),
offset + ehdr.e64->e_shoff
+ offsetof (Elf64_Shdr, sh_size))
!= sizeof (Elf64_Xword)))
8 years, 1 month