mirror of
				https://github.com/beego/bee.git
				synced 2025-10-31 17:33:26 +00:00 
			
		
		
		
	Update vendor folder (Delve support)
This commit is contained in:
		
							
								
								
									
										146
									
								
								vendor/golang.org/x/debug/macho/fat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								vendor/golang.org/x/debug/macho/fat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| // Copyright 2014 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 | ||||
|  | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| // A FatFile is a Mach-O universal binary that contains at least one architecture. | ||||
| type FatFile struct { | ||||
| 	Magic  uint32 | ||||
| 	Arches []FatArch | ||||
| 	closer io.Closer | ||||
| } | ||||
|  | ||||
| // A FatArchHeader represents a fat header for a specific image architecture. | ||||
| type FatArchHeader struct { | ||||
| 	Cpu    Cpu | ||||
| 	SubCpu uint32 | ||||
| 	Offset uint32 | ||||
| 	Size   uint32 | ||||
| 	Align  uint32 | ||||
| } | ||||
|  | ||||
| const fatArchHeaderSize = 5 * 4 | ||||
|  | ||||
| // A FatArch is a Mach-O File inside a FatFile. | ||||
| type FatArch struct { | ||||
| 	FatArchHeader | ||||
| 	*File | ||||
| } | ||||
|  | ||||
| // ErrNotFat is returned from NewFatFile or OpenFat when the file is not a | ||||
| // universal binary but may be a thin binary, based on its magic number. | ||||
| var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil} | ||||
|  | ||||
| // NewFatFile creates a new FatFile for accessing all the Mach-O images in a | ||||
| // universal binary. The Mach-O binary is expected to start at position 0 in | ||||
| // the ReaderAt. | ||||
| func NewFatFile(r io.ReaderAt) (*FatFile, error) { | ||||
| 	var ff FatFile | ||||
| 	sr := io.NewSectionReader(r, 0, 1<<63-1) | ||||
|  | ||||
| 	// Read the fat_header struct, which is always in big endian. | ||||
| 	// Start with the magic number. | ||||
| 	err := binary.Read(sr, binary.BigEndian, &ff.Magic) | ||||
| 	if err != nil { | ||||
| 		return nil, &FormatError{0, "error reading magic number", nil} | ||||
| 	} else if ff.Magic != MagicFat { | ||||
| 		// See if this is a Mach-O file via its magic number. The magic | ||||
| 		// must be converted to little endian first though. | ||||
| 		var buf [4]byte | ||||
| 		binary.BigEndian.PutUint32(buf[:], ff.Magic) | ||||
| 		leMagic := binary.LittleEndian.Uint32(buf[:]) | ||||
| 		if leMagic == Magic32 || leMagic == Magic64 { | ||||
| 			return nil, ErrNotFat | ||||
| 		} else { | ||||
| 			return nil, &FormatError{0, "invalid magic number", nil} | ||||
| 		} | ||||
| 	} | ||||
| 	offset := int64(4) | ||||
|  | ||||
| 	// Read the number of FatArchHeaders that come after the fat_header. | ||||
| 	var narch uint32 | ||||
| 	err = binary.Read(sr, binary.BigEndian, &narch) | ||||
| 	if err != nil { | ||||
| 		return nil, &FormatError{offset, "invalid fat_header", nil} | ||||
| 	} | ||||
| 	offset += 4 | ||||
|  | ||||
| 	if narch < 1 { | ||||
| 		return nil, &FormatError{offset, "file contains no images", nil} | ||||
| 	} | ||||
|  | ||||
| 	// Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure | ||||
| 	// there are not duplicate architectures. | ||||
| 	seenArches := make(map[uint64]bool, narch) | ||||
| 	// Make sure that all images are for the same MH_ type. | ||||
| 	var machoType Type | ||||
|  | ||||
| 	// Following the fat_header comes narch fat_arch structs that index | ||||
| 	// Mach-O images further in the file. | ||||
| 	ff.Arches = make([]FatArch, narch) | ||||
| 	for i := uint32(0); i < narch; i++ { | ||||
| 		fa := &ff.Arches[i] | ||||
| 		err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader) | ||||
| 		if err != nil { | ||||
| 			return nil, &FormatError{offset, "invalid fat_arch header", nil} | ||||
| 		} | ||||
| 		offset += fatArchHeaderSize | ||||
|  | ||||
| 		fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size)) | ||||
| 		fa.File, err = NewFile(fr) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// Make sure the architecture for this image is not duplicate. | ||||
| 		seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu) | ||||
| 		if o, k := seenArches[seenArch]; o || k { | ||||
| 			return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil} | ||||
| 		} | ||||
| 		seenArches[seenArch] = true | ||||
|  | ||||
| 		// Make sure the Mach-O type matches that of the first image. | ||||
| 		if i == 0 { | ||||
| 			machoType = fa.Type | ||||
| 		} else { | ||||
| 			if fa.Type != machoType { | ||||
| 				return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &ff, nil | ||||
| } | ||||
|  | ||||
| // OpenFat opens the named file using os.Open and prepares it for use as a Mach-O | ||||
| // universal binary. | ||||
| func OpenFat(name string) (ff *FatFile, err error) { | ||||
| 	f, err := os.Open(name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	ff, err = NewFatFile(f) | ||||
| 	if err != nil { | ||||
| 		f.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	ff.closer = f | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (ff *FatFile) Close() error { | ||||
| 	var err error | ||||
| 	if ff.closer != nil { | ||||
| 		err = ff.closer.Close() | ||||
| 		ff.closer = nil | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										525
									
								
								vendor/golang.org/x/debug/macho/file.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										525
									
								
								vendor/golang.org/x/debug/macho/file.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,525 @@ | ||||
| // 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. | ||||
| package macho | ||||
|  | ||||
| // High level access to low level data structures. | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
|  | ||||
| 	"golang.org/x/debug/dwarf" | ||||
| ) | ||||
|  | ||||
| // A File represents an open Mach-O file. | ||||
| type File struct { | ||||
| 	FileHeader | ||||
| 	ByteOrder binary.ByteOrder | ||||
| 	Loads     []Load | ||||
| 	Sections  []*Section | ||||
|  | ||||
| 	Symtab   *Symtab | ||||
| 	Dysymtab *Dysymtab | ||||
|  | ||||
| 	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, error) { | ||||
| 	dat := make([]byte, s.sr.Size()) | ||||
| 	n, err := s.sr.ReadAt(dat, 0) | ||||
| 	if n == len(dat) { | ||||
| 		err = nil | ||||
| 	} | ||||
| 	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, error) { | ||||
| 	dat := make([]byte, s.sr.Size()) | ||||
| 	n, err := s.sr.ReadAt(dat, 0) | ||||
| 	if n == len(dat) { | ||||
| 		err = nil | ||||
| 	} | ||||
| 	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) } | ||||
|  | ||||
| // A Dylib represents a Mach-O load dynamic library command. | ||||
| type Dylib struct { | ||||
| 	LoadBytes | ||||
| 	Name           string | ||||
| 	Time           uint32 | ||||
| 	CurrentVersion uint32 | ||||
| 	CompatVersion  uint32 | ||||
| } | ||||
|  | ||||
| // A Symtab represents a Mach-O symbol table command. | ||||
| type Symtab struct { | ||||
| 	LoadBytes | ||||
| 	SymtabCmd | ||||
| 	Syms []Symbol | ||||
| } | ||||
|  | ||||
| // A Dysymtab represents a Mach-O dynamic symbol table command. | ||||
| type Dysymtab struct { | ||||
| 	LoadBytes | ||||
| 	DysymtabCmd | ||||
| 	IndirectSyms []uint32 // indices into Symtab.Syms | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Mach-O reader | ||||
|  */ | ||||
|  | ||||
| // FormatError is returned by some operations if the data does | ||||
| // not have the correct format for an object file. | ||||
| type FormatError struct { | ||||
| 	off int64 | ||||
| 	msg string | ||||
| 	val interface{} | ||||
| } | ||||
|  | ||||
| func (e *FormatError) Error() 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, error) { | ||||
| 	f, err := os.Open(name) | ||||
| 	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() error { | ||||
| 	var err error | ||||
| 	if f.closer != nil { | ||||
| 		err = f.closer.Close() | ||||
| 		f.closer = nil | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // NewFile creates a new File for accessing 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, 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]byte | ||||
| 	if _, err := r.ReadAt(ident[0:], 0); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	be := binary.BigEndian.Uint32(ident[0:]) | ||||
| 	le := binary.LittleEndian.Uint32(ident[0:]) | ||||
| 	switch Magic32 &^ 1 { | ||||
| 	case be &^ 1: | ||||
| 		f.ByteOrder = binary.BigEndian | ||||
| 		f.Magic = be | ||||
| 	case le &^ 1: | ||||
| 		f.ByteOrder = binary.LittleEndian | ||||
| 		f.Magic = le | ||||
| 	default: | ||||
| 		return nil, &FormatError{0, "invalid magic number", nil} | ||||
| 	} | ||||
|  | ||||
| 	// 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 LoadCmdDylib: | ||||
| 			var hdr DylibCmd | ||||
| 			b := bytes.NewReader(cmddat) | ||||
| 			if err := binary.Read(b, bo, &hdr); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			l := new(Dylib) | ||||
| 			if hdr.Name >= uint32(len(cmddat)) { | ||||
| 				return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name} | ||||
| 			} | ||||
| 			l.Name = cstring(cmddat[hdr.Name:]) | ||||
| 			l.Time = hdr.Time | ||||
| 			l.CurrentVersion = hdr.CurrentVersion | ||||
| 			l.CompatVersion = hdr.CompatVersion | ||||
| 			l.LoadBytes = LoadBytes(cmddat) | ||||
| 			f.Loads[i] = l | ||||
|  | ||||
| 		case LoadCmdSymtab: | ||||
| 			var hdr SymtabCmd | ||||
| 			b := bytes.NewReader(cmddat) | ||||
| 			if err := binary.Read(b, bo, &hdr); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			strtab := make([]byte, hdr.Strsize) | ||||
| 			if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			var symsz int | ||||
| 			if f.Magic == Magic64 { | ||||
| 				symsz = 16 | ||||
| 			} else { | ||||
| 				symsz = 12 | ||||
| 			} | ||||
| 			symdat := make([]byte, int(hdr.Nsyms)*symsz) | ||||
| 			if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			f.Loads[i] = st | ||||
| 			f.Symtab = st | ||||
|  | ||||
| 		case LoadCmdDysymtab: | ||||
| 			var hdr DysymtabCmd | ||||
| 			b := bytes.NewReader(cmddat) | ||||
| 			if err := binary.Read(b, bo, &hdr); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			dat := make([]byte, hdr.Nindirectsyms*4) | ||||
| 			if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			x := make([]uint32, hdr.Nindirectsyms) | ||||
| 			if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			st := new(Dysymtab) | ||||
| 			st.LoadBytes = LoadBytes(cmddat) | ||||
| 			st.DysymtabCmd = hdr | ||||
| 			st.IndirectSyms = x | ||||
| 			f.Loads[i] = st | ||||
| 			f.Dysymtab = st | ||||
|  | ||||
| 		case LoadCmdSegment: | ||||
| 			var seg32 Segment32 | ||||
| 			b := bytes.NewReader(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[0:]) | ||||
| 			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[0:]) | ||||
| 				sh.Seg = cstring(sh32.Seg[0:]) | ||||
| 				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.NewReader(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[0:]) | ||||
| 			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[0:]) | ||||
| 				sh.Seg = cstring(sh64.Seg[0:]) | ||||
| 				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) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) { | ||||
| 	bo := f.ByteOrder | ||||
| 	symtab := make([]Symbol, hdr.Nsyms) | ||||
| 	b := bytes.NewReader(symdat) | ||||
| 	for i := range symtab { | ||||
| 		var n Nlist64 | ||||
| 		if f.Magic == Magic64 { | ||||
| 			if err := binary.Read(b, bo, &n); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} else { | ||||
| 			var n32 Nlist32 | ||||
| 			if err := binary.Read(b, bo, &n32); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			n.Name = n32.Name | ||||
| 			n.Type = n32.Type | ||||
| 			n.Sect = n32.Sect | ||||
| 			n.Desc = n32.Desc | ||||
| 			n.Value = uint64(n32.Value) | ||||
| 		} | ||||
| 		sym := &symtab[i] | ||||
| 		if n.Name >= uint32(len(strtab)) { | ||||
| 			return nil, &FormatError{offset, "invalid name in symbol table", n.Name} | ||||
| 		} | ||||
| 		sym.Name = cstring(strtab[n.Name:]) | ||||
| 		sym.Type = n.Type | ||||
| 		sym.Sect = n.Sect | ||||
| 		sym.Desc = n.Desc | ||||
| 		sym.Value = n.Value | ||||
| 	} | ||||
| 	st := new(Symtab) | ||||
| 	st.LoadBytes = LoadBytes(cmddat) | ||||
| 	st.Syms = symtab | ||||
| 	return st, nil | ||||
| } | ||||
|  | ||||
| func (f *File) pushSection(sh *Section, r io.ReaderAt) { | ||||
| 	f.Sections = append(f.Sections, 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, 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", "frame", "info", "line", "str"} | ||||
| 	var dat [len(names)][]byte | ||||
| 	for i, name := range names { | ||||
| 		name = "__debug_" + name | ||||
| 		s := f.Section(name) | ||||
| 		if s == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		b, err := s.Data() | ||||
| 		if err != nil && uint64(len(b)) < s.Size { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		dat[i] = b | ||||
| 	} | ||||
|  | ||||
| 	abbrev, frame, info, line, str := dat[0], dat[1], dat[2], dat[3], dat[4] | ||||
| 	return dwarf.New(abbrev, nil, frame, info, line, nil, nil, str) | ||||
| } | ||||
|  | ||||
| // ImportedSymbols returns the names of all symbols | ||||
| // referred to by the binary f that are expected to be | ||||
| // satisfied by other libraries at dynamic load time. | ||||
| func (f *File) ImportedSymbols() ([]string, error) { | ||||
| 	if f.Dysymtab == nil || f.Symtab == nil { | ||||
| 		return nil, &FormatError{0, "missing symbol table", nil} | ||||
| 	} | ||||
|  | ||||
| 	st := f.Symtab | ||||
| 	dt := f.Dysymtab | ||||
| 	var all []string | ||||
| 	for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] { | ||||
| 		all = append(all, s.Name) | ||||
| 	} | ||||
| 	return all, nil | ||||
| } | ||||
|  | ||||
| // ImportedLibraries returns the paths of all libraries | ||||
| // referred to by the binary f that are expected to be | ||||
| // linked with the binary at dynamic link time. | ||||
| func (f *File) ImportedLibraries() ([]string, error) { | ||||
| 	var all []string | ||||
| 	for _, l := range f.Loads { | ||||
| 		if lib, ok := l.(*Dylib); ok { | ||||
| 			all = append(all, lib.Name) | ||||
| 		} | ||||
| 	} | ||||
| 	return all, nil | ||||
| } | ||||
							
								
								
									
										316
									
								
								vendor/golang.org/x/debug/macho/macho.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								vendor/golang.org/x/debug/macho/macho.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,316 @@ | ||||
| // 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. | ||||
|  | ||||
| // Mach-O header data structures | ||||
| // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html | ||||
|  | ||||
| package macho | ||||
|  | ||||
| import "strconv" | ||||
|  | ||||
| // A FileHeader represents a Mach-O file header. | ||||
| type FileHeader struct { | ||||
| 	Magic  uint32 | ||||
| 	Cpu    Cpu | ||||
| 	SubCpu uint32 | ||||
| 	Type   Type | ||||
| 	Ncmd   uint32 | ||||
| 	Cmdsz  uint32 | ||||
| 	Flags  uint32 | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	fileHeaderSize32 = 7 * 4 | ||||
| 	fileHeaderSize64 = 8 * 4 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	Magic32  uint32 = 0xfeedface | ||||
| 	Magic64  uint32 = 0xfeedfacf | ||||
| 	MagicFat uint32 = 0xcafebabe | ||||
| ) | ||||
|  | ||||
| // A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library. | ||||
| type Type uint32 | ||||
|  | ||||
| const ( | ||||
| 	TypeObj    Type = 1 | ||||
| 	TypeExec   Type = 2 | ||||
| 	TypeDylib  Type = 6 | ||||
| 	TypeBundle Type = 8 | ||||
| ) | ||||
|  | ||||
| // A Cpu is a Mach-O cpu type. | ||||
| type Cpu uint32 | ||||
|  | ||||
| const cpuArch64 = 0x01000000 | ||||
|  | ||||
| const ( | ||||
| 	Cpu386   Cpu = 7 | ||||
| 	CpuAmd64 Cpu = Cpu386 | cpuArch64 | ||||
| 	CpuArm   Cpu = 12 | ||||
| 	CpuPpc   Cpu = 18 | ||||
| 	CpuPpc64 Cpu = CpuPpc | cpuArch64 | ||||
| ) | ||||
|  | ||||
| var cpuStrings = []intName{ | ||||
| 	{uint32(Cpu386), "Cpu386"}, | ||||
| 	{uint32(CpuAmd64), "CpuAmd64"}, | ||||
| 	{uint32(CpuArm), "CpuArm"}, | ||||
| 	{uint32(CpuPpc), "CpuPpc"}, | ||||
| 	{uint32(CpuPpc64), "CpuPpc64"}, | ||||
| } | ||||
|  | ||||
| func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) } | ||||
| func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) } | ||||
|  | ||||
| // A LoadCmd is a Mach-O load command. | ||||
| type LoadCmd uint32 | ||||
|  | ||||
| const ( | ||||
| 	LoadCmdSegment    LoadCmd = 1 | ||||
| 	LoadCmdSymtab     LoadCmd = 2 | ||||
| 	LoadCmdThread     LoadCmd = 4 | ||||
| 	LoadCmdUnixThread LoadCmd = 5 // thread+stack | ||||
| 	LoadCmdDysymtab   LoadCmd = 11 | ||||
| 	LoadCmdDylib      LoadCmd = 12 | ||||
| 	LoadCmdDylinker   LoadCmd = 15 | ||||
| 	LoadCmdSegment64  LoadCmd = 25 | ||||
| ) | ||||
|  | ||||
| var cmdStrings = []intName{ | ||||
| 	{uint32(LoadCmdSegment), "LoadCmdSegment"}, | ||||
| 	{uint32(LoadCmdThread), "LoadCmdThread"}, | ||||
| 	{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"}, | ||||
| 	{uint32(LoadCmdDylib), "LoadCmdDylib"}, | ||||
| 	{uint32(LoadCmdSegment64), "LoadCmdSegment64"}, | ||||
| } | ||||
|  | ||||
| func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) } | ||||
| func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) } | ||||
|  | ||||
| // A Segment64 is a 64-bit Mach-O segment load command. | ||||
| type Segment64 struct { | ||||
| 	Cmd     LoadCmd | ||||
| 	Len     uint32 | ||||
| 	Name    [16]byte | ||||
| 	Addr    uint64 | ||||
| 	Memsz   uint64 | ||||
| 	Offset  uint64 | ||||
| 	Filesz  uint64 | ||||
| 	Maxprot uint32 | ||||
| 	Prot    uint32 | ||||
| 	Nsect   uint32 | ||||
| 	Flag    uint32 | ||||
| } | ||||
|  | ||||
| // A Segment32 is a 32-bit Mach-O segment load command. | ||||
| type Segment32 struct { | ||||
| 	Cmd     LoadCmd | ||||
| 	Len     uint32 | ||||
| 	Name    [16]byte | ||||
| 	Addr    uint32 | ||||
| 	Memsz   uint32 | ||||
| 	Offset  uint32 | ||||
| 	Filesz  uint32 | ||||
| 	Maxprot uint32 | ||||
| 	Prot    uint32 | ||||
| 	Nsect   uint32 | ||||
| 	Flag    uint32 | ||||
| } | ||||
|  | ||||
| // A DylibCmd is a Mach-O load dynamic library command. | ||||
| type DylibCmd struct { | ||||
| 	Cmd            LoadCmd | ||||
| 	Len            uint32 | ||||
| 	Name           uint32 | ||||
| 	Time           uint32 | ||||
| 	CurrentVersion uint32 | ||||
| 	CompatVersion  uint32 | ||||
| } | ||||
|  | ||||
| // A Section32 is a 32-bit Mach-O section header. | ||||
| type Section32 struct { | ||||
| 	Name     [16]byte | ||||
| 	Seg      [16]byte | ||||
| 	Addr     uint32 | ||||
| 	Size     uint32 | ||||
| 	Offset   uint32 | ||||
| 	Align    uint32 | ||||
| 	Reloff   uint32 | ||||
| 	Nreloc   uint32 | ||||
| 	Flags    uint32 | ||||
| 	Reserve1 uint32 | ||||
| 	Reserve2 uint32 | ||||
| } | ||||
|  | ||||
| // A Section32 is a 64-bit Mach-O section header. | ||||
| type Section64 struct { | ||||
| 	Name     [16]byte | ||||
| 	Seg      [16]byte | ||||
| 	Addr     uint64 | ||||
| 	Size     uint64 | ||||
| 	Offset   uint32 | ||||
| 	Align    uint32 | ||||
| 	Reloff   uint32 | ||||
| 	Nreloc   uint32 | ||||
| 	Flags    uint32 | ||||
| 	Reserve1 uint32 | ||||
| 	Reserve2 uint32 | ||||
| 	Reserve3 uint32 | ||||
| } | ||||
|  | ||||
| // A SymtabCmd is a Mach-O symbol table command. | ||||
| type SymtabCmd struct { | ||||
| 	Cmd     LoadCmd | ||||
| 	Len     uint32 | ||||
| 	Symoff  uint32 | ||||
| 	Nsyms   uint32 | ||||
| 	Stroff  uint32 | ||||
| 	Strsize uint32 | ||||
| } | ||||
|  | ||||
| // A DysymtabCmd is a Mach-O dynamic symbol table command. | ||||
| type DysymtabCmd struct { | ||||
| 	Cmd            LoadCmd | ||||
| 	Len            uint32 | ||||
| 	Ilocalsym      uint32 | ||||
| 	Nlocalsym      uint32 | ||||
| 	Iextdefsym     uint32 | ||||
| 	Nextdefsym     uint32 | ||||
| 	Iundefsym      uint32 | ||||
| 	Nundefsym      uint32 | ||||
| 	Tocoffset      uint32 | ||||
| 	Ntoc           uint32 | ||||
| 	Modtaboff      uint32 | ||||
| 	Nmodtab        uint32 | ||||
| 	Extrefsymoff   uint32 | ||||
| 	Nextrefsyms    uint32 | ||||
| 	Indirectsymoff uint32 | ||||
| 	Nindirectsyms  uint32 | ||||
| 	Extreloff      uint32 | ||||
| 	Nextrel        uint32 | ||||
| 	Locreloff      uint32 | ||||
| 	Nlocrel        uint32 | ||||
| } | ||||
|  | ||||
| // An Nlist32 is a Mach-O 32-bit symbol table entry. | ||||
| type Nlist32 struct { | ||||
| 	Name  uint32 | ||||
| 	Type  uint8 | ||||
| 	Sect  uint8 | ||||
| 	Desc  uint16 | ||||
| 	Value uint32 | ||||
| } | ||||
|  | ||||
| // An Nlist64 is a Mach-O 64-bit symbol table entry. | ||||
| type Nlist64 struct { | ||||
| 	Name  uint32 | ||||
| 	Type  uint8 | ||||
| 	Sect  uint8 | ||||
| 	Desc  uint16 | ||||
| 	Value uint64 | ||||
| } | ||||
|  | ||||
| // A Symbol is a Mach-O 32-bit or 64-bit symbol table entry. | ||||
| type Symbol struct { | ||||
| 	Name  string | ||||
| 	Type  uint8 | ||||
| 	Sect  uint8 | ||||
| 	Desc  uint16 | ||||
| 	Value uint64 | ||||
| } | ||||
|  | ||||
| // A Thread is a Mach-O thread state command. | ||||
| type Thread struct { | ||||
| 	Cmd  LoadCmd | ||||
| 	Len  uint32 | ||||
| 	Type uint32 | ||||
| 	Data []uint32 | ||||
| } | ||||
|  | ||||
| // Regs386 is the Mach-O 386 register structure. | ||||
| type Regs386 struct { | ||||
| 	AX    uint32 | ||||
| 	BX    uint32 | ||||
| 	CX    uint32 | ||||
| 	DX    uint32 | ||||
| 	DI    uint32 | ||||
| 	SI    uint32 | ||||
| 	BP    uint32 | ||||
| 	SP    uint32 | ||||
| 	SS    uint32 | ||||
| 	FLAGS uint32 | ||||
| 	IP    uint32 | ||||
| 	CS    uint32 | ||||
| 	DS    uint32 | ||||
| 	ES    uint32 | ||||
| 	FS    uint32 | ||||
| 	GS    uint32 | ||||
| } | ||||
|  | ||||
| // RegsAMD64 is the Mach-O AMD64 register structure. | ||||
| type RegsAMD64 struct { | ||||
| 	AX    uint64 | ||||
| 	BX    uint64 | ||||
| 	CX    uint64 | ||||
| 	DX    uint64 | ||||
| 	DI    uint64 | ||||
| 	SI    uint64 | ||||
| 	BP    uint64 | ||||
| 	SP    uint64 | ||||
| 	R8    uint64 | ||||
| 	R9    uint64 | ||||
| 	R10   uint64 | ||||
| 	R11   uint64 | ||||
| 	R12   uint64 | ||||
| 	R13   uint64 | ||||
| 	R14   uint64 | ||||
| 	R15   uint64 | ||||
| 	IP    uint64 | ||||
| 	FLAGS uint64 | ||||
| 	CS    uint64 | ||||
| 	FS    uint64 | ||||
| 	GS    uint64 | ||||
| } | ||||
|  | ||||
| type intName struct { | ||||
| 	i uint32 | ||||
| 	s string | ||||
| } | ||||
|  | ||||
| func stringName(i uint32, names []intName, goSyntax bool) string { | ||||
| 	for _, n := range names { | ||||
| 		if n.i == i { | ||||
| 			if goSyntax { | ||||
| 				return "macho." + n.s | ||||
| 			} | ||||
| 			return n.s | ||||
| 		} | ||||
| 	} | ||||
| 	return strconv.FormatUint(uint64(i), 10) | ||||
| } | ||||
|  | ||||
| func flagName(i uint32, names []intName, goSyntax bool) string { | ||||
| 	s := "" | ||||
| 	for _, n := range names { | ||||
| 		if n.i&i == n.i { | ||||
| 			if len(s) > 0 { | ||||
| 				s += "+" | ||||
| 			} | ||||
| 			if goSyntax { | ||||
| 				s += "macho." | ||||
| 			} | ||||
| 			s += n.s | ||||
| 			i -= n.i | ||||
| 		} | ||||
| 	} | ||||
| 	if len(s) == 0 { | ||||
| 		return "0x" + strconv.FormatUint(uint64(i), 16) | ||||
| 	} | ||||
| 	if i != 0 { | ||||
| 		s += "+0x" + strconv.FormatUint(uint64(i), 16) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Faissal Elamraoui
					Faissal Elamraoui