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

// Package macho implements access to Mach-O object files, as defined by
// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html.
package macho

// High level access to low level data structures.

import (
	"bytes";
	"debug/dwarf";
	"encoding/binary";
	"fmt";
	"io";
	"os";
)

// A File represents an open Mach-O file.
type File struct {
	FileHeader;
	ByteOrder	binary.ByteOrder;
	Loads		[]Load;
	Sections	[]*Section;

	closer	io.Closer;
}

// A Load represents any Mach-O load command.
type Load interface {
	Raw() []byte;
}

// A LoadBytes is the uninterpreted bytes of a Mach-O load command.
type LoadBytes []byte

func (b LoadBytes) Raw() []byte	{ return b }

// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command.
type SegmentHeader struct {
	Cmd	LoadCmd;
	Len	uint32;
	Name	string;
	Addr	uint64;
	Memsz	uint64;
	Offset	uint64;
	Filesz	uint64;
	Maxprot	uint32;
	Prot	uint32;
	Nsect	uint32;
	Flag	uint32;
}

// A Segment represents a Mach-O 32-bit or 64-bit load segment command.
type Segment struct {
	LoadBytes;
	SegmentHeader;

	// Embed ReaderAt for ReadAt method.
	// Do not embed SectionReader directly
	// to avoid having Read and Seek.
	// If a client wants Read and Seek it must use
	// Open() to avoid fighting over the seek offset
	// with other clients.
	io.ReaderAt;
	sr	*io.SectionReader;
}

// Data reads and returns the contents of the segment.
func (s *Segment) Data() ([]byte, os.Error) {
	dat := make([]byte, s.sr.Size());
	n, err := s.sr.ReadAt(dat, 0);
	return dat[0:n], err;
}

// Open returns a new ReadSeeker reading the segment.
func (s *Segment) Open() io.ReadSeeker	{ return io.NewSectionReader(s.sr, 0, 1<<63-1) }

type SectionHeader struct {
	Name	string;
	Seg	string;
	Addr	uint64;
	Size	uint64;
	Offset	uint32;
	Align	uint32;
	Reloff	uint32;
	Nreloc	uint32;
	Flags	uint32;
}

type Section struct {
	SectionHeader;

	// Embed ReaderAt for ReadAt method.
	// Do not embed SectionReader directly
	// to avoid having Read and Seek.
	// If a client wants Read and Seek it must use
	// Open() to avoid fighting over the seek offset
	// with other clients.
	io.ReaderAt;
	sr	*io.SectionReader;
}

// Data reads and returns the contents of the Mach-O section.
func (s *Section) Data() ([]byte, os.Error) {
	dat := make([]byte, s.sr.Size());
	n, err := s.sr.ReadAt(dat, 0);
	return dat[0:n], err;
}

// Open returns a new ReadSeeker reading the Mach-O section.
func (s *Section) Open() io.ReadSeeker	{ return io.NewSectionReader(s.sr, 0, 1<<63-1) }


/*
 * Mach-O reader
 */

type FormatError struct {
	off	int64;
	msg	string;
	val	interface{};
}

func (e *FormatError) String() string {
	msg := e.msg;
	if e.val != nil {
		msg += fmt.Sprintf(" '%v' ", e.val)
	}
	msg += fmt.Sprintf("in record at byte %#x", e.off);
	return msg;
}

// Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
func Open(name string) (*File, os.Error) {
	f, err := os.Open(name, os.O_RDONLY, 0);
	if err != nil {
		return nil, err
	}
	ff, err := NewFile(f);
	if err != nil {
		f.Close();
		return nil, err;
	}
	ff.closer = f;
	return ff, nil;
}

// Close closes the File.
// If the File was created using NewFile directly instead of Open,
// Close has no effect.
func (f *File) Close() os.Error {
	var err os.Error;
	if f.closer != nil {
		err = f.closer.Close();
		f.closer = nil;
	}
	return err;
}

