Home | History | Annotate | Download | only in ld
      1 // Do not edit. Bootstrap copy of /usr/local/google/buildbot/src/android/build-tools/out/obj/go/src/cmd/link/internal/ld/decodesym.go
      2 
      3 //line /usr/local/google/buildbot/src/android/build-tools/out/obj/go/src/cmd/link/internal/ld/decodesym.go:1
      4 // Copyright 2012 The Go Authors. All rights reserved.
      5 // Use of this source code is governed by a BSD-style
      6 // license that can be found in the LICENSE file.
      7 
      8 package ld
      9 
     10 import (
     11 	"bootstrap/internal/obj"
     12 	"debug/elf"
     13 )
     14 
     15 // Decoding the type.* symbols.	 This has to be in sync with
     16 // ../../runtime/type.go, or more specifically, with what
     17 // ../gc/reflect.c stuffs in these.
     18 
     19 func decode_reloc(s *LSym, off int32) *Reloc {
     20 	for i := 0; i < len(s.R); i++ {
     21 		if s.R[i].Off == off {
     22 			return &s.R[i:][0]
     23 		}
     24 	}
     25 	return nil
     26 }
     27 
     28 func decode_reloc_sym(s *LSym, off int32) *LSym {
     29 	r := decode_reloc(s, off)
     30 	if r == nil {
     31 		return nil
     32 	}
     33 	return r.Sym
     34 }
     35 
     36 func decode_inuxi(p []byte, sz int) uint64 {
     37 	switch sz {
     38 	case 2:
     39 		return uint64(Ctxt.Arch.ByteOrder.Uint16(p))
     40 	case 4:
     41 		return uint64(Ctxt.Arch.ByteOrder.Uint32(p))
     42 	case 8:
     43 		return Ctxt.Arch.ByteOrder.Uint64(p)
     44 	default:
     45 		Exitf("dwarf: decode inuxi %d", sz)
     46 		panic("unreachable")
     47 	}
     48 }
     49 
     50 // commonsize returns the size of the common prefix for all type
     51 // structures (runtime._type).
     52 func commonsize() int {
     53 	return 8*Thearch.Ptrsize + 8
     54 }
     55 
     56 // Type.commonType.kind
     57 func decodetype_kind(s *LSym) uint8 {
     58 	return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindMask) //  0x13 / 0x1f
     59 }
     60 
     61 // Type.commonType.kind
     62 func decodetype_noptr(s *LSym) uint8 {
     63 	return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindNoPointers) //  0x13 / 0x1f
     64 }
     65 
     66 // Type.commonType.kind
     67 func decodetype_usegcprog(s *LSym) uint8 {
     68 	return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindGCProg) //  0x13 / 0x1f
     69 }
     70 
     71 // Type.commonType.size
     72 func decodetype_size(s *LSym) int64 {
     73 	return int64(decode_inuxi(s.P, Thearch.Ptrsize)) // 0x8 / 0x10
     74 }
     75 
     76 // Type.commonType.ptrdata
     77 func decodetype_ptrdata(s *LSym) int64 {
     78 	return int64(decode_inuxi(s.P[Thearch.Ptrsize:], Thearch.Ptrsize)) // 0x8 / 0x10
     79 }
     80 
     81 // Find the elf.Section of a given shared library that contains a given address.
     82 func findShlibSection(path string, addr uint64) *elf.Section {
     83 	for _, shlib := range Ctxt.Shlibs {
     84 		if shlib.Path == path {
     85 			for _, sect := range shlib.File.Sections {
     86 				if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
     87 					return sect
     88 				}
     89 			}
     90 		}
     91 	}
     92 	return nil
     93 }
     94 
     95 // Type.commonType.gc
     96 func decodetype_gcprog(s *LSym) []byte {
     97 	if s.Type == obj.SDYNIMPORT {
     98 		addr := decodetype_gcprog_shlib(s)
     99 		sect := findShlibSection(s.File, addr)
    100 		if sect != nil {
    101 			// A gcprog is a 4-byte uint32 indicating length, followed by
    102 			// the actual program.
    103 			progsize := make([]byte, 4)
    104 			sect.ReadAt(progsize, int64(addr-sect.Addr))
    105 			progbytes := make([]byte, Ctxt.Arch.ByteOrder.Uint32(progsize))
    106 			sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
    107 			return append(progsize, progbytes...)
    108 		}
    109 		Exitf("cannot find gcprog for %s", s.Name)
    110 		return nil
    111 	}
    112 	return decode_reloc_sym(s, 2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize)).P
    113 }
    114 
    115 func decodetype_gcprog_shlib(s *LSym) uint64 {
    116 	return decode_inuxi(s.P[2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize):], Thearch.Ptrsize)
    117 }
    118 
    119 func decodetype_gcmask(s *LSym) []byte {
    120 	if s.Type == obj.SDYNIMPORT {
    121 		addr := decodetype_gcprog_shlib(s)
    122 		ptrdata := decodetype_ptrdata(s)
    123 		sect := findShlibSection(s.File, addr)
    124 		if sect != nil {
    125 			r := make([]byte, ptrdata/int64(Thearch.Ptrsize))
    126 			sect.ReadAt(r, int64(addr-sect.Addr))
    127 			return r
    128 		}
    129 		Exitf("cannot find gcmask for %s", s.Name)
    130 		return nil
    131 	}
    132 	mask := decode_reloc_sym(s, 2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
    133 	return mask.P
    134 }
    135 
    136 // Type.ArrayType.elem and Type.SliceType.Elem
    137 func decodetype_arrayelem(s *LSym) *LSym {
    138 	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
    139 }
    140 
    141 func decodetype_arraylen(s *LSym) int64 {
    142 	return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Ptrsize))
    143 }
    144 
    145 // Type.PtrType.elem
    146 func decodetype_ptrelem(s *LSym) *LSym {
    147 	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
    148 }
    149 
    150 // Type.MapType.key, elem
    151 func decodetype_mapkey(s *LSym) *LSym {
    152 	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
    153 }
    154 
    155 func decodetype_mapvalue(s *LSym) *LSym {
    156 	return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)) // 0x20 / 0x38
    157 }
    158 
    159 // Type.ChanType.elem
    160 func decodetype_chanelem(s *LSym) *LSym {
    161 	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
    162 }
    163 
    164 // Type.FuncType.dotdotdot
    165 func decodetype_funcdotdotdot(s *LSym) int {
    166 	return int(s.P[commonsize()])
    167 }
    168 
    169 // Type.FuncType.in.length
    170 func decodetype_funcincount(s *LSym) int {
    171 	return int(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize))
    172 }
    173 
    174 func decodetype_funcoutcount(s *LSym) int {
    175 	return int(decode_inuxi(s.P[commonsize()+3*Thearch.Ptrsize+2*Thearch.Intsize:], Thearch.Intsize))
    176 }
    177 
    178 func decodetype_funcintype(s *LSym, i int) *LSym {
    179 	r := decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize))
    180 	if r == nil {
    181 		return nil
    182 	}
    183 	return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
    184 }
    185 
    186 func decodetype_funcouttype(s *LSym, i int) *LSym {
    187 	r := decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize))
    188 	if r == nil {
    189 		return nil
    190 	}
    191 	return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
    192 }
    193 
    194 // Type.StructType.fields.Slice::length
    195 func decodetype_structfieldcount(s *LSym) int {
    196 	return int(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
    197 }
    198 
    199 func structfieldsize() int {
    200 	return 5 * Thearch.Ptrsize
    201 }
    202 
    203 // Type.StructType.fields[]-> name, typ and offset.
    204 func decodetype_structfieldname(s *LSym, i int) string {
    205 	// go.string."foo"  0x28 / 0x40
    206 	s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize()))
    207 
    208 	if s == nil { // embedded structs have a nil name.
    209 		return ""
    210 	}
    211 	r := decode_reloc(s, 0) // s has a pointer to the string data at offset 0
    212 	if r == nil {           // shouldn't happen.
    213 		return ""
    214 	}
    215 	return cstring(r.Sym.P[r.Add:])
    216 }
    217 
    218 func decodetype_structfieldtype(s *LSym, i int) *LSym {
    219 	return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize())+2*int32(Thearch.Ptrsize))
    220 }
    221 
    222 func decodetype_structfieldoffs(s *LSym, i int) int64 {
    223 	return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize))
    224 }
    225 
    226 // InterfaceType.methods.length
    227 func decodetype_ifacemethodcount(s *LSym) int64 {
    228 	return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
    229 }
    230