2017-04-21 06:55:53 +00:00
package core
2017-02-08 20:22:04 +00:00
import (
"bytes"
2017-05-29 13:20:01 +00:00
"debug/elf"
2017-02-08 20:22:04 +00:00
"encoding/binary"
2024-06-20 19:50:18 +00:00
"errors"
2017-02-08 20:22:04 +00:00
"fmt"
"io"
"os"
2018-10-16 10:48:59 +00:00
"strings"
2017-02-08 20:22:04 +00:00
2021-01-29 21:39:33 +00:00
"github.com/go-delve/delve/pkg/elfwriter"
2019-01-04 18:39:25 +00:00
"github.com/go-delve/delve/pkg/proc"
2020-12-14 17:39:01 +00:00
"github.com/go-delve/delve/pkg/proc/amd64util"
2019-01-04 18:39:25 +00:00
"github.com/go-delve/delve/pkg/proc/linutil"
2017-02-08 20:22:04 +00:00
)
2017-04-03 09:17:54 +00:00
// Copied from golang.org/x/sys/unix.Timeval since it's not available on all
// systems.
2020-03-26 12:05:09 +00:00
type linuxCoreTimeval struct {
2017-04-03 09:17:54 +00:00
Sec int64
Usec int64
}
2018-08-31 18:08:18 +00:00
// NT_FILE is file mapping information, e.g. program text mappings. Desc is a LinuxNTFile.
2020-03-26 12:05:09 +00:00
const _NT_FILE elf . NType = 0x46494c45 // "FILE".
2018-08-31 18:08:18 +00:00
// NT_X86_XSTATE is other registers, including AVX and such.
2020-03-26 12:05:09 +00:00
const _NT_X86_XSTATE elf . NType = 0x202 // Note type for notes containing X86 XSAVE area.
2017-02-08 20:22:04 +00:00
2018-05-29 15:01:51 +00:00
// NT_AUXV is the note type for notes containing a copy of the Auxv array
2020-03-26 12:05:09 +00:00
const _NT_AUXV elf . NType = 0x6
2018-05-29 15:01:51 +00:00
2020-02-17 17:29:17 +00:00
// NT_FPREGSET is the note type for floating point registers.
2020-03-26 12:05:09 +00:00
const _NT_FPREGSET elf . NType = 0x2
2020-02-17 17:29:17 +00:00
// Fetch architecture using exeELF.Machine from core file
2024-07-11 15:03:32 +00:00
// Refer https://man7.org/linux/man-pages/man5/elf.5.html
2020-02-17 17:29:17 +00:00
const (
2020-03-26 12:05:09 +00:00
_EM_AARCH64 = 183
_EM_X86_64 = 62
2024-10-11 19:34:25 +00:00
_EM_RISCV = 243
2020-02-17 17:29:17 +00:00
_ARM_FP_HEADER_START = 512
)
2018-10-16 10:48:59 +00:00
const elfErrorBadMagicNumber = "bad magic number"
2020-11-09 19:28:40 +00:00
func linuxThreadsFromNotes ( p * process , notes [ ] * note , machineType elf . Machine ) proc . Thread {
var currentThread proc . Thread
2024-10-21 16:12:34 +00:00
var lastThread osThread
2024-10-11 19:34:25 +00:00
2020-02-17 17:29:17 +00:00
for _ , note := range notes {
switch note . Type {
case elf . NT_PRSTATUS :
2024-10-21 16:12:34 +00:00
switch machineType {
case _EM_X86_64 :
2020-03-26 12:05:09 +00:00
t := note . Desc . ( * linuxPrStatusAMD64 )
2024-10-21 16:12:34 +00:00
lastThread = & linuxAMD64Thread { linutil . AMD64Registers { Regs : & t . Reg } , t }
case _EM_AARCH64 :
2020-03-26 12:05:09 +00:00
t := note . Desc . ( * linuxPrStatusARM64 )
2024-10-21 16:12:34 +00:00
lastThread = & linuxARM64Thread { linutil . ARM64Registers { Regs : & t . Reg } , t }
case _EM_RISCV :
2024-10-11 19:34:25 +00:00
t := note . Desc . ( * linuxPrStatusRISCV64 )
2024-10-21 16:12:34 +00:00
lastThread = & linuxRISCV64Thread { linutil . RISCV64Registers { Regs : & t . Reg } , t }
default :
continue
}
p . Threads [ lastThread . ThreadID ( ) ] = & thread { lastThread , p , proc . CommonThread { } }
if currentThread == nil {
currentThread = p . Threads [ lastThread . ThreadID ( ) ]
2020-02-17 17:29:17 +00:00
}
2020-03-26 12:05:09 +00:00
case _NT_FPREGSET :
2024-10-21 16:12:34 +00:00
switch th := lastThread . ( type ) {
case * linuxARM64Thread :
th . regs . Fpregs = note . Desc . ( * linutil . ARM64PtraceFpRegs ) . Decode ( )
case * linuxRISCV64Thread :
th . regs . Fpregs = note . Desc . ( * linutil . RISCV64PtraceFpRegs ) . Decode ( )
2020-02-17 17:29:17 +00:00
}
2020-03-26 12:05:09 +00:00
case _NT_X86_XSTATE :
2024-10-21 16:12:34 +00:00
if lastThread != nil {
lastThread . ( * linuxAMD64Thread ) . regs . Fpregs = note . Desc . ( * amd64util . AMD64Xstate ) . Decode ( )
2020-02-17 17:29:17 +00:00
}
case elf . NT_PRPSINFO :
2020-03-26 12:05:09 +00:00
p . pid = int ( note . Desc . ( * linuxPrPsInfo ) . Pid )
2020-02-17 17:29:17 +00:00
}
}
2020-11-09 19:28:40 +00:00
return currentThread
2020-02-17 17:29:17 +00:00
}
2024-10-21 16:12:34 +00:00
var supportedLinuxMachines = map [ elf . Machine ] string {
_EM_X86_64 : "amd64" ,
_EM_AARCH64 : "arm64" ,
_EM_RISCV : "riscv64" ,
}
2021-01-29 21:39:33 +00:00
// readLinuxOrPlatformIndependentCore reads a core file from corePath
// corresponding to the executable at exePath. For details on the Linux ELF
// core format, see:
2024-07-11 15:03:32 +00:00
// https://www.gabriel.urdhr.fr/2015/05/29/core-file/,
// https://uhlo.blogspot.com/2012/05/brief-look-into-core-dumps.html,
// elf_core_dump in https://elixir.bootlin.com/linux/v4.20.17/source/fs/binfmt_elf.c,
2017-02-08 20:22:04 +00:00
// and, if absolutely desperate, readelf.c from the binutils source.
2021-01-29 21:39:33 +00:00
func readLinuxOrPlatformIndependentCore ( corePath , exePath string ) ( * process , proc . Thread , error ) {
2017-07-20 19:04:00 +00:00
coreFile , err := elf . Open ( corePath )
2017-02-08 20:22:04 +00:00
if err != nil {
2018-10-16 10:48:59 +00:00
if _ , isfmterr := err . ( * elf . FormatError ) ; isfmterr && ( strings . Contains ( err . Error ( ) , elfErrorBadMagicNumber ) || strings . Contains ( err . Error ( ) , " at offset 0x0: too short" ) ) {
// Go >=1.11 and <1.11 produce different errors when reading a non-elf file.
2020-11-09 19:28:40 +00:00
return nil , nil , ErrUnrecognizedFormat
2018-10-16 10:48:59 +00:00
}
2020-11-09 19:28:40 +00:00
return nil , nil , err
2017-02-08 20:22:04 +00:00
}
2017-07-20 19:04:00 +00:00
if coreFile . Type != elf . ET_CORE {
2020-11-09 19:28:40 +00:00
return nil , nil , fmt . Errorf ( "%v is not a core file" , coreFile )
2017-02-08 20:22:04 +00:00
}
2021-01-29 21:39:33 +00:00
machineType := coreFile . Machine
notes , platformIndependentDelveCore , err := readNotes ( coreFile , machineType )
if err != nil {
return nil , nil , err
2018-06-29 22:02:53 +00:00
}
2017-02-08 20:22:04 +00:00
2021-01-29 21:39:33 +00:00
exe , err := os . Open ( exePath )
2017-02-08 20:22:04 +00:00
if err != nil {
2020-11-09 19:28:40 +00:00
return nil , nil , err
2017-02-08 20:22:04 +00:00
}
2021-01-29 21:39:33 +00:00
exeELF , err := elf . NewFile ( exe )
if err != nil {
if ! platformIndependentDelveCore {
return nil , nil , err
}
} else {
if exeELF . Machine != machineType {
return nil , nil , fmt . Errorf ( "architecture mismatch between core file (%#x) and executable file (%#x)" , machineType , exeELF . Machine )
}
if exeELF . Type != elf . ET_EXEC && exeELF . Type != elf . ET_DYN {
return nil , nil , fmt . Errorf ( "%v is not an exe file" , exeELF )
}
}
2018-06-29 22:02:53 +00:00
memory := buildMemory ( coreFile , exeELF , exe , notes )
2017-02-08 20:22:04 +00:00
2020-03-10 16:34:40 +00:00
// TODO support 386
var bi * proc . BinaryInfo
2021-01-29 21:39:33 +00:00
if platformIndependentDelveCore {
goos , goarch , err := platformFromNotes ( notes )
if err != nil {
return nil , nil , err
}
bi = proc . NewBinaryInfo ( goos , goarch )
2024-10-21 16:12:34 +00:00
} else if goarch , ok := supportedLinuxMachines [ machineType ] ; ok {
bi = proc . NewBinaryInfo ( "linux" , goarch )
2021-01-29 21:39:33 +00:00
} else {
2024-10-21 16:12:34 +00:00
return nil , nil , errors . New ( "unsupported machine type" )
2017-02-08 20:22:04 +00:00
}
2020-03-10 16:34:40 +00:00
entryPoint := findEntryPoint ( notes , bi . Arch . PtrSize ( ) )
2020-03-26 12:05:09 +00:00
p := & process {
2020-03-10 16:34:40 +00:00
mem : memory ,
2020-03-26 12:05:09 +00:00
Threads : map [ int ] * thread { } ,
2020-03-10 16:34:40 +00:00
entryPoint : entryPoint ,
bi : bi ,
breakpoints : proc . NewBreakpointMap ( ) ,
}
2021-01-29 21:39:33 +00:00
if platformIndependentDelveCore {
currentThread , err := threadsFromDelveNotes ( p , notes )
return p , currentThread , err
}
2020-11-09 19:28:40 +00:00
currentThread := linuxThreadsFromNotes ( p , notes , machineType )
return p , currentThread , nil
2018-10-18 07:13:11 +00:00
}
type linuxAMD64Thread struct {
regs linutil . AMD64Registers
2020-03-26 12:05:09 +00:00
t * linuxPrStatusAMD64
2020-02-17 17:29:17 +00:00
}
type linuxARM64Thread struct {
regs linutil . ARM64Registers
2020-03-26 12:05:09 +00:00
t * linuxPrStatusARM64
2017-02-08 20:22:04 +00:00
}
2024-10-11 19:34:25 +00:00
type linuxRISCV64Thread struct {
regs linutil . RISCV64Registers
t * linuxPrStatusRISCV64
}
2024-10-21 16:12:34 +00:00
func ( t * linuxAMD64Thread ) Registers ( ) ( proc . Registers , error ) {
2018-10-18 07:13:11 +00:00
var r linutil . AMD64Registers
r . Regs = t . regs . Regs
2020-05-13 18:56:50 +00:00
r . Fpregs = t . regs . Fpregs
2018-10-18 07:13:11 +00:00
return & r , nil
}
2018-05-29 15:01:51 +00:00
2024-10-21 16:12:34 +00:00
func ( t * linuxARM64Thread ) Registers ( ) ( proc . Registers , error ) {
2020-02-17 17:29:17 +00:00
var r linutil . ARM64Registers
r . Regs = t . regs . Regs
2020-05-13 18:56:50 +00:00
r . Fpregs = t . regs . Fpregs
2020-02-17 17:29:17 +00:00
return & r , nil
}
2024-10-21 16:12:34 +00:00
func ( t * linuxRISCV64Thread ) Registers ( ) ( proc . Registers , error ) {
2024-10-11 19:34:25 +00:00
var r linutil . RISCV64Registers
r . Regs = t . regs . Regs
r . Fpregs = t . regs . Fpregs
return & r , nil
}
2024-10-21 16:12:34 +00:00
func ( t * linuxAMD64Thread ) ThreadID ( ) int {
2018-10-18 07:13:11 +00:00
return int ( t . t . Pid )
2017-02-08 20:22:04 +00:00
}
2024-10-21 16:12:34 +00:00
func ( t * linuxARM64Thread ) ThreadID ( ) int {
2020-02-17 17:29:17 +00:00
return int ( t . t . Pid )
}
2024-10-21 16:12:34 +00:00
func ( t * linuxRISCV64Thread ) ThreadID ( ) int {
2024-10-11 19:34:25 +00:00
return int ( t . t . Pid )
}
2017-02-08 20:22:04 +00:00
// Note is a note from the PT_NOTE prog.
// Relevant types:
// - NT_FILE: File mapping information, e.g. program text mappings. Desc is a LinuxNTFile.
// - NT_PRPSINFO: Information about a process, including PID and signal. Desc is a LinuxPrPsInfo.
// - NT_PRSTATUS: Information about a thread, including base registers, state, etc. Desc is a LinuxPrStatus.
// - NT_FPREGSET (Not implemented): x87 floating point registers.
2017-07-20 19:04:00 +00:00
// - NT_X86_XSTATE: Other registers, including AVX and such.
2020-03-26 12:05:09 +00:00
type note struct {
2017-02-08 20:22:04 +00:00
Type elf . NType
Name string
Desc interface { } // Decoded Desc from the
}
// readNotes reads all the notes from the notes prog in core.
2021-01-29 21:39:33 +00:00
func readNotes ( core * elf . File , machineType elf . Machine ) ( [ ] * note , bool , error ) {
2017-02-08 20:22:04 +00:00
var notesProg * elf . Prog
for _ , prog := range core . Progs {
if prog . Type == elf . PT_NOTE {
notesProg = prog
break
}
}
r := notesProg . Open ( )
2021-01-29 21:39:33 +00:00
hasDelveThread := false
hasDelveHeader := false
hasElfPrStatus := false
2020-03-26 12:05:09 +00:00
notes := [ ] * note { }
2017-02-08 20:22:04 +00:00
for {
2020-02-17 17:29:17 +00:00
note , err := readNote ( r , machineType )
2017-02-08 20:22:04 +00:00
if err == io . EOF {
break
}
if err != nil {
2021-01-29 21:39:33 +00:00
return nil , false , err
}
switch note . Type {
case elfwriter . DelveHeaderNoteType :
hasDelveHeader = true
case elfwriter . DelveThreadNodeType :
hasDelveThread = true
case elf . NT_PRSTATUS :
hasElfPrStatus = true
2017-02-08 20:22:04 +00:00
}
notes = append ( notes , note )
}
2021-01-29 21:39:33 +00:00
return notes , hasDelveThread && hasDelveHeader && ! hasElfPrStatus , nil
2017-02-08 20:22:04 +00:00
}
// readNote reads a single note from r, decoding the descriptor if possible.
2020-03-26 12:05:09 +00:00
func readNote ( r io . ReadSeeker , machineType elf . Machine ) ( * note , error ) {
2017-02-08 20:22:04 +00:00
// Notes are laid out as described in the SysV ABI:
2024-07-11 15:03:32 +00:00
// https://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section
2020-03-26 12:05:09 +00:00
note := & note { }
hdr := & elfNotesHdr { }
2017-02-08 20:22:04 +00:00
err := binary . Read ( r , binary . LittleEndian , hdr )
if err != nil {
return nil , err // don't wrap so readNotes sees EOF.
}
note . Type = elf . NType ( hdr . Type )
name := make ( [ ] byte , hdr . Namesz )
if _ , err := r . Read ( name ) ; err != nil {
return nil , fmt . Errorf ( "reading name: %v" , err )
}
note . Name = string ( name )
if err := skipPadding ( r , 4 ) ; err != nil {
return nil , fmt . Errorf ( "aligning after name: %v" , err )
}
desc := make ( [ ] byte , hdr . Descsz )
if _ , err := r . Read ( desc ) ; err != nil {
return nil , fmt . Errorf ( "reading desc: %v" , err )
}
descReader := bytes . NewReader ( desc )
switch note . Type {
case elf . NT_PRSTATUS :
2023-11-22 17:07:08 +00:00
switch machineType {
case _EM_X86_64 :
2020-03-26 12:05:09 +00:00
note . Desc = & linuxPrStatusAMD64 { }
2023-11-22 17:07:08 +00:00
case _EM_AARCH64 :
2020-03-26 12:05:09 +00:00
note . Desc = & linuxPrStatusARM64 { }
2024-10-11 19:34:25 +00:00
case _EM_RISCV :
note . Desc = & linuxPrStatusRISCV64 { }
2023-11-22 17:07:08 +00:00
default :
2024-06-20 19:50:18 +00:00
return nil , errors . New ( "unsupported machine type" )
2020-02-17 17:29:17 +00:00
}
2017-02-08 20:22:04 +00:00
if err := binary . Read ( descReader , binary . LittleEndian , note . Desc ) ; err != nil {
return nil , fmt . Errorf ( "reading NT_PRSTATUS: %v" , err )
}
case elf . NT_PRPSINFO :
2020-03-26 12:05:09 +00:00
note . Desc = & linuxPrPsInfo { }
2017-02-08 20:22:04 +00:00
if err := binary . Read ( descReader , binary . LittleEndian , note . Desc ) ; err != nil {
return nil , fmt . Errorf ( "reading NT_PRPSINFO: %v" , err )
}
2020-03-26 12:05:09 +00:00
case _NT_FILE :
2017-02-08 20:22:04 +00:00
// No good documentation reference, but the structure is
// simply a header, including entry count, followed by that
// many entries, and then the file name of each entry,
// null-delimited. Not reading the names here.
2020-03-26 12:05:09 +00:00
data := & linuxNTFile { }
if err := binary . Read ( descReader , binary . LittleEndian , & data . linuxNTFileHdr ) ; err != nil {
2017-02-08 20:22:04 +00:00
return nil , fmt . Errorf ( "reading NT_FILE header: %v" , err )
}
for i := 0 ; i < int ( data . Count ) ; i ++ {
2020-03-26 12:05:09 +00:00
entry := & linuxNTFileEntry { }
2017-02-08 20:22:04 +00:00
if err := binary . Read ( descReader , binary . LittleEndian , entry ) ; err != nil {
2018-05-29 15:01:51 +00:00
return nil , fmt . Errorf ( "reading NT_FILE entry %v: %v" , i , err )
2017-02-08 20:22:04 +00:00
}
data . entries = append ( data . entries , entry )
}
note . Desc = data
2020-03-26 12:05:09 +00:00
case _NT_X86_XSTATE :
if machineType == _EM_X86_64 {
2020-12-14 17:39:01 +00:00
var fpregs amd64util . AMD64Xstate
2024-10-21 16:16:57 +00:00
if err := amd64util . AMD64XstateRead ( desc , true , & fpregs , 0 ) ; err != nil {
2020-02-17 17:29:17 +00:00
return nil , err
}
note . Desc = & fpregs
2017-07-20 19:04:00 +00:00
}
2021-01-29 21:39:33 +00:00
case _NT_AUXV , elfwriter . DelveHeaderNoteType , elfwriter . DelveThreadNodeType :
2018-05-29 15:01:51 +00:00
note . Desc = desc
2020-03-26 12:05:09 +00:00
case _NT_FPREGSET :
if machineType == _EM_AARCH64 {
2024-10-21 16:12:34 +00:00
err = readFpregsetNote ( note , & linutil . ARM64PtraceFpRegs { } , desc [ : _ARM_FP_HEADER_START ] )
2024-10-11 19:34:25 +00:00
} else if machineType == _EM_RISCV {
2024-10-21 16:12:34 +00:00
err = readFpregsetNote ( note , & linutil . RISCV64PtraceFpRegs { } , desc )
}
if err != nil {
return nil , err
2020-02-17 17:29:17 +00:00
}
2017-02-08 20:22:04 +00:00
}
if err := skipPadding ( r , 4 ) ; err != nil {
return nil , fmt . Errorf ( "aligning after desc: %v" , err )
}
return note , nil
}
2024-10-21 16:12:34 +00:00
func readFpregsetNote ( note * note , fpregs interface { Byte ( ) [ ] byte } , desc [ ] byte ) error {
rdr := bytes . NewReader ( desc )
if err := binary . Read ( rdr , binary . LittleEndian , fpregs . Byte ( ) ) ; err != nil {
return err
}
note . Desc = fpregs
return nil
}
2017-02-08 20:22:04 +00:00
// skipPadding moves r to the next multiple of pad.
func skipPadding ( r io . ReadSeeker , pad int64 ) error {
2022-12-12 18:16:49 +00:00
pos , err := r . Seek ( 0 , io . SeekCurrent )
2017-02-08 20:22:04 +00:00
if err != nil {
return err
}
if pos % pad == 0 {
return nil
}
2022-12-12 18:16:49 +00:00
if _ , err := r . Seek ( pad - ( pos % pad ) , io . SeekCurrent ) ; err != nil {
2017-02-08 20:22:04 +00:00
return err
}
return nil
}
2020-03-26 12:05:09 +00:00
func buildMemory ( core , exeELF * elf . File , exe io . ReaderAt , notes [ ] * note ) proc . MemoryReader {
2023-03-16 19:13:10 +00:00
memory := & SplicedMemory { }
2017-02-08 20:22:04 +00:00
// For now, assume all file mappings are to the exe.
for _ , note := range notes {
2020-03-26 12:05:09 +00:00
if note . Type == _NT_FILE {
fileNote := note . Desc . ( * linuxNTFile )
2017-02-08 20:22:04 +00:00
for _ , entry := range fileNote . entries {
2020-03-26 12:05:09 +00:00
r := & offsetReaderAt {
2017-02-08 20:22:04 +00:00
reader : exe ,
2020-09-09 17:36:15 +00:00
offset : entry . Start - ( entry . FileOfs * fileNote . PageSize ) ,
2017-02-08 20:22:04 +00:00
}
2020-09-09 17:36:15 +00:00
memory . Add ( r , entry . Start , entry . End - entry . Start )
2017-02-08 20:22:04 +00:00
}
}
}
2018-06-29 22:02:53 +00:00
// Load memory segments from exe and then from the core file,
// allowing the corefile to overwrite previously loaded segments
for _ , elfFile := range [ ] * elf . File { exeELF , core } {
2021-01-29 21:39:33 +00:00
if elfFile == nil {
continue
}
2018-06-29 22:02:53 +00:00
for _ , prog := range elfFile . Progs {
if prog . Type == elf . PT_LOAD {
if prog . Filesz == 0 {
continue
}
2020-03-26 12:05:09 +00:00
r := & offsetReaderAt {
2018-06-29 22:02:53 +00:00
reader : prog . ReaderAt ,
2020-09-09 17:36:15 +00:00
offset : prog . Vaddr ,
2018-06-29 22:02:53 +00:00
}
2020-09-09 17:36:15 +00:00
memory . Add ( r , prog . Vaddr , prog . Filesz )
2017-02-08 20:22:04 +00:00
}
}
}
return memory
}
2020-03-26 12:05:09 +00:00
func findEntryPoint ( notes [ ] * note , ptrSize int ) uint64 {
2018-05-29 15:01:51 +00:00
for _ , note := range notes {
2020-03-26 12:05:09 +00:00
if note . Type == _NT_AUXV {
2020-03-10 16:34:40 +00:00
return linutil . EntryPointFromAuxv ( note . Desc . ( [ ] byte ) , ptrSize )
2018-05-29 15:01:51 +00:00
}
}
return 0
}
2018-08-31 18:08:18 +00:00
// LinuxPrPsInfo has various structures from the ELF spec and the Linux kernel.
2017-02-08 20:22:04 +00:00
// AMD64 specific primarily because of unix.PtraceRegs, but also
// because some of the fields are word sized.
2024-07-11 15:03:32 +00:00
// See https://elixir.bootlin.com/linux/v4.20.17/source/include/uapi/linux/elfcore.h
2020-03-26 12:05:09 +00:00
type linuxPrPsInfo struct {
2017-02-08 20:22:04 +00:00
State uint8
Sname int8
Zomb uint8
Nice int8
_ [ 4 ] uint8
Flag uint64
Uid , Gid uint32
Pid , Ppid , Pgrp , Sid int32
Fname [ 16 ] uint8
Args [ 80 ] uint8
}
2020-02-17 17:29:17 +00:00
// LinuxPrStatusAMD64 is a copy of the prstatus kernel struct.
2020-03-26 12:05:09 +00:00
type linuxPrStatusAMD64 struct {
Siginfo linuxSiginfo
2017-02-08 20:22:04 +00:00
Cursig uint16
_ [ 2 ] uint8
Sigpend uint64
Sighold uint64
Pid , Ppid , Pgrp , Sid int32
2020-03-26 12:05:09 +00:00
Utime , Stime , CUtime , CStime linuxCoreTimeval
2018-10-17 14:55:53 +00:00
Reg linutil . AMD64PtraceRegs
2017-02-08 20:22:04 +00:00
Fpvalid int32
}
2020-02-17 17:29:17 +00:00
// LinuxPrStatusARM64 is a copy of the prstatus kernel struct.
2020-03-26 12:05:09 +00:00
type linuxPrStatusARM64 struct {
Siginfo linuxSiginfo
2020-02-17 17:29:17 +00:00
Cursig uint16
_ [ 2 ] uint8
Sigpend uint64
Sighold uint64
Pid , Ppid , Pgrp , Sid int32
2020-03-26 12:05:09 +00:00
Utime , Stime , CUtime , CStime linuxCoreTimeval
2020-02-17 17:29:17 +00:00
Reg linutil . ARM64PtraceRegs
Fpvalid int32
}
2024-10-11 19:34:25 +00:00
// LinuxPrStatusRISCV64 is a copy of the prstatus kernel struct.
type linuxPrStatusRISCV64 struct {
Siginfo linuxSiginfo
Cursig uint16
_ [ 2 ] uint8
Sigpend uint64
Sighold uint64
Pid , Ppid , Pgrp , Sid int32
Utime , Stime , CUtime , CStime linuxCoreTimeval
Reg linutil . RISCV64PtraceRegs
Fpvalid int32
}
2018-08-31 18:08:18 +00:00
// LinuxSiginfo is a copy of the
// siginfo kernel struct.
2020-03-26 12:05:09 +00:00
type linuxSiginfo struct {
2017-02-08 20:22:04 +00:00
Signo int32
Code int32
Errno int32
}
2018-08-31 18:08:18 +00:00
// LinuxNTFile contains information on mapped files.
2020-03-26 12:05:09 +00:00
type linuxNTFile struct {
linuxNTFileHdr
entries [ ] * linuxNTFileEntry
2017-02-08 20:22:04 +00:00
}
2018-08-31 18:08:18 +00:00
// LinuxNTFileHdr is a header struct for NTFile.
2020-03-26 12:05:09 +00:00
type linuxNTFileHdr struct {
2017-02-08 20:22:04 +00:00
Count uint64
PageSize uint64
}
2018-08-31 18:08:18 +00:00
// LinuxNTFileEntry is an entry of an NT_FILE note.
2020-03-26 12:05:09 +00:00
type linuxNTFileEntry struct {
2017-02-08 20:22:04 +00:00
Start uint64
End uint64
FileOfs uint64
}
2020-03-26 12:05:09 +00:00
// elfNotesHdr is the ELF Notes header.
2018-08-31 18:08:18 +00:00
// Same size on 64 and 32-bit machines.
2020-03-26 12:05:09 +00:00
type elfNotesHdr struct {
2017-02-08 20:22:04 +00:00
Namesz uint32
Descsz uint32
Type uint32
}