github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/8l/list.c (about) 1 // Inferno utils/8l/list.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/list.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 // Printing. 32 33 #include "l.h" 34 #include "../ld/lib.h" 35 36 void 37 listinit(void) 38 { 39 40 fmtinstall('R', Rconv); 41 fmtinstall('A', Aconv); 42 fmtinstall('D', Dconv); 43 fmtinstall('S', Sconv); 44 fmtinstall('P', Pconv); 45 fmtinstall('I', Iconv); 46 } 47 48 static Prog *bigP; 49 50 int 51 Pconv(Fmt *fp) 52 { 53 Prog *p; 54 55 p = va_arg(fp->args, Prog*); 56 bigP = p; 57 switch(p->as) { 58 case ATEXT: 59 if(p->from.scale) { 60 fmtprint(fp, "(%d) %A %D,%d,%D", 61 p->line, p->as, &p->from, p->from.scale, &p->to); 62 break; 63 } 64 default: 65 fmtprint(fp, "(%d) %A %D,%D", 66 p->line, p->as, &p->from, &p->to); 67 break; 68 case ADATA: 69 case AINIT_: 70 case ADYNT_: 71 fmtprint(fp, "(%d) %A %D/%d,%D", 72 p->line, p->as, &p->from, p->from.scale, &p->to); 73 break; 74 } 75 bigP = P; 76 return 0; 77 } 78 79 int 80 Aconv(Fmt *fp) 81 { 82 int i; 83 84 i = va_arg(fp->args, int); 85 return fmtstrcpy(fp, anames[i]); 86 } 87 88 char* 89 xsymname(Sym *s) 90 { 91 if(s == nil) 92 return "!!noname!!"; 93 return s->name; 94 } 95 96 int 97 Dconv(Fmt *fp) 98 { 99 char str[STRINGSZ], s[STRINGSZ]; 100 Adr *a; 101 int i; 102 103 a = va_arg(fp->args, Adr*); 104 i = a->type; 105 if(i >= D_INDIR && i < 2*D_INDIR) { 106 if(a->offset) 107 snprint(str, sizeof str, "%d(%R)", a->offset, i-D_INDIR); 108 else 109 snprint(str, sizeof str, "(%R)", i-D_INDIR); 110 goto brk; 111 } 112 switch(i) { 113 114 default: 115 snprint(str, sizeof str, "%R", i); 116 break; 117 118 case D_NONE: 119 str[0] = 0; 120 break; 121 122 case D_BRANCH: 123 if(bigP != P && bigP->pcond != P) 124 if(a->sym != S) 125 snprint(str, sizeof str, "%ux+%s", bigP->pcond->pc, 126 a->sym->name); 127 else 128 snprint(str, sizeof str, "%ux", bigP->pcond->pc); 129 else 130 snprint(str, sizeof str, "%d(PC)", a->offset); 131 break; 132 133 case D_EXTERN: 134 snprint(str, sizeof str, "%s+%d(SB)", xsymname(a->sym), a->offset); 135 break; 136 137 case D_STATIC: 138 snprint(str, sizeof str, "%s<%d>+%d(SB)", xsymname(a->sym), 139 a->sym->version, a->offset); 140 break; 141 142 case D_AUTO: 143 snprint(str, sizeof str, "%s+%d(SP)", xsymname(a->sym), a->offset); 144 break; 145 146 case D_PARAM: 147 if(a->sym) 148 snprint(str, sizeof str, "%s+%d(FP)", a->sym->name, a->offset); 149 else 150 snprint(str, sizeof str, "%d(FP)", a->offset); 151 break; 152 153 case D_CONST: 154 snprint(str, sizeof str, "$%d", a->offset); 155 break; 156 157 case D_CONST2: 158 snprint(str, sizeof str, "$%d-%d", a->offset, a->offset2); 159 break; 160 161 case D_FCONST: 162 snprint(str, sizeof str, "$(%.8ux,%.8ux)", a->ieee.h, a->ieee.l); 163 break; 164 165 case D_SCONST: 166 snprint(str, sizeof str, "$\"%S\"", a->scon); 167 break; 168 169 case D_ADDR: 170 a->type = a->index; 171 a->index = D_NONE; 172 snprint(str, sizeof str, "$%D", a); 173 a->index = a->type; 174 a->type = D_ADDR; 175 goto conv; 176 } 177 brk: 178 if(a->index != D_NONE) { 179 sprint(s, "(%R*%d)", (int)a->index, a->scale); 180 strcat(str, s); 181 } 182 conv: 183 fmtstrcpy(fp, str); 184 // if(a->gotype) 185 // fmtprint(fp, "«%s»", a->gotype->name); 186 return 0; 187 } 188 189 char* regstr[] = 190 { 191 "AL", /* [D_AL] */ 192 "CL", 193 "DL", 194 "BL", 195 "AH", 196 "CH", 197 "DH", 198 "BH", 199 200 "AX", /* [D_AX] */ 201 "CX", 202 "DX", 203 "BX", 204 "SP", 205 "BP", 206 "SI", 207 "DI", 208 209 "F0", /* [D_F0] */ 210 "F1", 211 "F2", 212 "F3", 213 "F4", 214 "F5", 215 "F6", 216 "F7", 217 218 "CS", /* [D_CS] */ 219 "SS", 220 "DS", 221 "ES", 222 "FS", 223 "GS", 224 225 "GDTR", /* [D_GDTR] */ 226 "IDTR", /* [D_IDTR] */ 227 "LDTR", /* [D_LDTR] */ 228 "MSW", /* [D_MSW] */ 229 "TASK", /* [D_TASK] */ 230 231 "CR0", /* [D_CR] */ 232 "CR1", 233 "CR2", 234 "CR3", 235 "CR4", 236 "CR5", 237 "CR6", 238 "CR7", 239 240 "DR0", /* [D_DR] */ 241 "DR1", 242 "DR2", 243 "DR3", 244 "DR4", 245 "DR5", 246 "DR6", 247 "DR7", 248 249 "TR0", /* [D_TR] */ 250 "TR1", 251 "TR2", 252 "TR3", 253 "TR4", 254 "TR5", 255 "TR6", 256 "TR7", 257 258 "X0", 259 "X1", 260 "X2", 261 "X3", 262 "X4", 263 "X5", 264 "X6", 265 "X7", 266 267 "NONE", /* [D_NONE] */ 268 }; 269 270 int 271 Rconv(Fmt *fp) 272 { 273 char str[STRINGSZ]; 274 int r; 275 276 r = va_arg(fp->args, int); 277 if(r >= D_AL && r <= D_NONE) 278 sprint(str, "%s", regstr[r-D_AL]); 279 else 280 sprint(str, "gok(%d)", r); 281 282 return fmtstrcpy(fp, str); 283 } 284 285 int 286 Sconv(Fmt *fp) 287 { 288 int i, c; 289 char str[STRINGSZ], *p, *a; 290 291 a = va_arg(fp->args, char*); 292 p = str; 293 for(i=0; i<sizeof(double); i++) { 294 c = a[i] & 0xff; 295 if(c >= 'a' && c <= 'z' || 296 c >= 'A' && c <= 'Z' || 297 c >= '0' && c <= '9') { 298 *p++ = c; 299 continue; 300 } 301 *p++ = '\\'; 302 switch(c) { 303 default: 304 if(c < 040 || c >= 0177) 305 break; /* not portable */ 306 p[-1] = c; 307 continue; 308 case 0: 309 *p++ = 'z'; 310 continue; 311 case '\\': 312 case '"': 313 *p++ = c; 314 continue; 315 case '\n': 316 *p++ = 'n'; 317 continue; 318 case '\t': 319 *p++ = 't'; 320 continue; 321 } 322 *p++ = (c>>6) + '0'; 323 *p++ = ((c>>3) & 7) + '0'; 324 *p++ = (c & 7) + '0'; 325 } 326 *p = 0; 327 return fmtstrcpy(fp, str); 328 } 329 330 int 331 Iconv(Fmt *fp) 332 { 333 int i, n; 334 uchar *p; 335 char *s; 336 Fmt fmt; 337 338 n = fp->prec; 339 fp->prec = 0; 340 if(!(fp->flags&FmtPrec) || n < 0) 341 return fmtstrcpy(fp, "%I"); 342 fp->flags &= ~FmtPrec; 343 p = va_arg(fp->args, uchar*); 344 345 // format into temporary buffer and 346 // call fmtstrcpy to handle padding. 347 fmtstrinit(&fmt); 348 for(i=0; i<n; i++) 349 fmtprint(&fmt, "%.2ux", *p++); 350 s = fmtstrflush(&fmt); 351 fmtstrcpy(fp, s); 352 free(s); 353 return 0; 354 } 355 356 void 357 diag(char *fmt, ...) 358 { 359 char buf[STRINGSZ], *tn, *sep; 360 va_list arg; 361 362 tn = ""; 363 sep = ""; 364 if(cursym != S) { 365 tn = cursym->name; 366 sep = ": "; 367 } 368 va_start(arg, fmt); 369 vseprint(buf, buf+sizeof(buf), fmt, arg); 370 va_end(arg); 371 print("%s%s%s\n", tn, sep, buf); 372 373 nerrors++; 374 if(nerrors > 20) { 375 print("too many errors\n"); 376 errorexit(); 377 } 378 }