// 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) < 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, 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, err
	}
	return textStart, 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) < 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()
}
