// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build go1.18
// +build go1.18

package buildinfo

// This file adds to buildinfo the functionality for extracting the PCLN table.

import (
	"debug/elf"
	"debug/macho"
	"debug/pe"
	"encoding/binary"
	"fmt"
	"io"
)

// SymbolInfo is derived from cmd/internal/objfile/elf.go:symbols, symbolData.
func (x *elfExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
	sym := x.lookupSymbol(name)
	if sym == nil {
		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
	}
	prog := x.progContaining(sym.Value)
	if prog == nil {
		return 0, 0, nil, fmt.Errorf("no Prog containing value %d for %q", sym.Value, name)
	}
	return sym.Value, prog.Vaddr, prog.ReaderAt, nil
}

func (x *elfExe) lookupSymbol(name string) *elf.Symbol {
	x.symbolsOnce.Do(func() {
		syms, _ := x.f.Symbols()
		x.symbols = make(map[string]*elf.Symbol, len(syms))
		for _, s := range syms {
			s := s // make a copy to prevent aliasing
			x.symbols[s.Name] = &s
		}
	})
	return x.symbols[name]
}

func (x *elfExe) progContaining(addr uint64) *elf.Prog {
	for _, p := range x.f.Progs {
		if addr >= p.Vaddr && addr < p.Vaddr+p.Filesz {
			return p
		}
	}
	return nil
}

const go12magic = 0xfffffffb
const go116magic = 0xfffffffa

// PCLNTab is derived from cmd/internal/objfile/elf.go:pcln.
func (x *elfExe) PCLNTab() ([]byte, uint64) {
	var offset uint64
	text := x.f.Section(".text")
	if text != nil {
		offset = text.Offset
	}
	pclntab := x.f.Section(".gopclntab")
	if pclntab == nil {
		// Addition: this code is added to support some form of stripping.
		pclntab = x.f.Section(".data.rel.ro.gopclntab")
		if pclntab == nil {
			pclntab = x.f.Section(".data.rel.ro")
			if pclntab == nil {
				return nil, 0
			}
			// Possibly the PCLN table has been stuck in the .data.rel.ro section, but without
			// its own section header. We can search for for the start by looking for the four
			// byte magic and the go magic.
			b, err := pclntab.Data()
			if err != nil {
				return nil, 0
			}
			// TODO(rolandshoemaker): I'm not sure if the 16 byte increment during the search is
			// actually correct. During testing it worked, but that may be because I got lucky
			// with the binary I was using, and we need to do four byte jumps to exhaustively
			// search the section?
			for i := 0; i < len(b); i += 16 {
				if len(b)-i > 16 && b[i+4] == 0 && b[i+5] == 0 &&
					(b[i+6] == 1 || b[i+6] == 2 || b[i+6] == 4) &&
					(b[i+7] == 4 || b[i+7] == 8) {
					// Also check for the go magic
					leMagic := binary.LittleEndian.Uint32(b[i:])
					beMagic := binary.BigEndian.Uint32(b[i:])
					switch {
					case leMagic == go12magic:
						fallthrough
					case beMagic == go12magic:
						fallthrough
					case leMagic == go116magic:
						fallthrough
					case beMagic == go116magic:
						return b[i:], offset
					}
				}
			}
		}
	}
	b, err := pclntab.Data()
	if err != nil {
		return nil, 0
	}
	return b, offset
}

// SymbolInfo is derived from cmd/internal/objfile/pe.go:findPESymbol, loadPETable.
func (x *peExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
	sym := x.lookupSymbol(name)
	if sym == nil {
		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
	}
	sect := x.f.Sections[sym.SectionNumber-1]
	// In PE, the symbol's value is the offset from the section start.
	return uint64(sym.Value), 0, sect.ReaderAt, nil
}

func (x *peExe) lookupSymbol(name string) *pe.Symbol {
	x.symbolsOnce.Do(func() {
		x.symbols = make(map[string]*pe.Symbol, len(x.f.Symbols))
		for _, s := range x.f.Symbols {
			x.symbols[s.Name] = s
		}
	})
	return x.symbols[name]
}

// PCLNTab is derived from cmd/internal/objfile/pe.go:pcln.
func (x *peExe) PCLNTab() ([]byte, uint64) {
	var textOffset uint64
	for _, section := range x.f.Sections {
		if section.Name == ".text" {
			textOffset = uint64(section.Offset)
			break
		}
	}

	var start, end int64
	var section int
	if s := x.lookupSymbol("runtime.pclntab"); s != nil {
		start = int64(s.Value)
		section = int(s.SectionNumber - 1)
	}
	if s := x.lookupSymbol("runtime.epclntab"); s != nil {
		end = int64(s.Value)
	}
	if start == 0 || end == 0 {
		return nil, 0
	}
	offset := int64(x.f.Sections[section].Offset) + start
	size := end - start

	pclntab := make([]byte, size)
	if _, err := x.r.ReadAt(pclntab, offset); err != nil {
		return nil, 0
	}
	return pclntab, textOffset
}

// SymbolInfo is derived from cmd/internal/objfile/macho.go:symbols.
func (x *machoExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
	sym := x.lookupSymbol(name)
	if sym == nil {
		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
	}
	seg := x.segmentContaining(sym.Value)
	if seg == nil {
		return 0, 0, nil, fmt.Errorf("no Segment containing value %d for %q", sym.Value, name)
	}
	return sym.Value, seg.Addr, seg.ReaderAt, nil
}

func (x *machoExe) lookupSymbol(name string) *macho.Symbol {
	x.symbolsOnce.Do(func() {
		x.symbols = make(map[string]*macho.Symbol, len(x.f.Symtab.Syms))
		for _, s := range x.f.Symtab.Syms {
			s := s // make a copy to prevent aliasing
			x.symbols[s.Name] = &s
		}
	})
	return x.symbols[name]
}

func (x *machoExe) segmentContaining(addr uint64) *macho.Segment {
	for _, load := range x.f.Loads {
		seg, ok := load.(*macho.Segment)
		if ok && seg.Addr <= addr && addr <= seg.Addr+seg.Filesz-1 && seg.Name != "__PAGEZERO" {
			return seg
		}
	}
	return nil
}

// SymbolInfo is derived from cmd/internal/objfile/macho.go:pcln.
func (x *machoExe) PCLNTab() ([]byte, uint64) {
	var textOffset uint64
	text := x.f.Section("__text")
	if text != nil {
		textOffset = uint64(text.Offset)
	}
	pclntab := x.f.Section("__gopclntab")
	if pclntab == nil {
		return nil, 0
	}
	b, err := pclntab.Data()
	if err != nil {
		return nil, 0
	}
	return b, textOffset
}
