github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8g/list.c (about)

     1  // Derived from Inferno utils/8c/list.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/8c/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), "%d(%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), "$%d,%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  		snprint(str, sizeof(str), "%d", a->u.branch->loc);
   111  		break;
   112  
   113  	case D_EXTERN:
   114  		snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
   115  		break;
   116  
   117  	case D_STATIC:
   118  		snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
   119  		break;
   120  
   121  	case D_AUTO:
   122  		snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
   123  		break;
   124  
   125  	case D_PARAM:
   126  		snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
   127  		break;
   128  
   129  	case D_CONST:
   130  		if(fp->flags & FmtLong) {
   131  			d1 = a->offset;
   132  			d2 = a->offset2;
   133  			snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
   134  			break;
   135  		}
   136  		snprint(str, sizeof(str), "$%d", a->offset);
   137  		break;
   138  
   139  	case D_FCONST:
   140  		snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
   141  		break;
   142  
   143  	case D_SCONST:
   144  		snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
   145  		break;
   146  
   147  	case D_ADDR:
   148  		a->type = a->index;
   149  		a->index = D_NONE;
   150  		snprint(str, sizeof(str), "$%D", a);
   151  		a->index = a->type;
   152  		a->type = D_ADDR;
   153  		goto conv;
   154  	}
   155  brk:
   156  	if(a->index != D_NONE) {
   157  		snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
   158  		strcat(str, s);
   159  	}
   160  conv:
   161  	fmtstrcpy(fp, str);
   162  	if(a->gotype)
   163  		fmtprint(fp, "{%s}", a->gotype->name);
   164  	return 0;
   165  }
   166  
   167  static	char*	regstr[] =
   168  {
   169  	"AL",		/* [D_AL] */
   170  	"CL",
   171  	"DL",
   172  	"BL",
   173  
   174  	"AH",	/* [D_AH] */
   175  	"CH",
   176  	"DH",
   177  	"BH",
   178  
   179  	"AX",		/* [D_AX] */
   180  	"CX",
   181  	"DX",
   182  	"BX",
   183  	"SP",
   184  	"BP",
   185  	"SI",
   186  	"DI",
   187  
   188  	"F0",		/* [D_F0] */
   189  	"F1",
   190  	"F2",
   191  	"F3",
   192  	"F4",
   193  	"F5",
   194  	"F6",
   195  	"F7",
   196  
   197  	"CS",		/* [D_CS] */
   198  	"SS",
   199  	"DS",
   200  	"ES",
   201  	"FS",
   202  	"GS",
   203  
   204  	"GDTR",		/* [D_GDTR] */
   205  	"IDTR",		/* [D_IDTR] */
   206  	"LDTR",		/* [D_LDTR] */
   207  	"MSW",		/* [D_MSW] */
   208  	"TASK",		/* [D_TASK] */
   209  
   210  	"CR0",		/* [D_CR] */
   211  	"CR1",
   212  	"CR2",
   213  	"CR3",
   214  	"CR4",
   215  	"CR5",
   216  	"CR6",
   217  	"CR7",
   218  
   219  	"DR0",		/* [D_DR] */
   220  	"DR1",
   221  	"DR2",
   222  	"DR3",
   223  	"DR4",
   224  	"DR5",
   225  	"DR6",
   226  	"DR7",
   227  
   228  	"TR0",		/* [D_TR] */
   229  	"TR1",
   230  	"TR2",
   231  	"TR3",
   232  	"TR4",
   233  	"TR5",
   234  	"TR6",
   235  	"TR7",
   236  
   237  	"X0",		/* [D_X0] */
   238  	"X1",
   239  	"X2",
   240  	"X3",
   241  	"X4",
   242  	"X5",
   243  	"X6",
   244  	"X7",
   245  
   246  	"NONE",		/* [D_NONE] */
   247  };
   248  
   249  int
   250  Rconv(Fmt *fp)
   251  {
   252  	char str[STRINGSZ];
   253  	int r;
   254  
   255  	r = va_arg(fp->args, int);
   256  	if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
   257  		snprint(str, sizeof(str), "BAD_R(%d)", r);
   258  		return fmtstrcpy(fp, str);
   259  	}
   260  	return fmtstrcpy(fp, regstr[r]);
   261  }
   262  
   263  int
   264  Aconv(Fmt *fp)
   265  {
   266  	int i;
   267  
   268  	i = va_arg(fp->args, int);
   269  	return fmtstrcpy(fp, anames[i]);
   270  }
   271  
   272  
   273  int
   274  Yconv(Fmt *fp)
   275  {
   276  	int i, c;
   277  	char str[STRINGSZ], *p, *a;
   278  
   279  	a = va_arg(fp->args, char*);
   280  	p = str;
   281  	for(i=0; i<sconsize; i++) {
   282  		c = a[i] & 0xff;
   283  		if((c >= 'a' && c <= 'z') ||
   284  		   (c >= 'A' && c <= 'Z') ||
   285  		   (c >= '0' && c <= '9')) {
   286  			*p++ = c;
   287  			continue;
   288  		}
   289  		*p++ = '\\';
   290  		switch(c) {
   291  		default:
   292  			if(c < 040 || c >= 0177)
   293  				break;	/* not portable */
   294  			p[-1] = c;
   295  			continue;
   296  		case 0:
   297  			*p++ = 'z';
   298  			continue;
   299  		case '\\':
   300  		case '"':
   301  			*p++ = c;
   302  			continue;
   303  		case '\n':
   304  			*p++ = 'n';
   305  			continue;
   306  		case '\t':
   307  			*p++ = 't';
   308  			continue;
   309  		}
   310  		*p++ = (c>>6) + '0';
   311  		*p++ = ((c>>3) & 7) + '0';
   312  		*p++ = (c & 7) + '0';
   313  	}
   314  	*p = 0;
   315  	return fmtstrcpy(fp, str);
   316  }