public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* eh_frame is debug info too
@ 2018-09-17 21:18 Sasha Da Rocha Pinheiro
  2018-09-18 11:37 ` Mark Wielaard
  0 siblings, 1 reply; 3+ messages in thread
From: Sasha Da Rocha Pinheiro @ 2018-09-17 21:18 UTC (permalink / raw)
  To: elfutils-devel, Mark Wielaard

Hi,
I have found a bug in Dyninst related to the fact that dwarf_begin_elf() won't create a (Dwarf *) handle given a stripped binary which contains the section ".eh_frame".
This section is sometimes generated to the detriment of ".debug_frames", which is omitted, while all info about frames are put in eh_frame.

Dyninst has already a whole abstraction in which keeps references to Dwarf handles depending on the info they have, such as type info, line info, and frame info. We do this in order to be able to load debug info from a different file other than the binary we are dealing with.

What happens now is that we try to create the handles to stripped file with ".eh_frame" and to the corresponding separate debug info binary but the first fails, and we don't get frame info. I know we could use dwarf_next_cfi() to go through the CIEs and FDEs in the stripped binary, but we wouldn't be able to use dwarf_cfi_addrframe and such. In addition to that we have this static map in which the key are Dwarf handles so that we can easily give a PC address to dwarf_cfi_addrframe. 

So my point is: can we make dwarf_begin_elf() open binaries that only contain ".eh_frame" to further be able to call dwarf_cfi_addrframe?

To make it more clear, in a Dyninst class, at some point, only has a Dwarf * handle. It doesn't know if it is stripped with only ".eh_frame" or if it contains ".debug_frame" and/or "eh_frame". 
What it does is try get both from the same handle as follows:

    // Try to get dwarf data from .debug_frame
    Dwarf_CFI * cfi = dwarf_getcfi(dbg);
    if (cfi)
    {
        cfi_data.push_back(cfi);
    }
    
    // Try to get dwarf data from .eh_frame
    Elf * elf = dwarf_getelf(dbg);
    cfi = dwarf_getcfi_elf(elf);
    if (cfi) 
    {
        cfi_data.push_back(cfi);
    }

Note that we try with dwarf_getcfi (for the .debug_frame section) giving the handle "dbg", and afterwards we have to get the Elf handle of this dwarf handle "dbg" to use dwarf_getcfi_elf (for the .eh_frame section).


Regards,
Sasha

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: eh_frame is debug info too
  2018-09-17 21:18 eh_frame is debug info too Sasha Da Rocha Pinheiro
@ 2018-09-18 11:37 ` Mark Wielaard
  2018-09-18 22:24   ` Sasha Da Rocha Pinheiro
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Wielaard @ 2018-09-18 11:37 UTC (permalink / raw)
  To: Sasha Da Rocha Pinheiro, elfutils-devel

Hi Sasha,

On Mon, 2018-09-17 at 21:18 +0000, Sasha Da Rocha Pinheiro wrote:
> So my point is: can we make dwarf_begin_elf() open binaries that only
> contain ".eh_frame" to further be able to call dwarf_cfi_addrframe?

I see your point and we have been more relax in determining what is or
isn't a real Dwarf file. Currently we allow a file that has a
.debug_info section or a .debug_line section or a .debug_frame section
(but up till 0.173 we only checked for .debug_info). Since those could
be used independently from each other.

But I am reluctant to make just having an .eh_frame enough. It really
isn't a debug/DWARF section. And as you also point out you don't need a
Dwarf handle for it. You would call dwarf_getcfi_elf (Elf *elf) to get
the CFI.

Allowing just .eh_frame being present would basically make any Elf file
a valid Dwarf file. I am somewhat worried that some existing programs
first try to open a file as Dwarf and only when it fails try to lookup
the separate debug file they need. We would break such programs.

I would note here that often the Dwarf debug file and the main Elf file
might not be the same (in the case of separate .debug file). And that
case you should really combine the CFI from the .debug_frame and the
CFI from the .eh_frame. They might cover different address ranges.

> To make it more clear, in a Dyninst class, at some point, only has a
> Dwarf * handle. It doesn't know if it is stripped with only
> ".eh_frame" or if it contains ".debug_frame" and/or "eh_frame". 
> What it does is try get both from the same handle as follows:
> 
>     // Try to get dwarf data from .debug_frame
>     Dwarf_CFI * cfi = dwarf_getcfi(dbg);
>     if (cfi)
>     {
>         cfi_data.push_back(cfi);
>     }
>     
>     // Try to get dwarf data from .eh_frame
>     Elf * elf = dwarf_getelf(dbg);
>     cfi = dwarf_getcfi_elf(elf);
>     if (cfi) 
>     {
>         cfi_data.push_back(cfi);
>     }
> 
> Note that we try with dwarf_getcfi (for the .debug_frame section)
> giving the handle "dbg", and afterwards we have to get the Elf handle
> of this dwarf handle "dbg" to use dwarf_getcfi_elf (for the .eh_frame
> section).

So in the above how does that work with a binary that has separate
debuginfo? (Do you use libdwfl, or dwelf_elf_gnu_debuglink or use
dwelf_elf_gnu_build_id to find it?) In that case dwarf_getelf () will
return the file containing the separate debuginfo, but the .eh_frame
would be in the main Elf file.

Also note that the returned cfi has different life-times. The Dwarf_CFI
 handle you get from dwarf_getcfi () is valid till the associated Dwarf
handle is closed. The Dwarf_CFI returned from dwarf_getcfi_elf is owned
by (and should be freed by) the called (and you will get a new one each
call). So be careful you don't have a memory leak here.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: eh_frame is debug info too
  2018-09-18 11:37 ` Mark Wielaard
