]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: split plist flushing from object writing
authorShahar Kohanim <skohanim@gmail.com>
Mon, 11 Apr 2016 14:35:55 +0000 (17:35 +0300)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 12 Apr 2016 21:07:16 +0000 (21:07 +0000)
Only splits into separate files, no other changes.

Change-Id: Icc0da2c5f18e03e9ed7c0043bd7c790f741900f2
Reviewed-on: https://go-review.googlesource.com/21804
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/plist.go [new file with mode: 0644]

index d44d4398b18dccb0b160fcf27fe850b3f4fcbd7d..146be6f98f6d59cfc0a9c5334781843314949b90 100644 (file)
@@ -730,27 +730,6 @@ const (
        Hwindows
 )
 
-type Plist struct {
-       Name    *LSym
-       Firstpc *Prog
-       Recur   int
-       Link    *Plist
-}
-
-/*
- * start a new Prog list.
- */
-func Linknewplist(ctxt *Link) *Plist {
-       pl := new(Plist)
-       if ctxt.Plist == nil {
-               ctxt.Plist = pl
-       } else {
-               ctxt.Plast.Link = pl
-       }
-       ctxt.Plast = pl
-       return pl
-}
-
 // AsmBuf is a simple buffer to assemble variable-length x86 instructions into.
 type AsmBuf struct {
        buf [100]byte
index ee21f39d108a7a7f9ea426ab02a8ebaeb6176a4e..7d88db2bccec81bf6a41b95240a8f813a4406360 100644 (file)
@@ -115,7 +115,6 @@ import (
        "log"
        "path/filepath"
        "sort"
-       "strings"
 )
 
 // The Go and C compilers, and the assembler, call writeobj to write
@@ -126,192 +125,6 @@ func Writeobjdirect(ctxt *Link, b *bio.Writer) {
        WriteObjFile(ctxt, b)
 }
 
-func Flushplist(ctxt *Link) {
-       flushplist(ctxt, ctxt.Debugasm == 0)
-}
-func FlushplistNoFree(ctxt *Link) {
-       flushplist(ctxt, false)
-}
-func flushplist(ctxt *Link, freeProgs bool) {
-       // Build list of symbols, and assign instructions to lists.
-       // Ignore ctxt->plist boundaries. There are no guarantees there,
-       // and the assemblers just use one big list.
-       var curtext *LSym
-       var etext *Prog
-       var text []*LSym
-
-       for pl := ctxt.Plist; pl != nil; pl = pl.Link {
-               var plink *Prog
-               for p := pl.Firstpc; p != nil; p = plink {
-                       if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
-                               fmt.Printf("obj: %v\n", p)
-                       }
-                       plink = p.Link
-                       p.Link = nil
-
-                       switch p.As {
-                       case AEND:
-                               continue
-
-                       case ATYPE:
-                               // Assume each TYPE instruction describes
-                               // a different local variable or parameter,
-                               // so no dedup.
-                               // Using only the TYPE instructions means
-                               // that we discard location information about local variables
-                               // in C and assembly functions; that information is inferred
-                               // from ordinary references, because there are no TYPE
-                               // instructions there. Without the type information, gdb can't
-                               // use the locations, so we don't bother to save them.
-                               // If something else could use them, we could arrange to
-                               // preserve them.
-                               if curtext == nil {
-                                       continue
-                               }
-                               a := new(Auto)
-                               a.Asym = p.From.Sym
-                               a.Aoffset = int32(p.From.Offset)
-                               a.Name = int16(p.From.Name)
-                               a.Gotype = p.From.Gotype
-                               a.Link = curtext.Autom
-                               curtext.Autom = a
-                               continue
-
-                       case AGLOBL:
-                               s := p.From.Sym
-                               if s.Seenglobl {
-                                       fmt.Printf("duplicate %v\n", p)
-                               }
-                               s.Seenglobl = true
-                               if s.Onlist {
-                                       log.Fatalf("symbol %s listed multiple times", s.Name)
-                               }
-                               s.Onlist = true
-                               ctxt.Data = append(ctxt.Data, s)
-                               s.Size = p.To.Offset
-                               if s.Type == 0 || s.Type == SXREF {
-                                       s.Type = SBSS
-                               }
-                               flag := int(p.From3.Offset)
-                               if flag&DUPOK != 0 {
-                                       s.Dupok = true
-                               }
-                               if flag&RODATA != 0 {
-                                       s.Type = SRODATA
-                               } else if flag&NOPTR != 0 {
-                                       s.Type = SNOPTRBSS
-                               } else if flag&TLSBSS != 0 {
-                                       s.Type = STLSBSS
-                               }
-                               continue
-
-                       case ATEXT:
-                               s := p.From.Sym
-                               if s == nil {
-                                       // func _() { }
-                                       curtext = nil
-
-                                       continue
-                               }
-
-                               if s.Text != nil {
-                                       log.Fatalf("duplicate TEXT for %s", s.Name)
-                               }
-                               if s.Onlist {
-                                       log.Fatalf("symbol %s listed multiple times", s.Name)
-                               }
-                               s.Onlist = true
-                               text = append(text, s)
-                               flag := int(p.From3Offset())
-                               if flag&DUPOK != 0 {
-                                       s.Dupok = true
-                               }
-                               if flag&NOSPLIT != 0 {
-                                       s.Nosplit = true
-                               }
-                               if flag&REFLECTMETHOD != 0 {
-                                       s.ReflectMethod = true
-                               }
-                               s.Type = STEXT
-                               s.Text = p
-                               etext = p
-                               curtext = s
-                               continue
-
-                       case AFUNCDATA:
-                               // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
-                               if curtext == nil { // func _() {}
-                                       continue
-                               }
-                               if p.To.Sym.Name == "go_args_stackmap" {
-                                       if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
-                                               ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
-                                       }
-                                       p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
-                               }
-
-                       }
-
-                       if curtext == nil {
-                               etext = nil
-                               continue
-                       }
-                       etext.Link = p
-                       etext = p
-               }
-       }
-
-       // Add reference to Go arguments for C or assembly functions without them.
-       for _, s := range text {
-               if !strings.HasPrefix(s.Name, "\"\".") {
-                       continue
-               }
-               found := false
-               var p *Prog
-               for p = s.Text; p != nil; p = p.Link {
-                       if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
-                               found = true
-                               break
-                       }
-               }
-
-               if !found {
-                       p = Appendp(ctxt, s.Text)
-                       p.As = AFUNCDATA
-                       p.From.Type = TYPE_CONST
-                       p.From.Offset = FUNCDATA_ArgsPointerMaps
-                       p.To.Type = TYPE_MEM
-                       p.To.Name = NAME_EXTERN
-                       p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
-               }
-       }
-
-       // Turn functions into machine code images.
-       for _, s := range text {
-               mkfwd(s)
-               linkpatch(ctxt, s)
-               if ctxt.Flag_optimize {
-                       ctxt.Arch.Follow(ctxt, s)
-               }
-               ctxt.Arch.Preprocess(ctxt, s)
-               ctxt.Arch.Assemble(ctxt, s)
-               fieldtrack(ctxt, s)
-               linkpcln(ctxt, s)
-               if freeProgs {
-                       s.Text = nil
-               }
-       }
-
-       // Add to running list in ctxt.
-       ctxt.Text = append(ctxt.Text, text...)
-       ctxt.Plist = nil
-       ctxt.Plast = nil
-       ctxt.Curp = nil
-       if freeProgs {
-               ctxt.freeProgs()
-       }
-}
-
 // objWriter writes Go object files.
 type objWriter struct {
        wr   *bufio.Writer
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
new file mode 100644 (file)
index 0000000..e55dbec
--- /dev/null
@@ -0,0 +1,218 @@
+// Copyright 2013 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.
+
+package obj
+
+import (
+       "fmt"
+       "log"
+       "strings"
+)
+
+type Plist struct {
+       Name    *LSym
+       Firstpc *Prog
+       Recur   int
+       Link    *Plist
+}
+
+/*
+ * start a new Prog list.
+ */
+func Linknewplist(ctxt *Link) *Plist {
+       pl := new(Plist)
+       if ctxt.Plist == nil {
+               ctxt.Plist = pl
+       } else {
+               ctxt.Plast.Link = pl
+       }
+       ctxt.Plast = pl
+       return pl
+}
+
+func Flushplist(ctxt *Link) {
+       flushplist(ctxt, ctxt.Debugasm == 0)
+}
+func FlushplistNoFree(ctxt *Link) {
+       flushplist(ctxt, false)
+}
+func flushplist(ctxt *Link, freeProgs bool) {
+       // Build list of symbols, and assign instructions to lists.
+       // Ignore ctxt->plist boundaries. There are no guarantees there,
+       // and the assemblers just use one big list.
+       var curtext *LSym
+       var etext *Prog
+       var text []*LSym
+
+       for pl := ctxt.Plist; pl != nil; pl = pl.Link {
+               var plink *Prog
+               for p := pl.Firstpc; p != nil; p = plink {
+                       if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
+                               fmt.Printf("obj: %v\n", p)
+                       }
+                       plink = p.Link
+                       p.Link = nil
+
+                       switch p.As {
+                       case AEND:
+                               continue
+
+                       case ATYPE:
+                               // Assume each TYPE instruction describes
+                               // a different local variable or parameter,
+                               // so no dedup.
+                               // Using only the TYPE instructions means
+                               // that we discard location information about local variables
+                               // in C and assembly functions; that information is inferred
+                               // from ordinary references, because there are no TYPE
+                               // instructions there. Without the type information, gdb can't
+                               // use the locations, so we don't bother to save them.
+                               // If something else could use them, we could arrange to
+                               // preserve them.
+                               if curtext == nil {
+                                       continue
+                               }
+                               a := new(Auto)
+                               a.Asym = p.From.Sym
+                               a.Aoffset = int32(p.From.Offset)
+                               a.Name = int16(p.From.Name)
+                               a.Gotype = p.From.Gotype
+                               a.Link = curtext.Autom
+                               curtext.Autom = a
+                               continue
+
+                       case AGLOBL:
+                               s := p.From.Sym
+                               if s.Seenglobl {
+                                       fmt.Printf("duplicate %v\n", p)
+                               }
+                               s.Seenglobl = true
+                               if s.Onlist {
+                                       log.Fatalf("symbol %s listed multiple times", s.Name)
+                               }
+                               s.Onlist = true
+                               ctxt.Data = append(ctxt.Data, s)
+                               s.Size = p.To.Offset
+                               if s.Type == 0 || s.Type == SXREF {
+                                       s.Type = SBSS
+                               }
+                               flag := int(p.From3.Offset)
+                               if flag&DUPOK != 0 {
+                                       s.Dupok = true
+                               }
+                               if flag&RODATA != 0 {
+                                       s.Type = SRODATA
+                               } else if flag&NOPTR != 0 {
+                                       s.Type = SNOPTRBSS
+                               } else if flag&TLSBSS != 0 {
+                                       s.Type = STLSBSS
+                               }
+                               continue
+
+                       case ATEXT:
+                               s := p.From.Sym
+                               if s == nil {
+                                       // func _() { }
+                                       curtext = nil
+
+                                       continue
+                               }
+
+                               if s.Text != nil {
+                                       log.Fatalf("duplicate TEXT for %s", s.Name)
+                               }
+                               if s.Onlist {
+                                       log.Fatalf("symbol %s listed multiple times", s.Name)
+                               }
+                               s.Onlist = true
+                               text = append(text, s)
+                               flag := int(p.From3Offset())
+                               if flag&DUPOK != 0 {
+                                       s.Dupok = true
+                               }
+                               if flag&NOSPLIT != 0 {
+                                       s.Nosplit = true
+                               }
+                               if flag&REFLECTMETHOD != 0 {
+                                       s.ReflectMethod = true
+                               }
+                               s.Type = STEXT
+                               s.Text = p
+                               etext = p
+                               curtext = s
+                               continue
+
+                       case AFUNCDATA:
+                               // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
+                               if curtext == nil { // func _() {}
+                                       continue
+                               }
+                               if p.To.Sym.Name == "go_args_stackmap" {
+                                       if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
+                                               ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
+                                       }
+                                       p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
+                               }
+
+                       }
+
+                       if curtext == nil {
+                               etext = nil
+                               continue
+                       }
+                       etext.Link = p
+                       etext = p
+               }
+       }
+
+       // Add reference to Go arguments for C or assembly functions without them.
+       for _, s := range text {
+               if !strings.HasPrefix(s.Name, "\"\".") {
+                       continue
+               }
+               found := false
+               var p *Prog
+               for p = s.Text; p != nil; p = p.Link {
+                       if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
+                               found = true
+                               break
+                       }
+               }
+
+               if !found {
+                       p = Appendp(ctxt, s.Text)
+                       p.As = AFUNCDATA
+                       p.From.Type = TYPE_CONST
+                       p.From.Offset = FUNCDATA_ArgsPointerMaps
+                       p.To.Type = TYPE_MEM
+                       p.To.Name = NAME_EXTERN
+                       p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
+               }
+       }
+
+       // Turn functions into machine code images.
+       for _, s := range text {
+               mkfwd(s)
+               linkpatch(ctxt, s)
+               if ctxt.Flag_optimize {
+                       ctxt.Arch.Follow(ctxt, s)
+               }
+               ctxt.Arch.Preprocess(ctxt, s)
+               ctxt.Arch.Assemble(ctxt, s)
+               fieldtrack(ctxt, s)
+               linkpcln(ctxt, s)
+               if freeProgs {
+                       s.Text = nil
+               }
+       }
+
+       // Add to running list in ctxt.
+       ctxt.Text = append(ctxt.Text, text...)
+       ctxt.Plist = nil
+       ctxt.Plast = nil
+       ctxt.Curp = nil
+       if freeProgs {
+               ctxt.freeProgs()
+       }
+}