Home | History | Annotate | Download | only in ld
      1 // Copyright 2015 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 ld
      6 
      7 import (
      8 	"bytes"
      9 	"encoding/binary"
     10 	"log"
     11 	"os"
     12 	"runtime"
     13 	"runtime/pprof"
     14 	"strings"
     15 	"time"
     16 )
     17 
     18 func cstring(x []byte) string {
     19 	i := bytes.IndexByte(x, '\x00')
     20 	if i >= 0 {
     21 		x = x[:i]
     22 	}
     23 	return string(x)
     24 }
     25 
     26 func tokenize(s string) []string {
     27 	var f []string
     28 	for {
     29 		s = strings.TrimLeft(s, " \t\r\n")
     30 		if s == "" {
     31 			break
     32 		}
     33 		quote := false
     34 		i := 0
     35 		for ; i < len(s); i++ {
     36 			if s[i] == '\'' {
     37 				if quote && i+1 < len(s) && s[i+1] == '\'' {
     38 					i++
     39 					continue
     40 				}
     41 				quote = !quote
     42 			}
     43 			if !quote && (s[i] == ' ' || s[i] == '\t' || s[i] == '\r' || s[i] == '\n') {
     44 				break
     45 			}
     46 		}
     47 		next := s[:i]
     48 		s = s[i:]
     49 		if strings.Contains(next, "'") {
     50 			var buf []byte
     51 			quote := false
     52 			for i := 0; i < len(next); i++ {
     53 				if next[i] == '\'' {
     54 					if quote && i+1 < len(next) && next[i+1] == '\'' {
     55 						i++
     56 						buf = append(buf, '\'')
     57 					}
     58 					quote = !quote
     59 					continue
     60 				}
     61 				buf = append(buf, next[i])
     62 			}
     63 			next = string(buf)
     64 		}
     65 		f = append(f, next)
     66 	}
     67 	return f
     68 }
     69 
     70 func cutStringAtNUL(s string) string {
     71 	if i := strings.Index(s, "\x00"); i >= 0 {
     72 		s = s[:i]
     73 	}
     74 	return s
     75 }
     76 
     77 func Access(name string, mode int) int {
     78 	if mode != 0 {
     79 		panic("bad access")
     80 	}
     81 	_, err := os.Stat(name)
     82 	if err != nil {
     83 		return -1
     84 	}
     85 	return 0
     86 }
     87 
     88 // strings.Compare, introduced in Go 1.5.
     89 func stringsCompare(a, b string) int {
     90 	if a == b {
     91 		return 0
     92 	}
     93 	if a < b {
     94 		return -1
     95 	}
     96 	return +1
     97 }
     98 
     99 var atExitFuncs []func()
    100 
    101 func AtExit(f func()) {
    102 	atExitFuncs = append(atExitFuncs, f)
    103 }
    104 
    105 func Exit(code int) {
    106 	for i := len(atExitFuncs) - 1; i >= 0; i-- {
    107 		f := atExitFuncs[i]
    108 		atExitFuncs = atExitFuncs[:i]
    109 		f()
    110 	}
    111 	os.Exit(code)
    112 }
    113 
    114 var (
    115 	cpuprofile     string
    116 	memprofile     string
    117 	memprofilerate int64
    118 )
    119 
    120 func startProfile() {
    121 	if cpuprofile != "" {
    122 		f, err := os.Create(cpuprofile)
    123 		if err != nil {
    124 			log.Fatalf("%v", err)
    125 		}
    126 		if err := pprof.StartCPUProfile(f); err != nil {
    127 			log.Fatalf("%v", err)
    128 		}
    129 		AtExit(pprof.StopCPUProfile)
    130 	}
    131 	if memprofile != "" {
    132 		if memprofilerate != 0 {
    133 			runtime.MemProfileRate = int(memprofilerate)
    134 		}
    135 		f, err := os.Create(memprofile)
    136 		if err != nil {
    137 			log.Fatalf("%v", err)
    138 		}
    139 		AtExit(func() {
    140 			runtime.GC() // profile all outstanding allocations
    141 			if err := pprof.WriteHeapProfile(f); err != nil {
    142 				log.Fatalf("%v", err)
    143 			}
    144 		})
    145 	}
    146 }
    147 
    148 func artrim(x []byte) string {
    149 	i := 0
    150 	j := len(x)
    151 	for i < len(x) && x[i] == ' ' {
    152 		i++
    153 	}
    154 	for j > i && x[j-1] == ' ' {
    155 		j--
    156 	}
    157 	return string(x[i:j])
    158 }
    159 
    160 func stringtouint32(x []uint32, s string) {
    161 	for i := 0; len(s) > 0; i++ {
    162 		var buf [4]byte
    163 		s = s[copy(buf[:], s):]
    164 		x[i] = binary.LittleEndian.Uint32(buf[:])
    165 	}
    166 }
    167 
    168 var start = time.Now()
    169 
    170 func elapsed() float64 {
    171 	return time.Since(start).Seconds()
    172 }
    173