[COMMITTED] tests: Don't printf a known NULL symname in backtrace-dwarf.c.

2019-05-01 Thread Mark Wielaard
GCC9 on 32bit systems might warn about '%s' directive argument is null
for symname in backtrace-dwarf.c. Just check whether symname is NULL.

This is an identical fix for the same issue as found in backtrace.c,
but now in backtrace-dwarf.c

Signed-off-by: Mark Wielaard 
---
 tests/ChangeLog | 5 +
 tests/backtrace-dwarf.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index a4f5dd3..d6dafa4 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,10 @@
 2019-04-30  Mark Wielaard  
 
+   * backtrace-dwarf.c (frame_callback): Explicitly check symname is
+   NULL.
+
+2019-04-30  Mark Wielaard  
+
* backtrace.c (frame_callback): Explicitly check symname is NULL.
 
 2019-03-04  Mark Wielaard  
diff --git a/tests/backtrace-dwarf.c b/tests/backtrace-dwarf.c
index dfbf185..f446bc3 100644
--- a/tests/backtrace-dwarf.c
+++ b/tests/backtrace-dwarf.c
@@ -101,7 +101,7 @@ frame_callback (Dwfl_Frame *state, void *frame_arg)
   if (mod)
 symname = dwfl_module_addrname (mod, pc_adjusted);
 
-  printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname);
+  printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname ?: "");
 
   if (symname && (strcmp (symname, "main") == 0
  || strcmp (symname, ".main") == 0))
-- 
1.8.3.1



[PATCH] libelf: Add n_namesz offset overflow check to gelf_get_note.

2019-05-01 Thread Mark Wielaard
During fuzzing of the new xlate_notes testcase I noticed that
gelf_get_note didn't check whether the n_namesz of a note was
too big. This could lead to offset wrapping around. Causing an
infinite loop going over all ELF notes. Fix by adding an overflow
check before updating offset.

Signed-off-by: Mark Wielaard 
---
 libelf/ChangeLog  | 5 +
 libelf/gelf_getnote.c | 5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 5eadaf7..924ff59 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2019-05-01  Mark Wielaard  
+
+   * gelf_getnote.c (gelf_getnote): Check n_namesz doesn't overflow
+   offset.
+
 2019-04-30  Mark Wielaard  
 
* note_xlate.h (elf_cvt_note): Indicate we only translated the note
diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c
index 6d33b35..0f7b9d6 100644
--- a/libelf/gelf_getnote.c
+++ b/libelf/gelf_getnote.c
@@ -80,11 +80,12 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr 
*result,
 the offset, after adding the namesz, and include padding
 in descsz to get to the end.  */
  *name_offset = offset;
