github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/cmd/internal/obj/plist.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package obj 6 7 import ( 8 "cmd/internal/objabi" 9 "fmt" 10 "strings" 11 ) 12 13 type Plist struct { 14 Firstpc *Prog 15 Curfn interface{} // holds a *gc.Node, if non-nil 16 } 17 18 // ProgAlloc is a function that allocates Progs. 19 // It is used to provide access to cached/bulk-allocated Progs to the assemblers. 20 type ProgAlloc func() *Prog 21 22 func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string) { 23 // Build list of symbols, and assign instructions to lists. 24 var curtext *LSym 25 var etext *Prog 26 var text []*LSym 27 28 var plink *Prog 29 for p := plist.Firstpc; p != nil; p = plink { 30 if ctxt.Debugasm && ctxt.Debugvlog { 31 fmt.Printf("obj: %v\n", p) 32 } 33 plink = p.Link 34 p.Link = nil 35 36 switch p.As { 37 case AEND: 38 continue 39 40 case ATEXT: 41 s := p.From.Sym 42 if s == nil { 43 // func _() { } 44 curtext = nil 45 continue 46 } 47 text = append(text, s) 48 etext = p 49 curtext = s 50 continue 51 52 case AFUNCDATA: 53 // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information. 54 if curtext == nil { // func _() {} 55 continue 56 } 57 if p.To.Sym.Name == "go_args_stackmap" { 58 if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_ArgsPointerMaps { 59 ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps") 60 } 61 p.To.Sym = ctxt.LookupDerived(curtext, curtext.Name+".args_stackmap") 62 } 63 64 } 65 66 if curtext == nil { 67 etext = nil 68 continue 69 } 70 etext.Link = p 71 etext = p 72 } 73 74 if newprog == nil { 75 newprog = ctxt.NewProg 76 } 77 78 // Add reference to Go arguments for C or assembly functions without them. 79 for _, s := range text { 80 if !strings.HasPrefix(s.Name, "\"\".") { 81 continue 82 } 83 found := false 84 for p := s.Func.Text; p != nil; p = p.Link { 85 if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == objabi.FUNCDATA_ArgsPointerMaps { 86 found = true 87 break 88 } 89 } 90 91 if !found { 92 p := Appendp(s.Func.Text, newprog) 93 p.As = AFUNCDATA 94 p.From.Type = TYPE_CONST 95 p.From.Offset = objabi.FUNCDATA_ArgsPointerMaps 96 p.To.Type = TYPE_MEM 97 p.To.Name = NAME_EXTERN 98 p.To.Sym = ctxt.LookupDerived(s, s.Name+".args_stackmap") 99 } 100 } 101 102 // Turn functions into machine code images. 103 for _, s := range text { 104 mkfwd(s) 105 linkpatch(ctxt, s, newprog) 106 ctxt.Arch.Preprocess(ctxt, s, newprog) 107 ctxt.Arch.Assemble(ctxt, s, newprog) 108 linkpcln(ctxt, s) 109 ctxt.populateDWARF(plist.Curfn, s, myimportpath) 110 } 111 } 112 113 func (ctxt *Link) InitTextSym(s *LSym, flag int) { 114 if s == nil { 115 // func _() { } 116 return 117 } 118 if s.Func != nil { 119 ctxt.Diag("InitTextSym double init for %s", s.Name) 120 } 121 s.Func = new(FuncInfo) 122 if s.Func.Text != nil { 123 ctxt.Diag("duplicate TEXT for %s", s.Name) 124 } 125 if s.OnList() { 126 ctxt.Diag("symbol %s listed multiple times", s.Name) 127 } 128 s.Set(AttrOnList, true) 129 s.Set(AttrDuplicateOK, flag&DUPOK != 0) 130 s.Set(AttrNoSplit, flag&NOSPLIT != 0) 131 s.Set(AttrReflectMethod, flag&REFLECTMETHOD != 0) 132 s.Set(AttrWrapper, flag&WRAPPER != 0) 133 s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0) 134 s.Set(AttrNoFrame, flag&NOFRAME != 0) 135 s.Type = objabi.STEXT 136 ctxt.Text = append(ctxt.Text, s) 137 138 // Set up DWARF entries for s. 139 info, loc, ranges, _ := ctxt.dwarfSym(s) 140 info.Type = objabi.SDWARFINFO 141 info.Set(AttrDuplicateOK, s.DuplicateOK()) 142 if loc != nil { 143 loc.Type = objabi.SDWARFLOC 144 loc.Set(AttrDuplicateOK, s.DuplicateOK()) 145 ctxt.Data = append(ctxt.Data, loc) 146 } 147 ranges.Type = objabi.SDWARFRANGE 148 ranges.Set(AttrDuplicateOK, s.DuplicateOK()) 149 ctxt.Data = append(ctxt.Data, info, ranges) 150 151 // Set up the function's gcargs and gclocals. 152 // They will be filled in later if needed. 153 gcargs := &s.Func.GCArgs 154 gcargs.Set(AttrDuplicateOK, true) 155 gcargs.Type = objabi.SRODATA 156 gclocals := &s.Func.GCLocals 157 gclocals.Set(AttrDuplicateOK, true) 158 gclocals.Type = objabi.SRODATA 159 } 160 161 func (ctxt *Link) Globl(s *LSym, size int64, flag int) { 162 if s.SeenGlobl() { 163 fmt.Printf("duplicate %v\n", s) 164 } 165 s.Set(AttrSeenGlobl, true) 166 if s.OnList() { 167 ctxt.Diag("symbol %s listed multiple times", s.Name) 168 } 169 s.Set(AttrOnList, true) 170 ctxt.Data = append(ctxt.Data, s) 171 s.Size = size 172 if s.Type == 0 { 173 s.Type = objabi.SBSS 174 } 175 if flag&DUPOK != 0 { 176 s.Set(AttrDuplicateOK, true) 177 } 178 if flag&RODATA != 0 { 179 s.Type = objabi.SRODATA 180 } else if flag&NOPTR != 0 { 181 if s.Type == objabi.SDATA { 182 s.Type = objabi.SNOPTRDATA 183 } else { 184 s.Type = objabi.SNOPTRBSS 185 } 186 } else if flag&TLSBSS != 0 { 187 s.Type = objabi.STLSBSS 188 } 189 }