summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO9
-rw-r--r--libdw/ChangeLog15
-rw-r--r--libdw/dwarf_getattrs.c33
-rw-r--r--libdw/dwarf_getsrclines.c6
-rw-r--r--libdw/dwarf_ranges.c11
-rw-r--r--libdw/libdwP.h41
-rw-r--r--libdwfl/ChangeLog5
-rw-r--r--libdwfl/dwfl_report_elf.c3
-rw-r--r--m4/ChangeLog4
-rw-r--r--m4/zip.m47
-rw-r--r--src/ChangeLog9
-rw-r--r--src/readelf.c52
12 files changed, 146 insertions, 49 deletions
diff --git a/TODO b/TODO
index 2221b2e5..0012a566 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,7 @@
ToDo list for elfutils -*-outline-*-
----------------------
-Time-stamp: <2009-01-26 13:07:11 drepper>
+Time-stamp: <2009-02-05 22:08:01 drepper>
* mkinstalldirs
@@ -110,6 +110,13 @@ Time-stamp: <2009-01-26 13:07:11 drepper>
Not implemented at all in the moment except for recognition of the option
itself.
+** variables with aliases in executables
+
+ When linking an executable with a references against a variable in a
+ DSO, create symbol table entries for all the aliases of the variable
+ in the DSO and create a relocation for one of them (a non-weak
+ definition)
+
* elflint
** additional checks
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 6ee143f7..d66f34b0 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,18 @@
+2009-01-28 Roland McGrath <roland@redhat.com>
+
+ * libdwP.h (struct Dwarf_Line_s): Move out of struct Dwarf_Lines_s
+ defn so C++ doesn't scope the name to not match the Dwarf_Line typedef.
+
+ * libdwP.h (struct Dwarf_Files_s): Replace dbg field with cu field.
+
+2009-01-26 Roland McGrath <roland@redhat.com>
+
+ * dwarf_ranges.c: Return 0 when no ranges or *_pc attrs at all.
+
+2009-01-25 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getattrs.c: Correctly skip attribute values when restarting.
+
2009-01-23 Roland McGrath <roland@redhat.com>
* Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back.
diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c
index 42f25ca0..051dc25f 100644
--- a/libdw/dwarf_getattrs.c
+++ b/libdw/dwarf_getattrs.c
@@ -1,5 +1,5 @@
/* Get attributes of the DIE.
- Copyright (C) 2004, 2005, 2008 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -62,6 +62,9 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
if (die == NULL)
return -1l;
+ if (unlikely (offset == 1))
+ return 1;
+
const unsigned char *die_addr = die->addr;
/* Get the abbreviation code. */
@@ -80,7 +83,8 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
}
/* This is where the attributes start. */
- const unsigned char *attrp = die->abbrev->attrp + offset;
+ const unsigned char *attrp = die->abbrev->attrp;
+ const unsigned char *const offset_attrp = die->abbrev->attrp + offset;
/* Go over the list of attributes. */
Dwarf *dbg = die->cu->dbg;
@@ -108,16 +112,21 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
offset of an attribute. */
return 1l;
- /* Fill in the rest. */
- attr.valp = (unsigned char *) die_addr;
- attr.cu = die->cu;
-
- /* Now call the callback function. */
- if (callback (&attr, arg) != DWARF_CB_OK)
- /* Return the offset of the start of the attribute, so that
- dwarf_getattrs() can be restarted from this point if the
- caller so desires. */
- return remembered_attrp - die->abbrev->attrp;
+ /* If we are not to OFFSET_ATTRP yet, we just have to skip
+ the values of the intervening attributes. */
+ if (remembered_attrp >= offset_attrp)
+ {
+ /* Fill in the rest. */
+ attr.valp = (unsigned char *) die_addr;
+ attr.cu = die->cu;
+
+ /* Now call the callback function. */
+ if (callback (&attr, arg) != DWARF_CB_OK)
+ /* Return the offset of the start of the attribute, so that
+ dwarf_getattrs() can be restarted from this point if the
+ caller so desires. */
+ return remembered_attrp - die->abbrev->attrp;
+ }
/* Skip over the rest of this attribute (if there is any). */
if (attr.form != 0)
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 9b3c97af..fe0e67d6 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -1,5 +1,5 @@
/* Return line number information of CU.
- Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc.
+ Copyright (C) 2004-2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -634,8 +634,8 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
dirs[i] = dirarray[i]->dir;
dirs[ndirlist] = NULL;
- /* Remember the debugging descriptor. */
- files->dbg = dbg;
+ /* Remember the referring CU. */
+ files->cu = cu;
/* Make the file data structure available through the CU. */
cu->files = files;
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c
index 89da0af4..1eef617b 100644
--- a/libdw/dwarf_ranges.c
+++ b/libdw/dwarf_ranges.c
@@ -1,5 +1,5 @@
/* Enumerate the PC ranges covered by a DIE.
- Copyright (C) 2005, 2007 Red Hat, Inc.
+ Copyright (C) 2005, 2007, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -78,8 +78,9 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
/* We have to look for a noncontiguous range. */
const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
- if (d == NULL)
+ if (d == NULL && offset != 0)
{
+ no_ranges:
__libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
return -1;
}
@@ -90,13 +91,17 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges,
&attr_mem);
if (attr == NULL)
- return -1;
+ /* No PC attributes in this DIE at all, so an empty range list. */
+ return 0;
/* Must have the form data4 or data8 which act as an offset. */
Dwarf_Word start_offset;
if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0)
return -1;
+ if (d == NULL)
+ goto no_ranges;
+
offset = start_offset;
assert ((Dwarf_Word) offset == start_offset);
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 867ad89b..1d5a9b27 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -1,5 +1,5 @@
/* Internal definitions for libdwarf.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
+ Copyright (C) 2002-2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -208,7 +208,7 @@ struct Dwarf_Abbrev
/* Files in line information records. */
struct Dwarf_Files_s
{
- Dwarf *dbg;
+ struct Dwarf_CU *cu;
unsigned int ndirs;
unsigned int nfiles;
struct Dwarf_Fileinfo_s
@@ -223,26 +223,27 @@ typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
/* Representation of a row in the line table. */
-struct Dwarf_Lines_s
- {
- size_t nlines;
- struct Dwarf_Line_s
- {
- Dwarf_Addr addr;
- unsigned int file;
- int line;
- unsigned short int column;
- unsigned int is_stmt:1;
- unsigned int basic_block:1;
- unsigned int end_sequence:1;
- unsigned int prologue_end:1;
- unsigned int epilogue_begin:1;
-
- Dwarf_Files *files;
- } info[0];
- };
+struct Dwarf_Line_s
+{
+ Dwarf_Addr addr;
+ unsigned int file;
+ int line;
+ unsigned short int column;
+ unsigned int is_stmt:1;
+ unsigned int basic_block:1;
+ unsigned int end_sequence:1;
+ unsigned int prologue_end:1;
+ unsigned int epilogue_begin:1;
+ Dwarf_Files *files;
+};
+
+struct Dwarf_Lines_s
+{
+ size_t nlines;
+ struct Dwarf_Line_s info[0];
+};
/* Representation of address ranges. */
struct Dwarf_Aranges_s
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5490f5f0..aafa1c92 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2009-01-27 Roland McGrath <roland@redhat.com>
+
+ * dwfl_report_elf.c (__libdwfl_report_elf): Ignore trailing PT_LOAD
+ with zero vaddr and memsz.
+
2009-01-22 Roland McGrath <roland@redhat.com>
* open.c (decompress): Move BUFFER, SIZE decls outside #if.
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 3482a229..9fc156fe 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -208,7 +208,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
if (unlikely (ph == NULL))
goto elf_error;
- if (ph->p_type == PT_LOAD)
+ if (ph->p_type == PT_LOAD
+ && ph->p_vaddr + ph->p_memsz > 0)
{
end = base + (ph->p_vaddr + ph->p_memsz);
break;
diff --git a/m4/ChangeLog b/m4/ChangeLog
index eea78ff0..25675634 100644
--- a/m4/ChangeLog
+++ b/m4/ChangeLog
@@ -1,3 +1,7 @@
+2009-02-01 Roland McGrath <roland@redhat.com>
+
+ * zip.m4: Fix --with/--without argument handling.
+
2009-01-08 Roland McGrath <roland@redhat.com>
* zip.am: New file.
diff --git a/m4/zip.m4 b/m4/zip.m4
index 398d1be5..19fa4926 100644
--- a/m4/zip.m4
+++ b/m4/zip.m4
@@ -1,10 +1,11 @@
-dnl Test for either zlib or bzlib.
+dnl -*- Autoconf -*- test for either zlib or bzlib.
dnl Defines --with-$1lib argument, $2LIB automake conditional,
dnl and sets AC_DEFINE(USE_$2LIB) and LIBS.
-AC_DEFUN([eu_ZIPLIB], [with_[$1]lib=default
+AC_DEFUN([eu_ZIPLIB], [dnl
AC_ARG_WITH([[$1]lib],
-AC_HELP_STRING([--with-[$1]lib], [support g[$1]ip compression in libdwfl]))
+AC_HELP_STRING([--with-[$1]lib], [support g[$1]ip compression in libdwfl]),,
+ [with_[$1]lib=default])
if test $with_[$1]lib != no; then
AC_SEARCH_LIBS([$4], [$3], [with_[$1]lib=yes],
[test $with_[$1]lib = default ||
diff --git a/src/ChangeLog b/src/ChangeLog
index 71a6da2f..287ead38 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -19,6 +19,15 @@
* objdump.c (parse_opt): Likewise.
* readelf.c (parse_opt): Likewise.
+2009-01-27 Roland McGrath <roland@redhat.com>
+
+ * readelf.c (print_ops): Notice short length, don't overrun buffer
+ (still need to fix LEB128).
+
+ * readelf.c (print_ops): Fix DW_OP_call[24] decoding.
+
+ * readelf.c (print_ops): Print (empty)\n when LEN == 0.
+
2009-01-24 Ulrich Drepper <drepper@redhat.com>
* readelf.c (print_debug_frame_section): Fix computation of vma_base
diff --git a/src/readelf.c b/src/readelf.c
index 51ce144d..c9f18896 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3785,6 +3785,14 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
[DW_OP_bit_piece] = "bit_piece",
};
+ if (len == 0)
+ {
+ printf ("%*s(empty)\n", indent, "");
+ return;
+ }
+
+#define NEED(n) if (len < n) goto invalid;
+
Dwarf_Word offset = 0;
while (len-- > 0)
{
@@ -3796,6 +3804,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_addr:;
/* Address operand. */
Dwarf_Word addr;
+ NEED (addrsize);
if (addrsize == 4)
addr = read_4ubyte_unaligned (dbg, data);
else
@@ -3825,6 +3834,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_pick:
case DW_OP_const1u:
// XXX value might be modified by relocation
+ NEED (1);
printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
indent, "", (uintmax_t) offset,
known[op], *((uint8_t *) data));
@@ -3834,6 +3844,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const2u:
+ NEED (2);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
indent, "", (uintmax_t) offset,
@@ -3844,6 +3855,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const4u:
+ NEED (4);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
indent, "", (uintmax_t) offset,
@@ -3854,6 +3866,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const8u:
+ NEED (8);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
indent, "", (uintmax_t) offset,
@@ -3864,6 +3877,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const1s:
+ NEED (1);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
indent, "", (uintmax_t) offset,
@@ -3874,6 +3888,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const2s:
+ NEED (2);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
indent, "", (uintmax_t) offset,
@@ -3884,6 +3899,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const4s:
+ NEED (4);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
indent, "", (uintmax_t) offset,
@@ -3894,6 +3910,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_const8s:
+ NEED (8);
// XXX value might be modified by relocation
printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
indent, "", (uintmax_t) offset,
@@ -3909,7 +3926,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_constu:;
const unsigned char *start = data;
unsigned int uleb;
- get_uleb128 (uleb, data);
+ get_uleb128 (uleb, data); /* XXX check overrun */
printf ("%*s[%4" PRIuMAX "] %s %u\n",
indent, "", (uintmax_t) offset, known[op], uleb);
len -= data - start;
@@ -3919,8 +3936,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_bit_piece:
start = data;
unsigned int uleb2;
- get_uleb128 (uleb, data);
- get_uleb128 (uleb2, data);
+ get_uleb128 (uleb, data); /* XXX check overrun */
+ get_uleb128 (uleb2, data); /* XXX check overrun */
printf ("%*s[%4" PRIuMAX "] %s %u, %u\n",
indent, "", (uintmax_t) offset, known[op], uleb, uleb2);
len -= data - start;
@@ -3932,7 +3949,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_consts:
start = data;
unsigned int sleb;
- get_sleb128 (sleb, data);
+ get_sleb128 (sleb, data); /* XXX check overrun */
printf ("%*s[%4" PRIuMAX "] %s %d\n",
indent, "", (uintmax_t) offset, known[op], sleb);
len -= data - start;
@@ -3941,8 +3958,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_bregx:
start = data;
- get_uleb128 (uleb, data);
- get_sleb128 (sleb, data);
+ get_uleb128 (uleb, data); /* XXX check overrun */
+ get_sleb128 (sleb, data); /* XXX check overrun */
printf ("%*s[%4" PRIuMAX "] %s %u %d\n",
indent, "", (uintmax_t) offset, known[op], uleb, sleb);
len -= data - start;
@@ -3950,9 +3967,26 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
break;
case DW_OP_call2:
+ NEED (2);
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
+ indent, "", (uintmax_t) offset, known[op],
+ read_2ubyte_unaligned (dbg, data));
+ len -= 2;
+ offset += 3;
+ break;
+
case DW_OP_call4:
+ NEED (4);
+ printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
+ indent, "", (uintmax_t) offset, known[op],
+ read_4ubyte_unaligned (dbg, data));
+ len -= 4;
+ offset += 5;
+ break;
+
case DW_OP_skip:
case DW_OP_bra:
+ NEED (2);
printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
indent, "", (uintmax_t) offset, known[op],
(uintmax_t) (offset + read_2sbyte_unaligned (dbg, data)));
@@ -3974,6 +4008,12 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
}
indent = indentrest;
+ continue;
+
+ invalid:
+ printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
+ indent, "", (uintmax_t) offset, known[op]);
+ break;
}
}