github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/link/internal/objfile/objfile.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package objfile reads Go object files for the Go linker, cmd/link. 6 // 7 // This package is similar to cmd/internal/objfile which also reads 8 // Go object files. 9 package objfile 10 11 import ( 12 "bufio" 13 "bytes" 14 "cmd/internal/bio" 15 "cmd/internal/dwarf" 16 "cmd/internal/obj" 17 "cmd/internal/objabi" 18 "cmd/internal/sys" 19 "cmd/link/internal/sym" 20 "io" 21 "log" 22 "strconv" 23 "strings" 24 ) 25 26 const ( 27 startmagic = "\x00go112ld" 28 endmagic = "\xffgo112ld" 29 ) 30 31 var emptyPkg = []byte(`"".`) 32 33 // objReader reads Go object files. 34 type objReader struct { 35 rd *bufio.Reader 36 arch *sys.Arch 37 syms *sym.Symbols 38 lib *sym.Library 39 pn string 40 dupSym *sym.Symbol 41 localSymVersion int 42 43 // rdBuf is used by readString and readSymName as scratch for reading strings. 44 rdBuf []byte 45 46 // List of symbol references for the file being read. 47 refs []*sym.Symbol 48 data []byte 49 reloc []sym.Reloc 50 pcdata []sym.Pcdata 51 autom []sym.Auto 52 funcdata []*sym.Symbol 53 funcdataoff []int64 54 file []*sym.Symbol 55 } 56 57 // Load loads an object file f into library lib. 58 // The symbols loaded are added to syms. 59 func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, length int64, pn string) { 60 start := f.Offset() 61 r := &objReader{ 62 rd: f.Reader, 63 lib: lib, 64 arch: arch, 65 syms: syms, 66 pn: pn, 67 dupSym: &sym.Symbol{Name: ".dup"}, 68 localSymVersion: syms.IncVersion(), 69 } 70 r.loadObjFile() 71 if f.Offset() != start+length { 72 log.Fatalf("%s: unexpected end at %d, want %d", pn, f.Offset(), start+length) 73 } 74 } 75 76 func (r *objReader) loadObjFile() { 77 // Magic header 78 var buf [8]uint8 79 r.readFull(buf[:]) 80 if string(buf[:]) != startmagic { 81 log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", r.pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]) 82 } 83 84 // Version 85 c, err := r.rd.ReadByte() 86 if err != nil || c != 1 { 87 log.Fatalf("%s: invalid file version number %d", r.pn, c) 88 } 89 90 // Autolib 91 for { 92 lib := r.readString() 93 if lib == "" { 94 break 95 } 96 r.lib.ImportStrings = append(r.lib.ImportStrings, lib) 97 } 98 99 // Symbol references 100 r.refs = []*sym.Symbol{nil} // zeroth ref is nil 101 for { 102 c, err := r.rd.Peek(1) 103 if err != nil { 104 log.Fatalf("%s: peeking: %v", r.pn, err) 105 } 106 if c[0] == 0xff { 107 r.rd.ReadByte() 108 break 109 } 110 r.readRef() 111 } 112 113 // Lengths 114 r.readSlices() 115 116 // Data section 117 r.readFull(r.data) 118 119 // Defined symbols 120 for { 121 c, err := r.rd.Peek(1) 122 if err != nil { 123 log.Fatalf("%s: peeking: %v", r.pn, err) 124 } 125 if c[0] == 0xff { 126 break 127 } 128 r.readSym() 129 } 130 131 // Magic footer 132 buf = [8]uint8{} 133 r.readFull(buf[:]) 134 if string(buf[:]) != endmagic { 135 log.Fatalf("%s: invalid file end", r.pn) 136 } 137 } 138 139 func (r *objReader) readSlices() { 140 n := r.readInt() 141 r.data = make([]byte, n) 142 n = r.readInt() 143 r.reloc = make([]sym.Reloc, n) 144 n = r.readInt() 145 r.pcdata = make([]sym.Pcdata, n) 146 n = r.readInt() 147 r.autom = make([]sym.Auto, n) 148 n = r.readInt() 149 r.funcdata = make([]*sym.Symbol, n) 150 r.funcdataoff = make([]int64, n) 151 n = r.readInt() 152 r.file = make([]*sym.Symbol, n) 153 } 154 155 // Symbols are prefixed so their content doesn't get confused with the magic footer. 156 const symPrefix = 0xfe 157 158 func (r *objReader) readSym() { 159 var c byte 160 var err error 161 if c, err = r.rd.ReadByte(); c != symPrefix || err != nil { 162 log.Fatalln("readSym out of sync") 163 } 164 if c, err = r.rd.ReadByte(); err != nil { 165 log.Fatalln("error reading input: ", err) 166 } 167 t := sym.AbiSymKindToSymKind[c] 168 s := r.readSymIndex() 169 flags := r.readInt() 170 dupok := flags&1 != 0 171 local := flags&2 != 0 172 makeTypelink := flags&4 != 0 173 size := r.readInt() 174 typ := r.readSymIndex() 175 data := r.readData() 176 nreloc := r.readInt() 177 pkg := objabi.PathToPrefix(r.lib.Pkg) 178 isdup := false 179 180 var dup *sym.Symbol 181 if s.Type != 0 && s.Type != sym.SXREF { 182 if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 { 183 if s.Size < int64(size) { 184 s.Size = int64(size) 185 } 186 if typ != nil && s.Gotype == nil { 187 s.Gotype = typ 188 } 189 return 190 } 191 192 if (s.Type == sym.SDATA || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 { 193 goto overwrite 194 } 195 if s.Type != sym.SBSS && s.Type != sym.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() { 196 log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn) 197 } 198 if len(s.P) > 0 { 199 dup = s 200 s = r.dupSym 201 isdup = true 202 } 203 } 204 205 overwrite: 206 s.File = pkg 207 s.Lib = r.lib 208 if dupok { 209 s.Attr |= sym.AttrDuplicateOK 210 } 211 if t == sym.SXREF { 212 log.Fatalf("bad sxref") 213 } 214 if t == 0 { 215 log.Fatalf("missing type for %s in %s", s.Name, r.pn) 216 } 217 if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) { 218 t = s.Type 219 } 220 s.Type = t 221 if s.Size < int64(size) { 222 s.Size = int64(size) 223 } 224 s.Attr.Set(sym.AttrLocal, local) 225 s.Attr.Set(sym.AttrMakeTypelink, makeTypelink) 226 if typ != nil { 227 s.Gotype = typ 228 } 229 if isdup && typ != nil { // if bss sym defined multiple times, take type from any one def 230 dup.Gotype = typ 231 } 232 s.P = data 233 if nreloc > 0 { 234 s.R = r.reloc[:nreloc:nreloc] 235 if !isdup { 236 r.reloc = r.reloc[nreloc:] 237 } 238 239 for i := 0; i < nreloc; i++ { 240 s.R[i] = sym.Reloc{ 241 Off: r.readInt32(), 242 Siz: r.readUint8(), 243 Type: objabi.RelocType(r.readInt32()), 244 Add: r.readInt64(), 245 Sym: r.readSymIndex(), 246 } 247 } 248 } 249 250 if s.Type == sym.STEXT { 251 s.FuncInfo = new(sym.FuncInfo) 252 pc := s.FuncInfo 253 254 pc.Args = r.readInt32() 255 pc.Locals = r.readInt32() 256 if r.readUint8() != 0 { 257 s.Attr |= sym.AttrNoSplit 258 } 259 flags := r.readInt() 260 if flags&(1<<2) != 0 { 261 s.Attr |= sym.AttrReflectMethod 262 } 263 if flags&(1<<3) != 0 { 264 s.Attr |= sym.AttrShared 265 } 266 n := r.readInt() 267 pc.Autom = r.autom[:n:n] 268 if !isdup { 269 r.autom = r.autom[n:] 270 } 271 272 for i := 0; i < n; i++ { 273 pc.Autom[i] = sym.Auto{ 274 Asym: r.readSymIndex(), 275 Aoffset: r.readInt32(), 276 Name: r.readInt16(), 277 Gotype: r.readSymIndex(), 278 } 279 } 280 281 pc.Pcsp.P = r.readData() 282 pc.Pcfile.P = r.readData() 283 pc.Pcline.P = r.readData() 284 pc.Pcinline.P = r.readData() 285 n = r.readInt() 286 pc.Pcdata = r.pcdata[:n:n] 287 if !isdup { 288 r.pcdata = r.pcdata[n:] 289 } 290 for i := 0; i < n; i++ { 291 pc.Pcdata[i].P = r.readData() 292 } 293 n = r.readInt() 294 pc.Funcdata = r.funcdata[:n:n] 295 pc.Funcdataoff = r.funcdataoff[:n:n] 296 if !isdup { 297 r.funcdata = r.funcdata[n:] 298 r.funcdataoff = r.funcdataoff[n:] 299 } 300 for i := 0; i < n; i++ { 301 pc.Funcdata[i] = r.readSymIndex() 302 } 303 for i := 0; i < n; i++ { 304 pc.Funcdataoff[i] = r.readInt64() 305 } 306 n = r.readInt() 307 pc.File = r.file[:n:n] 308 if !isdup { 309 r.file = r.file[n:] 310 } 311 for i := 0; i < n; i++ { 312 pc.File[i] = r.readSymIndex() 313 } 314 n = r.readInt() 315 pc.InlTree = make([]sym.InlinedCall, n) 316 for i := 0; i < n; i++ { 317 pc.InlTree[i].Parent = r.readInt32() 318 pc.InlTree[i].File = r.readSymIndex() 319 pc.InlTree[i].Line = r.readInt32() 320 pc.InlTree[i].Func = r.readSymIndex() 321 pc.InlTree[i].ParentPC = r.readInt32() 322 } 323 324 if !dupok { 325 if s.Attr.OnList() { 326 log.Fatalf("symbol %s listed multiple times", s.Name) 327 } 328 s.Attr |= sym.AttrOnList 329 r.lib.Textp = append(r.lib.Textp, s) 330 } else { 331 // there may ba a dup in another package 332 // put into a temp list and add to text later 333 if !isdup { 334 r.lib.DupTextSyms = append(r.lib.DupTextSyms, s) 335 } else { 336 r.lib.DupTextSyms = append(r.lib.DupTextSyms, dup) 337 } 338 } 339 } 340 if s.Type == sym.SDWARFINFO { 341 r.patchDWARFName(s) 342 } 343 } 344 345 func (r *objReader) patchDWARFName(s *sym.Symbol) { 346 // This is kind of ugly. Really the package name should not 347 // even be included here. 348 if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION { 349 return 350 } 351 e := bytes.IndexByte(s.P, 0) 352 if e == -1 { 353 return 354 } 355 p := bytes.Index(s.P[:e], emptyPkg) 356 if p == -1 { 357 return 358 } 359 pkgprefix := []byte(objabi.PathToPrefix(r.lib.Pkg) + ".") 360 patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1) 361 362 s.P = append(patched, s.P[e:]...) 363 delta := int64(len(s.P)) - s.Size 364 s.Size = int64(len(s.P)) 365 for i := range s.R { 366 r := &s.R[i] 367 if r.Off > int32(e) { 368 r.Off += int32(delta) 369 } 370 } 371 } 372 373 func (r *objReader) readFull(b []byte) { 374 _, err := io.ReadFull(r.rd, b) 375 if err != nil { 376 log.Fatalf("%s: error reading %s", r.pn, err) 377 } 378 } 379 380 func (r *objReader) readRef() { 381 if c, err := r.rd.ReadByte(); c != symPrefix || err != nil { 382 log.Fatalf("readSym out of sync") 383 } 384 name := r.readSymName() 385 var v int 386 if abi := r.readInt(); abi == -1 { 387 // Static 388 v = r.localSymVersion 389 } else if abiver := sym.ABIToVersion(obj.ABI(abi)); abiver != -1 { 390 // Note that data symbols are "ABI0", which maps to version 0. 391 v = abiver 392 } else { 393 log.Fatalf("invalid symbol ABI for %q: %d", name, abi) 394 } 395 s := r.syms.Lookup(name, v) 396 r.refs = append(r.refs, s) 397 398 if s == nil || v == r.localSymVersion { 399 return 400 } 401 if s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 { 402 x, err := strconv.ParseUint(s.Name[5:], 16, 64) 403 if err != nil { 404 log.Panicf("failed to parse $-symbol %s: %v", s.Name, err) 405 } 406 s.Type = sym.SRODATA 407 s.Attr |= sym.AttrLocal 408 switch s.Name[:5] { 409 case "$f32.": 410 if uint64(uint32(x)) != x { 411 log.Panicf("$-symbol %s too large: %d", s.Name, x) 412 } 413 s.AddUint32(r.arch, uint32(x)) 414 case "$f64.", "$i64.": 415 s.AddUint64(r.arch, x) 416 default: 417 log.Panicf("unrecognized $-symbol: %s", s.Name) 418 } 419 s.Attr.Set(sym.AttrReachable, false) 420 } 421 if strings.HasPrefix(s.Name, "runtime.gcbits.") { 422 s.Attr |= sym.AttrLocal 423 } 424 } 425 426 func (r *objReader) readInt64() int64 { 427 uv := uint64(0) 428 for shift := uint(0); ; shift += 7 { 429 if shift >= 64 { 430 log.Fatalf("corrupt input") 431 } 432 c, err := r.rd.ReadByte() 433 if err != nil { 434 log.Fatalln("error reading input: ", err) 435 } 436 uv |= uint64(c&0x7F) << shift 437 if c&0x80 == 0 { 438 break 439 } 440 } 441 442 return int64(uv>>1) ^ (int64(uv<<63) >> 63) 443 } 444 445 func (r *objReader) readInt() int { 446 n := r.readInt64() 447 if int64(int(n)) != n { 448 log.Panicf("%v out of range for int", n) 449 } 450 return int(n) 451 } 452 453 func (r *objReader) readInt32() int32 { 454 n := r.readInt64() 455 if int64(int32(n)) != n { 456 log.Panicf("%v out of range for int32", n) 457 } 458 return int32(n) 459 } 460 461 func (r *objReader) readInt16() int16 { 462 n := r.readInt64() 463 if int64(int16(n)) != n { 464 log.Panicf("%v out of range for int16", n) 465 } 466 return int16(n) 467 } 468 469 func (r *objReader) readUint8() uint8 { 470 n := r.readInt64() 471 if int64(uint8(n)) != n { 472 log.Panicf("%v out of range for uint8", n) 473 } 474 return uint8(n) 475 } 476 477 func (r *objReader) readString() string { 478 n := r.readInt() 479 if cap(r.rdBuf) < n { 480 r.rdBuf = make([]byte, 2*n) 481 } 482 r.readFull(r.rdBuf[:n]) 483 return string(r.rdBuf[:n]) 484 } 485 486 func (r *objReader) readData() []byte { 487 n := r.readInt() 488 p := r.data[:n:n] 489 r.data = r.data[n:] 490 return p 491 } 492 493 // readSymName reads a symbol name, replacing all "". with pkg. 494 func (r *objReader) readSymName() string { 495 pkg := objabi.PathToPrefix(r.lib.Pkg) 496 n := r.readInt() 497 if n == 0 { 498 r.readInt64() 499 return "" 500 } 501 if cap(r.rdBuf) < n { 502 r.rdBuf = make([]byte, 2*n) 503 } 504 origName, err := r.rd.Peek(n) 505 if err == bufio.ErrBufferFull { 506 // Long symbol names are rare but exist. One source is type 507 // symbols for types with long string forms. See #15104. 508 origName = make([]byte, n) 509 r.readFull(origName) 510 } else if err != nil { 511 log.Fatalf("%s: error reading symbol: %v", r.pn, err) 512 } 513 adjName := r.rdBuf[:0] 514 for { 515 i := bytes.Index(origName, emptyPkg) 516 if i == -1 { 517 s := string(append(adjName, origName...)) 518 // Read past the peeked origName, now that we're done with it, 519 // using the rfBuf (also no longer used) as the scratch space. 520 // TODO: use bufio.Reader.Discard if available instead? 521 if err == nil { 522 r.readFull(r.rdBuf[:n]) 523 } 524 r.rdBuf = adjName[:0] // in case 2*n wasn't enough 525 return s 526 } 527 adjName = append(adjName, origName[:i]...) 528 adjName = append(adjName, pkg...) 529 adjName = append(adjName, '.') 530 origName = origName[i+len(emptyPkg):] 531 } 532 } 533 534 // Reads the index of a symbol reference and resolves it to a symbol 535 func (r *objReader) readSymIndex() *sym.Symbol { 536 i := r.readInt() 537 return r.refs[i] 538 }