return nil
}
-// readInt reads a zigzag varint from the input file.
-func (r *objReader) readInt() int64 {
- var u uint64
-
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- r.error(errCorruptObject)
- return 0
- }
- c := r.readByte()
- u |= uint64(c&0x7F) << shift
- if c&0x80 == 0 {
- break
- }
- }
-
- return int64(u>>1) ^ (int64(u) << 63 >> 63)
-}
-
-// readString reads a length-delimited string from the input file.
-func (r *objReader) readString() string {
- n := r.readInt()
- buf := make([]byte, n)
- r.readFull(buf)
- return string(buf)
-}
-
-// readSymID reads a SymID from the input file.
-func (r *objReader) readSymID() SymID {
- i := r.readInt()
- return r.p.SymRefs[i]
-}
-
-func (r *objReader) readRef() {
- name, abiOrStatic := r.readString(), r.readInt()
-
- // In a symbol name in an object file, "". denotes the
- // prefix for the package in which the object file has been found.
- // Expand it.
- name = strings.ReplaceAll(name, `"".`, r.pkgprefix)
-
- // The ABI field records either the ABI or -1 for static symbols.
- //
- // To distinguish different static symbols with the same name,
- // we use the symbol "version". Version 0 corresponds to
- // global symbols, and each file has a unique version > 0 for
- // all of its static symbols. The version is incremented on
- // each call to parseObject.
- //
- // For global symbols, we currently ignore the ABI.
- //
- // TODO(austin): Record the ABI in SymID. Since this is a
- // public API, we'll have to keep Version as 0 and record the
- // ABI in a new field (which differs from how the linker does
- // this, but that's okay). Show the ABI in things like
- // objdump.
- var vers int64
- if abiOrStatic == -1 {
- // Static symbol
- vers = r.p.MaxVersion
- }
- r.p.SymRefs = append(r.p.SymRefs, SymID{name, vers})
-}
-
-// readData reads a data reference from the input file.
-func (r *objReader) readData() Data {
- n := r.readInt()
- d := Data{Offset: r.dataOffset, Size: n}
- r.dataOffset += n
- return d
-}
-
// skip skips n bytes in the input.
func (r *objReader) skip(n int64) {
if n < 0 {
if err != nil {
return err
}
- if bytes.Equal(p, []byte(goobj2.Magic)) {
- r.readNew()
- return nil
- }
- r.readFull(r.tmp[:8])
- if !bytes.Equal(r.tmp[:8], []byte("\x00go114ld")) {
+ if !bytes.Equal(p, []byte(goobj2.Magic)) {
return r.error(errCorruptObject)
}
-
- b := r.readByte()
- if b != 1 {
- return r.error(errCorruptObject)
- }
-
- // Direct package dependencies.
- for {
- s := r.readString()
- if s == "" {
- break
- }
- r.p.Imports = append(r.p.Imports, s)
- }
-
- // Read filenames for dwarf info.
- count := r.readInt()
- for i := int64(0); i < count; i++ {
- r.p.DWARFFileList = append(r.p.DWARFFileList, r.readString())
- }
-
- r.p.SymRefs = []SymID{{"", 0}}
- for {
- if b := r.readByte(); b != 0xfe {
- if b != 0xff {
- return r.error(errCorruptObject)
- }
- break
- }
-
- r.readRef()
- }
-
- dataLength := r.readInt()
- r.readInt() // n relocations - ignore
- r.readInt() // n pcdata - ignore
- r.readInt() // n autom - ignore
- r.readInt() // n funcdata - ignore
- r.readInt() // n files - ignore
-
- r.dataOffset = r.offset
- r.skip(dataLength)
-
- // Symbols.
- for {
- if b := r.readByte(); b != 0xfe {
- if b != 0xff {
- return r.error(errCorruptObject)
- }
- break
- }
-
- typ := r.readByte()
- s := &Sym{SymID: r.readSymID()}
- r.p.Syms = append(r.p.Syms, s)
- s.Kind = objabi.SymKind(typ)
- flags := r.readInt()
- s.DupOK = flags&1 != 0
- s.Size = r.readInt()
- s.Type = r.readSymID()
- s.Data = r.readData()
- s.Reloc = make([]Reloc, r.readInt())
- for i := range s.Reloc {
- rel := &s.Reloc[i]
- rel.Offset = r.readInt()
- rel.Size = r.readInt()
- rel.Type = objabi.RelocType(r.readInt())
- rel.Add = r.readInt()
- rel.Sym = r.readSymID()
- }
-
- if s.Kind == objabi.STEXT {
- f := new(Func)
- s.Func = f
- f.Args = r.readInt()
- f.Frame = r.readInt()
- f.Align = uint32(r.readInt())
- flags := r.readInt()
- f.Leaf = flags&(1<<0) != 0
- f.TopFrame = flags&(1<<4) != 0
- f.NoSplit = r.readInt() != 0
- f.Var = make([]Var, r.readInt())
- for i := range f.Var {
- v := &f.Var[i]
- v.Name = r.readSymID().Name
- v.Offset = r.readInt()
- v.Kind = r.readInt()
- v.Type = r.readSymID()
- }
-
- f.PCSP = r.readData()
- f.PCFile = r.readData()
- f.PCLine = r.readData()
- f.PCInline = r.readData()
- f.PCData = make([]Data, r.readInt())
- for i := range f.PCData {
- f.PCData[i] = r.readData()
- }
- f.FuncData = make([]FuncData, r.readInt())
- for i := range f.FuncData {
- f.FuncData[i].Sym = r.readSymID()
- }
- for i := range f.FuncData {
- f.FuncData[i].Offset = r.readInt() // TODO
- }
- f.File = make([]string, r.readInt())
- for i := range f.File {
- f.File[i] = r.readSymID().Name
- }
- f.InlTree = make([]InlinedCall, r.readInt())
- for i := range f.InlTree {
- f.InlTree[i].Parent = r.readInt()
- f.InlTree[i].File = r.readSymID().Name
- f.InlTree[i].Line = r.readInt()
- f.InlTree[i].Func = r.readSymID()
- f.InlTree[i].ParentPC = r.readInt()
- }
- }
- }
-
- r.readFull(r.tmp[:7])
- if !bytes.Equal(r.tmp[:7], []byte("go114ld")) {
- return r.error(errCorruptObject)
- }
-
+ r.readNew()
return nil
}