elfunwindinfo

package
v0.0.0-...-3b12f0d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

README

Extracting stack deltas from DWARF

The code in this directory is responsible for extracting stack deltas from the DWARF information in executables or their debug symbols.

What are stack deltas?

In order to unwind native stack frames if the frame pointer has been omitted, it is necessary to locate the "top of the function frame" when given a RIP. This is usually at some offset from the current stack pointer RSP - the stack pointer can vary throughout the function by pushing arguments to called functions etc.

In short, for every RIP in a given binary, there is an associated value that can provide the "top" of the function frame, e.g. the address where the return address is stored, if added to RSP. We call this value 'stack delta'.

From where can we obtain stack deltas?

The "safest" way to obtain them would be to perform a full disassembly and then to track the stack pointer accordingly. This would deal with hand-written code where the compiler cannot generate debug information etc.

This is too time-consuming to develop at the moment. As a stopgap, it turns out that modern ELF executables (e.g. those compiled in the last few years) have all the necessary information to obtain the stack deltas in the .eh_frame section; it is placed there to enable stack unwinding for C++ exceptions. This is very useful for us.

How do we obtain stack deltas from the .eh_frame section?

The section is in almost the same format as the .debug_frame section in the debugging symbols. The DWARF format is optimized to both minimize the necessary storage as well as supporting 20+ different CPU architectures; the solution in DWARF is a fairly involved bytecode format and a small VM that allows the calculation of the stack delta given an address.

Fortunately the .eh_frame can contain only a fraction of DWARF commands, so we implement that ourselves to parse efficiently the stack deltas, and other needed information such RBP location in CFA to recover it.

Future work?

The .eh_frame section is often buggy, not all compilers generate it, and there are many other problems with it. The approach (disassemble & reconstruct) discussed above was implemented by researchers; the following presentation gives a good overview of the challenges and problems of working with DWARF (as well as references to papers that validate unwind tables etc.)

https://entropy2018.sciencesconf.org/data/nardelli.pdf

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Extract

func Extract(filename string, interval *sdtypes.IntervalData) error

Extract takes a filename for a modern ELF file that is accessible and provides the stack delta intervals in the interval parameter

func ExtractELF

func ExtractELF(elfRef *pfelf.Reference, interval *sdtypes.IntervalData) error

ExtractELF takes a pfelf.Reference and provides the stack delta intervals for it in the interval parameter.

func IsGo118orNewer

func IsGo118orNewer(magic uint32) bool

IsGo118orNewer returns true if magic matches with the Go 1.18 or newer.

func PclntabHeaderSize

func PclntabHeaderSize() int

PclntabHeaderSize returns the minimal pclntab header size.

func SearchGoPclntab

func SearchGoPclntab(ef *pfelf.File) ([]byte, error)

SearchGoPclntab uses heuristic to find the gopclntab from RO data.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL