github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/6g/list.c (about) 1 // Derived from Inferno utils/6c/list.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/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 #include <u.h> 32 #include <libc.h> 33 #include "gg.h" 34 35 static int sconsize; 36 void 37 listinit(void) 38 { 39 40 fmtinstall('A', Aconv); // as 41 fmtinstall('P', Pconv); // Prog* 42 fmtinstall('D', Dconv); // Addr* 43 fmtinstall('R', Rconv); // reg 44 fmtinstall('Y', Yconv); // sconst 45 } 46 47 int 48 Pconv(Fmt *fp) 49 { 50 char str[STRINGSZ]; 51 Prog *p; 52 char scale[40]; 53 54 p = va_arg(fp->args, Prog*); 55 sconsize = 8; 56 scale[0] = '\0'; 57 if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT)) 58 snprint(scale, sizeof scale, "%d,", p->from.scale); 59 switch(p->as) { 60 default: 61 snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D", 62 p->loc, p->lineno, p->as, &p->from, scale, &p->to); 63 break; 64 65 case ADATA: 66 sconsize = p->from.scale; 67 snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D", 68 p->loc, p->lineno, p->as, &p->from, sconsize, &p->to); 69 break; 70 71 case ATEXT: 72 snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD", 73 p->loc, p->lineno, p->as, &p->from, scale, &p->to); 74 break; 75 } 76 return fmtstrcpy(fp, str); 77 } 78 79 int 80 Dconv(Fmt *fp) 81 { 82 char str[STRINGSZ], s[STRINGSZ]; 83 Addr *a; 84 int i; 85 uint32 d1, d2; 86 87 a = va_arg(fp->args, Addr*); 88 i = a->type; 89 if(i >= D_INDIR) { 90 if(a->offset) 91 snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR); 92 else 93 snprint(str, sizeof(str), "(%R)", i-D_INDIR); 94 goto brk; 95 } 96 switch(i) { 97 98 default: 99 if(a->offset) 100 snprint(str, sizeof(str), "$%lld,%R", a->offset, i); 101 else 102 snprint(str, sizeof(str), "%R", i); 103 break; 104 105 case D_NONE: 106 str[0] = 0; 107 break; 108 109 case D_BRANCH: 110 if(a->u.branch == nil) 111 snprint(str, sizeof(str), "<nil>"); 112 else 113 snprint(str, sizeof(str), "%d", a->u.branch->loc); 114 break; 115 116 case D_EXTERN: 117 snprint(str, sizeof(str), "%S+%lld(SB)", a->sym, a->offset); 118 break; 119 120 case D_STATIC: 121 snprint(str, sizeof(str), "%S<>+%lld(SB)", a->sym, a->offset); 122 break; 123 124 case D_AUTO: 125 snprint(str, sizeof(str), "%S+%lld(SP)", a->sym, a->offset); 126 break; 127 128 case D_PARAM: 129 snprint(str, sizeof(str), "%S+%lld(FP)", a->sym, a->offset); 130 break; 131 132 case D_CONST: 133 if(fp->flags & FmtLong) { 134 d1 = a->offset & 0xffffffffLL; 135 d2 = (a->offset>>32) & 0xffffffffLL; 136 snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2); 137 break; 138 } 139 snprint(str, sizeof(str), "$%lld", a->offset); 140 break; 141 142 case D_FCONST: 143 snprint(str, sizeof(str), "$(%.17e)", a->u.dval); 144 break; 145 146 case D_SCONST: 147 snprint(str, sizeof(str), "$\"%Y\"", a->u.sval); 148 break; 149 150 case D_ADDR: 151 a->type = a->index; 152 a->index = D_NONE; 153 snprint(str, sizeof(str), "$%D", a); 154 a->index = a->type; 155 a->type = D_ADDR; 156 goto conv; 157 } 158 brk: 159 if(a->index != D_NONE) { 160 snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale); 161 strcat(str, s); 162 } 163 conv: 164 fmtstrcpy(fp, str); 165 if(a->gotype) 166 fmtprint(fp, "{%s}", a->gotype->name); 167 return 0; 168 } 169 170 static char* regstr[] = 171 { 172 "AL", /* [D_AL] */ 173 "CL", 174 "DL", 175 "BL", 176 "SPB", 177 "BPB", 178 "SIB", 179 "DIB", 180 "R8B", 181 "R9B", 182 "R10B", 183 "R11B", 184 "R12B", 185 "R13B", 186 "R14B", 187 "R15B", 188 189 "AX", /* [D_AX] */ 190 "CX", 191 "DX", 192 "BX", 193 "SP", 194 "BP", 195 "SI", 196 "DI", 197 "R8", 198 "R9", 199 "R10", 200 "R11", 201 "R12", 202 "R13", 203 "R14", 204 "R15", 205 206 "AH", 207 "CH", 208 "DH", 209 "BH", 210 211 "F0", /* [D_F0] */ 212 "F1", 213 "F2", 214 "F3", 215 "F4", 216 "F5", 217 "F6", 218 "F7", 219 220 "M0", 221 "M1", 222 "M2", 223 "M3", 224 "M4", 225 "M5", 226 "M6", 227 "M7", 228 229 "X0", 230 "X1", 231 "X2", 232 "X3", 233 "X4", 234 "X5", 235 "X6", 236 "X7", 237 "X8", 238 "X9", 239 "X10", 240 "X11", 241 "X12", 242 "X13", 243 "X14", 244 "X15", 245 246 "CS", /* [D_CS] */ 247 "SS", 248 "DS", 249 "ES", 250 "FS", 251 "GS", 252 253 "GDTR", /* [D_GDTR] */ 254 "IDTR", /* [D_IDTR] */ 255 "LDTR", /* [D_LDTR] */ 256 "MSW", /* [D_MSW] */ 257 "TASK", /* [D_TASK] */ 258 259 "CR0", /* [D_CR] */ 260 "CR1", 261 "CR2", 262 "CR3", 263 "CR4", 264 "CR5", 265 "CR6", 266 "CR7", 267 "CR8", 268 "CR9", 269 "CR10", 270 "CR11", 271 "CR12", 272 "CR13", 273 "CR14", 274 "CR15", 275 276 "DR0", /* [D_DR] */ 277 "DR1", 278 "DR2", 279 "DR3", 280 "DR4", 281 "DR5", 282 "DR6", 283 "DR7", 284 285 "TR0", /* [D_TR] */ 286 "TR1", 287 "TR2", 288 "TR3", 289 "TR4", 290 "TR5", 291 "TR6", 292 "TR7", 293 294 "NONE", /* [D_NONE] */ 295 }; 296 297 int 298 Rconv(Fmt *fp) 299 { 300 char str[STRINGSZ]; 301 int r; 302 303 r = va_arg(fp->args, int); 304 if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) { 305 snprint(str, sizeof(str), "BAD_R(%d)", r); 306 return fmtstrcpy(fp, str); 307 } 308 return fmtstrcpy(fp, regstr[r]); 309 } 310 311 int 312 Aconv(Fmt *fp) 313 { 314 int i; 315 316 i = va_arg(fp->args, int); 317 return fmtstrcpy(fp, anames[i]); 318 } 319 320 321 int 322 Yconv(Fmt *fp) 323 { 324 int i, c; 325 char str[STRINGSZ], *p, *a; 326 327 a = va_arg(fp->args, char*); 328 p = str; 329 for(i=0; i<sconsize; i++) { 330 c = a[i] & 0xff; 331 if((c >= 'a' && c <= 'z') || 332 (c >= 'A' && c <= 'Z') || 333 (c >= '0' && c <= '9')) { 334 *p++ = c; 335 continue; 336 } 337 *p++ = '\\'; 338 switch(c) { 339 default: 340 if(c < 040 || c >= 0177) 341 break; /* not portable */ 342 p[-1] = c; 343 continue; 344 case 0: 345 *p++ = 'z'; 346 continue; 347 case '\\': 348 case '"': 349 *p++ = c; 350 continue; 351 case '\n': 352 *p++ = 'n'; 353 continue; 354 case '\t': 355 *p++ = 't'; 356 continue; 357 } 358 *p++ = (c>>6) + '0'; 359 *p++ = ((c>>3) & 7) + '0'; 360 *p++ = (c & 7) + '0'; 361 } 362 *p = 0; 363 return fmtstrcpy(fp, str); 364 }