- offset += n->n_namesz;
- if (offset > data->d_size)
+ if (n->n_namesz > data->d_size
+ || offset > data->d_size - n->n_namesz)
offset = 0;
  else
{
+ offset += n->n_namesz;
  /* Include padding.  Check below for overflow.  */
  GElf_Word descsz = (data->d_type == ELF_T_NHDR8
  ? NOTE_ALIGN8 (n->n_descsz)
-- 
1.8.3.1



Re: Dwarf_Op

2019-05-01 Thread Sasha Da Rocha Pinheiro
Hi Mark,

yes, I did use dwarf_frame_register(), I believe I mentioned that :).
In the case I brought up you're saying it was an elfutils' libdw decision to 
provide negative number as DW_OP_plus_uconst (unsigned constant)? So there 
would be no harm to cast it to a signed int??

Do you know if the rules to find the registers will always have only another 
one register associated to it? Because libdwarf function 
dwarf_get_fde_info_for_reg3() returns a register_num, which is described as:
"Argument register_num should point to a location which will hold the register 
number associated with the register rule."

elfutils only gives us a location description in an array of Dwarf_Op. Does it 
provide methods to "execute" it so we can get the result of the expressions? Or 
it delegates it to the consumer?

Regards
Sasha




From: Mark Wielaard 
Sent: Saturday, April 27, 2019 12:57 PM
To: Sasha Da Rocha Pinheiro
Cc: elfutils-devel@sourceware.org
Subject: Re: Dwarf_Op
 
On Fri, Apr 26, 2019 at 04:48:49PM +, Sasha Da Rocha Pinheiro wrote:

> The output from dwarfdump:
>
> <    5><0x00400918:0x00400974> 0>
>    
> 0x00400918: 
> 0x0040091c:   
> 0x00400920:   
> 0x00400970: 
>
> I'm getting the rules for r30 at PC 0x0040091c.
> The value you see -24 from cfa is passed delivered by libdw as:
>
> (gdb) p/x locations[i]
> $19 = {atom = 0x23, number = 0xffe8, number2 = 0x0, offset = 0x0}
>
> The atom here is DW_OP_plus_uconst.
> Previously I have said it was 0xffe8, because the printf with specifier 
> %x printed that way. But gdb seems to print its full 8 bytes.
> I used dwarf_frame_register.
>
> Even though, the member number is of unsigned int type with signed encoded 
> values. Am I correct?

Yes, a Dwarf_Op struct holds two number elements which are (unsigned 64bit)
Dwarf_Words:

typedef struct
{
  uint8_t atom; /* Operation */
  Dwarf_Word number;    /* Operand */
  Dwarf_Word number2;   /* Possible second operand */
  Dwarf_Word offset;    /* Offset in location expression */
} Dwarf_Op;

I assume you are using dwarf_frame_register () to turn the CFI for a
particular register into a location expression (array of Dwarf_Ops).
Which in this case would indeed produce DW_OP_call_frame_cfa,
DW_OP_plus_uconst (with the constant -24 in number).

Unfortunately there is no better/precise way to turn the CFI register
rule into a Dwarf Expression Location.

But note that if you use the Dwarf_Ops to calculate an Dwarf_Addr,
then the 64bit unsigned arithmetic will work out (because the plus of
the big unsigned constant will wrap around and turn into a small minus
constant).

Cheers,

Mark


[Bug tools/24509] New: eu-readelf does not know how to dissect DW_AT_discr_list

2019-05-01 Thread tromey at sourceware dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24509

Bug ID: 24509
   Summary: eu-readelf does not know how to dissect
DW_AT_discr_list
   Product: elfutils
   Version: unspecified
Status: NEW
  Severity: normal
  Priority: P2
 Component: tools
  Assignee: unassigned at sourceware dot org
  Reporter: tromey at sourceware dot org
CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Consider the Ada test case in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83935#c2.

Compiling to a .o and then using eu-readelf will yield something
like:

...
 [6b]variant  abbrev: 5
 discr_list   (block1) 7 byte block: 01 01 ff ff ff ff
07

discr_list has a specified structure, and it would be nice
if eu-readelf could dump it more verbosely.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug tools/24509] eu-readelf does not know how to dissect DW_AT_discr_list

2019-05-01 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=24509

Mark Wielaard  changed:

   What|Removed |Added

 CC||mark at klomp dot org

--- Comment #1 from Mark Wielaard  ---
Created attachment 11760
  --> https://sourceware.org/bugzilla/attachment.cgi?id=11760&action=edit
quick DW_AT_discr_list prototype

Here is a quick hack to show something more intelligent. It doesn't yet handle
signed values.

Could you provide a few different examples that we could use as testcases?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Re: Dwarf_Op

2019-05-01 Thread Mark Wielaard
On Wed, May 01, 2019 at 05:08:15PM +, Sasha Da Rocha Pinheiro wrote:
> yes, I did use dwarf_frame_register(), I believe I mentioned that :).

Sorry, I missed that.

> In the case I brought up you're saying it was an elfutils' libdw
> decision to provide negative number as DW_OP_plus_uconst (unsigned
> constant)? So there would be no harm to cast it to a signed int??

Yes, since I don't believe there is a better representation.
There is no DW_OP_plus_sconst for example.

> Do you know if the rules to find the registers will always have only
> another one register associated to it?  Because libdwarf function
> dwarf_get_fde_info_for_reg3() returns a register_num, which is
> described as: "Argument register_num should point to a location
> which will hold the register number associated with the register
> rule."

I am not familiar with libdwarf, so don't know how to answer this question

> elfutils only gives us a location description in an array of
> Dwarf_Op. Does it provide methods to "execute" it so we can get the
> result of the expressions? Or it delegates it to the consumer?

It doesn't have a generic location description "executor". It really
should have. But to make it generic it needs a lot of context.

libdwfl does contain a partial operator interpreter for unwinding. See
expr_eval in libdwfl/frame_unwind.c. To turn that into something more
generic we would need some way to provide it with things like memory
accessors and register values. libdwfl provides some of that through
dwfl_attach_state.

Cheers,

Mark