github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6g/gobj.c (about) 1 // Derived from Inferno utils/6c/swt.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c 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 #include <u.h> 32 #include <libc.h> 33 #include "gg.h" 34 35 void 36 zname(Biobuf *b, Sym *s, int t) 37 { 38 BPUTLE2(b, ANAME); /* as */ 39 BPUTC(b, t); /* type */ 40 BPUTC(b, s->sym); /* sym */ 41 42 Bputname(b, s); 43 } 44 45 void 46 zfile(Biobuf *b, char *p, int n) 47 { 48 BPUTLE2(b, ANAME); 49 BPUTC(b, D_FILE); 50 BPUTC(b, 1); 51 BPUTC(b, '<'); 52 Bwrite(b, p, n); 53 BPUTC(b, 0); 54 } 55 56 void 57 zhist(Biobuf *b, int line, vlong offset) 58 { 59 Addr a; 60 61 BPUTLE2(b, AHISTORY); 62 BPUTLE4(b, line); 63 zaddr(b, &zprog.from, 0, 0); 64 a = zprog.to; 65 if(offset != 0) { 66 a.offset = offset; 67 a.type = D_CONST; 68 } 69 zaddr(b, &a, 0, 0); 70 } 71 72 void 73 zaddr(Biobuf *b, Addr *a, int s, int gotype) 74 { 75 int32 l; 76 uint64 e; 77 int i, t; 78 char *n; 79 80 t = 0; 81 if(a->index != D_NONE || a->scale != 0) 82 t |= T_INDEX; 83 if(s != 0) 84 t |= T_SYM; 85 if(gotype != 0) 86 t |= T_GOTYPE; 87 88 switch(a->type) { 89 90 case D_BRANCH: 91 if(a->u.branch == nil) 92 fatal("unpatched branch"); 93 a->offset = a->u.branch->loc; 94 95 default: 96 t |= T_TYPE; 97 98 case D_NONE: 99 if(a->offset != 0) { 100 t |= T_OFFSET; 101 l = a->offset; 102 if((vlong)l != a->offset) 103 t |= T_64; 104 } 105 break; 106 case D_FCONST: 107 t |= T_FCONST; 108 break; 109 case D_SCONST: 110 t |= T_SCONST; 111 break; 112 } 113 BPUTC(b, t); 114 115 if(t & T_INDEX) { /* implies index, scale */ 116 BPUTC(b, a->index); 117 BPUTC(b, a->scale); 118 } 119 if(t & T_OFFSET) { /* implies offset */ 120 l = a->offset; 121 BPUTLE4(b, l); 122 if(t & T_64) { 123 l = a->offset>>32; 124 BPUTLE4(b, l); 125 } 126 } 127 if(t & T_SYM) /* implies sym */ 128 BPUTC(b, s); 129 if(t & T_FCONST) { 130 ieeedtod(&e, a->u.dval); 131 BPUTLE4(b, e); 132 BPUTLE4(b, e >> 32); 133 return; 134 } 135 if(t & T_SCONST) { 136 n = a->u.sval; 137 for(i=0; i<NSNAME; i++) { 138 BPUTC(b, *n); 139 n++; 140 } 141 return; 142 } 143 if(t & T_TYPE) 144 BPUTC(b, a->type); 145 if(t & T_GOTYPE) 146 BPUTC(b, gotype); 147 } 148 149 static struct { 150 struct { Sym *sym; short type; } h[NSYM]; 151 int sym; 152 } z; 153 154 static void 155 zsymreset(void) 156 { 157 for(z.sym=0; z.sym<NSYM; z.sym++) { 158 z.h[z.sym].sym = S; 159 z.h[z.sym].type = 0; 160 } 161 z.sym = 1; 162 } 163 164 static int 165 zsym(Sym *s, int t, int *new) 166 { 167 int i; 168 169 *new = 0; 170 if(s == S) 171 return 0; 172 173 i = s->sym; 174 if(i < 0 || i >= NSYM) 175 i = 0; 176 if(z.h[i].type == t && z.h[i].sym == s) 177 return i; 178 i = z.sym; 179 s->sym = i; 180 zname(bout, s, t); 181 z.h[i].sym = s; 182 z.h[i].type = t; 183 if(++z.sym >= NSYM) 184 z.sym = 1; 185 *new = 1; 186 return i; 187 } 188 189 static int 190 zsymaddr(Addr *a, int *new) 191 { 192 int t; 193 194 t = a->type; 195 if(t == D_ADDR) 196 t = a->index; 197 return zsym(a->sym, t, new); 198 } 199 200 void 201 dumpfuncs(void) 202 { 203 Plist *pl; 204 int sf, st, gf, gt, new; 205 Sym *s; 206 Prog *p; 207 208 zsymreset(); 209 210 // fix up pc 211 pcloc = 0; 212 for(pl=plist; pl!=nil; pl=pl->link) { 213 if(isblank(pl->name)) 214 continue; 215 for(p=pl->firstpc; p!=P; p=p->link) { 216 p->loc = pcloc; 217 if(p->as != ADATA && p->as != AGLOBL) 218 pcloc++; 219 } 220 } 221 222 // put out functions 223 for(pl=plist; pl!=nil; pl=pl->link) { 224 if(isblank(pl->name)) 225 continue; 226 227 // -S prints code; -SS prints code and data 228 if(debug['S'] && (pl->name || debug['S']>1)) { 229 s = S; 230 if(pl->name != N) 231 s = pl->name->sym; 232 print("\n--- prog list \"%S\" ---\n", s); 233 for(p=pl->firstpc; p!=P; p=p->link) 234 print("%P\n", p); 235 } 236 237 for(p=pl->firstpc; p!=P; p=p->link) { 238 for(;;) { 239 sf = zsymaddr(&p->from, &new); 240 gf = zsym(p->from.gotype, D_EXTERN, &new); 241 if(new && sf == gf) 242 continue; 243 st = zsymaddr(&p->to, &new); 244 if(new && (st == sf || st == gf)) 245 continue; 246 gt = zsym(p->to.gotype, D_EXTERN, &new); 247 if(new && (gt == sf || gt == gf || gt == st)) 248 continue; 249 break; 250 } 251 252 BPUTLE2(bout, p->as); 253 BPUTLE4(bout, p->lineno); 254 zaddr(bout, &p->from, sf, gf); 255 zaddr(bout, &p->to, st, gt); 256 } 257 } 258 } 259 260 int 261 dsname(Sym *s, int off, char *t, int n) 262 { 263 Prog *p; 264 265 p = gins(ADATA, N, N); 266 p->from.type = D_EXTERN; 267 p->from.index = D_NONE; 268 p->from.offset = off; 269 p->from.scale = n; 270 p->from.sym = s; 271 272 p->to.type = D_SCONST; 273 p->to.index = D_NONE; 274 memmove(p->to.u.sval, t, n); 275 return off + n; 276 } 277 278 /* 279 * make a refer to the data s, s+len 280 * emitting DATA if needed. 281 */ 282 void 283 datastring(char *s, int len, Addr *a) 284 { 285 Sym *sym; 286 287 sym = stringsym(s, len); 288 a->type = D_EXTERN; 289 a->sym = sym; 290 a->node = sym->def; 291 a->offset = widthptr+widthint; // skip header 292 a->etype = simtype[TINT]; 293 } 294 295 /* 296 * make a refer to the string sval, 297 * emitting DATA if needed. 298 */ 299 void 300 datagostring(Strlit *sval, Addr *a) 301 { 302 Sym *sym; 303 304 sym = stringsym(sval->s, sval->len); 305 a->type = D_EXTERN; 306 a->sym = sym; 307 a->node = sym->def; 308 a->offset = 0; // header 309 a->etype = TINT32; 310 } 311 312 void 313 gdata(Node *nam, Node *nr, int wid) 314 { 315 Prog *p; 316 317 if(nr->op == OLITERAL) { 318 switch(nr->val.ctype) { 319 case CTCPLX: 320 gdatacomplex(nam, nr->val.u.cval); 321 return; 322 case CTSTR: 323 gdatastring(nam, nr->val.u.sval); 324 return; 325 } 326 } 327 p = gins(ADATA, nam, nr); 328 p->from.scale = wid; 329 } 330 331 void 332 gdatacomplex(Node *nam, Mpcplx *cval) 333 { 334 Prog *p; 335 int w; 336 337 w = cplxsubtype(nam->type->etype); 338 w = types[w]->width; 339 340 p = gins(ADATA, nam, N); 341 p->from.scale = w; 342 p->to.type = D_FCONST; 343 p->to.u.dval = mpgetflt(&cval->real); 344 345 p = gins(ADATA, nam, N); 346 p->from.scale = w; 347 p->from.offset += w; 348 p->to.type = D_FCONST; 349 p->to.u.dval = mpgetflt(&cval->imag); 350 } 351 352 void 353 gdatastring(Node *nam, Strlit *sval) 354 { 355 Prog *p; 356 Node nod1; 357 358 p = gins(ADATA, nam, N); 359 datastring(sval->s, sval->len, &p->to); 360 p->from.scale = types[tptr]->width; 361 p->to.index = p->to.type; 362 p->to.type = D_ADDR; 363 //print("%P\n", p); 364 365 nodconst(&nod1, types[TINT], sval->len); 366 p = gins(ADATA, nam, &nod1); 367 p->from.scale = widthint; 368 p->from.offset += widthptr; 369 } 370 371 int 372 dstringptr(Sym *s, int off, char *str) 373 { 374 Prog *p; 375 376 off = rnd(off, widthptr); 377 p = gins(ADATA, N, N); 378 p->from.type = D_EXTERN; 379 p->from.index = D_NONE; 380 p->from.sym = s; 381 p->from.offset = off; 382 p->from.scale = widthptr; 383 384 datastring(str, strlen(str)+1, &p->to); 385 p->to.index = p->to.type; 386 p->to.type = D_ADDR; 387 p->to.etype = simtype[TINT]; 388 off += widthptr; 389 390 return off; 391 } 392 393 int 394 dgostrlitptr(Sym *s, int off, Strlit *lit) 395 { 396 Prog *p; 397 398 if(lit == nil) 399 return duintptr(s, off, 0); 400 401 off = rnd(off, widthptr); 402 p = gins(ADATA, N, N); 403 p->from.type = D_EXTERN; 404 p->from.index = D_NONE; 405 p->from.sym = s; 406 p->from.offset = off; 407 p->from.scale = widthptr; 408 datagostring(lit, &p->to); 409 p->to.index = p->to.type; 410 p->to.type = D_ADDR; 411 p->to.etype = simtype[TINT]; 412 off += widthptr; 413 414 return off; 415 } 416 417 int 418 dgostringptr(Sym *s, int off, char *str) 419 { 420 int n; 421 Strlit *lit; 422 423 if(str == nil) 424 return duintptr(s, off, 0); 425 426 n = strlen(str); 427 lit = mal(sizeof *lit + n); 428 strcpy(lit->s, str); 429 lit->len = n; 430 return dgostrlitptr(s, off, lit); 431 } 432 433 int 434 duintxx(Sym *s, int off, uint64 v, int wid) 435 { 436 Prog *p; 437 438 off = rnd(off, wid); 439 440 p = gins(ADATA, N, N); 441 p->from.type = D_EXTERN; 442 p->from.index = D_NONE; 443 p->from.sym = s; 444 p->from.offset = off; 445 p->from.scale = wid; 446 p->to.type = D_CONST; 447 p->to.index = D_NONE; 448 p->to.offset = v; 449 off += wid; 450 451 return off; 452 } 453 454 int 455 dsymptr(Sym *s, int off, Sym *x, int xoff) 456 { 457 Prog *p; 458 459 off = rnd(off, widthptr); 460 461 p = gins(ADATA, N, N); 462 p->from.type = D_EXTERN; 463 p->from.index = D_NONE; 464 p->from.sym = s; 465 p->from.offset = off; 466 p->from.scale = widthptr; 467 p->to.type = D_ADDR; 468 p->to.index = D_EXTERN; 469 p->to.sym = x; 470 p->to.offset = xoff; 471 off += widthptr; 472 473 return off; 474 } 475 476 void 477 nopout(Prog *p) 478 { 479 p->as = ANOP; 480 } 481