...

Source file src/cmd/internal/obj/sym.go

     1	// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
     2	// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
     3	// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
     4	//
     5	//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     6	//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     7	//	Portions Copyright © 1997-1999 Vita Nuova Limited
     8	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     9	//	Portions Copyright © 2004,2006 Bruce Ellis
    10	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    11	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    12	//	Portions Copyright © 2009 The Go Authors. All rights reserved.
    13	//
    14	// Permission is hereby granted, free of charge, to any person obtaining a copy
    15	// of this software and associated documentation files (the "Software"), to deal
    16	// in the Software without restriction, including without limitation the rights
    17	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    18	// copies of the Software, and to permit persons to whom the Software is
    19	// furnished to do so, subject to the following conditions:
    20	//
    21	// The above copyright notice and this permission notice shall be included in
    22	// all copies or substantial portions of the Software.
    23	//
    24	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    25	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    26	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    27	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    28	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    29	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    30	// THE SOFTWARE.
    31	
    32	package obj
    33	
    34	import (
    35		"cmd/internal/objabi"
    36		"fmt"
    37		"log"
    38		"math"
    39	)
    40	
    41	func Linknew(arch *LinkArch) *Link {
    42		ctxt := new(Link)
    43		ctxt.hash = make(map[string]*LSym)
    44		ctxt.funchash = make(map[string]*LSym)
    45		ctxt.statichash = make(map[string]*LSym)
    46		ctxt.Arch = arch
    47		ctxt.Pathname = objabi.WorkingDir()
    48	
    49		if err := ctxt.Headtype.Set(objabi.GOOS); err != nil {
    50			log.Fatalf("unknown goos %s", objabi.GOOS)
    51		}
    52	
    53		ctxt.Flag_optimize = true
    54		ctxt.Framepointer_enabled = objabi.Framepointer_enabled(objabi.GOOS, arch.Name)
    55		return ctxt
    56	}
    57	
    58	// LookupDerived looks up or creates the symbol with name name derived from symbol s.
    59	// The resulting symbol will be static iff s is.
    60	func (ctxt *Link) LookupDerived(s *LSym, name string) *LSym {
    61		if s.Static() {
    62			return ctxt.LookupStatic(name)
    63		}
    64		return ctxt.Lookup(name)
    65	}
    66	
    67	// LookupStatic looks up the static symbol with name name.
    68	// If it does not exist, it creates it.
    69	func (ctxt *Link) LookupStatic(name string) *LSym {
    70		s := ctxt.statichash[name]
    71		if s == nil {
    72			s = &LSym{Name: name, Attribute: AttrStatic}
    73			ctxt.statichash[name] = s
    74		}
    75		return s
    76	}
    77	
    78	// LookupABI looks up a symbol with the given ABI.
    79	// If it does not exist, it creates it.
    80	func (ctxt *Link) LookupABI(name string, abi ABI) *LSym {
    81		var hash map[string]*LSym
    82		switch abi {
    83		case ABI0:
    84			hash = ctxt.hash
    85		case ABIInternal:
    86			hash = ctxt.funchash
    87		default:
    88			panic("unknown ABI")
    89		}
    90	
    91		ctxt.hashmu.Lock()
    92		s := hash[name]
    93		if s == nil {
    94			s = &LSym{Name: name}
    95			s.SetABI(abi)
    96			hash[name] = s
    97		}
    98		ctxt.hashmu.Unlock()
    99		return s
   100	}
   101	
   102	// Lookup looks up the symbol with name name.
   103	// If it does not exist, it creates it.
   104	func (ctxt *Link) Lookup(name string) *LSym {
   105		return ctxt.LookupInit(name, nil)
   106	}
   107	
   108	// LookupInit looks up the symbol with name name.
   109	// If it does not exist, it creates it and
   110	// passes it to init for one-time initialization.
   111	func (ctxt *Link) LookupInit(name string, init func(s *LSym)) *LSym {
   112		ctxt.hashmu.Lock()
   113		s := ctxt.hash[name]
   114		if s == nil {
   115			s = &LSym{Name: name}
   116			ctxt.hash[name] = s
   117			if init != nil {
   118				init(s)
   119			}
   120		}
   121		ctxt.hashmu.Unlock()
   122		return s
   123	}
   124	
   125	func (ctxt *Link) Float32Sym(f float32) *LSym {
   126		i := math.Float32bits(f)
   127		name := fmt.Sprintf("$f32.%08x", i)
   128		return ctxt.LookupInit(name, func(s *LSym) {
   129			s.Size = 4
   130			s.Set(AttrLocal, true)
   131		})
   132	}
   133	
   134	func (ctxt *Link) Float64Sym(f float64) *LSym {
   135		i := math.Float64bits(f)
   136		name := fmt.Sprintf("$f64.%016x", i)
   137		return ctxt.LookupInit(name, func(s *LSym) {
   138			s.Size = 8
   139			s.Set(AttrLocal, true)
   140		})
   141	}
   142	
   143	func (ctxt *Link) Int64Sym(i int64) *LSym {
   144		name := fmt.Sprintf("$i64.%016x", uint64(i))
   145		return ctxt.LookupInit(name, func(s *LSym) {
   146			s.Size = 8
   147			s.Set(AttrLocal, true)
   148		})
   149	}
   150	

View as plain text