pfelf

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: 20 Imported by: 0

Documentation

Overview

package pfelf implements functions for processing of ELF files and extracting data from them. This file provides a cacheable file offset to virtual address mapping.

package pfelf implements functions for processing of ELF files and extracting data from them. This file provides convenience functions for golang debug/elf standard library.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoBuildID = errors.New("no build ID")
View Source
var ErrNoDebugLink = errors.New("no debug link")
View Source
var ErrNotELF = errors.New("not an ELF file")

ErrNotELF is returned when the file is not an ELF

View Source
var ErrSymbolNotFound = errors.New("symbol not found")

ErrSymbolNotFound is returned when requested symbol was not found

View Source
var SystemOpener systemOpener

Functions

func CalculateID

func CalculateID(fileName string) (libpf.FileID, error)

CalculateID calculates a 128-bit executable ID of the contents of a file. For kernel files (modules & kernel image), use CalculateKernelFileID instead.

func CalculateIDFromReader

func CalculateIDFromReader(reader io.ReadSeeker) (libpf.FileID, error)

CalculateIDFromReader calculates a 128-bit executable ID of the contents of a reader. For kernel files (modules & kernel image), use CalculateKernelFileID instead.

func CalculateIDString

func CalculateIDString(fileName string) (string, error)

CalculateIDString provides a string representation of the hash of a given file.

func CalculateKernelFileID

func CalculateKernelFileID(buildID string) (fileID libpf.FileID)

CalculateKernelFileID returns the FileID of a kernel image or module, which consists of a hash of its GNU BuildID in hex string form. The hashing step is to ensure that the FileID remains an opaque concept to the end user.

func FileHash

func FileHash(fileName string) ([]byte, error)

func GetBuildID

func GetBuildID(elfFile *elf.File) (string, error)

GetBuildID extracts the build ID from the provided ELF file. This is read from the .note.gnu.build-id or .notes section of the ELF, and may not exist. If no build ID is present an ErrNoBuildID is returned.

func GetBuildIDFromNotesFile

func GetBuildIDFromNotesFile(filePath string) (string, error)

GetBuildIDFromNotesFile returns the build ID contained in a file with the format of an ELF notes section.

func GetDebugLink(elfFile *elf.File) (linkName string, crc32 int32, err error)

GetDebugLink reads and parses the .gnu_debuglink section of given ELF file. Error is returned if the data is malformed. If the link does not exist then ErrNoDebugLink is returned.

func GetDynamicSymbols

func GetDynamicSymbols(elfFile *elf.File) (*libpf.SymbolMap, error)

GetDynamicSymbols gets the dynamic symbols of elf.File and returns them as libpf.SymbolMap for fast lookup by address and name.

func GetKernelVersionBytes

func GetKernelVersionBytes(elfFile *elf.File) ([]byte, error)

GetKernelVersionBytes returns the kernel version from a kernel image, as it appears in /proc/version

This makes the assumption that the string is the first one in ".rodata" that starts with "Linux version ".

func GetSectionAddress

func GetSectionAddress(e *elf.File, sectionName string) (
	addr uint64, found bool, err error)

GetSectionAddress returns the address of an ELF section. `found` is set to false if such a section does not exist.

func HasCodeSection

func HasCodeSection(elfFile *elf.File) bool

HasCodeSection returns true if the file contains at least one non-empty executable code section.

func HasDWARFData

func HasDWARFData(elfFile *elf.File) bool

HasDWARFData returns true if the provided ELF file contains actionable DWARF debugging information. This function does not call `elfFile.DWARF()` on purpose, as it can be extremely expensive in terms of CPU/memory, possibly uncompressing all data in `.zdebug_` sections. This function being used extensively by the indexing service, it is preferable to keep it lightweight.

func HasSection

func HasSection(file *elf.File, section string) (bool, error)

HasSection returns true if the provided file contains a specific section.

func IsELF

func IsELF(filePath string) (bool, error)

