obj

package
v0.0.0-...-f342860 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2024 License: BSD-3-Clause Imports: 13 Imported by: 1

Documentation

Overview

Package obj provide a common abstraction for working with different object formats.

Index

Constants

View Source
const NoSym = ^SymID(0)

NoSym is a placeholder SymID used to indicate "no symbol".

Variables

This section is empty.

Functions

func SynthesizeSizes

func SynthesizeSizes(syms []Sym)

SynthesizeSizes assigns sizes to syms that don't have sizes using heuristics.

Types

type AsDebugDwarf

type AsDebugDwarf interface {
	File
	AsDebugDwarf() (*dwarf.Data, error)
}

AsDebugDwarf is implemented by File types that can return their *debug/dwarf.Data DWARF data. AsDebugDwarf may return nil, so the caller must both check that the type implements AsDebugDwarf and check the result of calling AsDebugDwarf.

type AsDebugElf

type AsDebugElf interface {
	File
	AsDebugElf() *elf.File
}

AsDebugElf is implemented by File types that can return an underlying *debug/elf.File for format-specific access. AsDebugElf may return nil, so the caller must both check that the type implements AsDebugElf and check the result of calling AsDebugElf.

type Data

type Data struct {
	// Addr is the address at which this data starts.
	//
	// If this Data is for a Section or a Sym, this is the base address
	// of the section or symbol.
	Addr uint64

	// B stores the raw byte data. Callers must not modify this.
	B []byte

	// R stores the relocations applied to this Data in increasing
	// address order.
	//
	// This may include relocations outside or partially outside of this
	// Data's address range.
	R []Reloc

	// Layout specifies the byte order and word size of this data. This
	// is inferred from the object file's architecture, and hence may
	// not be correct for sections or symbols that have a fixed byte
	// order regardless of the host order.
	Layout arch.Layout
}

Data represents byte data in an object file.

type ErrNoData

type ErrNoData struct {
	Detail string
}

An ErrNoData error indicates that an entity is not backed by data.

func (*ErrNoData) Error

func (e *ErrNoData) Error() string

type File

type File interface {
	// Close closes this object file, releasing any OS resources used by it.
	//
	// It's possible that referencing a Data object returned from this File
	// after closing the File will panic.
	Close()

	// Info returns metadata about the whole object file.
	Info() FileInfo

	// Sections returns a slice of sections in this object file, indexed
	// by SectionID.
	//
	// All data in the object file (code, program data, etc) is stored
	// in sections. Often many metadata tables (e.g., symbol tables) are
	// as well.
	//
	// Each section has a name that generally follows a platform
	// convention, such as ".text" or ".data".
	//
	// All addresses within an object file, such as symbol addresses,
	// relocation targets, etc. are relative to some section of the
	// object file. Each section may or may not have a fixed base
	// address and sections may overlap. For example, in an executable
	// image, all of the mapped sections will have base addresses and
	// will not overlap, but there may be additional information in
	// non-mapped sections such as debugging info. In an unlinked
	// object file, typically none of the sections have base addresses.
	// And in a position-independent executable, sections may have base
	// addresses, but may be relocated to another address.
	Sections() []*Section

	// Section returns the i'th section. If i is out of range, it panics.
	Section(i SectionID) *Section

	// ResolveAddr finds the Section containing the given address in the
	// mapped address space. It returns nil if addr is not in a mapped
	// section. Not all sections are mapped, and some types of object
	// files don't have any mapped address space at all (for example,
	// ELF relocatable objects).
	//
	// TODO: Reconsider this API. Eventually it would be nice to be able
	// to handle addresses from relocated PIE images and core files. Do
	// those just implement the File interface and present the
	// underlying file relocated to the target addresses given by the
	// PIE loading/core file?
	//
	// TODO: Does this need to be a method on File at all or can it be a
	// global function?
	ResolveAddr(addr uint64) *Section

	// Sym returns i'th symbol. If i is our of range, it panics.
	Sym(i SymID) Sym

	// NumSyms returns the number of symbols.
	//
	// If an object file has more than one symbol table, they will be
	// concatenated. As a result, the "same" symbol may appear multiple times.
	NumSyms() SymID
	// contains filtered or unexported methods
}

A File represents an object file.

func Open

func Open(r io.ReaderAt) (File, error)

Open attempts to open r as a known object file format.

type FileInfo

type FileInfo struct {
	// Arch is the machine architecture of this object file, or
	// nil if unknown.
	Arch *arch.Arch
}

type Reader

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

func NewReader

func NewReader(d *Data) *Reader

func (*Reader) Addr

