diff options
author | Wim <wim@42.be> | 2018-08-06 21:47:05 +0200 |
---|---|---|
committer | Wim <wim@42.be> | 2018-08-06 21:47:05 +0200 |
commit | 51062863a5c34d81e296cf15c61140911037cf3b (patch) | |
tree | 9b5e044672486326c7a0ca8fb26430f37bf4d83c /vendor/github.com/google/gops/internal/obj/objfile.go | |
parent | 4fb4b7aa6c02a54db8ad8dd98e4d321396926c0d (diff) | |
download | matterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.tar.gz matterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.tar.bz2 matterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.zip |
Use mod vendor for vendored directory (backwards compatible)
Diffstat (limited to 'vendor/github.com/google/gops/internal/obj/objfile.go')
-rw-r--r-- | vendor/github.com/google/gops/internal/obj/objfile.go | 606 |
1 files changed, 0 insertions, 606 deletions
diff --git a/vendor/github.com/google/gops/internal/obj/objfile.go b/vendor/github.com/google/gops/internal/obj/objfile.go deleted file mode 100644 index 8a897f09..00000000 --- a/vendor/github.com/google/gops/internal/obj/objfile.go +++ /dev/null @@ -1,606 +0,0 @@ -// 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. - -// Writing of Go object files. -// -// Originally, Go object files were Plan 9 object files, but no longer. -// Now they are more like standard object files, in that each symbol is defined -// by an associated memory image (bytes) and a list of relocations to apply -// during linking. We do not (yet?) use a standard file format, however. -// For now, the format is chosen to be as simple as possible to read and write. -// It may change for reasons of efficiency, or we may even switch to a -// standard file format if there are compelling benefits to doing so. -// See golang.org/s/go13linker for more background. -// -// The file format is: -// -// - magic header: "\x00\x00go17ld" -// - byte 1 - version number -// - sequence of strings giving dependencies (imported packages) -// - empty string (marks end of sequence) -// - sequence of symbol references used by the defined symbols -// - byte 0xff (marks end of sequence) -// - sequence of integer lengths: -// - total data length -// - total number of relocations -// - total number of pcdata -// - total number of automatics -// - total number of funcdata -// - total number of files -// - data, the content of the defined symbols -// - sequence of defined symbols -// - byte 0xff (marks end of sequence) -// - magic footer: "\xff\xffgo17ld" -// -// All integers are stored in a zigzag varint format. -// See golang.org/s/go12symtab for a definition. -// -// Data blocks and strings are both stored as an integer -// followed by that many bytes. -// -// A symbol reference is a string name followed by a version. -// -// A symbol points to other symbols using an index into the symbol -// reference sequence. Index 0 corresponds to a nil LSym* pointer. -// In the symbol layout described below "symref index" stands for this -// index. -// -// Each symbol is laid out as the following fields (taken from LSym*): -// -// - byte 0xfe (sanity check for synchronization) -// - type [int] -// - name & version [symref index] -// - flags [int] -// 1<<0 dupok -// 1<<1 local -// 1<<2 add to typelink table -// - size [int] -// - gotype [symref index] -// - p [data block] -// - nr [int] -// - r [nr relocations, sorted by off] -// -// If type == STEXT, there are a few more fields: -// -// - args [int] -// - locals [int] -// - nosplit [int] -// - flags [int] -// 1<<0 leaf -// 1<<1 C function -// 1<<2 function may call reflect.Type.Method -// - nlocal [int] -// - local [nlocal automatics] -// - pcln [pcln table] -// -// Each relocation has the encoding: -// -// - off [int] -// - siz [int] -// - type [int] -// - add [int] -// - sym [symref index] -// -// Each local has the encoding: -// -// - asym [symref index] -// - offset [int] -// - type [int] -// - gotype [symref index] -// -// The pcln table has the encoding: -// -// - pcsp [data block] -// - pcfile [data block] -// - pcline [data block] -// - npcdata [int] -// - pcdata [npcdata data blocks] -// - nfuncdata [int] -// - funcdata [nfuncdata symref index] -// - funcdatasym [nfuncdata ints] -// - nfile [int] -// - file [nfile symref index] -// -// The file layout and meaning of type integers are architecture-independent. -// -// TODO(rsc): The file format is good for a first pass but needs work. -// - There are SymID in the object file that should really just be strings. - -package obj - -import ( - "bufio" - "fmt" - "log" - "path/filepath" - "sort" - - "github.com/google/gops/internal/dwarf" - "github.com/google/gops/internal/sys" -) - -// The Go and C compilers, and the assembler, call writeobj to write -// out a Go object file. The linker does not call this; the linker -// does not write out object files. -func Writeobjdirect(ctxt *Link, b *bufio.Writer) { - Flushplist(ctxt) - WriteObjFile(ctxt, b) -} - -// objWriter writes Go object files. -type objWriter struct { - wr *bufio.Writer - ctxt *Link - // Temporary buffer for zigzag int writing. - varintbuf [10]uint8 - - // Provide the the index of a symbol reference by symbol name. - // One map for versioned symbols and one for unversioned symbols. - // Used for deduplicating the symbol reference list. - refIdx map[string]int - vrefIdx map[string]int - - // Number of objects written of each type. - nRefs int - nData int - nReloc int - nPcdata int - nAutom int - nFuncdata int - nFile int -} - -func (w *objWriter) addLengths(s *LSym) { - w.nData += len(s.P) - w.nReloc += len(s.R) - - if s.Type != STEXT { - return - } - - pc := s.Pcln - - data := 0 - data += len(pc.Pcsp.P) - data += len(pc.Pcfile.P) - data += len(pc.Pcline.P) - for i := 0; i < len(pc.Pcdata); i++ { - data += len(pc.Pcdata[i].P) - } - - w.nData += data - w.nPcdata += len(pc.Pcdata) - - autom := 0 - for a := s.Autom; a != nil; a = a.Link { - autom++ - } - w.nAutom += autom - w.nFuncdata += len(pc.Funcdataoff) - w.nFile += len(pc.File) -} - -func (w *objWriter) writeLengths() { - w.writeInt(int64(w.nData)) - w.writeInt(int64(w.nReloc)) - w.writeInt(int64(w.nPcdata)) - w.writeInt(int64(w.nAutom)) - w.writeInt(int64(w.nFuncdata)) - w.writeInt(int64(w.nFile)) -} - -func newObjWriter(ctxt *Link, b *bufio.Writer) *objWriter { - return &objWriter{ - ctxt: ctxt, - wr: b, - vrefIdx: make(map[string]int), - refIdx: make(map[string]int), - } -} - -func WriteObjFile(ctxt *Link, b *bufio.Writer) { - w := newObjWriter(ctxt, b) - - // Magic header - w.wr.WriteString("\x00\x00go17ld") - - // Version - w.wr.WriteByte(1) - - // Autolib - for _, pkg := range ctxt.Imports { - w.writeString(pkg) - } - w.writeString("") - - // Symbol references - for _, s := range ctxt.Text { - w.writeRefs(s) - w.addLengths(s) - } - for _, s := range ctxt.Data { - w.writeRefs(s) - w.addLengths(s) - } - // End symbol references - w.wr.WriteByte(0xff) - - // Lengths - w.writeLengths() - - // Data block - for _, s := range ctxt.Text { - w.wr.Write(s.P) - pc := s.Pcln - w.wr.Write(pc.Pcsp.P) - w.wr.Write(pc.Pcfile.P) - w.wr.Write(pc.Pcline.P) - for i := 0; i < len(pc.Pcdata); i++ { - w.wr.Write(pc.Pcdata[i].P) - } - } - for _, s := range ctxt.Data { - w.wr.Write(s.P) - } - - // Symbols - for _, s := range ctxt.Text { - w.writeSym(s) - } - for _, s := range ctxt.Data { - w.writeSym(s) - } - - // Magic footer - w.wr.WriteString("\xff\xffgo17ld") -} - -// Symbols are prefixed so their content doesn't get confused with the magic footer. -const symPrefix = 0xfe - -func (w *objWriter) writeRef(s *LSym, isPath bool) { - if s == nil || s.RefIdx != 0 { - return - } - var m map[string]int - switch s.Version { - case 0: - m = w.refIdx - case 1: - m = w.vrefIdx - default: - log.Fatalf("%s: invalid version number %d", s.Name, s.Version) - } - - idx := m[s.Name] - if idx != 0 { - s.RefIdx = idx - return - } - w.wr.WriteByte(symPrefix) - if isPath { - w.writeString(filepath.ToSlash(s.Name)) - } else { - w.writeString(s.Name) - } - w.writeInt(int64(s.Version)) - w.nRefs++ - s.RefIdx = w.nRefs - m[s.Name] = w.nRefs -} - -func (w *objWriter) writeRefs(s *LSym) { - w.writeRef(s, false) - w.writeRef(s.Gotype, false) - for i := range s.R { - w.writeRef(s.R[i].Sym, false) - } - - if s.Type == STEXT { - for a := s.Autom; a != nil; a = a.Link { - w.writeRef(a.Asym, false) - w.writeRef(a.Gotype, false) - } - pc := s.Pcln - for _, d := range pc.Funcdata { - w.writeRef(d, false) - } - for _, f := range pc.File { - w.writeRef(f, true) - } - } -} - -func (w *objWriter) writeSymDebug(s *LSym) { - ctxt := w.ctxt - fmt.Fprintf(ctxt.Bso, "%s ", s.Name) - if s.Version != 0 { - fmt.Fprintf(ctxt.Bso, "v=%d ", s.Version) - } - if s.Type != 0 { - fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type) - } - if s.DuplicateOK() { - fmt.Fprintf(ctxt.Bso, "dupok ") - } - if s.CFunc() { - fmt.Fprintf(ctxt.Bso, "cfunc ") - } - if s.NoSplit() { - fmt.Fprintf(ctxt.Bso, "nosplit ") - } - fmt.Fprintf(ctxt.Bso, "size=%d", s.Size) - if s.Type == STEXT { - fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals)) - if s.Leaf() { - fmt.Fprintf(ctxt.Bso, " leaf") - } - } - - fmt.Fprintf(ctxt.Bso, "\n") - for p := s.Text; p != nil; p = p.Link { - fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p) - } - var c int - var j int - for i := 0; i < len(s.P); { - fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i)) - for j = i; j < i+16 && j < len(s.P); j++ { - fmt.Fprintf(ctxt.Bso, " %02x", s.P[j]) - } - for ; j < i+16; j++ { - fmt.Fprintf(ctxt.Bso, " ") - } - fmt.Fprintf(ctxt.Bso, " ") - for j = i; j < i+16 && j < len(s.P); j++ { - c = int(s.P[j]) - if ' ' <= c && c <= 0x7e { - fmt.Fprintf(ctxt.Bso, "%c", c) - } else { - fmt.Fprintf(ctxt.Bso, ".") - } - } - - fmt.Fprintf(ctxt.Bso, "\n") - i += 16 - } - - sort.Sort(relocByOff(s.R)) // generate stable output - for _, r := range s.R { - name := "" - if r.Sym != nil { - name = r.Sym.Name - } else if r.Type == R_TLS_LE { - name = "TLS" - } - if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add)) - } else { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add) - } - } -} - -func (w *objWriter) writeSym(s *LSym) { - ctxt := w.ctxt - if ctxt.Debugasm != 0 { - w.writeSymDebug(s) - } - - w.wr.WriteByte(symPrefix) - w.writeInt(int64(s.Type)) - w.writeRefIndex(s) - flags := int64(0) - if s.DuplicateOK() { - flags |= 1 - } - if s.Local() { - flags |= 1 << 1 - } - if s.MakeTypelink() { - flags |= 1 << 2 - } - w.writeInt(flags) - w.writeInt(s.Size) - w.writeRefIndex(s.Gotype) - w.writeInt(int64(len(s.P))) - - w.writeInt(int64(len(s.R))) - var r *Reloc - for i := 0; i < len(s.R); i++ { - r = &s.R[i] - w.writeInt(int64(r.Off)) - w.writeInt(int64(r.Siz)) - w.writeInt(int64(r.Type)) - w.writeInt(r.Add) - w.writeRefIndex(r.Sym) - } - - if s.Type != STEXT { - return - } - - w.writeInt(int64(s.Args)) - w.writeInt(int64(s.Locals)) - if s.NoSplit() { - w.writeInt(1) - } else { - w.writeInt(0) - } - flags = int64(0) - if s.Leaf() { - flags |= 1 - } - if s.CFunc() { - flags |= 1 << 1 - } - if s.ReflectMethod() { - flags |= 1 << 2 - } - w.writeInt(flags) - n := 0 - for a := s.Autom; a != nil; a = a.Link { - n++ - } - w.writeInt(int64(n)) - for a := s.Autom; a != nil; a = a.Link { - w.writeRefIndex(a.Asym) - w.writeInt(int64(a.Aoffset)) - if a.Name == NAME_AUTO { - w.writeInt(A_AUTO) - } else if a.Name == NAME_PARAM { - w.writeInt(A_PARAM) - } else { - log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name) - } - w.writeRefIndex(a.Gotype) - } - - pc := s.Pcln - w.writeInt(int64(len(pc.Pcsp.P))) - w.writeInt(int64(len(pc.Pcfile.P))) - w.writeInt(int64(len(pc.Pcline.P))) - w.writeInt(int64(len(pc.Pcdata))) - for i := 0; i < len(pc.Pcdata); i++ { - w.writeInt(int64(len(pc.Pcdata[i].P))) - } - w.writeInt(int64(len(pc.Funcdataoff))) - for i := 0; i < len(pc.Funcdataoff); i++ { - w.writeRefIndex(pc.Funcdata[i]) - } - for i := 0; i < len(pc.Funcdataoff); i++ { - w.writeInt(pc.Funcdataoff[i]) - } - w.writeInt(int64(len(pc.File))) - for _, f := range pc.File { - w.writeRefIndex(f) - } -} - -func (w *objWriter) writeInt(sval int64) { - var v uint64 - uv := (uint64(sval) << 1) ^ uint64(sval>>63) - p := w.varintbuf[:] - for v = uv; v >= 0x80; v >>= 7 { - p[0] = uint8(v | 0x80) - p = p[1:] - } - p[0] = uint8(v) - p = p[1:] - w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)]) -} - -func (w *objWriter) writeString(s string) { - w.writeInt(int64(len(s))) - w.wr.WriteString(s) -} - -func (w *objWriter) writeRefIndex(s *LSym) { - if s == nil { - w.writeInt(0) - return - } - if s.RefIdx == 0 { - log.Fatalln("writing an unreferenced symbol", s.Name) - } - w.writeInt(int64(s.RefIdx)) -} - -// relocByOff sorts relocations by their offsets. -type relocByOff []Reloc - -func (x relocByOff) Len() int { return len(x) } -func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off } -func (x relocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -// implement dwarf.Context -type dwCtxt struct{ *Link } - -func (c dwCtxt) PtrSize() int { - return c.Arch.PtrSize -} -func (c dwCtxt) AddInt(s dwarf.Sym, size int, i int64) { - ls := s.(*LSym) - ls.WriteInt(c.Link, ls.Size, size, i) -} -func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) { - ls := s.(*LSym) - ls.WriteBytes(c.Link, ls.Size, b) -} -func (c dwCtxt) AddString(s dwarf.Sym, v string) { - ls := s.(*LSym) - ls.WriteString(c.Link, ls.Size, len(v), v) - ls.WriteInt(c.Link, ls.Size, 1, 0) -} -func (c dwCtxt) SymValue(s dwarf.Sym) int64 { - return 0 -} -func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { - rsym := data.(*LSym) - ls := s.(*LSym) - size := c.PtrSize() - ls.WriteAddr(c.Link, ls.Size, size, rsym, value) -} -func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { - ls := s.(*LSym) - rsym := t.(*LSym) - ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs) - r := &ls.R[len(ls.R)-1] - r.Type = R_DWARFREF -} - -func gendwarf(ctxt *Link, text []*LSym) []*LSym { - dctxt := dwCtxt{ctxt} - var dw []*LSym - - for _, s := range text { - dsym := Linklookup(ctxt, dwarf.InfoPrefix+s.Name, int(s.Version)) - if dsym.Size != 0 { - continue - } - dw = append(dw, dsym) - dsym.Type = SDWARFINFO - dsym.Set(AttrDuplicateOK, s.DuplicateOK()) - var vars dwarf.Var - var abbrev int - var offs int32 - for a := s.Autom; a != nil; a = a.Link { - switch a.Name { - case NAME_AUTO: - abbrev = dwarf.DW_ABRV_AUTO - offs = a.Aoffset - if ctxt.FixedFrameSize() == 0 { - offs -= int32(ctxt.Arch.PtrSize) - } - if Framepointer_enabled(GOOS, GOARCH) { - offs -= int32(ctxt.Arch.PtrSize) - } - - case NAME_PARAM: - abbrev = dwarf.DW_ABRV_PARAM - offs = a.Aoffset + int32(ctxt.FixedFrameSize()) - - default: - continue - } - typename := dwarf.InfoPrefix + a.Gotype.Name[len("type."):] - dwvar := &dwarf.Var{ - Name: a.Asym.Name, - Abbrev: abbrev, - Offset: int32(offs), - Type: Linklookup(ctxt, typename, 0), - } - dws := &vars.Link - for ; *dws != nil; dws = &(*dws).Link { - if offs <= (*dws).Offset { - break - } - } - dwvar.Link = *dws - *dws = dwvar - } - dwarf.PutFunc(dctxt, dsym, s.Name, s.Version == 0, s, s.Size, vars.Link) - } - return dw -} |