// Copyright 2018 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.

// Parsing of XCOFF executable (AIX)

package objfile

import (
	"debug/dwarf"
	"fmt"
	"internal/xcoff"
	"io"
	"unicode"
)

type xcoffFile struct {
	xcoff *xcoff.File
}

func openXcoff(r io.ReaderAt) (rawFile, error) {
	f, err := xcoff.NewFile(r)
	if err != nil {
		return nil, err
	}
	return &xcoffFile{f}, nil
}

func (f *xcoffFile) symbols() ([]Sym, error) {
	var syms []Sym
	for _, s := range f.xcoff.Symbols {
		const (
			N_UNDEF = 0  // An undefined (extern) symbol
			N_ABS   = -1 // An absolute symbol (e_value is a constant, not an address)
			N_DEBUG = -2 // A debugging symbol
		)
		sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}

		switch s.SectionNumber {
		case N_UNDEF:
			sym.Code = 'U'
		case N_ABS:
			sym.Code = 'C'
		case N_DEBUG:
			sym.Code = '?'
		default:
			if s.SectionNumber < 0 || len(f.xcoff.Sections) < int(s.SectionNumber) {
				return nil, fmt.Errorf("invalid section number in symbol table")
			}
			sect := f.xcoff.Sections[s.SectionNumber-1]

			// debug/xcoff returns an offset in the section not the actual address
			sym.Addr += sect.VirtualAddress

			if s.AuxCSect.SymbolType&0x3 == xcoff.XTY_LD {
				// The size of a function is contained in the
				// AUX_FCN entry
				sym.Size = s.AuxFcn.Size
			} else {
				sym.Size = s.AuxCSect.Length
			}

			sym.Size = s.AuxCSect.Length

			switch sect.Type {
			case xcoff.STYP_TEXT:
				if s.AuxCSect.StorageMappingClass == xcoff.XMC_RO {
					sym.Code = 'R'
				} else {
					sym.Code = 'T'
				}
			case xcoff.STYP_DATA:
				sym.Code = 'D'
			case xcoff.STYP_BSS:
				sym.Code = 'B'
			}

			if s.StorageClass == xcoff.C_HIDEXT {
				// Local symbol
				sym.Code = unicode.ToLower(sym.Code)
			}

		}
		syms = append(syms, sym)
	}

	return syms, nil
}

func (f *xcoffFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
	if sect := f.xcoff.Section(".text"); sect != nil {
		textStart = sect.VirtualAddress
	}
	if pclntab, err = loadXCOFFTable(f.xcoff, "runtime.pclntab", "runtime.epclntab"); err != nil {
		return 0, nil, nil, err
	}
	symtab, _ = loadXCOFFTable(f.xcoff, "runtime.symtab", "runtime.esymtab") // ignore error, this symbol is not useful anyway
	return textStart, symtab, pclntab, nil
}

func (f *xcoffFile) text() (textStart uint64, text []byte, err error) {
	sect := f.xcoff.Section(".text")
	if sect == nil {
		return 0, nil, fmt.Errorf("text section not found")
	}
	textStart = sect.VirtualAddress
	text, err = sect.Data()
	return
}

func findXCOFFSymbol(f *xcoff.File, name string) (*xcoff.Symbol, error) {
	for _, s := range f.Symbols {
		if s.Name != name {
			continue
		}
		if s.SectionNumber <= 0 {
			return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
		}
		if len(f.Sections) < int(s.SectionNumber) {
			return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
		}
		return s, nil
	}
	return nil, fmt.Errorf("no %s symbol found", name)
}

func loadXCOFFTable(f *xcoff.File, sname, ename string) ([]byte, error) {
	ssym, err := findXCOFFSymbol(f, sname)
	if err != nil {
		return nil, err
	}
	esym, err := findXCOFFSymbol(f, ename)
	if err != nil {
		return nil, err
	}
	if ssym.SectionNumber != esym.SectionNumber {
		return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
	}
	sect := f.Sections[ssym.SectionNumber-1]
	data, err := sect.Data()
	if err != nil {
		return nil, err
	}
	return data[ssym.Value:esym.Value], nil
}

func (f *xcoffFile) goarch() string {
	switch f.xcoff.TargetMachine {
	case xcoff.U802TOCMAGIC:
		return "ppc"
	case xcoff.U64_TOCMAGIC:
		return "ppc64"
	}
	return ""
}

func (f *xcoffFile) loadAddress() (uint64, error) {
	return 0, fmt.Errorf("unknown load address")
}

func (f *xcoffFile) dwarf() (*dwarf.Data, error) {
	return f.xcoff.DWARF()
}