@ 2018-09-18 22:24   ` Sasha Da Rocha Pinheiro
  0 siblings, 0 replies; 3+ messages in thread
From: Sasha Da Rocha Pinheiro @ 2018-09-18 22:24 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

It's not working but I'm fixing it.
We don't use  Elfutils to find the corresponding separate debug info. It was already implemented by searching the gnu_debuglink section and getting the info.

Sasha

 
From: Mark Wielaard <mark@klomp.org>
Sent: Tuesday, September 18, 2018 6:36 AM
To: Sasha Da Rocha Pinheiro; elfutils-devel@sourceware.org
Subject: Re: eh_frame is debug info too
  

Hi Sasha,

On Mon, 2018-09-17 at 21:18 +0000, Sasha Da Rocha Pinheiro wrote:
> So my point is: can we make dwarf_begin_elf() open binaries that only
> contain ".eh_frame" to further be able to call dwarf_cfi_addrframe?

I see your point and we have been more relax in determining what is or
isn't a real Dwarf file. Currently we allow a file that has a
.debug_info section or a .debug_line section or a .debug_frame section
(but up till 0.173 we only checked for .debug_info). Since those could
be used independently from each other.

But I am reluctant to make just having an .eh_frame enough. It really
isn't a debug/DWARF section. And as you also point out you don't need a
Dwarf handle for it. You would call dwarf_getcfi_elf (Elf *elf) to get
the CFI.

Allowing just .eh_frame being present would basically make any Elf file
a valid Dwarf file. I am somewhat worried that some existing programs
first try to open a file as Dwarf and only when it fails try to lookup
the separate debug file they need. We would break such programs.

I would note here that often the Dwarf debug file and the main Elf file
might not be the same (in the case of separate .debug file). And that
case you should really combine the CFI from the .debug_frame and the
CFI from the .eh_frame. They might cover different address ranges.

> To make it more clear, in a Dyninst class, at some point, only has a
> Dwarf * handle. It doesn't know if it is stripped with only
> ".eh_frame" or if it contains ".debug_frame" and/or "eh_frame". 
> What it does is try get both from the same handle as follows:
> 
>     // Try to get dwarf data from .debug_frame
>     Dwarf_CFI * cfi = dwarf_getcfi(dbg);
>     if (cfi)
>     {
>         cfi_data.push_back(cfi);
>     }
>     
>     // Try to get dwarf data from .eh_frame
>     Elf * elf = dwarf_getelf(dbg);
>     cfi = dwarf_getcfi_elf(elf);
>     if (cfi) 
>     {
>         cfi_data.push_back(cfi);
>     }
> 
> Note that we try with dwarf_getcfi (for the .debug_frame section)
> giving the handle "dbg", and afterwards we have to get the Elf handle
> of this dwarf handle "dbg" to use dwarf_getcfi_elf (for the .eh_frame
> section).

So in the above how does that work with a binary that has separate
debuginfo? (Do you use libdwfl, or dwelf_elf_gnu_debuglink or use
dwelf_elf_gnu_build_id to find it?) In that case dwarf_getelf () will
return the file containing the separate debuginfo, but the .eh_frame
would be in the main Elf file.

Also note that the returned cfi has different life-times. The Dwarf_CFI
 handle you get from dwarf_getcfi () is valid till the associated Dwarf
handle is closed. The Dwarf_CFI returned from dwarf_getcfi_elf is owned
by (and should be freed by) the called (and you will get a new one each
call). So be careful you don't have a memory leak here.

Cheers,

Mark
    

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-09-18 22:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-17 21:18 eh_frame is debug info too Sasha Da Rocha Pinheiro
2018-09-18 11:37 ` Mark Wielaard
2018-09-18 22:24   ` Sasha Da Rocha Pinheiro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).