...

Source file src/pkg/cmd/link/internal/sym/symbols.go

     1	// Derived from Inferno utils/6l/l.h and related files.
     2	// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
     3	//
     4	//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5	//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6	//	Portions Copyright © 1997-1999 Vita Nuova Limited
     7	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8	//	Portions Copyright © 2004,2006 Bruce Ellis
     9	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11	//	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12	//
    13	// Permission is hereby granted, free of charge, to any person obtaining a copy
    14	// of this software and associated documentation files (the "Software"), to deal
    15	// in the Software without restriction, including without limitation the rights
    16	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17	// copies of the Software, and to permit persons to whom the Software is
    18	// furnished to do so, subject to the following conditions:
    19	//
    20	// The above copyright notice and this permission notice shall be included in
    21	// all copies or substantial portions of the Software.
    22	//
    23	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29	// THE SOFTWARE.
    30	
    31	package sym
    32	
    33	type Symbols struct {
    34		symbolBatch []Symbol
    35	
    36		// Symbol lookup based on name and indexed by version.
    37		hash []map[string]*Symbol
    38	
    39		Allsym []*Symbol
    40	}
    41	
    42	func NewSymbols() *Symbols {
    43		hash := make([]map[string]*Symbol, SymVerStatic)
    44		// Preallocate about 2mb for hash of non static symbols
    45		hash[0] = make(map[string]*Symbol, 100000)
    46		// And another 1mb for internal ABI text symbols.
    47		hash[SymVerABIInternal] = make(map[string]*Symbol, 50000)
    48		return &Symbols{
    49			hash:   hash,
    50			Allsym: make([]*Symbol, 0, 100000),
    51		}
    52	}
    53	
    54	func (syms *Symbols) Newsym(name string, v int) *Symbol {
    55		batch := syms.symbolBatch
    56		if len(batch) == 0 {
    57			batch = make([]Symbol, 1000)
    58		}
    59		s := &batch[0]
    60		syms.symbolBatch = batch[1:]
    61	
    62		s.Dynid = -1
    63		s.Name = name
    64		s.Version = int16(v)
    65		syms.Allsym = append(syms.Allsym, s)
    66	
    67		return s
    68	}
    69	
    70	// Look up the symbol with the given name and version, creating the
    71	// symbol if it is not found.
    72	func (syms *Symbols) Lookup(name string, v int) *Symbol {
    73		m := syms.hash[v]
    74		s := m[name]
    75		if s != nil {
    76			return s
    77		}
    78		s = syms.Newsym(name, v)
    79		m[name] = s
    80		return s
    81	}
    82	
    83	// Look up the symbol with the given name and version, returning nil
    84	// if it is not found.
    85	func (syms *Symbols) ROLookup(name string, v int) *Symbol {
    86		return syms.hash[v][name]
    87	}
    88	
    89	// Allocate a new version (i.e. symbol namespace).
    90	func (syms *Symbols) IncVersion() int {
    91		syms.hash = append(syms.hash, make(map[string]*Symbol))
    92		return len(syms.hash) - 1
    93	}
    94	
    95	// Rename renames a symbol.
    96	func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Symbol) {
    97		s := syms.hash[v][old]
    98		oldExtName := s.Extname()
    99		s.Name = new
   100		if oldExtName == old {
   101			s.SetExtname(new)
   102		}
   103		delete(syms.hash[v], old)
   104	
   105		dup := syms.hash[v][new]
   106		if dup == nil {
   107			syms.hash[v][new] = s
   108		} else {
   109			if s.Type == 0 {
   110				dup.Attr |= s.Attr
   111				if s.Attr.Reachable() && reachparent != nil {
   112					reachparent[dup] = reachparent[s]
   113				}
   114				*s = *dup
   115			} else if dup.Type == 0 {
   116				s.Attr |= dup.Attr
   117				if dup.Attr.Reachable() && reachparent != nil {
   118					reachparent[s] = reachparent[dup]
   119				}
   120				*dup = *s
   121				syms.hash[v][new] = s
   122			}
   123		}
   124	}
   125	

View as plain text