IsELF checks if the first four bytes of the provided file match the ELF magic bytes and returns true if so, or false otherwise.

func IsELFReader

func IsELFReader(reader io.ReadSeeker) (bool, error)

IsELFReader checks if the first four bytes of the provided ReadSeeker match the ELF magic bytes, and returns true if so, or false otherwise.

*** WARNING *** ANY CHANGE IN BEHAVIOR CAN EASILY BREAK OUR INFRASTRUCTURE, POSSIBLY MAKING THE ENTIRETY OF THE DEBUG INDEX OR FRAME METADATA WORTHLESS (BREAKING BACKWARDS COMPATIBILITY).

func IsGoBinary

func IsGoBinary(file *elf.File) (bool, error)

IsGoBinary returns true if the provided file is a Go binary (= an ELF file with a known Golang section).

func KernelFileIDToggleDebug

func KernelFileIDToggleDebug(kernelFileID libpf.FileID) (fileID libpf.FileID)

KernelFileIDToggleDebug returns the FileID of a kernel debug file (image or module) based on the FileID of its non-debug counterpart. This function is its own inverse, so it can be used for the opposite operation. This provides 2 properties:

  • FileIDs must be different between kernel files and their debug files.
  • A kernel FileID (debug and non-debug) must only depend on its GNU BuildID (see KernelFileID), and can always be computed in the Host Agent or during indexing without external information.
func ParseDebugLink(data []byte) (linkName string, crc32 int32, err error)

ParseDebugLink parses the name and CRC32 of the debug info file from the provided section data. Error is returned if the data is malformed.

Types

type AddressMapper

type AddressMapper struct {
	// contains filtered or unexported fields
}

AddressMapper contains minimal information about PHDRs needed for address mapping

func (*AddressMapper) FileOffsetToVirtualAddress

func (am *AddressMapper) FileOffsetToVirtualAddress(fileOffset uint64) (uint64, bool)

FileOffsetToVirtualAddress attempts to convert an on-disk file offset to the ELF virtual address where it would be mapped by default.

type ELFOpener

type ELFOpener interface {
	OpenELF(string) (*File, error)
}

ELFOpener is the interface to open ELF files from arbitrary location with given filename.

Implementations must be safe to be called from different threads simultaneously.

type File

type File struct {

	// ROData is a slice of pointers to the read-only data segments of the ELF
	// These are sorted so that segments marked as "read" appear before those
	// marked as "read-execute"
	ROData []*Prog

	// Progs contains the program header
	Progs []Prog

	// Sections contains the program sections if loaded
	Sections []Section

	// InsideCore indicates that this ELF is mapped from a coredump ELF
	InsideCore bool

	// Fields to mimic elf.debug
	Type    elf.Type
	Machine elf.Machine
	Entry   uint64
	// contains filtered or unexported fields
}

File represents an open ELF file

func NewFile

func NewFile(r io.ReaderAt, loadAddress uint64, hasMusl bool) (*File, error)

NewFile creates a new ELF file object that borrows the given reader.

func Open

func Open(name string) (*File, error)

Open opens the named file using os.Open and prepares it for use as an ELF binary.

func (*File) CRC32

func (f *File) CRC32() (int32, error)

CRC32 calculates the .gnu_debuglink compatible CRC-32 of the ELF file

func (*File) Close

func (f *File) Close() (err error)

Close closes the File.

func (*File) DynString

func (f *File) DynString(tag elf.DynTag) ([]string, error)

DynString returns the strings listed for the given tag in the file's dynamic program header.

func (*File) EHFrame

func (f *File) EHFrame() (*Prog, error)

EHFrame constructs a Program header with the EH Frame sections

func (*File) GetAddressMapper

func (f *File) GetAddressMapper() AddressMapper

NewAddressMapper returns an address mapper for given ELF File

func (*File) GetBuildID

func (f *File) GetBuildID() (string, error)