func (r *Reader) Addr() uint64

Addr returns the current position of r's cursor as an address in r's Data.

func (*Reader) Avail

func (r *Reader) Avail() int

Avail returns the number of bytes remaining in r's Data.

func (*Reader) CString

func (r *Reader) CString() []byte

CString reads a NULL-terminated string. The result omits the final NULL byte. If there is no NULL, this reads to the end of r's Data.

func (*Reader) Int16

func (r *Reader) Int16() int16

func (*Reader) Int32

func (r *Reader) Int32() int32

func (*Reader) Int64

func (r *Reader) Int64() int64

func (*Reader) Int8

func (r *Reader) Int8() int8

func (*Reader) SetAddr

func (r *Reader) SetAddr(addr uint64)

SetAddr moves r's cursor to the given address. If addr is out of range for r's Data, it panics.

func (*Reader) SetOffset

func (r *Reader) SetOffset(offset int)

SetOffset moves r's cursor to the given offset from the beginning of r's data.

func (*Reader) Uint16

func (r *Reader) Uint16() uint16

func (*Reader) Uint32

func (r *Reader) Uint32() uint32

func (*Reader) Uint64

func (r *Reader) Uint64() uint64

func (*Reader) Uint8

func (r *Reader) Uint8() uint8

func (*Reader) Word

func (r *Reader) Word() uint64

Word reads a word from r using the word size from r's Data.

type Reloc

type Reloc struct {
	// Addr is the address where this Reloc is applied.
	//
	// This is an absolute address within some section. Hence, to compute the
	// offset of the Reloc within a Section, use Addr - Section.Addr, and to
	// compute the byte offset of the Reloc within a Data, use Addr - Data.Addr.
	Addr uint64
	// Type is the relocation type. This determines how to calculate the value
	// that would be stored at Offset.
	Type RelocType
	// Symbol is the target of this Reloc, or NoSym if Type does not have a
	// symbol as an input.
	Symbol SymID
	// Addend is the addend input to Type, if any.
	//
	// If the file format uses addends smaller than 64-bits, they will be sign
	// extended.
	//
	// Objects formats store addends either explicitly in the relocations table
	// or implicitly at the target of the relocation. The obj package hides this
	// difference and populate Addend in either case.
	Addend int64
}

A Reloc is a relocation.

type RelocType

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

RelocType gives the type of a relocation. Relocations vary widely by architecture and operating system, so the interface to this is fairly opaque.

func (RelocType) Size

func (r RelocType) Size() int

Size returns the size of the relocation target in bytes, or -1 if unknown.

func (RelocType) String

func (r RelocType) String() string

type Section

type Section struct {
	// File is the object file containing this section.
	File File

	// Name is the name of this section. This typically follows platform
	// conventions, such as ".text" or ".data", but isn't necessarily
	// meaningful.
	Name string

	// ID is the obj-internal index of this section.
	ID SectionID

	// RawID is the index of this section in the underlying format's
	// representation, or -1 if this is not meaningful.
	RawID int

	// Addr is the virtual address at which this section begins in
	// memory, or 0 if either this section should not be loaded into
	// memory, or it has not yet been assigned a meaningful address.
	Addr uint64

	// Size is the size of this section in memory, in bytes.
	//
	// This may not be the size of the section on disk. For example, a
	// section that is all zeros may not be represented on disk at all,
	// or the section on disk may be compressed.
	Size uint64

	// SectionFlags stores flags for this section. This field is
	// embedded so Section inherits the methods of SectionFlags.
	SectionFlags
}

A Section is a contiguous region of address space in an object file.

An object file may have multiple sections whose addresses are not meaningfully related, so addresses within an object file must always be specified with respect to a given section.

func (*Section) Bounds

func (s *Section) Bounds() (addr, size uint64)

Bounds returns the starting address and size in bytes of Section s.

func (*Section) Data

func (s *Section) Data(addr, size uint64) (*Data, error)

Data reads size bytes of data from this section, starting at the given address. It panics if the requested byte range is out of range for the section.

func (*Section) String

func (s *Section) String() string

String returns the name of section s.

type SectionFlags

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

SectionFlags is a set of symbol flags.

func (SectionFlags) Mapped

func (s SectionFlags) Mapped() bool

Mapped indicates a section is mapped into the executable address space.

Because mapped sections are loaded into an address space, they should not overlap. Addresses in one mapped section may refer to another mapped section without any relocations (though mapped sections may still be relocatable).

func (SectionFlags) ReadOnly

func (s SectionFlags) ReadOnly() bool

ReadOnly indicates a section's data is read-only.