// NewFile creates a new File for acecssing a Mach-O binary in an underlying reader.
// The Mach-O binary is expected to start at position 0 in the ReaderAt.
func NewFile(r io.ReaderAt) (*File, os.Error) {
	f := new(File);
	sr := io.NewSectionReader(r, 0, 1<<63-1);

	// Read and decode Mach magic to determine byte order, size.
	// Magic32 and Magic64 differ only in the bottom bit.
	var ident [4]uint8;
	if _, err := r.ReadAt(&ident, 0); err != nil {
		return nil, err
	}
	be := binary.BigEndian.Uint32(&ident);
	le := binary.LittleEndian.Uint32(&ident);
	switch Magic32 &^ 1 {
	case be &^ 1:
		f.ByteOrder = binary.BigEndian;
		f.Magic = be;
	case le &^ 1:
		f.ByteOrder = binary.LittleEndian;
		f.Magic = le;
	}

	// Read entire file header.
	if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil {
		return nil, err
	}

	// Then load commands.
	offset := int64(fileHeaderSize32);
	if f.Magic == Magic64 {
		offset = fileHeaderSize64
	}
	dat := make([]byte, f.Cmdsz);
	if _, err := r.ReadAt(dat, offset); err != nil {
		return nil, err
	}
	f.Loads = make([]Load, f.Ncmd);
	bo := f.ByteOrder;
	for i := range f.Loads {
		// Each load command begins with uint32 command and length.
		if len(dat) < 8 {
			return nil, &FormatError{offset, "command block too small", nil}
		}
		cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8]);
		if siz < 8 || siz > uint32(len(dat)) {
			return nil, &FormatError{offset, "invalid command block size", nil}
		}
		var cmddat []byte;
		cmddat, dat = dat[0:siz], dat[siz:];
		offset += int64(siz);
		var s *Segment;
		switch cmd {
		default:
			f.Loads[i] = LoadBytes(cmddat)

		case LoadCmdSegment:
			var seg32 Segment32;
			b := bytes.NewBuffer(cmddat);
			if err := binary.Read(b, bo, &seg32); err != nil {
				return nil, err
			}
			s = new(Segment);
			s.LoadBytes = cmddat;
			s.Cmd = cmd;
			s.Len = siz;
			s.Name = cstring(&seg32.Name);
			s.Addr = uint64(seg32.Addr);
			s.Memsz = uint64(seg32.Memsz);
			s.Offset = uint64(seg32.Offset);
			s.Filesz = uint64(seg32.Filesz);
			s.Maxprot = seg32.Maxprot;
			s.Prot = seg32.Prot;
			s.Nsect = seg32.Nsect;
			s.Flag = seg32.Flag;
			f.Loads[i] = s;
			for i := 0; i < int(s.Nsect); i++ {
				var sh32 Section32;
				if err := binary.Read(b, bo, &sh32); err != nil {
					return nil, err
				}
				sh := new(Section);
				sh.Name = cstring(&sh32.Name);
				sh.Seg = cstring(&sh32.Seg);
				sh.Addr = uint64(sh32.Addr);
				sh.Size = uint64(sh32.Size);
				sh.Offset = sh32.Offset;
				sh.Align = sh32.Align;
				sh.Reloff = sh32.Reloff;
				sh.Nreloc = sh32.Nreloc;
				sh.Flags = sh32.Flags;
				f.pushSection(sh, r);
			}

		case LoadCmdSegment64:
			var seg64 Segment64;
			b := bytes.NewBuffer(cmddat);
			if err := binary.Read(b, bo, &seg64); err != nil {
				return nil, err
			}
			s = new(Segment);
			s.LoadBytes = cmddat;
			s.Cmd = cmd;
			s.Len = siz;
			s.Name = cstring(&seg64.Name);
			s.Addr = seg64.Addr;
			s.Memsz = seg64.Memsz;
			s.Offset = seg64.Offset;
			s.Filesz = seg64.Filesz;
			s.Maxprot = seg64.Maxprot;
			s.Prot = seg64.Prot;
			s.Nsect = seg64.Nsect;
			s.Flag = seg64.Flag;
			f.Loads[i] = s;
			for i := 0; i < int(s.Nsect); i++ {
				var sh64 Section64;
				if err := binary.Read(b, bo, &sh64); err != nil {
					return nil, err
				}
				sh := new(Section);
				sh.Name = cstring(&sh64.Name);
				sh.Seg = cstring(&sh64.Seg);
				sh.Addr = sh64.Addr;
				sh.Size = sh64.Size;
				sh.Offset = sh64.Offset;
				sh.Align = sh64.Align;
				sh.Reloff = sh64.Reloff;
				sh.Nreloc = sh64.Nreloc;
				sh.Flags = sh64.Flags;
				f.pushSection(sh, r);
			}
		}
		if s != nil {
			s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz));
			s.ReaderAt = s.sr;
		}
	}
	return f, nil;
}

func (f *File) pushSection(sh *Section, r io.ReaderAt) {
	n := len(f.Sections);
	if n >= cap(f.Sections) {
		m := (n + 1) * 2;
		new := make([]*Section, n, m);
		for i, sh := range f.Sections {
			new[i] = sh
		}
		f.Sections = new;
	}
	f.Sections = f.Sections[0 : n+1];
	f.Sections[n] = sh;
	sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size));
	sh.ReaderAt = sh.sr;
}

func cstring(b []byte) string {
	var i int;
	for i = 0; i < len(b) && b[i] != 0; i++ {
	}
	return string(b[0:i]);
}

// Segment returns the first Segment with the given name, or nil if no such segment exists.
func (f *File) Segment(name string) *Segment {
	for _, l := range f.Loads {
		if s, ok := l.(*Segment); ok && s.Name == name {
			return s
		}
	}
	return nil;
}

// Section returns the first section with the given name, or nil if no such
// section exists.
func (f *File) Section(name string) *Section {
	for _, s := range f.Sections {
		if s.Name == name {
			return s
		}
	}
	return nil;
}

// DWARF returns the DWARF debug information for the Mach-O file.
func (f *File) DWARF() (*dwarf.Data, os.Error) {
	// There are many other DWARF sections, but these
	// are the required ones, and the debug/dwarf package
	// does not use the others, so don't bother loading them.
	var names = [...]string{"abbrev", "info", "str"};
	var dat [len(names)][]byte;
	for i, name := range names {
		name = "__debug_" + name;
		s := f.Section(name);
		if s == nil {
			return nil, os.NewError("missing Mach-O section " + name)
		}
		b, err := s.Data();
		if err != nil && uint64(len(b)) < s.Size {
			return nil, err
		}
		dat[i] = b;
	}

	abbrev, info, str := dat[0], dat[1], dat[2];
	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str);
}
