From d0c7c9d55bf941eeda521dd241c5e0ff248d17e5 Mon Sep 17 00:00:00 2001 From: Zxilly Date: Fri, 26 Jan 2024 04:42:46 +0800 Subject: [PATCH] fix: follow the official objfile implementation --- elf.go | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/elf.go b/elf.go index 0e15888..541b354 100644 --- a/elf.go +++ b/elf.go @@ -82,19 +82,57 @@ func (e *elfFile) GetFile() *os.File { return e.osFile } +func (e *elfFile) getSymbolData(start, end string) ([]byte, error) { + elfSyms, err := e.file.Symbols() + if err != nil { + return nil, err + } + var addr, eaddr uint64 + for _, s := range elfSyms { + if s.Name == start { + addr = s.Value + } else if s.Name == end { + eaddr = s.Value + } + if addr != 0 && eaddr != 0 { + break + } + } + if addr == 0 || eaddr < addr { + return nil, fmt.Errorf("could not find the symbol %s", start) + } + size := eaddr - addr + data := make([]byte, size) + for _, prog := range e.file.Progs { + if prog.Vaddr <= addr && addr+size-1 <= prog.Vaddr+prog.Filesz-1 { + if _, err := prog.ReadAt(data, int64(addr-prog.Vaddr)); err != nil { + return nil, fmt.Errorf("could not read the symbol data: %w", err) + } + return data, nil + } + } + return nil, fmt.Errorf("could not find the symbol %s", start) +} + func (e *elfFile) getPCLNTab() (*gosym.Table, error) { pclnSection := e.file.Section(".gopclntab") if pclnSection == nil { // No section found. Check if the PIE section exist instead. pclnSection = e.file.Section(".data.rel.ro.gopclntab") } - if pclnSection == nil { - return nil, fmt.Errorf("no gopclntab section found") - } + var pclndat []byte + var err error - pclndat, err := pclnSection.Data() - if err != nil { - return nil, fmt.Errorf("could not get the data for the pclntab: %w", err) + if pclnSection == nil { + pclndat, err = e.getSymbolData("runtime.pclntab", "runtime.epclntab") + if err != nil { + return nil, fmt.Errorf("could not get the pclntab data: %w", err) + } + } else { + pclndat, err = pclnSection.Data() + if err != nil { + return nil, fmt.Errorf("could not get the data for the pclntab: %w", err) + } } var pcln *gosym.LineTable