summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2020-11-01 23:45:32 +0100
committerMark Wielaard <mark@klomp.org>2020-11-01 23:45:32 +0100
commit8dd97a0a871672b3f7a58e1fb50b6f7195d8f32d (patch)
tree3a86d4fb1d7abf6966ff94a1e25f13f7e1809c48 /src
parent50a6eeef7d87623faa65126dc3d16c2a8e613aea (diff)
parentb503c358dde835d8a1ae3ebd4968755ff396f814 (diff)
downloadelfutils-dts-0.182.tar.gz
Merge tag 'elfutils-0.182' into mjw/RH-DTSdts-0.182
elfutils 0.182 release
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog59
-rw-r--r--src/ar.c65
-rw-r--r--src/elfclassify.c3
-rw-r--r--src/elflint.c3
-rw-r--r--src/ranlib.c44
-rw-r--r--src/readelf.c115
-rw-r--r--src/stack.c7
-rw-r--r--src/unstrip.c25
8 files changed, 248 insertions, 73 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 512d7b54..7f923c5d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,62 @@
+2020-10-27 Érico N. Rolim <erico.erc@gmail.com>
+
+ * unstrip.c (make_directories): Use strndup, not strndupa.
+
+2020-09-28 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (next_listptr_offset): Take idx as pointer, to be updated
+ and use new Dwarf_Off as offset to match.
+ (listptr_attr): New function.
+ (print_debug_loclists_section): Check for DW_AT_GNU_locviews to show
+ view pairs.
+ (print_debug_loc_section): Adjust next_listptr_offset call.
+
+2020-09-03 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_cfa_program): Take ehdr as argument. Use it to
+ recognize DW_CFA_AARCH64_negate_ra_state.
+ (print_debug_frame_section): Pass ehdr to print_cfa_program.
+ (print_debug): Don't warn if we dump frames, but cannot get dbg.
+
+2020-09-01 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_debug_ranges_section): Base address entry can
+ be first.
+ (print_debug_loc_section): Likewise.
+
+2020-09-04 Mark Wielaard <mark@klomp.org>
+
+ * elflint.c (special_sections): Add .debug_line_str.
+
+2020-08-26 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_debug_line_section): It is not an error if there
+ are no line number statements at the end of a debug line section.
+
+2020-07-19 Mark Wielaard <mark@klomp.org>
+
+ * elfclassify.c (process_current_path): Handle fwrite failing.
+
+2020-07-05 Mark Wielaard <mark@klomp.org>
+
+ * stack.c (module_callback): Don't assert if dwfl_module_info fails.
+ * unstrip.c (adjust_relocs): Produce a proper error when HAS
+ section has inconsistent size or entsize.
+ (match_module): Don't assert if dwfl_module_info fails.
+
+2020-06-16 Mark Wielaard <mark@klomp.org>
+
+ * ar.c (do_oper_extract): Split large if statement. Call fchown
+ before fchmod and explicitly ignore the return value.
+ (do_oper_delete): Likewise.
+ (do_oper_insert): Likewise.
+ * ranlib.c (handle_file): Likewise.
+
+2020-06-16 Mark Wielaard <mark@klomp.org>
+
+ * elflint.c (check_elf_header): Explicitly check and ignore
+ any error from elf_compress.
+
2020-06-07 Mark Wielaard <mark@klomp.org>
* nm.c (sort_by_name_strtab): Replace by...
diff --git a/src/ar.c b/src/ar.c
index d70f1f46..7d33d814 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -787,26 +787,30 @@ cannot rename temporary file to %.*s"),
else
rest_off = SARMAG;
- if ((symtab.symsnamelen != 0
+ if (symtab.symsnamelen != 0
&& ((write_retry (newfd, symtab.symsoff,
symtab.symsofflen)
!= (ssize_t) symtab.symsofflen)
|| (write_retry (newfd, symtab.symsname,
symtab.symsnamelen)
!= (ssize_t) symtab.symsnamelen)))
- /* Even if the original file had content before the
- symbol table, we write it in the correct order. */
- || (index_off != SARMAG
- && copy_content (elf, newfd, SARMAG, index_off - SARMAG))
- || copy_content (elf, newfd, rest_off, st.st_size - rest_off)
- /* Set the mode of the new file to the same values the
- original file has. */
- || fchmod (newfd, st.st_mode & ALLPERMS) != 0
- /* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid,
- st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0))
+ goto nonew_unlink;
+ /* Even if the original file had content before the
+ symbol table, we write it in the correct order. */
+ if ((index_off != SARMAG
+ && copy_content (elf, newfd, SARMAG, index_off - SARMAG))
+ || copy_content (elf, newfd, rest_off, st.st_size - rest_off))
+ goto nonew_unlink;
+
+ /* Never complain about fchown failing. */
+ if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; }
+ /* Set the mode of the new file to the same values the
+ original file has. */
+ if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ || close (newfd) != 0)
+ goto nonew_unlink;
+ newfd = -1;
+ if (rename (tmpfname, arfname) != 0)
goto nonew_unlink;
}
}
@@ -1052,12 +1056,15 @@ do_oper_delete (const char *arfname, char **argv, int argc,
}
/* Set the mode of the new file to the same values the original file
- has. */
+ has. Never complain about fchown failing. But do it before
+ setting the mode (which might be reset/ignored if the owner is
+ wrong. */
+ if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; }
if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
- /* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0))
+ || close (newfd) != 0)
+ goto nonew_unlink;
+ newfd = -1;
+ if (rename (tmpfname, arfname) != 0)
goto nonew_unlink;
errout:
@@ -1534,13 +1541,19 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
/* Set the mode of the new file to the same values the original file
has. */
- if (fd != -1
- && (fchmod (newfd, st.st_mode & ALLPERMS) != 0
- /* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0)))
- goto nonew_unlink;
+ if (fd != -1)
+ {
+ /* Never complain about fchown failing. But do it before
+ setting the modes, or they might be reset/ignored if the
+ owner is wrong. */
+ if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; }
+ if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ || close (newfd) != 0)
+ goto nonew_unlink;
+ newfd = -1;
+ if (rename (tmpfname, arfname) != 0)
+ goto nonew_unlink;
+ }
errout:
for (int cnt = 0; cnt < argc; ++cnt)
diff --git a/src/elfclassify.c b/src/elfclassify.c
index 535cc49f..624bb861 100644
--- a/src/elfclassify.c
+++ b/src/elfclassify.c
@@ -827,7 +827,8 @@ process_current_path (int *status)
break;
case do_print0:
if (checks_passed == flag_print_matching)
- fwrite (current_path, strlen (current_path) + 1, 1, stdout);
+ if (fwrite (current_path, strlen (current_path) + 1, 1, stdout) < 1)
+ issue (errno, N_("writing to standard output"));
break;
case no_print:
if (!checks_passed)
diff --git a/src/elflint.c b/src/elflint.c
index 72584de0..ef3e3732 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -467,7 +467,7 @@ invalid number of section header table entries\n"));
break;
/* If the section wasn't compressed this does nothing, but
returns an error. We don't care. */
- elf_compress (scn, 0, 0);
+ if (elf_compress (scn, 0, 0) < 0) { ; }
}
if (scnt < shnum)
ERROR (gettext ("Can only check %u headers, shnum was %u\n"), scnt, shnum);
@@ -3631,6 +3631,7 @@ static const struct
{ ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
{ ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
{ ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 },
+ { ".debug_line_str", 16, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 },
{ ".debug", 6, SHT_PROGBITS, exact, 0, 0 },
{ ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
{ ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
diff --git a/src/ranlib.c b/src/ranlib.c
index b9083484..483a1b65 100644
--- a/src/ranlib.c
+++ b/src/ranlib.c
@@ -245,25 +245,31 @@ handle_file (const char *fname)
else
rest_off = SARMAG;
- if ((symtab.symsnamelen != 0
- && ((write_retry (newfd, symtab.symsoff,
- symtab.symsofflen)
- != (ssize_t) symtab.symsofflen)
- || (write_retry (newfd, symtab.symsname,
- symtab.symsnamelen)
- != (ssize_t) symtab.symsnamelen)))
- /* Even if the original file had content before the
- symbol table, we write it in the correct order. */
- || (index_off > SARMAG
- && copy_content (arelf, newfd, SARMAG, index_off - SARMAG))
- || copy_content (arelf, newfd, rest_off, st.st_size - rest_off)
- /* Set the mode of the new file to the same values the
- original file has. */
- || fchmod (newfd, st.st_mode & ALLPERMS) != 0
- /* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, fname) != 0))
+ if (symtab.symsnamelen != 0
+ && ((write_retry (newfd, symtab.symsoff,
+ symtab.symsofflen)
+ != (ssize_t) symtab.symsofflen)
+ || (write_retry (newfd, symtab.symsname,
+ symtab.symsnamelen)
+ != (ssize_t) symtab.symsnamelen)))
+ goto nonew_unlink;
+
+ /* Even if the original file had content before the
+ symbol table, we write it in the correct order. */
+ if ((index_off > SARMAG
+ && copy_content (arelf, newfd, SARMAG, index_off - SARMAG))
+ || copy_content (arelf, newfd, rest_off, st.st_size - rest_off))
+ goto nonew_unlink;
+
+ /* Never complain about fchown failing. */
+ if (fchown (newfd, st.st_uid, st.st_gid) != 0) { ; }
+ /* Set the mode of the new file to the same values the
+ original file has. */
+ if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ || close (newfd) != 0)
+ goto nonew_unlink;
+ newfd = -1;
+ if (rename (tmpfname, fname) != 0)
goto nonew_unlink;
}
}
diff --git a/src/readelf.c b/src/readelf.c
index 685d0b17..f6d13afa 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4993,17 +4993,19 @@ skip_listptr_hole (struct listptr_table *table, size_t *idxp,
}
static Dwarf_Off
-next_listptr_offset (struct listptr_table *table, size_t idx)
+next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
{
/* Note that multiple attributes could in theory point to the same loclist
offset, so make sure we pick one that is bigger than the current one.
The table is sorted on offset. */
- Dwarf_Off offset = table->table[idx].offset;
- while (++idx < table->n)
+ if (*idxp < table->n)
{
- Dwarf_Off next = table->table[idx].offset;
- if (next > offset)
- return next;
+ while (++*idxp < table->n)
+ {
+ Dwarf_Off next = table->table[*idxp].offset;
+ if (next > off)
+ return next;
+ }
}
return 0;
}
@@ -5036,13 +5038,36 @@ listptr_cu (struct listptr_table *table, size_t *idxp,
struct listptr *p = &table->table[*idxp];
*base = listptr_base (p);
*cu = p->cu;
- ++*idxp;
return true;
}
return false;
}
+/* Returns the next index with the current CU for the given attribute.
+ If there is none false is returned, otherwise true. Assumes the
+ table has been sorted. */
+static bool
+listptr_attr (struct listptr_table *table, size_t idxp,
+ Dwarf_Off offset, unsigned int attr)
+{
+ struct listptr *listptr;
+ do
+ {
+ listptr = get_listptr (table, idxp);
+ if (listptr == NULL)
+ return false;
+
+ if (listptr->offset == offset && listptr->attr == attr)
+ return true;
+
+ idxp++;
+ }
+ while (listptr->offset <= offset);
+
+ return false;
+}
+
static void
print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
@@ -6045,10 +6070,16 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
{
- printf (gettext (" [%6tx] base address\n "), offset);
+ if (first)
+ printf (" [%6tx] ", offset);
+ else
+ printf (" ");
+ puts (gettext ("base address"));
+ printf (" ");
print_dwarf_addr (dwflmod, address_size, end, end);
printf ("\n");
base = end;
+ first = false;
}
else if (begin == 0 && end == 0) /* End of list entry. */
{
@@ -6176,7 +6207,7 @@ print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
int data_align,
unsigned int version, unsigned int ptr_size,
unsigned int encoding,
- Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
+ Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
{
char regnamebuf[REGNAMESZ];
const char *regname (unsigned int regno)
@@ -6399,8 +6430,11 @@ print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
op1, pc += op1 * code_align);
break;
- case DW_CFA_GNU_window_save:
- puts (" GNU_window_save");
+ case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
+ if (ehdr->e_machine == EM_AARCH64)
+ puts (" AARCH64_negate_ra_state");
+ else
+ puts (" GNU_window_save");
break;
case DW_CFA_GNU_args_size:
if ((uint64_t) (endp - readp) < 1)
@@ -6930,7 +6964,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
else
print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
data_alignment_factor, version, ptr_size,
- fde_encoding, dwflmod, ebl, dbg);
+ fde_encoding, dwflmod, ebl, ehdr, dbg);
readp = cieend;
}
}
@@ -8642,7 +8676,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
printf (", ");
}
printf ("\n");
- if (linep >= lineendp)
+ if (linep > lineendp)
goto invalid_unit;
}
}
@@ -8685,6 +8719,12 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
++linep;
}
+ if (linep == lineendp)
+ {
+ puts (gettext ("\nNo line number statements."));
+ return;
+ }
+
puts (gettext ("\nLine number statements:"));
Dwarf_Word address = 0;
unsigned int op_index = 0;
@@ -9156,6 +9196,43 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
bool start_of_list = true;
while (readp < nexthdr)
{
+ Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
+ if (listptr_attr (&known_loclistsptr, listptr_idx, off,
+ DW_AT_GNU_locviews))
+ {
+ Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
+ &listptr_idx, off);
+ const unsigned char *locp = readp;
+ const unsigned char *locendp;
+ if (next_off == 0
+ || next_off > (size_t) (nexthdr - ((const unsigned char *)
+ data->d_buf)))
+ locendp = nexthdr;
+ else
+ locendp = (const unsigned char *) data->d_buf + next_off;
+
+ printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
+ (uint64_t) (readp - (unsigned char *) data->d_buf),
+ (uint64_t) (readp - offset_array_start));
+
+ while (locp < locendp)
+ {
+ uint64_t v1, v2;
+ get_uleb128 (v1, locp, locendp);
+ if (locp >= locendp)
+ {
+ printf (gettext (" <INVALID DATA>\n"));
+ break;
+ }
+ get_uleb128 (v2, locp, locendp);
+ printf (" view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
+ }
+
+ printf ("\n");
+ readp = (unsigned char *) locendp;
+ continue;
+ }
+
uint8_t kind = *readp++;
uint64_t op1, op2, len;
@@ -9487,7 +9564,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
if (attr == DW_AT_GNU_locviews)
{
Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
- listptr_idx);
+ &listptr_idx, offset);
const unsigned char *locp = readp;
const unsigned char *locendp;
if (next_off == 0
@@ -9609,10 +9686,16 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
{
- printf (gettext (" [%6tx] base address\n "), offset);
+ if (first)
+ printf (" [%6tx] ", offset);
+ else
+ printf (" ");
+ puts (gettext ("base address"));
+ printf (" ");
print_dwarf_addr (dwflmod, address_size, end, end);
printf ("\n");
base = end;
+ first = false;
}
else if (begin == 0 && end == 0) /* End of list entry. */
{
@@ -11082,7 +11165,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
};
if (dbg == NULL)
{
- if ((print_debug_sections & ~section_exception) != 0)
+ if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
error (0, 0, gettext ("cannot get debug context descriptor: %s"),
dwfl_errmsg (-1));
dbg = &dummy_dbg;
diff --git a/src/stack.c b/src/stack.c
index 4daabce7..2ec7c972 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -143,7 +143,12 @@ module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
const char *debugfile;
const char *modname = dwfl_module_info (mod, NULL, NULL, &end, NULL,
NULL, &mainfile, &debugfile);
- assert (strcmp (modname, name) == 0);
+ if (modname == NULL || strcmp (modname, name) != 0)
+ {
+ end = start + 1;
+ mainfile = NULL;
+ debugfile = NULL;
+ }
int width = get_addr_width (mod);
printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
diff --git a/src/unstrip.c b/src/unstrip.c
index 9b8c09a1..0257d9cc 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -311,12 +311,18 @@ make_directories (const char *path)
if (lastslash == path)
return;
- char *dir = strndupa (path, lastslash - path);
+ char *dir = strndup (path, lastslash - path);
+ if (dir == NULL)
+ error(EXIT_FAILURE, errno, _("memory exhausted"));
+
while (mkdir (dir, 0777) < 0 && errno != EEXIST)
- if (errno == ENOENT)
- make_directories (dir);
- else
- error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
+ {
+ if (errno == ENOENT)
+ make_directories (dir);
+ else
+ error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
+ }
+ free (dir);
}
/* Keep track of new section data we are creating, so we can free it
@@ -500,7 +506,8 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
const size_t onent = shdr->sh_size / shdr->sh_entsize;
- assert (data->d_size == shdr->sh_size);
+ if (data->d_size != shdr->sh_size)
+ error (EXIT_FAILURE, 0, "HASH section has inconsistent size");
#define CONVERT_HASH(Hash_Word) \
{ \
@@ -509,7 +516,8 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
const size_t nchain = old_hash[1]; \
const Hash_Word *const old_bucket = &old_hash[2]; \
const Hash_Word *const old_chain = &old_bucket[nbucket]; \
- assert (onent == 2 + nbucket + nchain); \
+ if (onent != 2 + nbucket + nchain) \
+ error (EXIT_FAILURE, 0, "HASH section has inconsistent entsize"); \
\
const size_t nent = 2 + nbucket + nsym; \
Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]); \
@@ -2469,8 +2477,7 @@ match_module (Dwfl_Module *mod,
const char *file;
const char *check = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, &file, NULL);
- assert (check == name);
- if (file == NULL)
+ if (check == NULL || strcmp (check, name) != 0 || file == NULL)
return DWARF_CB_OK;
name = file;