Skip to content
Snippets Groups Projects
loader.go 30 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		}
    		s.Attr.Set(sym.AttrLocal, local)
    		s.Attr.Set(sym.AttrMakeTypelink, makeTypelink)
    
    
    		if s.Type == sym.SDWARFINFO {
    			// For DWARF symbols, replace `"".` to actual package prefix
    			// in the symbol content.
    			// TODO: maybe we should do this in the compiler and get rid
    			// of this.
    			patchDWARFName(s, r)
    		}
    
    
    		if s.Type != sym.STEXT {
    			continue
    		}
    
    		// FuncInfo
    		if isym == -1 {
    			continue
    		}
    
    		info := goobj2.FuncInfo{}
    		info.Read(b)
    
    		if info.NoSplit != 0 {
    			s.Attr |= sym.AttrNoSplit
    		}
    
    			s.Attr |= sym.AttrReflectMethod
    		}
    
    		if r.Flags()&goobj2.ObjFlagShared != 0 {
    
    			s.Attr |= sym.AttrShared
    		}
    
    			s.Attr |= sym.AttrTopFrame
    		}
    
    		info.Pcdata = append(info.Pcdata, info.PcdataEnd) // for the ease of knowing where it ends
    
    		pc := s.FuncInfo
    		if pc == nil {
    			pc = &sym.FuncInfo{}
    			s.FuncInfo = pc
    		}
    		pc.Args = int32(info.Args)
    		pc.Locals = int32(info.Locals)
    		pc.Pcdata = make([]sym.Pcdata, len(info.Pcdata)-1) // -1 as we appended one above
    		pc.Funcdataoff = make([]int64, len(info.Funcdataoff))
    		pc.File = make([]*sym.Symbol, len(info.File))
    
    		pc.InlTree = make([]sym.InlinedCall, len(info.InlTree))
    
    		pc.Pcsp.P = r.BytesAt(pcdataBase+info.Pcsp, int(info.Pcfile-info.Pcsp))
    		pc.Pcfile.P = r.BytesAt(pcdataBase+info.Pcfile, int(info.Pcline-info.Pcfile))
    		pc.Pcline.P = r.BytesAt(pcdataBase+info.Pcline, int(info.Pcinline-info.Pcline))
    		pc.Pcinline.P = r.BytesAt(pcdataBase+info.Pcinline, int(info.Pcdata[0]-info.Pcinline))
    		for k := range pc.Pcdata {
    			pc.Pcdata[k].P = r.BytesAt(pcdataBase+info.Pcdata[k], int(info.Pcdata[k+1]-info.Pcdata[k]))
    		}
    
    			pc.Funcdataoff[k] = int64(info.Funcdataoff[k])
    		}
    		for k := range pc.File {
    			pc.File[k] = resolveSymRef(info.File[k])
    		}
    
    		for k := range pc.InlTree {
    			inl := &info.InlTree[k]
    			pc.InlTree[k] = sym.InlinedCall{
    				Parent:   inl.Parent,
    				File:     resolveSymRef(inl.File),
    				Line:     inl.Line,
    
    				Func:     l.SymName(l.resolve(r, inl.Func)),
    
    
    		if !dupok {
    			if s.Attr.OnList() {
    				log.Fatalf("symbol %s listed multiple times", s.Name)
    			}
    			s.Attr.Set(sym.AttrOnList, true)
    			lib.Textp = append(lib.Textp, s)
    		} else {
    			// there may ba a dup in another package
    			// put into a temp list and add to text later
    			lib.DupTextSyms = append(lib.DupTextSyms, s)
    		}
    
    func patchDWARFName(s *sym.Symbol, r *oReader) {
    	// This is kind of ugly. Really the package name should not
    	// even be included here.
    	if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
    		return
    	}
    	e := bytes.IndexByte(s.P, 0)
    	if e == -1 {
    		return
    	}
    	p := bytes.Index(s.P[:e], emptyPkg)
    	if p == -1 {
    		return
    	}
    	pkgprefix := []byte(r.pkgprefix)
    	patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1)
    
    	s.P = append(patched, s.P[e:]...)
    	s.Attr.Set(sym.AttrReadOnly, false)
    	delta := int64(len(s.P)) - s.Size
    	s.Size = int64(len(s.P))
    	for i := range s.R {
    		r := &s.R[i]
    		if r.Off > int32(e) {
    			r.Off += int32(delta)
    		}
    	}
    }
    
    
    // For debugging.
    func (l *Loader) Dump() {
    	fmt.Println("objs")
    	for _, obj := range l.objs {
    		if obj.r != nil {
    			fmt.Println(obj.i, obj.r.unit.Lib)
    		}
    	}
    	fmt.Println("syms")
    	for i, s := range l.Syms {
    		if i == 0 {
    			continue
    		}
    		if s != nil {
    			fmt.Println(i, s, s.Type)
    		} else {
    			fmt.Println(i, l.SymName(Sym(i)), "<not loaded>")
    		}
    	}
    	fmt.Println("overwrite:", l.overwrite)
    	fmt.Println("symsByName")
    
    	for name, i := range l.symsByName[0] {
    		fmt.Println(i, name, 0)
    	}
    	for name, i := range l.symsByName[1] {
    		fmt.Println(i, name, 1)