func (*SectionFlags) SetMapped

func (s *SectionFlags) SetMapped(v bool)

SetMapped sets the Mapped flag to v.

func (*SectionFlags) SetReadOnly

func (s *SectionFlags) SetReadOnly(v bool)

SetReadOnly sets the ReadOnly flag to v.

func (*SectionFlags) SetZeroInitialized

func (s *SectionFlags) SetZeroInitialized(v bool)

SetZeroInitialized sets the ZeroInitialized flag to v.

func (SectionFlags) ZeroInitialize

func (s SectionFlags) ZeroInitialize() bool

ZeroInitialized indicates a section is in a zero-initialized section.

type SectionID

type SectionID int

SectionID is an index for a section in an object file. These indexes are compact and start at 0.

These may not correspond to any section numbering used by the object format itself; see Section.RawID for this. For example, ELF section number 0 is reserved, so this slice starts at section 1 in ELF objects.

type Sym

type Sym struct {
	// Name is the string name of this symbol.
	Name string
	// Section is the section this symbol is defined in, or nil if this symbol
	// is not defined in any section. A symbol has data if and only if Section
	// is non-nil.
	Section *Section
	// Value is the value of this symbol. The interpretation of this differs
	// between different kinds of symbols. If this is a data symbol (Section is
	// non-nil), this is an absolute address within Section.
	Value uint64
	// Size is the size of this symbol in bytes, if it is a data symbol, or 0 if
	// unknown.
	Size uint64
	// Kind gives the general kind of this symbol.
	Kind SymKind
	// SymFlags stores flags for this symbol. This field is embedded so Sym
	// inherits the methods of SymFlags.
	SymFlags
}

A Sym is a symbol in an object file.

func (*Sym) Bounds

func (s *Sym) Bounds() (addr, size uint64)

Bounds returns the starting address and size in bytes of symbol s. For undefined symbols, it returns 0, 0.

func (*Sym) Data

func (s *Sym) Data(addr, size uint64) (*Data, error)

Data reads size bytes of data from this symbol, starting at the given address. If s is an undefined symbol or otherwise not backed by data, it returns an ErrNoData error. It panics if the requested byte range is out of range for the section.

func (*Sym) String

func (s *Sym) String() string

String returns the name of symbol s.

type SymFlags

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

SymFlags is a set of symbol flags.

func (SymFlags) Local

func (s SymFlags) Local() bool

Local indicates a symbol's name is only meaningful withing its defining compilation unit.

func (*SymFlags) SetLocal

func (s *SymFlags) SetLocal(v bool)

SetLocal sets the Local flag to v.

func (*SymFlags) SetSizeSynthesized

func (s *SymFlags) SetSizeSynthesized(v bool)

SetSizeSynthesized set the SizeSynthesized flag to v.

func (SymFlags) SizeSynthesized

func (s SymFlags) SizeSynthesized() bool

SizeSynthesized indicates a symbol's size was synthensized using heuristics.

func (SymFlags) String

func (s SymFlags) String() string

String returns a string representation of the flags set in s.

type SymID

type SymID uint32

A SymID uniquely identifies a symbol within an object file. Symbols within an object file are always numbered sequentially from 0.

This does not necessarily correspond to the symbol indexing scheme used by a given object format.

Some formats can have multiple symbol tables (e.g., ELF). These tables will be combined in a single global index space.

func (SymID) String

func (id SymID) String() string

type SymKind

type SymKind uint8

SymKind indicates the general kind of a symbol. The exact mappings from different object formats to these kinds is generally fuzzy, so different versions of the obj package may change how symbols are categorized.

const (
	// SymUnknown indicates a symbol could not be categorized into one of the
	// supported kinds.
	SymUnknown SymKind = '?'
	// SymUndef symbols are not defined in this object (it will be resolved by
	// linking against other objects).
	SymUndef SymKind = 'U'
	// SymText symbols are in an executable code section.
	SymText SymKind = 'T'
	// SymData symbols are in a data section. This includes read-only
	// and zero-initialized (BSS) data.
	SymData SymKind = 'D'
	// SymAbsolute symbols have an absolute value that won't be changed by
	// linking. Generally, the "value" of an absolute symbol is not an address
	// like most symbols, but the actual value of the symbol.
	SymAbsolute SymKind = 'A'
	// SymSection symbols represent a section. Some object formats put sections
	// in the symbol table and others don't.
	SymSection SymKind = 'S'
)

func (SymKind) String

func (k SymKind) String() string

String returns a string representation of k. This is a single character in the style of "nm".

Jump to

Keyboard shortcuts

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