aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/newlink/scan.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/newlink/scan.go')
-rw-r--r--src/cmd/newlink/scan.go187
1 files changed, 0 insertions, 187 deletions
diff --git a/src/cmd/newlink/scan.go b/src/cmd/newlink/scan.go
deleted file mode 100644
index 7feb0d8900..0000000000
--- a/src/cmd/newlink/scan.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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.
-
-// Initial scan of packages making up a program.
-
-// TODO(rsc): Rename goobj.SymID.Version to StaticID to avoid confusion with the ELF meaning of version.
-// TODO(rsc): Fix file format so that SBSS/SNOPTRBSS with data is listed as SDATA/SNOPTRDATA.
-// TODO(rsc): Parallelize scan to overlap file i/o where possible.
-
-package main
-
-import (
- "cmd/internal/goobj"
- "os"
- "sort"
- "strings"
-)
-
-// scan scans all packages making up the program, starting with package main defined in mainfile.
-func (p *Prog) scan(mainfile string) {
- p.initScan()
- p.scanFile("main", mainfile)
- if len(p.Missing) > 0 && !p.omitRuntime {
- p.scanImport("runtime")
- }
-
- var missing []string
- for sym := range p.Missing {
- if !p.isAuto(sym) {
- missing = append(missing, sym.String())
- }
- }
-
- if missing != nil {
- sort.Strings(missing)
- for _, sym := range missing {
- p.errorf("undefined: %s", sym)
- }
- }
-
- // TODO(rsc): Walk import graph to diagnose cycles.
-}
-
-// initScan initializes the Prog fields needed by scan.
-func (p *Prog) initScan() {
- p.Packages = make(map[string]*Package)
- p.Syms = make(map[goobj.SymID]*Sym)
- p.Missing = make(map[goobj.SymID]bool)
- p.Missing[p.startSym] = true
-}
-
-// scanFile reads file to learn about the package with the given import path.
-func (p *Prog) scanFile(pkgpath string, file string) {
- pkg := &Package{
- File: file,
- }
- p.Packages[pkgpath] = pkg
-
- f, err := os.Open(file)
- if err != nil {
- p.errorf("%v", err)
- return
- }
- gp, err := goobj.Parse(f, pkgpath)
- f.Close()
- if err != nil {
- p.errorf("reading %s: %v", file, err)
- return
- }
-
- // TODO(rsc): Change cmd/internal/goobj to record package name as gp.Name.
- // TODO(rsc): If pkgpath == "main", check that gp.Name == "main".
-
- pkg.Package = gp
-
- for _, gs := range gp.Syms {
- // TODO(rsc): Fix file format instead of this workaround.
- if gs.Data.Size > 0 {
- switch gs.Kind {
- case goobj.SBSS:
- gs.Kind = goobj.SDATA
- case goobj.SNOPTRBSS:
- gs.Kind = goobj.SNOPTRDATA
- }
- }
-
- if gs.Version != 0 {
- gs.Version += p.MaxVersion
- }
- for i := range gs.Reloc {
- r := &gs.Reloc[i]
- if r.Sym.Version != 0 {
- r.Sym.Version += p.MaxVersion
- }
- if p.Syms[r.Sym] == nil {
- p.Missing[r.Sym] = true
- }
- }
- if gs.Func != nil {
- for i := range gs.Func.FuncData {
- fdata := &gs.Func.FuncData[i]
- if fdata.Sym.Name != "" {
- if fdata.Sym.Version != 0 {
- fdata.Sym.Version += p.MaxVersion
- }
- if p.Syms[fdata.Sym] == nil {
- p.Missing[fdata.Sym] = true
- }
- }
- }
- }
- if old := p.Syms[gs.SymID]; old != nil {
- // Duplicate definition of symbol. Is it okay?
- // TODO(rsc): Write test for this code.
- switch {
- // If both symbols are BSS (no data), take max of sizes
- // but otherwise ignore second symbol.
- case old.Data.Size == 0 && gs.Data.Size == 0:
- if old.Size < gs.Size {
- old.Size = gs.Size
- }
- continue
-
- // If one is in BSS and one is not, use the one that is not.
- case old.Data.Size > 0 && gs.Data.Size == 0:
- continue
- case gs.Data.Size > 0 && old.Data.Size == 0:
- break // install gs as new symbol below
-
- // If either is marked as DupOK, we can keep either one.
- // Keep the one that we saw first.
- case old.DupOK || gs.DupOK:
- continue
-
- // Otherwise, there's an actual conflict:
- default:
- p.errorf("symbol %s defined in both %s and %s %v %v", gs.SymID, old.Package.File, file, old.Data, gs.Data)
- continue
- }
- }
- s := &Sym{
- Sym: gs,
- Package: pkg,
- }
- p.addSym(s)
- delete(p.Missing, gs.SymID)
-
- if s.Data.Size > int64(s.Size) {
- p.errorf("%s: initialized data larger than symbol (%d > %d)", s, s.Data.Size, s.Size)
- }
- }
- p.MaxVersion += pkg.MaxVersion
-
- for i, pkgpath := range pkg.Imports {
- // TODO(rsc): Fix file format to drop .a from recorded import path.
- pkgpath = strings.TrimSuffix(pkgpath, ".a")
- pkg.Imports[i] = pkgpath
-
- p.scanImport(pkgpath)
- }
-}
-
-func (p *Prog) addSym(s *Sym) {
- pkg := s.Package
- if pkg == nil {
- pkg = p.Packages[""]
- if pkg == nil {
- pkg = &Package{}
- p.Packages[""] = pkg
- }
- s.Package = pkg
- }
- pkg.Syms = append(pkg.Syms, s)
- p.Syms[s.SymID] = s
- p.SymOrder = append(p.SymOrder, s)
-}
-
-// scanImport finds the object file for the given import path and then scans it.
-func (p *Prog) scanImport(pkgpath string) {
- if p.Packages[pkgpath] != nil {
- return // already loaded
- }
-
- // TODO(rsc): Implement correct search to find file.
- p.scanFile(pkgpath, p.pkgdir+"/"+pkgpath+".a")
-}