GetBuildID returns the ELF BuildID if present

func (f *File) GetDebugLink() (linkName string, crc int32, err error)

GetDebugLink reads and parses the .gnu_debuglink section. If the link does not exist then ErrNoDebugLink is returned.

func (*File) GetRemoteMemory

func (f *File) GetRemoteMemory() remotememory.RemoteMemory

GetRemoteMemory returns RemoteMemory interface for the core dump

func (*File) IsGolang

func (f *File) IsGolang() bool

IsGolang determines if this ELF is a Golang executable

func (*File) LoadSections

func (f *File) LoadSections() error

LoadSections loads the ELF file sections

func (*File) LookupSymbol

func (f *File) LookupSymbol(symbol libpf.SymbolName) (*libpf.Symbol, error)

LookupSymbol searches for a given symbol in the ELF

func (*File) LookupSymbolAddress

func (f *File) LookupSymbolAddress(symbol libpf.SymbolName) (libpf.SymbolValue, error)

LookupSymbol searches for a given symbol in the ELF

func (f *File) OpenDebugLink(elfFilePath string, elfOpener ELFOpener) (
	debugELF *File, debugFile string)

OpenDebugLink tries to locate and open the corresponding debug ELF for this DSO.

func (*File) ReadAt

func (f *File) ReadAt(p []byte, addr int64) (int, error)

ReadAt reads bytes from given virtual address

func (*File) ReadDynamicSymbols

func (f *File) ReadDynamicSymbols() (*libpf.SymbolMap, error)

ReadDynamicSymbols reads the full dynamic symbol table from the ELF

func (*File) ReadSymbols

func (f *File) ReadSymbols() (*libpf.SymbolMap, error)

ReadSymbols reads the full dynamic symbol table from the ELF

func (*File) ReadVirtualMemory

func (f *File) ReadVirtualMemory(p []byte, addr int64) (int, error)

ReadVirtualMemory reads bytes from given virtual address

func (*File) Section

func (f *File) Section(name string) *Section

Section returns a section with the given name, or nil if no such section exists.

type Prog

type Prog struct {
	elf.ProgHeader
	// contains filtered or unexported fields
}

Prog represents a program header, and data associated with it

func (*Prog) Data

func (ph *Prog) Data(maxSize uint) ([]byte, error)

Data loads the whole program header referenced data, and returns it as slice.

func (*Prog) DataReader

func (ph *Prog) DataReader(maxSize uint) (io.Reader, error)

DataReader loads the whole program header referenced data, and returns reader to it.

func (*Prog) Open

func (ph *Prog) Open() io.ReadSeeker

Open returns a new ReadSeeker reading the ELF program body.

func (*Prog) ReadAt

func (ph *Prog) ReadAt(p []byte, off int64) (n int, err error)

ReadAt implements the io.ReaderAt interface

type Reference

type Reference struct {
	// Interface to open ELF files as needed
	ELFOpener
	// contains filtered or unexported fields
}

Reference is a reference to an ELF file which is loaded and cached on demand.

func NewReference

func NewReference(fileName string, elfOpener ELFOpener) *Reference

NewReference returns a new Reference

func (*Reference) Close

func (ref *Reference) Close()

Close closes the File if it has been opened earlier.

func (*Reference) FileName

func (ref *Reference) FileName() string

FileName returns the file name associated with this Reference

func (*Reference) GetELF

func (ref *Reference) GetELF() (*File, error)

GetELF returns the File to access this File and keeps it cached. The caller of this functions must not Close the File.

type Section

type Section struct {
	elf.SectionHeader

	// Embed ReaderAt for ReadAt method.
	io.ReaderAt
	// contains filtered or unexported fields
}

Section represents a section header, and data associated with it

func (*Section) Data

func (sh *Section) Data(maxSize uint) ([]byte, error)

Data loads the whole section header referenced data, and returns it as a slice.

Jump to

Keyboard shortcuts

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