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