2015-02-13 14:40:36 -05:00
|
|
|
// Copyright 2009 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 gc
|
|
|
|
|
|
|
|
|
|
import (
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
"cmd/compile/internal/types"
|
2016-04-06 21:45:29 -07:00
|
|
|
"cmd/internal/bio"
|
2015-02-13 14:40:36 -05:00
|
|
|
"cmd/internal/obj"
|
2016-03-10 11:14:22 -08:00
|
|
|
"crypto/sha256"
|
2015-02-13 14:40:36 -05:00
|
|
|
"fmt"
|
2016-03-10 11:14:22 -08:00
|
|
|
"io"
|
2015-03-12 18:45:30 -04:00
|
|
|
"strconv"
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// architecture-independent object file output
|
2015-02-13 14:40:36 -05:00
|
|
|
const (
|
|
|
|
|
ArhdrSize = 60
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func formathdr(arhdr []byte, name string, size int64) {
|
|
|
|
|
copy(arhdr[:], fmt.Sprintf("%-16s%-12d%-6d%-6d%-8o%-10d`\n", name, 0, 0, 0, 0644, size))
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-26 21:50:59 -04:00
|
|
|
// These modes say which kind of object file to generate.
|
|
|
|
|
// The default use of the toolchain is to set both bits,
|
|
|
|
|
// generating a combined compiler+linker object, one that
|
|
|
|
|
// serves to describe the package to both the compiler and the linker.
|
|
|
|
|
// In fact the compiler and linker read nearly disjoint sections of
|
|
|
|
|
// that file, though, so in a distributed build setting it can be more
|
|
|
|
|
// efficient to split the output into two files, supplying the compiler
|
|
|
|
|
// object only to future compilations and the linker object only to
|
|
|
|
|
// future links.
|
|
|
|
|
//
|
|
|
|
|
// By default a combined object is written, but if -linkobj is specified
|
|
|
|
|
// on the command line then the default -o output is a compiler object
|
|
|
|
|
// and the -linkobj output is a linker object.
|
|
|
|
|
const (
|
|
|
|
|
modeCompilerObj = 1 << iota
|
|
|
|
|
modeLinkerObj
|
|
|
|
|
)
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
func dumpobj() {
|
cmd/compile: add -dolinkobj flag
When set to false, the -dolinkobj flag instructs the compiler
not to generate or emit linker information.
This is handy when you need the compiler's export data,
e.g. for use with go/importer,
but you want to avoid the cost of full compilation.
This must be used with care, since the resulting
files are unusable for linking.
This CL interacts with #18369,
where adding gcflags and ldflags to buildid has been mooted.
On the one hand, adding gcflags would make safe use of this
flag easier, since if the full object files were needed,
a simple 'go install' would fix it.
On the other hand, this would mean that
'go install -gcflags=-dolinkobj=false' would rebuild the object files,
although any existing object files would probably suffice.
Change-Id: I8dc75ab5a40095c785c1a4d2260aeb63c4d10f73
Reviewed-on: https://go-review.googlesource.com/37384
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-22 00:05:18 -08:00
|
|
|
if !dolinkobj {
|
|
|
|
|
dumpobj1(outfile, modeCompilerObj)
|
|
|
|
|
return
|
|
|
|
|
}
|
2016-04-26 21:50:59 -04:00
|
|
|
if linkobj == "" {
|
|
|
|
|
dumpobj1(outfile, modeCompilerObj|modeLinkerObj)
|
cmd/compile: add -dolinkobj flag
When set to false, the -dolinkobj flag instructs the compiler
not to generate or emit linker information.
This is handy when you need the compiler's export data,
e.g. for use with go/importer,
but you want to avoid the cost of full compilation.
This must be used with care, since the resulting
files are unusable for linking.
This CL interacts with #18369,
where adding gcflags and ldflags to buildid has been mooted.
On the one hand, adding gcflags would make safe use of this
flag easier, since if the full object files were needed,
a simple 'go install' would fix it.
On the other hand, this would mean that
'go install -gcflags=-dolinkobj=false' would rebuild the object files,
although any existing object files would probably suffice.
Change-Id: I8dc75ab5a40095c785c1a4d2260aeb63c4d10f73
Reviewed-on: https://go-review.googlesource.com/37384
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-22 00:05:18 -08:00
|
|
|
return
|
2016-04-26 21:50:59 -04:00
|
|
|
}
|
cmd/compile: add -dolinkobj flag
When set to false, the -dolinkobj flag instructs the compiler
not to generate or emit linker information.
This is handy when you need the compiler's export data,
e.g. for use with go/importer,
but you want to avoid the cost of full compilation.
This must be used with care, since the resulting
files are unusable for linking.
This CL interacts with #18369,
where adding gcflags and ldflags to buildid has been mooted.
On the one hand, adding gcflags would make safe use of this
flag easier, since if the full object files were needed,
a simple 'go install' would fix it.
On the other hand, this would mean that
'go install -gcflags=-dolinkobj=false' would rebuild the object files,
although any existing object files would probably suffice.
Change-Id: I8dc75ab5a40095c785c1a4d2260aeb63c4d10f73
Reviewed-on: https://go-review.googlesource.com/37384
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-22 00:05:18 -08:00
|
|
|
dumpobj1(outfile, modeCompilerObj)
|
|
|
|
|
dumpobj1(linkobj, modeLinkerObj)
|
2016-04-26 21:50:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dumpobj1(outfile string, mode int) {
|
2015-02-13 14:40:36 -05:00
|
|
|
var err error
|
2016-04-06 21:45:29 -07:00
|
|
|
bout, err = bio.Create(outfile)
|
2015-02-13 14:40:36 -05:00
|
|
|
if err != nil {
|
2016-09-15 15:45:10 +10:00
|
|
|
flusherrors()
|
2015-02-13 14:40:36 -05:00
|
|
|
fmt.Printf("can't create %s: %v\n", outfile, err)
|
|
|
|
|
errorexit()
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
startobj := int64(0)
|
|
|
|
|
var arhdr [ArhdrSize]byte
|
2016-04-13 18:37:18 -07:00
|
|
|
if writearchive {
|
2016-04-06 21:45:29 -07:00
|
|
|
bout.WriteString("!<arch>\n")
|
2015-02-13 14:40:36 -05:00
|
|
|
arhdr = [ArhdrSize]byte{}
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Write(arhdr[:])
|
2016-04-08 19:14:03 +10:00
|
|
|
startobj = bout.Offset()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-26 21:50:59 -04:00
|
|
|
printheader := func() {
|
2016-09-09 08:13:16 -04:00
|
|
|
fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.GOOS, obj.GOARCH, obj.Version, obj.Expstring())
|
2016-04-26 21:50:59 -04:00
|
|
|
if buildid != "" {
|
|
|
|
|
fmt.Fprintf(bout, "build id %q\n", buildid)
|
|
|
|
|
}
|
|
|
|
|
if localpkg.Name == "main" {
|
|
|
|
|
fmt.Fprintf(bout, "main\n")
|
|
|
|
|
}
|
|
|
|
|
if safemode {
|
|
|
|
|
fmt.Fprintf(bout, "safe\n")
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Fprintf(bout, "----\n") // room for some other tool to write "safe"
|
|
|
|
|
}
|
|
|
|
|
fmt.Fprintf(bout, "\n") // header ends with blank line
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printheader()
|
|
|
|
|
|
|
|
|
|
if mode&modeCompilerObj != 0 {
|
|
|
|
|
dumpexport()
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-13 18:37:18 -07:00
|
|
|
if writearchive {
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Flush()
|
2016-04-08 19:14:03 +10:00
|
|
|
size := bout.Offset() - startobj
|
2015-02-13 14:40:36 -05:00
|
|
|
if size&1 != 0 {
|
2016-04-06 21:45:29 -07:00
|
|
|
bout.WriteByte(0)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-04-08 19:14:03 +10:00
|
|
|
bout.Seek(startobj-ArhdrSize, 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
formathdr(arhdr[:], "__.PKGDEF", size)
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Write(arhdr[:])
|
|
|
|
|
bout.Flush()
|
2016-04-08 19:14:03 +10:00
|
|
|
bout.Seek(startobj+size+(size&1), 0)
|
2016-04-26 21:50:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if mode&modeLinkerObj == 0 {
|
|
|
|
|
bout.Close()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if writearchive {
|
|
|
|
|
// start object file
|
2015-02-13 14:40:36 -05:00
|
|
|
arhdr = [ArhdrSize]byte{}
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Write(arhdr[:])
|
2016-04-08 19:14:03 +10:00
|
|
|
startobj = bout.Offset()
|
2016-04-26 21:50:59 -04:00
|
|
|
printheader()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if pragcgobuf != "" {
|
2016-04-13 18:37:18 -07:00
|
|
|
if writearchive {
|
2015-02-13 14:40:36 -05:00
|
|
|
// write empty export section; must be before cgo section
|
|
|
|
|
fmt.Fprintf(bout, "\n$$\n\n$$\n\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(bout, "\n$$ // cgo\n")
|
|
|
|
|
fmt.Fprintf(bout, "%s\n$$\n\n", pragcgobuf)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(bout, "\n!\n")
|
|
|
|
|
|
2015-09-10 15:57:39 +10:00
|
|
|
externs := len(externdcl)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
dumpglobls()
|
2016-08-25 20:29:15 -04:00
|
|
|
dumpptabs()
|
2015-02-13 14:40:36 -05:00
|
|
|
dumptypestructs()
|
|
|
|
|
|
|
|
|
|
// Dump extra globals.
|
2015-02-23 16:07:24 -05:00
|
|
|
tmp := externdcl
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-09-10 15:57:39 +10:00
|
|
|
if externdcl != nil {
|
|
|
|
|
externdcl = externdcl[externs:]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
dumpglobls()
|
|
|
|
|
externdcl = tmp
|
|
|
|
|
|
2016-04-19 08:31:04 -07:00
|
|
|
if zerosize > 0 {
|
2017-03-30 13:19:18 -07:00
|
|
|
zero := mappkg.Lookup("zero")
|
2016-04-19 08:31:04 -07:00
|
|
|
ggloblsym(zero, int32(zerosize), obj.DUPOK|obj.RODATA)
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-14 06:35:53 -07:00
|
|
|
addGCLocals()
|
|
|
|
|
|
2017-02-17 16:52:16 -05:00
|
|
|
obj.WriteObjFile(Ctxt, bout.Writer)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-13 18:37:18 -07:00
|
|
|
if writearchive {
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Flush()
|
2016-04-08 19:14:03 +10:00
|
|
|
size := bout.Offset() - startobj
|
2015-02-13 14:40:36 -05:00
|
|
|
if size&1 != 0 {
|
2016-04-06 21:45:29 -07:00
|
|
|
bout.WriteByte(0)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-04-08 19:14:03 +10:00
|
|
|
bout.Seek(startobj-ArhdrSize, 0)
|
2015-05-21 13:28:17 -04:00
|
|
|
formathdr(arhdr[:], "_go_.o", size)
|
2015-05-01 11:51:47 +10:00
|
|
|
bout.Write(arhdr[:])
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-06 21:45:29 -07:00
|
|
|
bout.Close()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-25 20:29:15 -04:00
|
|
|
func dumpptabs() {
|
|
|
|
|
if !Ctxt.Flag_dynlink || localpkg.Name != "main" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
for _, exportn := range exportlist {
|
|
|
|
|
s := exportn.Sym
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
n := asNode(s.Def)
|
2016-08-25 20:29:15 -04:00
|
|
|
if n == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if n.Op != ONAME {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if !exportname(s.Name) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if s.Pkg.Name != "main" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if n.Type.Etype == TFUNC && n.Class == PFUNC {
|
|
|
|
|
// function
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
ptabs = append(ptabs, ptabEntry{s: s, t: asNode(s.Def).Type})
|
2016-08-25 20:29:15 -04:00
|
|
|
} else {
|
|
|
|
|
// variable
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(asNode(s.Def).Type)})
|
2016-08-25 20:29:15 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
func dumpglobls() {
|
|
|
|
|
// add globals
|
2015-09-10 15:57:39 +10:00
|
|
|
for _, n := range externdcl {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Op != ONAME {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Type == nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("external %v nil type\n", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
if n.Class == PFUNC {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if n.Sym.Pkg != localpkg {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
dowidth(n.Type)
|
|
|
|
|
ggloblnod(n)
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 11:33:29 -07:00
|
|
|
for _, s := range funcsyms {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
sf := s.Pkg.Lookup(funcsymname(s))
|
2017-03-24 11:33:29 -07:00
|
|
|
dsymptr(sf, 0, s, 0)
|
|
|
|
|
ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not reprocess funcsyms on next dumpglobls call.
|
|
|
|
|
funcsyms = nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-14 06:35:53 -07:00
|
|
|
// addGCLocals adds gcargs and gclocals symbols to Ctxt.Data.
|
|
|
|
|
// It takes care not to add any duplicates.
|
|
|
|
|
// Though the object file format handles duplicates efficiently,
|
|
|
|
|
// storing only a single copy of the data,
|
|
|
|
|
// failure to remove these duplicates adds a few percent to object file size.
|
|
|
|
|
func addGCLocals() {
|
|
|
|
|
seen := make(map[string]bool)
|
|
|
|
|
for _, s := range Ctxt.Text {
|
2017-04-18 10:18:34 -07:00
|
|
|
if s.Func == nil {
|
2017-04-14 06:35:53 -07:00
|
|
|
continue
|
|
|
|
|
}
|
2017-04-18 10:18:34 -07:00
|
|
|
for _, gcsym := range []*obj.LSym{&s.Func.GCArgs, &s.Func.GCLocals} {
|
2017-04-14 06:35:53 -07:00
|
|
|
if seen[gcsym.Name] {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
Ctxt.Data = append(Ctxt.Data, gcsym)
|
|
|
|
|
seen[gcsym.Name] = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-13 06:31:05 -07:00
|
|
|
func linksymname(s *types.Sym) string {
|
|
|
|
|
if isblanksym(s) {
|
|
|
|
|
return "_"
|
|
|
|
|
}
|
|
|
|
|
if s.Linkname != "" {
|
|
|
|
|
return s.Linkname
|
|
|
|
|
}
|
|
|
|
|
return s.Pkg.Prefix + "." + s.Name
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func Linksym(s *types.Sym) *obj.LSym {
|
2015-02-13 14:40:36 -05:00
|
|
|
if s == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2017-04-13 06:31:05 -07:00
|
|
|
if s.Lsym == nil {
|
|
|
|
|
s.Lsym = Ctxt.Lookup(linksymname(s), 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-04-13 06:31:05 -07:00
|
|
|
return s.Lsym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func duintxx(s *types.Sym, off int, v uint64, wid int) int {
|
2016-03-16 22:22:58 -07:00
|
|
|
return duintxxLSym(Linksym(s), off, v, wid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func duintxxLSym(s *obj.LSym, off int, v uint64, wid int) int {
|
2017-04-16 08:11:38 -07:00
|
|
|
if s.Type == 0 {
|
|
|
|
|
// TODO(josharian): Do this in obj.prepwrite instead.
|
|
|
|
|
s.Type = obj.SDATA
|
|
|
|
|
}
|
|
|
|
|
if off&(wid-1) != 0 {
|
|
|
|
|
Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
|
|
|
|
|
}
|
|
|
|
|
s.WriteInt(Ctxt, int64(off), wid, int64(v))
|
|
|
|
|
return off + wid
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func duint8(s *types.Sym, off int, v uint8) int {
|
2015-02-13 14:40:36 -05:00
|
|
|
return duintxx(s, off, uint64(v), 1)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func duint16(s *types.Sym, off int, v uint16) int {
|
2015-02-13 14:40:36 -05:00
|
|
|
return duintxx(s, off, uint64(v), 2)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func duint32(s *types.Sym, off int, v uint32) int {
|
2015-02-13 14:40:36 -05:00
|
|
|
return duintxx(s, off, uint64(v), 4)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func duintptr(s *types.Sym, off int, v uint64) int {
|
2015-02-13 14:40:36 -05:00
|
|
|
return duintxx(s, off, v, Widthptr)
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-14 06:35:53 -07:00
|
|
|
func duint8LSym(s *obj.LSym, off int, v uint8) int {
|
|
|
|
|
return duintxxLSym(s, off, uint64(v), 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func duint32LSym(s *obj.LSym, off int, v uint32) int {
|
|
|
|
|
return duintxxLSym(s, off, uint64(v), 4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dbvecLSym(s *obj.LSym, off int, bv bvec) int {
|
2016-10-11 11:34:20 -07:00
|
|
|
// Runtime reads the bitmaps as byte arrays. Oblige.
|
|
|
|
|
for j := 0; int32(j) < bv.n; j += 8 {
|
2016-10-11 10:23:14 -07:00
|
|
|
word := bv.b[j/32]
|
2017-04-14 06:35:53 -07:00
|
|
|
off = duint8LSym(s, off, uint8(word>>(uint(j)%32)))
|
2016-10-11 10:23:14 -07:00
|
|
|
}
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-13 22:31:46 +03:00
|
|
|
func stringsym(s string) (data *obj.LSym) {
|
2015-03-06 12:02:24 -08:00
|
|
|
var symname string
|
2015-02-13 14:40:36 -05:00
|
|
|
if len(s) > 100 {
|
2016-03-10 11:14:22 -08:00
|
|
|
// Huge strings are hashed to avoid long names in object files.
|
|
|
|
|
// Indulge in some paranoia by writing the length of s, too,
|
|
|
|
|
// as protection against length extension attacks.
|
|
|
|
|
h := sha256.New()
|
|
|
|
|
io.WriteString(h, s)
|
|
|
|
|
symname = fmt.Sprintf(".gostring.%d.%x", len(s), h.Sum(nil))
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2016-03-10 11:14:22 -08:00
|
|
|
// Small strings get named directly by their contents.
|
2015-03-12 18:45:30 -04:00
|
|
|
symname = strconv.Quote(s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-16 22:22:58 -07:00
|
|
|
const prefix = "go.string."
|
|
|
|
|
symdataname := prefix + symname
|
|
|
|
|
|
2017-04-06 09:54:14 -07:00
|
|
|
symdata := Ctxt.Lookup(symdataname, 0)
|
2016-03-16 22:22:58 -07:00
|
|
|
|
2016-10-24 23:15:41 +03:00
|
|
|
if !symdata.SeenGlobl() {
|
2016-10-13 22:31:46 +03:00
|
|
|
// string data
|
|
|
|
|
off := dsnameLSym(symdata, 0, s)
|
|
|
|
|
ggloblLSym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-10-13 22:31:46 +03:00
|
|
|
return symdata
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var slicebytes_gen int
|
|
|
|
|
|
|
|
|
|
func slicebytes(nam *Node, s string, len int) {
|
|
|
|
|
slicebytes_gen++
|
2015-03-06 12:02:24 -08:00
|
|
|
symname := fmt.Sprintf(".gobytes.%d", slicebytes_gen)
|
2017-03-30 13:19:18 -07:00
|
|
|
sym := localpkg.Lookup(symname)
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
sym.Def = asTypesNode(newname(sym))
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-11 18:54:37 -08:00
|
|
|
off := dsname(sym, 0, s)
|
2015-04-18 08:14:08 +12:00
|
|
|
ggloblsym(sym, int32(off), obj.NOPTR|obj.LOCAL)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if nam.Op != ONAME {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("slicebytes %v", nam)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
off = int(nam.Xoffset)
|
|
|
|
|
off = dsymptr(nam.Sym, off, sym, 0)
|
|
|
|
|
off = duintxx(nam.Sym, off, uint64(len), Widthint)
|
|
|
|
|
duintxx(nam.Sym, off, uint64(len), Widthint)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func dsname(s *types.Sym, off int, t string) int {
|
2016-03-16 22:22:58 -07:00
|
|
|
return dsnameLSym(Linksym(s), off, t)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dsnameLSym(s *obj.LSym, off int, t string) int {
|
|
|
|
|
s.WriteString(Ctxt, int64(off), len(t), t)
|
2015-02-13 14:40:36 -05:00
|
|
|
return off + len(t)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func dsymptr(s *types.Sym, off int, x *types.Sym, xoff int) int {
|
2016-03-16 22:22:58 -07:00
|
|
|
return dsymptrLSym(Linksym(s), off, Linksym(x), xoff)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dsymptrLSym(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
|
2015-02-13 14:40:36 -05:00
|
|
|
off = int(Rnd(int64(off), int64(Widthptr)))
|
2016-03-16 22:22:58 -07:00
|
|
|
s.WriteAddr(Ctxt, int64(off), Widthptr, x, int64(xoff))
|
2015-02-13 14:40:36 -05:00
|
|
|
off += Widthptr
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-27 10:21:48 -04:00
|
|
|
func dsymptrOffLSym(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
|
|
|
|
|
s.WriteOff(Ctxt, int64(off), x, int64(xoff))
|
|
|
|
|
off += 4
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-21 16:58:55 -05:00
|
|
|
func dsymptrWeakOffLSym(s *obj.LSym, off int, x *obj.LSym) int {
|
|
|
|
|
s.WriteWeakOff(Ctxt, int64(off), x, 0)
|
|
|
|
|
off += 4
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
func gdata(nam *Node, nr *Node, wid int) {
|
2016-03-13 12:16:43 -07:00
|
|
|
if nam.Op != ONAME {
|
2016-04-22 07:14:10 -07:00
|
|
|
Fatalf("gdata nam op %v", nam.Op)
|
2016-03-13 12:16:43 -07:00
|
|
|
}
|
|
|
|
|
if nam.Sym == nil {
|
|
|
|
|
Fatalf("gdata nil nam sym")
|
|
|
|
|
}
|
2016-10-19 13:13:31 -07:00
|
|
|
s := Linksym(nam.Sym)
|
2016-03-13 12:16:43 -07:00
|
|
|
|
|
|
|
|
switch nr.Op {
|
|
|
|
|
case OLITERAL:
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := nr.Val().U.(type) {
|
|
|
|
|
case bool:
|
|
|
|
|
i := int64(obj.Bool2int(u))
|
2016-10-19 13:13:31 -07:00
|
|
|
s.WriteInt(Ctxt, nam.Xoffset, wid, i)
|
2016-03-13 12:16:43 -07:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpint:
|
2016-10-19 13:13:31 -07:00
|
|
|
s.WriteInt(Ctxt, nam.Xoffset, wid, u.Int64())
|
2016-04-22 12:27:29 -07:00
|
|
|
|
|
|
|
|
case *Mpflt:
|
|
|
|
|
f := u.Float64()
|
2016-03-13 12:16:43 -07:00
|
|
|
switch nam.Type.Etype {
|
|
|
|
|
case TFLOAT32:
|
|
|
|
|
s.WriteFloat32(Ctxt, nam.Xoffset, float32(f))
|
|
|
|
|
case TFLOAT64:
|
|
|
|
|
s.WriteFloat64(Ctxt, nam.Xoffset, f)
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-19 13:13:31 -07:00
|
|
|
case *Mpcplx:
|
|
|
|
|
r := u.Real.Float64()
|
|
|
|
|
i := u.Imag.Float64()
|
|
|
|
|
switch nam.Type.Etype {
|
|
|
|
|
case TCOMPLEX64:
|
|
|
|
|
s.WriteFloat32(Ctxt, nam.Xoffset, float32(r))
|
|
|
|
|
s.WriteFloat32(Ctxt, nam.Xoffset+4, float32(i))
|
|
|
|
|
case TCOMPLEX128:
|
|
|
|
|
s.WriteFloat64(Ctxt, nam.Xoffset, r)
|
|
|
|
|
s.WriteFloat64(Ctxt, nam.Xoffset+8, i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case string:
|
|
|
|
|
symdata := stringsym(u)
|
|
|
|
|
s.WriteAddr(Ctxt, nam.Xoffset, Widthptr, symdata, 0)
|
|
|
|
|
s.WriteInt(Ctxt, nam.Xoffset+int64(Widthptr), Widthint, int64(len(u)))
|
|
|
|
|
|
2016-03-13 12:16:43 -07:00
|
|
|
default:
|
|
|
|
|
Fatalf("gdata unhandled OLITERAL %v", nr)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-13 12:16:43 -07:00
|
|
|
case OADDR:
|
|
|
|
|
if nr.Left.Op != ONAME {
|
2016-09-09 21:08:46 -07:00
|
|
|
Fatalf("gdata ADDR left op %v", nr.Left.Op)
|
2016-03-13 12:16:43 -07:00
|
|
|
}
|
|
|
|
|
to := nr.Left
|
2016-10-19 13:13:31 -07:00
|
|
|
s.WriteAddr(Ctxt, nam.Xoffset, wid, Linksym(to.Sym), to.Xoffset)
|
2016-03-13 12:16:43 -07:00
|
|
|
|
|
|
|
|
case ONAME:
|
|
|
|
|
if nr.Class != PFUNC {
|
|
|
|
|
Fatalf("gdata NAME not PFUNC %d", nr.Class)
|
|
|
|
|
}
|
2016-10-19 13:13:31 -07:00
|
|
|
s.WriteAddr(Ctxt, nam.Xoffset, wid, Linksym(funcsym(nr.Sym)), nr.Xoffset)
|
2016-03-13 12:16:43 -07:00
|
|
|
|
|
|
|
|
default:
|
2016-04-22 07:14:10 -07:00
|
|
|
Fatalf("gdata unhandled op %v %v\n", nr, nr.Op)
|
2016-03-13 12:16:43 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|