github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/obj/data.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/obj/data.go 2 3 // Derived from Inferno utils/6l/obj.c and utils/6l/span.c 4 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c 5 // http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c 6 // 7 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 8 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 9 // Portions Copyright © 1997-1999 Vita Nuova Limited 10 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 11 // Portions Copyright © 2004,2006 Bruce Ellis 12 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 13 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 14 // Portions Copyright © 2009 The Go Authors. All rights reserved. 15 // 16 // Permission is hereby granted, free of charge, to any person obtaining a copy 17 // of this software and associated documentation files (the "Software"), to deal 18 // in the Software without restriction, including without limitation the rights 19 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 // copies of the Software, and to permit persons to whom the Software is 21 // furnished to do so, subject to the following conditions: 22 // 23 // The above copyright notice and this permission notice shall be included in 24 // all copies or substantial portions of the Software. 25 // 26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 32 // THE SOFTWARE. 33 34 package obj 35 36 import ( 37 "log" 38 "math" 39 ) 40 41 func mangle(file string) { 42 log.Fatalf("%s: mangled input file", file) 43 } 44 45 func Symgrow(ctxt *Link, s *LSym, lsiz int64) { 46 siz := int(lsiz) 47 if int64(siz) != lsiz { 48 log.Fatalf("Symgrow size %d too long", lsiz) 49 } 50 if len(s.P) >= siz { 51 return 52 } 53 for cap(s.P) < siz { 54 s.P = append(s.P[:cap(s.P)], 0) 55 } 56 s.P = s.P[:siz] 57 } 58 59 func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { 60 off := int32(p.From.Offset) 61 siz := int32(p.From3.Offset) 62 if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 { 63 mangle(pn) 64 } 65 if ctxt.Enforce_data_order != 0 && off < int32(len(s.P)) { 66 ctxt.Diag("data out of order (already have %d)\n%P", len(s.P), p) 67 } 68 Symgrow(ctxt, s, int64(off+siz)) 69 70 switch int(p.To.Type) { 71 default: 72 ctxt.Diag("bad data: %P", p) 73 74 case TYPE_FCONST: 75 switch siz { 76 default: 77 ctxt.Diag("unexpected %d-byte floating point constant", siz) 78 79 case 4: 80 flt := math.Float32bits(float32(p.To.Val.(float64))) 81 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], flt) 82 83 case 8: 84 flt := math.Float64bits(p.To.Val.(float64)) 85 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt) 86 } 87 88 case TYPE_SCONST: 89 copy(s.P[off:off+siz], p.To.Val.(string)) 90 91 case TYPE_CONST, TYPE_ADDR: 92 if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR { 93 r := Addrel(s) 94 r.Off = off 95 r.Siz = uint8(siz) 96 r.Sym = p.To.Sym 97 r.Type = R_ADDR 98 r.Add = p.To.Offset 99 break 100 } 101 o := p.To.Offset 102 switch siz { 103 default: 104 ctxt.Diag("unexpected %d-byte integer constant", siz) 105 case 1: 106 s.P[off] = byte(o) 107 case 2: 108 ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(o)) 109 case 4: 110 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(o)) 111 case 8: 112 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o)) 113 } 114 } 115 } 116 117 func Addrel(s *LSym) *Reloc { 118 s.R = append(s.R, Reloc{}) 119 return &s.R[len(s.R)-1] 120 } 121 122 func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { 123 if s.Type == 0 { 124 s.Type = SDATA 125 } 126 if s.Size < off+wid { 127 s.Size = off + wid 128 Symgrow(ctxt, s, s.Size) 129 } 130 131 switch wid { 132 case 1: 133 s.P[off] = uint8(v) 134 case 2: 135 ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v)) 136 case 4: 137 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v)) 138 case 8: 139 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(v)) 140 } 141 142 return off + wid 143 } 144 145 func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 { 146 off := s.Size 147 Setuintxx(ctxt, s, off, v, int64(wid)) 148 return off 149 } 150 151 func adduint8(ctxt *Link, s *LSym, v uint8) int64 { 152 return adduintxx(ctxt, s, uint64(v), 1) 153 } 154 155 func adduint16(ctxt *Link, s *LSym, v uint16) int64 { 156 return adduintxx(ctxt, s, uint64(v), 2) 157 } 158 159 func Adduint32(ctxt *Link, s *LSym, v uint32) int64 { 160 return adduintxx(ctxt, s, uint64(v), 4) 161 } 162 163 func Adduint64(ctxt *Link, s *LSym, v uint64) int64 { 164 return adduintxx(ctxt, s, v, 8) 165 } 166 167 func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 { 168 return Setuintxx(ctxt, s, r, uint64(v), 1) 169 } 170 171 func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 { 172 return Setuintxx(ctxt, s, r, uint64(v), 2) 173 } 174 175 func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 { 176 return Setuintxx(ctxt, s, r, uint64(v), 4) 177 } 178 179 func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 { 180 return Setuintxx(ctxt, s, r, v, 8) 181 } 182 183 func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 { 184 if s.Type == 0 { 185 s.Type = SDATA 186 } 187 i := s.Size 188 s.Size += int64(ctxt.Arch.Ptrsize) 189 Symgrow(ctxt, s, s.Size) 190 r := Addrel(s) 191 r.Sym = t 192 r.Off = int32(i) 193 r.Siz = uint8(ctxt.Arch.Ptrsize) 194 r.Type = R_ADDR 195 r.Add = add 196 return i + int64(r.Siz) 197 } 198 199 func addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 { 200 if s.Type == 0 { 201 s.Type = SDATA 202 } 203 i := s.Size 204 s.Size += 4 205 Symgrow(ctxt, s, s.Size) 206 r := Addrel(s) 207 r.Sym = t 208 r.Off = int32(i) 209 r.Add = add 210 r.Type = R_PCREL 211 r.Siz = 4 212 return i + int64(r.Siz) 213 } 214 215 func addaddr(ctxt *Link, s *LSym, t *LSym) int64 { 216 return addaddrplus(ctxt, s, t, 0) 217 } 218 219 func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 { 220 if s.Type == 0 { 221 s.Type = SDATA 222 } 223 if off+int64(ctxt.Arch.Ptrsize) > s.Size { 224 s.Size = off + int64(ctxt.Arch.Ptrsize) 225 Symgrow(ctxt, s, s.Size) 226 } 227 228 r := Addrel(s) 229 r.Sym = t 230 r.Off = int32(off) 231 r.Siz = uint8(ctxt.Arch.Ptrsize) 232 r.Type = R_ADDR 233 r.Add = add 234 return off + int64(r.Siz) 235 } 236 237 func setaddr(ctxt *Link, s *LSym, off int64, t *LSym) int64 { 238 return setaddrplus(ctxt, s, off, t, 0) 239 } 240 241 func addsize(ctxt *Link, s *LSym, t *LSym) int64 { 242 if s.Type == 0 { 243 s.Type = SDATA 244 } 245 i := s.Size 246 s.Size += int64(ctxt.Arch.Ptrsize) 247 Symgrow(ctxt, s, s.Size) 248 r := Addrel(s) 249 r.Sym = t 250 r.Off = int32(i) 251 r.Siz = uint8(ctxt.Arch.Ptrsize) 252 r.Type = R_SIZE 253 return i + int64(r.Siz) 254 } 255 256 func addaddrplus4(ctxt *Link, s *LSym, t *LSym, add int64) int64 { 257 if s.Type == 0 { 258 s.Type = SDATA 259 } 260 i := s.Size 261 s.Size += 4 262 Symgrow(ctxt, s, s.Size) 263 r := Addrel(s) 264 r.Sym = t 265 r.Off = int32(i) 266 r.Siz = 4 267 r.Type = R_ADDR 268 r.Add = add 269 return i + int64(r.Siz) 270 }