Home | History | Annotate | Download | only in obj
      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 }
    190