1*38103Sbostic /* 2*38103Sbostic * Copyright (c) 1983 The Regents of the University of California. 3*38103Sbostic * All rights reserved. 4*38103Sbostic * 5*38103Sbostic * Redistribution and use in source and binary forms are permitted 6*38103Sbostic * provided that the above copyright notice and this paragraph are 7*38103Sbostic * duplicated in all such forms and that any documentation, 8*38103Sbostic * advertising materials, and other materials related to such 9*38103Sbostic * distribution and use acknowledge that the software was developed 10*38103Sbostic * by the University of California, Berkeley. The name of the 11*38103Sbostic * University may not be used to endorse or promote products derived 12*38103Sbostic * from this software without specific prior written permission. 13*38103Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*38103Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*38103Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*38103Sbostic */ 17*38103Sbostic 18*38103Sbostic #ifndef lint 19*38103Sbostic static char sccsid[] = "@(#)sun.c 5.1 (Berkeley) 05/23/89"; 20*38103Sbostic #endif /* not lint */ 21*38103Sbostic 22*38103Sbostic /* 23*38103Sbostic * Target machine dependent stuff. 24*38103Sbostic */ 25*38103Sbostic 26*38103Sbostic #include "defs.h" 27*38103Sbostic #include "machine.h" 28*38103Sbostic #include "process.h" 29*38103Sbostic #include "runtime.h" 30*38103Sbostic #include "events.h" 31*38103Sbostic #include "main.h" 32*38103Sbostic #include "symbols.h" 33*38103Sbostic #include "source.h" 34*38103Sbostic #include "mappings.h" 35*38103Sbostic #include "object.h" 36*38103Sbostic #include "tree.h" 37*38103Sbostic #include "eval.h" 38*38103Sbostic #include "keywords.h" 39*38103Sbostic #include "ops.h" 40*38103Sbostic 41*38103Sbostic #ifndef public 42*38103Sbostic typedef unsigned int Address; 43*38103Sbostic typedef unsigned char Byte; 44*38103Sbostic typedef unsigned int Word; 45*38103Sbostic 46*38103Sbostic /* 47*38103Sbostic * On the 68000, the pc isn't in a register, but we make believe 48*38103Sbostic * so there's one more register. 49*38103Sbostic * 50*38103Sbostic * Note that there's also no argument pointer, this means code 51*38103Sbostic * involving "ARGP" should always be #ifdef'd. 52*38103Sbostic * 53*38103Sbostic * The address corresponding to the beginning of a function is recorded 54*38103Sbostic * as the address + FUNCOFFSET (skip the link instruction so that 55*38103Sbostic * local information is available). 56*38103Sbostic */ 57*38103Sbostic 58*38103Sbostic #define NREG 17 59*38103Sbostic 60*38103Sbostic #define FRP 14 61*38103Sbostic #define STKP 15 62*38103Sbostic #define PROGCTR 16 63*38103Sbostic 64*38103Sbostic #define CALL_RETADDR 0x800c /* Return address for 'call' command */ 65*38103Sbostic #define FUNCOFFSET 4 66*38103Sbostic 67*38103Sbostic #ifdef sun 68*38103Sbostic # define CODESTART 0x8000 69*38103Sbostic #else /* IRIS */ 70*38103Sbostic # define CODESTART 0x1000 71*38103Sbostic #endif 72*38103Sbostic 73*38103Sbostic #define optab_init() 74*38103Sbostic 75*38103Sbostic #define BITSPERBYTE 8 76*38103Sbostic #define BITSPERWORD (BITSPERBYTE * sizeof(Word)) 77*38103Sbostic 78*38103Sbostic /* 79*38103Sbostic * This magic macro enables us to look at the process' registers 80*38103Sbostic * in its user structure. 81*38103Sbostic */ 82*38103Sbostic 83*38103Sbostic #define regloc(reg) (ctob(UPAGES) + (sizeof(Word) * ((reg) - PC)) - 10) 84*38103Sbostic 85*38103Sbostic #include "source.h" 86*38103Sbostic #include "symbols.h" 87*38103Sbostic #include <signal.h> 88*38103Sbostic #include <sys/param.h> 89*38103Sbostic #include <sys/dir.h> 90*38103Sbostic #include <machine/psl.h> 91*38103Sbostic #include <machine/pte.h> 92*38103Sbostic #include <sys/user.h> 93*38103Sbostic #undef DELETE /* XXX */ 94*38103Sbostic #include <sys/vm.h> 95*38103Sbostic #include <machine/reg.h> 96*38103Sbostic 97*38103Sbostic Address pc; 98*38103Sbostic Address prtaddr; 99*38103Sbostic 100*38103Sbostic #endif 101*38103Sbostic 102*38103Sbostic /* 103*38103Sbostic * Indices into u. for use in collecting registers values. 104*38103Sbostic */ 105*38103Sbostic public int rloc[] ={ 106*38103Sbostic #ifdef sun 107*38103Sbostic R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, PC 108*38103Sbostic #else /* IRIS */ 109*38103Sbostic R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, 16 110*38103Sbostic #endif 111*38103Sbostic }; 112*38103Sbostic 113*38103Sbostic private Address printop(); 114*38103Sbostic 115*38103Sbostic /* 116*38103Sbostic * Decode and print the instructions within the given address range. 117*38103Sbostic */ 118*38103Sbostic 119*38103Sbostic public printinst(lowaddr, highaddr) 120*38103Sbostic Address lowaddr; 121*38103Sbostic Address highaddr; 122*38103Sbostic { 123*38103Sbostic register Address addr; 124*38103Sbostic 125*38103Sbostic for (addr = lowaddr; addr <= highaddr; ) { 126*38103Sbostic addr = printop(addr); 127*38103Sbostic } 128*38103Sbostic prtaddr = addr; 129*38103Sbostic } 130*38103Sbostic 131*38103Sbostic /* 132*38103Sbostic * Another approach: print n instructions starting at the given address. 133*38103Sbostic */ 134*38103Sbostic 135*38103Sbostic public printninst(count, addr) 136*38103Sbostic int count; 137*38103Sbostic Address addr; 138*38103Sbostic { 139*38103Sbostic register Integer i; 140*38103Sbostic register Address newaddr; 141*38103Sbostic 142*38103Sbostic if (count <= 0) { 143*38103Sbostic error("non-positive repetition count"); 144*38103Sbostic } else { 145*38103Sbostic newaddr = addr; 146*38103Sbostic for (i = 0; i < count; i++) { 147*38103Sbostic newaddr = printop(newaddr); 148*38103Sbostic } 149*38103Sbostic prtaddr = newaddr; 150*38103Sbostic } 151*38103Sbostic } 152*38103Sbostic 153*38103Sbostic /* 154*38103Sbostic * Print the contents of the addresses within the given range 155*38103Sbostic * according to the given format. 156*38103Sbostic */ 157*38103Sbostic 158*38103Sbostic typedef struct { 159*38103Sbostic String name; 160*38103Sbostic String printfstring; 161*38103Sbostic int length; 162*38103Sbostic } Format; 163*38103Sbostic 164*38103Sbostic private Format fmt[] = { 165*38103Sbostic { "d", " %d", sizeof(short) }, 166*38103Sbostic { "D", " %ld", sizeof(long) }, 167*38103Sbostic { "o", " %o", sizeof(short) }, 168*38103Sbostic { "O", " %lo", sizeof(long) }, 169*38103Sbostic { "x", " %04x", sizeof(short) }, 170*38103Sbostic { "X", " %08x", sizeof(long) }, 171*38103Sbostic { "b", " \\%o", sizeof(char) }, 172*38103Sbostic { "c", " '%c'", sizeof(char) }, 173*38103Sbostic { "s", "%c", sizeof(char) }, 174*38103Sbostic { "f", " %f", sizeof(float) }, 175*38103Sbostic { "g", " %g", sizeof(double) }, 176*38103Sbostic { nil, nil, 0 } 177*38103Sbostic }; 178*38103Sbostic 179*38103Sbostic private Format *findformat(s) 180*38103Sbostic String s; 181*38103Sbostic { 182*38103Sbostic register Format *f; 183*38103Sbostic 184*38103Sbostic f = &fmt[0]; 185*38103Sbostic while (f->name != nil and not streq(f->name, s)) { 186*38103Sbostic ++f; 187*38103Sbostic } 188*38103Sbostic if (f->name == nil) { 189*38103Sbostic error("bad print format \"%s\"", s); 190*38103Sbostic } 191*38103Sbostic return f; 192*38103Sbostic } 193*38103Sbostic 194*38103Sbostic /* 195*38103Sbostic * Retrieve and print out the appropriate data in the given format. 196*38103Sbostic * Floats have to be handled specially to allow the compiler to 197*38103Sbostic * convert them to doubles when passing to printf. 198*38103Sbostic */ 199*38103Sbostic 200*38103Sbostic private printformat (f, addr) 201*38103Sbostic Format *f; 202*38103Sbostic Address addr; 203*38103Sbostic { 204*38103Sbostic union { 205*38103Sbostic char charv; 206*38103Sbostic short shortv; 207*38103Sbostic int intv; 208*38103Sbostic float floatv; 209*38103Sbostic double doublev; 210*38103Sbostic } value; 211*38103Sbostic 212*38103Sbostic value.intv = 0; 213*38103Sbostic dread(&value, addr, f->length); 214*38103Sbostic if (streq(f->name, "f")) { 215*38103Sbostic printf(f->printfstring, value.floatv); 216*38103Sbostic } else { 217*38103Sbostic printf(f->printfstring, value); 218*38103Sbostic } 219*38103Sbostic } 220*38103Sbostic 221*38103Sbostic public Address printdata(lowaddr, highaddr, format) 222*38103Sbostic Address lowaddr; 223*38103Sbostic Address highaddr; 224*38103Sbostic String format; 225*38103Sbostic { 226*38103Sbostic int n; 227*38103Sbostic register Address addr; 228*38103Sbostic Format *f; 229*38103Sbostic 230*38103Sbostic if (lowaddr > highaddr) { 231*38103Sbostic error("first address larger than second"); 232*38103Sbostic } 233*38103Sbostic f = findformat(format); 234*38103Sbostic n = 0; 235*38103Sbostic for (addr = lowaddr; addr <= highaddr; addr += f->length) { 236*38103Sbostic if (n == 0) { 237*38103Sbostic printf("%08x: ", addr); 238*38103Sbostic } 239*38103Sbostic printformat(f, addr); 240*38103Sbostic ++n; 241*38103Sbostic if (n >= (16 div f->length)) { 242*38103Sbostic printf("\n"); 243*38103Sbostic n = 0; 244*38103Sbostic } 245*38103Sbostic } 246*38103Sbostic if (n != 0) { 247*38103Sbostic printf("\n"); 248*38103Sbostic } 249*38103Sbostic prtaddr = addr; 250*38103Sbostic return addr; 251*38103Sbostic } 252*38103Sbostic 253*38103Sbostic /* 254*38103Sbostic * The other approach is to print n items starting with a given address. 255*38103Sbostic */ 256*38103Sbostic 257*38103Sbostic public printndata(count, startaddr, format) 258*38103Sbostic int count; 259*38103Sbostic Address startaddr; 260*38103Sbostic String format; 261*38103Sbostic { 262*38103Sbostic int i, n; 263*38103Sbostic Address addr; 264*38103Sbostic Format *f; 265*38103Sbostic Boolean isstring; 266*38103Sbostic char c; 267*38103Sbostic 268*38103Sbostic if (count <= 0) { 269*38103Sbostic error("non-positive repetition count"); 270*38103Sbostic } 271*38103Sbostic f = findformat(format); 272*38103Sbostic isstring = (Boolean) streq(f->name, "s"); 273*38103Sbostic n = 0; 274*38103Sbostic addr = startaddr; 275*38103Sbostic for (i = 0; i < count; i++) { 276*38103Sbostic if (n == 0) { 277*38103Sbostic printf("%08x: ", addr); 278*38103Sbostic } 279*38103Sbostic if (isstring) { 280*38103Sbostic printf("\""); 281*38103Sbostic dread(&c, addr, sizeof(char)); 282*38103Sbostic while (c != '\0') { 283*38103Sbostic printchar(c); 284*38103Sbostic ++addr; 285*38103Sbostic dread(&c, addr, sizeof(char)); 286*38103Sbostic } 287*38103Sbostic printf("\"\n"); 288*38103Sbostic n = 0; 289*38103Sbostic addr += sizeof(String); 290*38103Sbostic } else { 291*38103Sbostic printformat(f, addr); 292*38103Sbostic ++n; 293*38103Sbostic if (n >= (16 div f->length)) { 294*38103Sbostic printf("\n"); 295*38103Sbostic n = 0; 296*38103Sbostic } 297*38103Sbostic addr += f->length; 298*38103Sbostic } 299*38103Sbostic } 300*38103Sbostic if (n != 0) { 301*38103Sbostic printf("\n"); 302*38103Sbostic } 303*38103Sbostic prtaddr = addr; 304*38103Sbostic } 305*38103Sbostic 306*38103Sbostic /* 307*38103Sbostic * Print out a value according to the given format. 308*38103Sbostic */ 309*38103Sbostic 310*38103Sbostic public printvalue(v, format) 311*38103Sbostic long v; 312*38103Sbostic String format; 313*38103Sbostic { 314*38103Sbostic Format *f; 315*38103Sbostic char *p, *q; 316*38103Sbostic 317*38103Sbostic f = findformat(format); 318*38103Sbostic if (streq(f->name, "s")) { 319*38103Sbostic putchar('"'); 320*38103Sbostic p = (char *) &v; 321*38103Sbostic q = p + sizeof(v); 322*38103Sbostic while (p < q) { 323*38103Sbostic printchar(*p); 324*38103Sbostic ++p; 325*38103Sbostic } 326*38103Sbostic putchar('"'); 327*38103Sbostic } else { 328*38103Sbostic printf(f->printfstring, v); 329*38103Sbostic } 330*38103Sbostic putchar('\n'); 331*38103Sbostic } 332*38103Sbostic 333*38103Sbostic /* 334*38103Sbostic * Print out an execution time error. 335*38103Sbostic * Assumes the source position of the error has been calculated. 336*38103Sbostic * 337*38103Sbostic * Have to check if the -r option was specified; if so then 338*38103Sbostic * the object file information hasn't been read in yet. 339*38103Sbostic */ 340*38103Sbostic 341*38103Sbostic public printerror() 342*38103Sbostic { 343*38103Sbostic extern Integer sys_nsig; 344*38103Sbostic extern String sys_siglist[]; 345*38103Sbostic integer err; 346*38103Sbostic 347*38103Sbostic if (isfinished(process)) { 348*38103Sbostic err = exitcode(process); 349*38103Sbostic if (err == 0) { 350*38103Sbostic printf("\"%s\" terminated normally\n", objname); 351*38103Sbostic } else { 352*38103Sbostic printf("\"%s\" terminated abnormally (exit code %d)\n", 353*38103Sbostic objname, err 354*38103Sbostic ); 355*38103Sbostic } 356*38103Sbostic erecover(); 357*38103Sbostic } 358*38103Sbostic err = errnum(process); 359*38103Sbostic putchar('\n'); 360*38103Sbostic printsig(err); 361*38103Sbostic putchar(' '); 362*38103Sbostic printloc(); 363*38103Sbostic putchar('\n'); 364*38103Sbostic if (curline > 0) { 365*38103Sbostic printlines(curline, curline); 366*38103Sbostic } else { 367*38103Sbostic printinst(pc, pc); 368*38103Sbostic } 369*38103Sbostic erecover(); 370*38103Sbostic } 371*38103Sbostic 372*38103Sbostic /* 373*38103Sbostic * Print out a signal. 374*38103Sbostic */ 375*38103Sbostic 376*38103Sbostic private String illinames[] = { 377*38103Sbostic "reserved addressing fault", 378*38103Sbostic "privileged instruction fault", 379*38103Sbostic "reserved operand fault" 380*38103Sbostic }; 381*38103Sbostic 382*38103Sbostic private String fpenames[] = { 383*38103Sbostic nil, 384*38103Sbostic "integer overflow trap", 385*38103Sbostic "integer divide by zero trap", 386*38103Sbostic "floating overflow trap", 387*38103Sbostic "floating/decimal divide by zero trap", 388*38103Sbostic "floating underflow trap", 389*38103Sbostic "decimal overflow trap", 390*38103Sbostic "subscript out of range trap", 391*38103Sbostic "floating overflow fault", 392*38103Sbostic "floating divide by zero fault", 393*38103Sbostic "floating underflow fault" 394*38103Sbostic }; 395*38103Sbostic 396*38103Sbostic public printsig (signo) 397*38103Sbostic integer signo; 398*38103Sbostic { 399*38103Sbostic integer code; 400*38103Sbostic 401*38103Sbostic if (signo < 0 or signo > sys_nsig) { 402*38103Sbostic printf("[signal %d]", signo); 403*38103Sbostic } else { 404*38103Sbostic printf("%s", sys_siglist[signo]); 405*38103Sbostic } 406*38103Sbostic code = errcode(process); 407*38103Sbostic if (signo == SIGILL) { 408*38103Sbostic if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) { 409*38103Sbostic printf(" (%s)", illinames[code]); 410*38103Sbostic } 411*38103Sbostic } else if (signo == SIGFPE) { 412*38103Sbostic if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) { 413*38103Sbostic printf(" (%s)", fpenames[code]); 414*38103Sbostic } 415*38103Sbostic } 416*38103Sbostic } 417*38103Sbostic 418*38103Sbostic /* 419*38103Sbostic * Note the termination of the program. We do this so as to avoid 420*38103Sbostic * having the process exit, which would make the values of variables 421*38103Sbostic * inaccessible. We do want to flush all output buffers here, 422*38103Sbostic * otherwise it'll never get done. 423*38103Sbostic */ 424*38103Sbostic 425*38103Sbostic public endprogram() 426*38103Sbostic { 427*38103Sbostic Integer exitcode; 428*38103Sbostic 429*38103Sbostic stepto(nextaddr(pc, true)); 430*38103Sbostic printnews(); 431*38103Sbostic exitcode = argn(1, nil); 432*38103Sbostic if (exitcode != 0) { 433*38103Sbostic printf("\nexecution completed (exit code %d)\n", exitcode); 434*38103Sbostic } else { 435*38103Sbostic printf("\nexecution completed\n"); 436*38103Sbostic } 437*38103Sbostic getsrcpos(); 438*38103Sbostic erecover(); 439*38103Sbostic } 440*38103Sbostic 441*38103Sbostic /* 442*38103Sbostic * Single step the machine a source line (or instruction if "inst_tracing" 443*38103Sbostic * is true). If "isnext" is true, skip over procedure calls. 444*38103Sbostic */ 445*38103Sbostic 446*38103Sbostic private Address getcall(); 447*38103Sbostic 448*38103Sbostic public dostep(isnext) 449*38103Sbostic Boolean isnext; 450*38103Sbostic { 451*38103Sbostic register Address addr; 452*38103Sbostic register Lineno line; 453*38103Sbostic String filename; 454*38103Sbostic Address startaddr; 455*38103Sbostic 456*38103Sbostic startaddr = pc; 457*38103Sbostic addr = nextaddr(pc, isnext); 458*38103Sbostic if (not inst_tracing and nlhdr.nlines != 0) { 459*38103Sbostic line = linelookup(addr); 460*38103Sbostic while (line == 0) { 461*38103Sbostic addr = nextaddr(addr, isnext); 462*38103Sbostic line = linelookup(addr); 463*38103Sbostic } 464*38103Sbostic curline = line; 465*38103Sbostic } else { 466*38103Sbostic curline = 0; 467*38103Sbostic } 468*38103Sbostic stepto(addr); 469*38103Sbostic filename = srcfilename(addr); 470*38103Sbostic setsource(filename); 471*38103Sbostic } 472*38103Sbostic 473*38103Sbostic typedef short Bpinst; 474*38103Sbostic 475*38103Sbostic extern Bpinst BP_OP; 476*38103Sbostic #ifdef sun 477*38103Sbostic asm("_BP_OP: trap #15"); 478*38103Sbostic #else /* IRIS */ 479*38103Sbostic asm("_BP_OP: trap #1"); 480*38103Sbostic #endif 481*38103Sbostic 482*38103Sbostic #define BP_ERRNO SIGTRAP /* signal received at a breakpoint */ 483*38103Sbostic 484*38103Sbostic /* 485*38103Sbostic * Setting a breakpoint at a location consists of saving 486*38103Sbostic * the word at the location and poking a BP_OP there. 487*38103Sbostic * 488*38103Sbostic * We save the locations and words on a list for use in unsetting. 489*38103Sbostic */ 490*38103Sbostic 491*38103Sbostic typedef struct Savelist *Savelist; 492*38103Sbostic 493*38103Sbostic struct Savelist { 494*38103Sbostic Address location; 495*38103Sbostic Bpinst save; 496*38103Sbostic short refcount; 497*38103Sbostic Savelist link; 498*38103Sbostic }; 499*38103Sbostic 500*38103Sbostic private Savelist savelist; 501*38103Sbostic 502*38103Sbostic /* 503*38103Sbostic * Set a breakpoint at the given address. Only save the word there 504*38103Sbostic * if it's not already a breakpoint. 505*38103Sbostic */ 506*38103Sbostic 507*38103Sbostic public setbp(addr) 508*38103Sbostic Address addr; 509*38103Sbostic { 510*38103Sbostic Bpinst w, save; 511*38103Sbostic register Savelist newsave, s; 512*38103Sbostic 513*38103Sbostic for (s = savelist; s != nil; s = s->link) { 514*38103Sbostic if (s->location == addr) { 515*38103Sbostic s->refcount++; 516*38103Sbostic return; 517*38103Sbostic } 518*38103Sbostic } 519*38103Sbostic iread(&save, addr, sizeof(save)); 520*38103Sbostic newsave = new(Savelist); 521*38103Sbostic newsave->location = addr; 522*38103Sbostic newsave->save = save; 523*38103Sbostic newsave->refcount = 1; 524*38103Sbostic newsave->link = savelist; 525*38103Sbostic savelist = newsave; 526*38103Sbostic w = BP_OP; 527*38103Sbostic iwrite(&w, addr, sizeof(w)); 528*38103Sbostic } 529*38103Sbostic 530*38103Sbostic /* 531*38103Sbostic * Unset a breakpoint; unfortunately we have to search the SAVELIST 532*38103Sbostic * to find the saved value. The assumption is that the SAVELIST will 533*38103Sbostic * usually be quite small. 534*38103Sbostic */ 535*38103Sbostic 536*38103Sbostic public unsetbp(addr) 537*38103Sbostic Address addr; 538*38103Sbostic { 539*38103Sbostic register Savelist s, prev; 540*38103Sbostic 541*38103Sbostic prev = nil; 542*38103Sbostic for (s = savelist; s != nil; s = s->link) { 543*38103Sbostic if (s->location == addr) { 544*38103Sbostic iwrite(&s->save, addr, sizeof(s->save)); 545*38103Sbostic s->refcount--; 546*38103Sbostic if (s->refcount == 0) { 547*38103Sbostic if (prev == nil) { 548*38103Sbostic savelist = s->link; 549*38103Sbostic } else { 550*38103Sbostic prev->link = s->link; 551*38103Sbostic } 552*38103Sbostic dispose(s); 553*38103Sbostic } 554*38103Sbostic return; 555*38103Sbostic } 556*38103Sbostic prev = s; 557*38103Sbostic } 558*38103Sbostic panic("unsetbp: couldn't find address %d", addr); 559*38103Sbostic } 560*38103Sbostic 561*38103Sbostic /* 562*38103Sbostic * Instruction decoding routines for 68000, derived from adb. 563*38103Sbostic * 564*38103Sbostic * The shared boolean variable "printing" is true if the decoded 565*38103Sbostic * instruction is to be printed, false if not. In either case, 566*38103Sbostic * the address of the next instruction after the given one is returned. 567*38103Sbostic */ 568*38103Sbostic 569*38103Sbostic private Boolean printing; 570*38103Sbostic private Boolean following; 571*38103Sbostic private Boolean followcalls; 572*38103Sbostic private Address instaddr; 573*38103Sbostic 574*38103Sbostic #define instread(var) \ 575*38103Sbostic { \ 576*38103Sbostic iread(&var, instaddr, sizeof(var)); \ 577*38103Sbostic instaddr += sizeof(var); \ 578*38103Sbostic } 579*38103Sbostic 580*38103Sbostic private Optab *decode(inst, addr) 581*38103Sbostic Word inst; 582*38103Sbostic Address addr; 583*38103Sbostic { 584*38103Sbostic register Optab *o; 585*38103Sbostic 586*38103Sbostic o = &optab[0]; 587*38103Sbostic while (o->mask != 0 and (inst&o->mask) != o->match) { 588*38103Sbostic ++o; 589*38103Sbostic } 590*38103Sbostic return o; 591*38103Sbostic } 592*38103Sbostic 593*38103Sbostic private Address printop(addr) 594*38103Sbostic Address addr; 595*38103Sbostic { 596*38103Sbostic Optab *o; 597*38103Sbostic short inst; 598*38103Sbostic 599*38103Sbostic printf("%08x ", addr); 600*38103Sbostic iread(&inst, addr, sizeof(inst)); 601*38103Sbostic o = decode(inst, addr); 602*38103Sbostic if (o->mask == 0) { 603*38103Sbostic printf("\tbadop"); 604*38103Sbostic instaddr = addr + sizeof(inst); 605*38103Sbostic } else { 606*38103Sbostic printing = true; 607*38103Sbostic following = false; 608*38103Sbostic instaddr = addr + sizeof(inst); 609*38103Sbostic (*o->opfun)(inst, o->farg); 610*38103Sbostic printing = false; 611*38103Sbostic } 612*38103Sbostic printf("\n"); 613*38103Sbostic return instaddr; 614*38103Sbostic } 615*38103Sbostic 616*38103Sbostic /* 617*38103Sbostic * Quickly find the return address of the current procedure or function 618*38103Sbostic * while single stepping. Just get the word pointed at by sp. 619*38103Sbostic */ 620*38103Sbostic 621*38103Sbostic private Address currtnaddr () 622*38103Sbostic { 623*38103Sbostic Address retaddr; 624*38103Sbostic 625*38103Sbostic dread(&retaddr, reg(STKP), sizeof(retaddr)); 626*38103Sbostic return retaddr; 627*38103Sbostic } 628*38103Sbostic 629*38103Sbostic /* 630*38103Sbostic * Print out the effective address for the given parameters. 631*38103Sbostic */ 632*38103Sbostic 633*38103Sbostic private printea(mode, reg, size) 634*38103Sbostic long mode, reg; 635*38103Sbostic int size; 636*38103Sbostic { 637*38103Sbostic long index, disp; 638*38103Sbostic static char *aregs[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp" }; 639*38103Sbostic Byte b; 640*38103Sbostic short w; 641*38103Sbostic long l; 642*38103Sbostic 643*38103Sbostic switch ((int)(mode)) { 644*38103Sbostic case 0: 645*38103Sbostic if (printing) { 646*38103Sbostic printf("d%D", reg); 647*38103Sbostic } 648*38103Sbostic break; 649*38103Sbostic 650*38103Sbostic case 1: 651*38103Sbostic if (printing) { 652*38103Sbostic printf("%s", aregs[reg]); 653*38103Sbostic } 654*38103Sbostic break; 655*38103Sbostic 656*38103Sbostic case 2: 657*38103Sbostic if (printing) { 658*38103Sbostic printf("%s@", aregs[reg]); 659*38103Sbostic } 660*38103Sbostic break; 661*38103Sbostic 662*38103Sbostic case 3: 663*38103Sbostic if (printing) { 664*38103Sbostic printf("%s@+", aregs[reg]); 665*38103Sbostic } 666*38103Sbostic break; 667*38103Sbostic 668*38103Sbostic case 4: 669*38103Sbostic if (printing) { 670*38103Sbostic printf("%s@-", aregs[reg]); 671*38103Sbostic } 672*38103Sbostic break; 673*38103Sbostic 674*38103Sbostic case 5: 675*38103Sbostic instread(w); 676*38103Sbostic if (printing) { 677*38103Sbostic printf("%s@(%D)", aregs[reg], w); 678*38103Sbostic } 679*38103Sbostic break; 680*38103Sbostic 681*38103Sbostic case 6: 682*38103Sbostic instread(w); 683*38103Sbostic if (printing) { 684*38103Sbostic index = w; 685*38103Sbostic disp = (char)(index&0377); 686*38103Sbostic printf("%s@(%d,%c%D:%c)", aregs[reg], disp, 687*38103Sbostic (index&0100000)?'a':'d',(index>>12)&07, 688*38103Sbostic (index&04000)?'l':'w'); 689*38103Sbostic } 690*38103Sbostic break; 691*38103Sbostic 692*38103Sbostic case 7: 693*38103Sbostic switch ((int)(reg)) { 694*38103Sbostic case 0: 695*38103Sbostic instread(w); 696*38103Sbostic if (printing) { 697*38103Sbostic index = w; 698*38103Sbostic psymoff(index); 699*38103Sbostic } 700*38103Sbostic break; 701*38103Sbostic 702*38103Sbostic case 1: 703*38103Sbostic instread(l); 704*38103Sbostic if (printing) { 705*38103Sbostic index = l; 706*38103Sbostic psymoff(index); 707*38103Sbostic } 708*38103Sbostic break; 709*38103Sbostic 710*38103Sbostic case 2: 711*38103Sbostic instread(w); 712*38103Sbostic if (printing) { 713*38103Sbostic disp = w; 714*38103Sbostic psymoff(disp + instaddr); 715*38103Sbostic } 716*38103Sbostic break; 717*38103Sbostic 718*38103Sbostic case 3: 719*38103Sbostic instread(w); 720*38103Sbostic if (printing) { 721*38103Sbostic index = w; 722*38103Sbostic disp = (char)(index&0377); 723*38103Sbostic printf("pc@(%D,%c%D:%c)", disp, 724*38103Sbostic (index&0100000)?'a':'d',(index>>12)&07, 725*38103Sbostic (index&04000)?'l':'w'); 726*38103Sbostic } 727*38103Sbostic break; 728*38103Sbostic 729*38103Sbostic case 4: 730*38103Sbostic switch (size) { 731*38103Sbostic case sizeof(b): 732*38103Sbostic instread(w); 733*38103Sbostic index = (w&0xff); 734*38103Sbostic break; 735*38103Sbostic 736*38103Sbostic case sizeof(w): 737*38103Sbostic instread(w); 738*38103Sbostic index = w; 739*38103Sbostic break; 740*38103Sbostic 741*38103Sbostic case sizeof(l): 742*38103Sbostic instread(l); 743*38103Sbostic index = l; 744*38103Sbostic break; 745*38103Sbostic 746*38103Sbostic default: 747*38103Sbostic if (printing) { 748*38103Sbostic printf("unexpected size %d in printea\n", size); 749*38103Sbostic } 750*38103Sbostic instread(l); 751*38103Sbostic index = l; 752*38103Sbostic break; 753*38103Sbostic } 754*38103Sbostic if (printing) { 755*38103Sbostic printf(IMDF, index); 756*38103Sbostic } 757*38103Sbostic break; 758*38103Sbostic 759*38103Sbostic default: 760*38103Sbostic if (printing) { 761*38103Sbostic printf("???"); 762*38103Sbostic } 763*38103Sbostic break; 764*38103Sbostic } 765*38103Sbostic break; 766*38103Sbostic 767*38103Sbostic default: 768*38103Sbostic if (printing) { 769*38103Sbostic printf("???"); 770*38103Sbostic } 771*38103Sbostic break; 772*38103Sbostic } 773*38103Sbostic } 774*38103Sbostic 775*38103Sbostic private printEA(ea, size) 776*38103Sbostic long ea; 777*38103Sbostic int size; 778*38103Sbostic { 779*38103Sbostic printea((ea>>3)&07, ea&07, size); 780*38103Sbostic } 781*38103Sbostic 782*38103Sbostic private mapsize(inst) 783*38103Sbostic register long inst; 784*38103Sbostic { 785*38103Sbostic int m; 786*38103Sbostic 787*38103Sbostic inst >>= 6; 788*38103Sbostic inst &= 03; 789*38103Sbostic switch (inst) { 790*38103Sbostic case 0: 791*38103Sbostic m = 1; 792*38103Sbostic break; 793*38103Sbostic 794*38103Sbostic case 1: 795*38103Sbostic m = 2; 796*38103Sbostic break; 797*38103Sbostic 798*38103Sbostic case 2: 799*38103Sbostic m = 4; 800*38103Sbostic break; 801*38103Sbostic 802*38103Sbostic default: 803*38103Sbostic m = -1; 804*38103Sbostic break; 805*38103Sbostic } 806*38103Sbostic return m; 807*38103Sbostic } 808*38103Sbostic 809*38103Sbostic private char suffix(size) 810*38103Sbostic int size; 811*38103Sbostic { 812*38103Sbostic char c; 813*38103Sbostic 814*38103Sbostic switch (size) { 815*38103Sbostic case 1: 816*38103Sbostic c = 'b'; 817*38103Sbostic break; 818*38103Sbostic 819*38103Sbostic case 2: 820*38103Sbostic c = 'w'; 821*38103Sbostic break; 822*38103Sbostic 823*38103Sbostic case 4: 824*38103Sbostic c = 'l'; 825*38103Sbostic break; 826*38103Sbostic 827*38103Sbostic default: 828*38103Sbostic panic("bad size %d in suffix", size); 829*38103Sbostic } 830*38103Sbostic return c; 831*38103Sbostic } 832*38103Sbostic 833*38103Sbostic /* 834*38103Sbostic * Print an address offset. Eventually this should attempt to be symbolic, 835*38103Sbostic * but for now its just printed in hex. 836*38103Sbostic */ 837*38103Sbostic 838*38103Sbostic private psymoff (off) 839*38103Sbostic Word off; 840*38103Sbostic { 841*38103Sbostic Symbol f; 842*38103Sbostic 843*38103Sbostic f = whatblock((Address) (off + FUNCOFFSET)); 844*38103Sbostic if (codeloc(f) == off + FUNCOFFSET) { 845*38103Sbostic printf("%s", symname(f)); 846*38103Sbostic } else { 847*38103Sbostic printf("0x%x", off); 848*38103Sbostic } 849*38103Sbostic } 850*38103Sbostic 851*38103Sbostic /* 852*38103Sbostic * Instruction class specific routines. 853*38103Sbostic */ 854*38103Sbostic 855*38103Sbostic public omove(inst, s) 856*38103Sbostic long inst; 857*38103Sbostic String s; 858*38103Sbostic { 859*38103Sbostic register int c; 860*38103Sbostic int size; 861*38103Sbostic 862*38103Sbostic c = s[0]; 863*38103Sbostic if (printing) { 864*38103Sbostic printf("\tmov%c\t", c); 865*38103Sbostic } 866*38103Sbostic size = ((c == 'b') ? 1 : (c == 'w') ? 2 : 4); 867*38103Sbostic printea((inst>>3)&07, inst&07, size); 868*38103Sbostic if (printing) { 869*38103Sbostic printf(","); 870*38103Sbostic } 871*38103Sbostic printea((inst>>6)&07, (inst>>9)&07, size); 872*38103Sbostic } 873*38103Sbostic 874*38103Sbostic /* 875*38103Sbostic * Two types: bsr (4 bytes) and bsrs (2 bytes) 876*38103Sbostic */ 877*38103Sbostic 878*38103Sbostic public obranch(inst, dummy) 879*38103Sbostic long inst; 880*38103Sbostic { 881*38103Sbostic long disp; 882*38103Sbostic String s; 883*38103Sbostic short w; 884*38103Sbostic Address startingaddr; /* address of branch instruction */ 885*38103Sbostic int branchtype; /* type of branch (0 = unconditional) */ 886*38103Sbostic Address dest; 887*38103Sbostic Address retaddr; /* for bsr instruction */ 888*38103Sbostic 889*38103Sbostic startingaddr = instaddr - 2; 890*38103Sbostic disp = inst&0377; 891*38103Sbostic s = "s "; 892*38103Sbostic if (disp == 0) { 893*38103Sbostic retaddr = startingaddr + 4; 894*38103Sbostic } else { 895*38103Sbostic retaddr = startingaddr + 2; 896*38103Sbostic } 897*38103Sbostic if (disp > 127) { 898*38103Sbostic disp |= ~0377; 899*38103Sbostic } else if (disp == 0){ 900*38103Sbostic s = " "; 901*38103Sbostic instread(w); 902*38103Sbostic disp = w; 903*38103Sbostic } 904*38103Sbostic branchtype = (int)((inst>>8)&017); 905*38103Sbostic dest = startingaddr + 2 + disp; 906*38103Sbostic if (printing) { 907*38103Sbostic printf("\tb%s%s\t", bname[branchtype], s); 908*38103Sbostic psymoff(dest); 909*38103Sbostic } 910*38103Sbostic if (following) { 911*38103Sbostic /* 912*38103Sbostic * If we're to follow the dynamic flow of instructions, 913*38103Sbostic * we must see where the branch leads. A branchtype of 0 914*38103Sbostic * indicates an unconditional branch which we simply take 915*38103Sbostic * as the new instruction address. For a conditional branch, 916*38103Sbostic * we continue execution up to the current address, single step, 917*38103Sbostic * and keep going. 918*38103Sbostic */ 919*38103Sbostic if (branchtype == 0) { 920*38103Sbostic instaddr = dest; 921*38103Sbostic } else if (branchtype == 01) { /* bsr */ 922*38103Sbostic if (followcalls) { 923*38103Sbostic steppast(startingaddr); 924*38103Sbostic curfunc = whatblock(pc, true); 925*38103Sbostic if (not isbperr()) { 926*38103Sbostic printstatus(); 927*38103Sbostic /* NOTREACHED */ 928*38103Sbostic } 929*38103Sbostic bpact(); 930*38103Sbostic if (nosource(curfunc) and canskip(curfunc) and 931*38103Sbostic nlhdr.nlines != 0) { 932*38103Sbostic stepto(retaddr); 933*38103Sbostic instaddr = pc; 934*38103Sbostic bpact(); 935*38103Sbostic } else { 936*38103Sbostic callnews(/* iscall = */ true); 937*38103Sbostic } 938*38103Sbostic } 939*38103Sbostic } else { 940*38103Sbostic steppast(startingaddr); 941*38103Sbostic } 942*38103Sbostic } 943*38103Sbostic } 944*38103Sbostic 945*38103Sbostic public odbcc(inst, form) 946*38103Sbostic long inst; 947*38103Sbostic String form; 948*38103Sbostic { 949*38103Sbostic long disp; 950*38103Sbostic short w; 951*38103Sbostic 952*38103Sbostic instread(w); 953*38103Sbostic if (printing) { 954*38103Sbostic printf(form, dbname[(int)((inst>>8)&017)], inst&07); 955*38103Sbostic psymoff(w + sizeof(w)); 956*38103Sbostic } 957*38103Sbostic } 958*38103Sbostic 959*38103Sbostic public oscc(inst, dummy) 960*38103Sbostic long inst; 961*38103Sbostic long dummy; 962*38103Sbostic { 963*38103Sbostic if (printing) { 964*38103Sbostic printf("\ts%s\t", cname[(int)((inst>>8)&017)]); 965*38103Sbostic } 966*38103Sbostic printea((inst>>3)&07, inst&07, 1); 967*38103Sbostic } 968*38103Sbostic 969*38103Sbostic public biti(inst, dummy) 970*38103Sbostic long inst; 971*38103Sbostic long dummy; 972*38103Sbostic { 973*38103Sbostic short w; 974*38103Sbostic 975*38103Sbostic if (printing) { 976*38103Sbostic printf("\t%s\t", bit[(int)((inst>>6)&03)]); 977*38103Sbostic } 978*38103Sbostic if (inst&0x0100) { 979*38103Sbostic if (printing) { 980*38103Sbostic printf("d%D,", inst>>9); 981*38103Sbostic } 982*38103Sbostic } else { 983*38103Sbostic instread(w); 984*38103Sbostic if (printing) { 985*38103Sbostic printf(IMDF, w); 986*38103Sbostic printf(","); 987*38103Sbostic } 988*38103Sbostic } 989*38103Sbostic printEA(inst); 990*38103Sbostic } 991*38103Sbostic 992*38103Sbostic public opmode(inst, opcode) 993*38103Sbostic long inst; 994*38103Sbostic long opcode; 995*38103Sbostic { 996*38103Sbostic register int opmode; 997*38103Sbostic register int reg; 998*38103Sbostic int size; 999*38103Sbostic 1000*38103Sbostic opmode = (int)((inst>>6) & 07); 1001*38103Sbostic reg = (int)((inst>>9) & 07); 1002*38103Sbostic if (opmode == 0 or opmode == 4) { 1003*38103Sbostic size = 1; 1004*38103Sbostic } else if (opmode == 1 or opmode == 3 or opmode == 5) { 1005*38103Sbostic size = 2; 1006*38103Sbostic } else { 1007*38103Sbostic size = 4; 1008*38103Sbostic } 1009*38103Sbostic if (printing) { 1010*38103Sbostic printf("\t%s%c\t", opcode, suffix(size)); 1011*38103Sbostic } 1012*38103Sbostic if (opmode >= 4 and opmode <= 6) { 1013*38103Sbostic if (printing) { 1014*38103Sbostic printf("d%d,", reg); 1015*38103Sbostic } 1016*38103Sbostic printea((inst>>3)&07, inst&07, size); 1017*38103Sbostic } else { 1018*38103Sbostic printea((inst>>3)&07, inst&07, size); 1019*38103Sbostic if (printing) { 1020*38103Sbostic printf(",%c%d",(opmode<=2) ? 'd' : 'a', reg); 1021*38103Sbostic } 1022*38103Sbostic } 1023*38103Sbostic } 1024*38103Sbostic 1025*38103Sbostic public shroi(inst, ds) 1026*38103Sbostic long inst; 1027*38103Sbostic String ds; 1028*38103Sbostic { 1029*38103Sbostic int rx, ry; 1030*38103Sbostic String opcode; 1031*38103Sbostic 1032*38103Sbostic if ((inst & 0xC0) == 0xC0) { 1033*38103Sbostic opcode = shro[(int)((inst>>9)&03)]; 1034*38103Sbostic if (printing) { 1035*38103Sbostic printf("\t%s%s\t", opcode, ds); 1036*38103Sbostic } 1037*38103Sbostic printEA(inst); 1038*38103Sbostic } else { 1039*38103Sbostic if (printing) { 1040*38103Sbostic opcode = shro[(int)((inst>>3)&03)]; 1041*38103Sbostic printf("\t%s%s%c\t", opcode, ds, suffix(mapsize(inst))); 1042*38103Sbostic rx = (int)((inst>>9)&07); ry = (int)(inst&07); 1043*38103Sbostic if ((inst>>5)&01) { 1044*38103Sbostic printf("d%d,d%d", rx, ry); 1045*38103Sbostic } else { 1046*38103Sbostic printf(IMDF, (rx ? rx : 8)); 1047*38103Sbostic printf(",d%d", ry); 1048*38103Sbostic } 1049*38103Sbostic } 1050*38103Sbostic } 1051*38103Sbostic } 1052*38103Sbostic 1053*38103Sbostic public oimmed(inst, opcode) 1054*38103Sbostic long inst; 1055*38103Sbostic register String opcode; 1056*38103Sbostic { 1057*38103Sbostic register int size; 1058*38103Sbostic long const; 1059*38103Sbostic short w; 1060*38103Sbostic 1061*38103Sbostic size = mapsize(inst); 1062*38103Sbostic if (size > 0) { 1063*38103Sbostic if (size == 4) { 1064*38103Sbostic instread(const); 1065*38103Sbostic } else { 1066*38103Sbostic instread(w); 1067*38103Sbostic const = w; 1068*38103Sbostic } 1069*38103Sbostic if (printing) { 1070*38103Sbostic printf("\t%s%c\t", opcode, suffix(size)); 1071*38103Sbostic printf(IMDF, const); 1072*38103Sbostic printf(","); 1073*38103Sbostic } 1074*38103Sbostic printEA(inst, size); 1075*38103Sbostic } else { 1076*38103Sbostic if (printing) { 1077*38103Sbostic printf("\tbadop"); 1078*38103Sbostic } 1079*38103Sbostic } 1080*38103Sbostic } 1081*38103Sbostic 1082*38103Sbostic public oreg(inst, opcode) 1083*38103Sbostic long inst; 1084*38103Sbostic register String opcode; 1085*38103Sbostic { 1086*38103Sbostic if (printing) { 1087*38103Sbostic printf(opcode, (inst & 07)); 1088*38103Sbostic } 1089*38103Sbostic } 1090*38103Sbostic 1091*38103Sbostic public extend(inst, opcode) 1092*38103Sbostic long inst; 1093*38103Sbostic String opcode; 1094*38103Sbostic { 1095*38103Sbostic register int size; 1096*38103Sbostic int ry, rx; 1097*38103Sbostic char c; 1098*38103Sbostic 1099*38103Sbostic if (printing) { 1100*38103Sbostic size = mapsize(inst); 1101*38103Sbostic ry = (inst&07); 1102*38103Sbostic rx = ((inst>>9)&07); 1103*38103Sbostic c = ((inst & 0x1000) ? suffix(size) : ' '); 1104*38103Sbostic printf("\t%s%c\t", opcode, c); 1105*38103Sbostic if (opcode[0] == 'e') { 1106*38103Sbostic if (inst & 0x0080) { 1107*38103Sbostic printf("d%D,a%D", rx, ry); 1108*38103Sbostic } else if (inst & 0x0008) { 1109*38103Sbostic printf("a%D,a%D", rx, ry); 1110*38103Sbostic } else { 1111*38103Sbostic printf("d%D,d%D", rx, ry); 1112*38103Sbostic } 1113*38103Sbostic } else if ((inst & 0xF000) == 0xB000) { 1114*38103Sbostic printf("a%D@+,a%D@+", ry, rx); 1115*38103Sbostic } else if (inst & 0x8) { 1116*38103Sbostic printf("a%D@-,a%D@-", ry, rx); 1117*38103Sbostic } else { 1118*38103Sbostic printf("d%D,d%D", ry, rx); 1119*38103Sbostic } 1120*38103Sbostic } 1121*38103Sbostic } 1122*38103Sbostic 1123*38103Sbostic public olink(inst, dummy) 1124*38103Sbostic long inst; 1125*38103Sbostic long dummy; 1126*38103Sbostic { 1127*38103Sbostic short w; 1128*38103Sbostic 1129*38103Sbostic instread(w); 1130*38103Sbostic if (printing) { 1131*38103Sbostic printf("\tlink\ta%D,", inst&07); 1132*38103Sbostic printf(IMDF, w); 1133*38103Sbostic } 1134*38103Sbostic } 1135*38103Sbostic 1136*38103Sbostic public otrap(inst, dummy) 1137*38103Sbostic long inst; 1138*38103Sbostic { 1139*38103Sbostic if (printing) { 1140*38103Sbostic printf("\ttrap\t"); 1141*38103Sbostic printf(IMDF, inst&017); 1142*38103Sbostic } 1143*38103Sbostic } 1144*38103Sbostic 1145*38103Sbostic public oneop(inst, opcode) 1146*38103Sbostic long inst; 1147*38103Sbostic register String opcode; 1148*38103Sbostic { 1149*38103Sbostic if (printing) { 1150*38103Sbostic printf("\t%s",opcode); 1151*38103Sbostic } 1152*38103Sbostic printEA(inst); 1153*38103Sbostic } 1154*38103Sbostic 1155*38103Sbostic public jsrop(inst, opcode) 1156*38103Sbostic long inst; 1157*38103Sbostic register String opcode; 1158*38103Sbostic { 1159*38103Sbostic Address startingaddr; /* beginning of jsr instruction */ 1160*38103Sbostic Address retaddr; /* can't call return_addr (frame not set up yet) */ 1161*38103Sbostic 1162*38103Sbostic startingaddr = instaddr - 2; 1163*38103Sbostic switch ((inst >> 3) & 07) { 1164*38103Sbostic case 2: 1165*38103Sbostic retaddr = instaddr; /* two byte instruction */ 1166*38103Sbostic break; 1167*38103Sbostic case 5: 1168*38103Sbostic case 6: 1169*38103Sbostic retaddr = instaddr + 2; /* four byte instruction */ 1170*38103Sbostic break; 1171*38103Sbostic case 7: 1172*38103Sbostic default: 1173*38103Sbostic switch (inst & 07) { 1174*38103Sbostic case 0: 1175*38103Sbostic case 2: 1176*38103Sbostic case 3: 1177*38103Sbostic retaddr = instaddr + 2; 1178*38103Sbostic break; 1179*38103Sbostic case 1: 1180*38103Sbostic default: 1181*38103Sbostic retaddr = instaddr + 4; /* six byte instruction */ 1182*38103Sbostic break; 1183*38103Sbostic } 1184*38103Sbostic break; 1185*38103Sbostic } 1186*38103Sbostic if (printing) { 1187*38103Sbostic printf("\t%s",opcode); 1188*38103Sbostic } 1189*38103Sbostic printEA(inst); 1190*38103Sbostic if (following and followcalls) { 1191*38103Sbostic steppast(startingaddr); 1192*38103Sbostic curfunc = whatblock(pc, true); 1193*38103Sbostic if (not isbperr()) { 1194*38103Sbostic printstatus(); 1195*38103Sbostic /* NOTREACHED */ 1196*38103Sbostic } 1197*38103Sbostic bpact(); 1198*38103Sbostic if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) { 1199*38103Sbostic stepto(retaddr); 1200*38103Sbostic instaddr = pc; 1201*38103Sbostic bpact(); 1202*38103Sbostic } else { 1203*38103Sbostic callnews(/* iscall = */ true); 1204*38103Sbostic } 1205*38103Sbostic } 1206*38103Sbostic } 1207*38103Sbostic 1208*38103Sbostic public jmpop(inst, opcode) 1209*38103Sbostic long inst; 1210*38103Sbostic register String opcode; 1211*38103Sbostic { 1212*38103Sbostic Address startingaddr; /* beginning of jump instruction */ 1213*38103Sbostic 1214*38103Sbostic startingaddr = instaddr - 2; 1215*38103Sbostic if (printing) { 1216*38103Sbostic printf("\t%s",opcode); 1217*38103Sbostic } 1218*38103Sbostic printEA(inst); 1219*38103Sbostic if (following) { 1220*38103Sbostic steppast(startingaddr); 1221*38103Sbostic } 1222*38103Sbostic } 1223*38103Sbostic 1224*38103Sbostic public pregmask(mask) 1225*38103Sbostic register int mask; 1226*38103Sbostic { 1227*38103Sbostic register int i; 1228*38103Sbostic register int flag = 0; 1229*38103Sbostic 1230*38103Sbostic if (printing) { 1231*38103Sbostic printf("#<"); 1232*38103Sbostic for (i=0; i<16; i++) { 1233*38103Sbostic if (mask&1) { 1234*38103Sbostic if (flag) { 1235*38103Sbostic printf(","); 1236*38103Sbostic } else { 1237*38103Sbostic ++flag; 1238*38103Sbostic } 1239*38103Sbostic printf("%c%d",(i<8) ? 'd' : 'a', i&07); 1240*38103Sbostic } 1241*38103Sbostic mask >>= 1; 1242*38103Sbostic } 1243*38103Sbostic printf(">"); 1244*38103Sbostic } 1245*38103Sbostic } 1246*38103Sbostic 1247*38103Sbostic public omovem(inst, dummy) 1248*38103Sbostic long inst; 1249*38103Sbostic long dummy; 1250*38103Sbostic { 1251*38103Sbostic register int i, list, mask; 1252*38103Sbostic register int reglist; 1253*38103Sbostic short w; 1254*38103Sbostic 1255*38103Sbostic i = 0; 1256*38103Sbostic list = 0; 1257*38103Sbostic mask = 0100000; 1258*38103Sbostic instread(w); 1259*38103Sbostic reglist = w; 1260*38103Sbostic if ((inst & 070) == 040) { /* predecrement */ 1261*38103Sbostic for (i = 15; i > 0; i -= 2) { 1262*38103Sbostic list |= ((mask & reglist) >> i); 1263*38103Sbostic mask >>= 1; 1264*38103Sbostic } 1265*38103Sbostic for (i = 1; i < 16; i += 2) { 1266*38103Sbostic list |= ((mask & reglist) << i); 1267*38103Sbostic mask >>= 1; 1268*38103Sbostic } 1269*38103Sbostic reglist = list; 1270*38103Sbostic } 1271*38103Sbostic if (printing) { 1272*38103Sbostic printf("\tmovem%c\t",(inst&100)?'l':'w'); 1273*38103Sbostic } 1274*38103Sbostic if (inst&02000) { 1275*38103Sbostic printEA(inst); 1276*38103Sbostic if (printing) { 1277*38103Sbostic printf(","); 1278*38103Sbostic } 1279*38103Sbostic pregmask(reglist); 1280*38103Sbostic } else { 1281*38103Sbostic pregmask(reglist); 1282*38103Sbostic if (printing) { 1283*38103Sbostic printf(","); 1284*38103Sbostic } 1285*38103Sbostic printEA(inst); 1286*38103Sbostic } 1287*38103Sbostic } 1288*38103Sbostic 1289*38103Sbostic public ochk(inst, opcode) 1290*38103Sbostic long inst; 1291*38103Sbostic register String opcode; 1292*38103Sbostic { 1293*38103Sbostic if (printing) { 1294*38103Sbostic printf("\t%s\t", opcode); 1295*38103Sbostic } 1296*38103Sbostic printEA(inst, sizeof(Byte)); 1297*38103Sbostic if (printing) { 1298*38103Sbostic printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07); 1299*38103Sbostic } 1300*38103Sbostic } 1301*38103Sbostic 1302*38103Sbostic public soneop(inst, opcode) 1303*38103Sbostic long inst; 1304*38103Sbostic register String opcode; 1305*38103Sbostic { 1306*38103Sbostic register int size; 1307*38103Sbostic 1308*38103Sbostic size = mapsize(inst); 1309*38103Sbostic if (size > 0) { 1310*38103Sbostic if (printing) { 1311*38103Sbostic printf("\t%s%c\t", opcode, suffix(size)); 1312*38103Sbostic } 1313*38103Sbostic printEA(inst); 1314*38103Sbostic } else { 1315*38103Sbostic if (printing) { 1316*38103Sbostic printf("\tbadop"); 1317*38103Sbostic } 1318*38103Sbostic } 1319*38103Sbostic } 1320*38103Sbostic 1321*38103Sbostic public oquick(inst, opcode) 1322*38103Sbostic long inst; 1323*38103Sbostic register String opcode; 1324*38103Sbostic { 1325*38103Sbostic register int size; 1326*38103Sbostic register int data; 1327*38103Sbostic 1328*38103Sbostic size = mapsize(inst); 1329*38103Sbostic data = (int)((inst>>9) & 07); 1330*38103Sbostic if (data == 0) { 1331*38103Sbostic data = 8; 1332*38103Sbostic } 1333*38103Sbostic if (size > 0) { 1334*38103Sbostic if (printing) { 1335*38103Sbostic printf("\t%s%c\t", opcode, suffix(size)); 1336*38103Sbostic printf(IMDF, data); 1337*38103Sbostic printf(","); 1338*38103Sbostic } 1339*38103Sbostic printEA(inst); 1340*38103Sbostic } else { 1341*38103Sbostic if (printing) { 1342*38103Sbostic printf("\tbadop"); 1343*38103Sbostic } 1344*38103Sbostic } 1345*38103Sbostic } 1346*38103Sbostic 1347*38103Sbostic public omoveq(inst, dummy) 1348*38103Sbostic long inst; 1349*38103Sbostic long dummy; 1350*38103Sbostic { 1351*38103Sbostic register int data; 1352*38103Sbostic 1353*38103Sbostic if (printing) { 1354*38103Sbostic data = (int)(inst & 0377); 1355*38103Sbostic if (data > 127) { 1356*38103Sbostic data |= ~0377; 1357*38103Sbostic } 1358*38103Sbostic printf("\tmoveq\t"); 1359*38103Sbostic printf(IMDF, data); 1360*38103Sbostic printf(",d%D", (inst>>9)&07); 1361*38103Sbostic } 1362*38103Sbostic } 1363*38103Sbostic 1364*38103Sbostic public oprint(inst, opcode) 1365*38103Sbostic long inst; 1366*38103Sbostic register String opcode; 1367*38103Sbostic { 1368*38103Sbostic if (printing) { 1369*38103Sbostic printf("\t%s",opcode); 1370*38103Sbostic } 1371*38103Sbostic } 1372*38103Sbostic 1373*38103Sbostic public ostop(inst, opcode) 1374*38103Sbostic long inst; 1375*38103Sbostic register String opcode; 1376*38103Sbostic { 1377*38103Sbostic short w; 1378*38103Sbostic 1379*38103Sbostic instread(w); 1380*38103Sbostic if (printing) { 1381*38103Sbostic printf(opcode, w); 1382*38103Sbostic } 1383*38103Sbostic } 1384*38103Sbostic 1385*38103Sbostic public orts(inst, opcode) 1386*38103Sbostic long inst; 1387*38103Sbostic register String opcode; 1388*38103Sbostic { 1389*38103Sbostic Address addr; 1390*38103Sbostic 1391*38103Sbostic if (following) { 1392*38103Sbostic callnews(/* iscall = */ false); 1393*38103Sbostic if (inst_tracing) { 1394*38103Sbostic addr = currtnaddr(); 1395*38103Sbostic } else { 1396*38103Sbostic addr = return_addr(); 1397*38103Sbostic if (addr == 0) { 1398*38103Sbostic stepto(instaddr - 2); 1399*38103Sbostic addr = currtnaddr(); 1400*38103Sbostic } 1401*38103Sbostic } 1402*38103Sbostic stepto(addr); 1403*38103Sbostic instaddr = pc; 1404*38103Sbostic } 1405*38103Sbostic if (printing) { 1406*38103Sbostic printf("\t%s",opcode); 1407*38103Sbostic } 1408*38103Sbostic } 1409*38103Sbostic 1410*38103Sbostic /* 1411*38103Sbostic * Not used by C compiler; does an rts but before doing so, pops 1412*38103Sbostic * arg bytes from the stack. 1413*38103Sbostic */ 1414*38103Sbostic 1415*38103Sbostic public ortspop(inst, opcode) 1416*38103Sbostic long inst; 1417*38103Sbostic register String opcode; 1418*38103Sbostic { 1419*38103Sbostic Address addr; 1420*38103Sbostic short w; 1421*38103Sbostic 1422*38103Sbostic instread(w); 1423*38103Sbostic if (following) { 1424*38103Sbostic callnews(/* iscall = */ false); 1425*38103Sbostic if (inst_tracing) { 1426*38103Sbostic addr = currtnaddr(); 1427*38103Sbostic } else { 1428*38103Sbostic addr = return_addr(); 1429*38103Sbostic } 1430*38103Sbostic stepto(addr); 1431*38103Sbostic instaddr = pc; 1432*38103Sbostic } 1433*38103Sbostic if (printing) { 1434*38103Sbostic printf(opcode, w); 1435*38103Sbostic } 1436*38103Sbostic } 1437*38103Sbostic 1438*38103Sbostic public omovs(inst, opcode) 1439*38103Sbostic long inst; 1440*38103Sbostic String opcode; 1441*38103Sbostic { 1442*38103Sbostic register int size; 1443*38103Sbostic register unsigned int controlword; 1444*38103Sbostic short w; 1445*38103Sbostic 1446*38103Sbostic size = mapsize(inst); 1447*38103Sbostic instread(w); 1448*38103Sbostic controlword = w >> 11; 1449*38103Sbostic if (printing) { 1450*38103Sbostic printf("\t%s%c\t", opcode, suffix(size)); 1451*38103Sbostic } 1452*38103Sbostic if (controlword & 1){ 1453*38103Sbostic controlword >>= 1; 1454*38103Sbostic if (printing) { 1455*38103Sbostic printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 ); 1456*38103Sbostic } 1457*38103Sbostic printEA(inst&0xff, size); 1458*38103Sbostic } else { 1459*38103Sbostic controlword >>= 1; 1460*38103Sbostic printEA(inst&0xff, size); 1461*38103Sbostic if (printing) { 1462*38103Sbostic printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7); 1463*38103Sbostic } 1464*38103Sbostic } 1465*38103Sbostic } 1466*38103Sbostic 1467*38103Sbostic public omovc(inst, opcode) 1468*38103Sbostic long inst; 1469*38103Sbostic String opcode; 1470*38103Sbostic { 1471*38103Sbostic register unsigned int controlword; 1472*38103Sbostic String creg; 1473*38103Sbostic short w; 1474*38103Sbostic 1475*38103Sbostic instread(w); 1476*38103Sbostic if (printing) { 1477*38103Sbostic controlword = w; 1478*38103Sbostic switch (controlword & 0xfff) { 1479*38103Sbostic case 0: 1480*38103Sbostic creg = "sfc"; 1481*38103Sbostic break; 1482*38103Sbostic 1483*38103Sbostic case 1: 1484*38103Sbostic creg = "dfc"; 1485*38103Sbostic break; 1486*38103Sbostic 1487*38103Sbostic case 0x800: 1488*38103Sbostic creg = "usp"; 1489*38103Sbostic break; 1490*38103Sbostic 1491*38103Sbostic case 0x801: 1492*38103Sbostic creg = "vbr"; 1493*38103Sbostic break; 1494*38103Sbostic 1495*38103Sbostic default: 1496*38103Sbostic creg = "???"; 1497*38103Sbostic break; 1498*38103Sbostic } 1499*38103Sbostic controlword >>= 12; 1500*38103Sbostic if (inst & 1){ 1501*38103Sbostic printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s", 1502*38103Sbostic opcode, controlword&7, creg ); 1503*38103Sbostic } else { 1504*38103Sbostic printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D", 1505*38103Sbostic opcode, creg, controlword&7 ); 1506*38103Sbostic } 1507*38103Sbostic } 1508*38103Sbostic } 1509*38103Sbostic 1510*38103Sbostic /* 1511*38103Sbostic * Compute the next address that will be executed from the given one. 1512*38103Sbostic * If "isnext" is true then consider a procedure call as straight line code. 1513*38103Sbostic * 1514*38103Sbostic * Unconditional branches we just follow, for conditional branches 1515*38103Sbostic * we continue execution to the current location and then single step 1516*38103Sbostic * the machine. 1517*38103Sbostic */ 1518*38103Sbostic 1519*38103Sbostic public Address nextaddr(startaddr, isnext) 1520*38103Sbostic Address startaddr; 1521*38103Sbostic Boolean isnext; 1522*38103Sbostic { 1523*38103Sbostic Optab *o; 1524*38103Sbostic short inst; 1525*38103Sbostic 1526*38103Sbostic instaddr = usignal(process); 1527*38103Sbostic if (instaddr == 0 or instaddr == 1) { 1528*38103Sbostic following = true; 1529*38103Sbostic followcalls = (Boolean) (not isnext); 1530*38103Sbostic printing = false; 1531*38103Sbostic iread(&inst, startaddr, sizeof(inst)); 1532*38103Sbostic instaddr = startaddr + sizeof(inst); 1533*38103Sbostic o = decode(inst, startaddr); 1534*38103Sbostic if (o->mask == 0) { 1535*38103Sbostic fprintf(stderr, 1536*38103Sbostic "[internal error: undecodable op at 0x%x]\n", startaddr); 1537*38103Sbostic fflush(stderr); 1538*38103Sbostic } else { 1539*38103Sbostic (*o->opfun)(inst, o->farg); 1540*38103Sbostic } 1541*38103Sbostic following = false; 1542*38103Sbostic } 1543*38103Sbostic return instaddr; 1544*38103Sbostic } 1545*38103Sbostic 1546*38103Sbostic /* 1547*38103Sbostic * Step to the given address and then execute one instruction past it. 1548*38103Sbostic * Set instaddr to the new instruction address. 1549*38103Sbostic */ 1550*38103Sbostic 1551*38103Sbostic private steppast(addr) 1552*38103Sbostic Address addr; 1553*38103Sbostic { 1554*38103Sbostic stepto(addr); 1555*38103Sbostic pstep(process, DEFSIG); 1556*38103Sbostic pc = reg(PROGCTR); 1557*38103Sbostic instaddr = pc; 1558*38103Sbostic } 1559*38103Sbostic 1560*38103Sbostic /* 1561*38103Sbostic * Enter a procedure by creating and executing a call instruction. 1562*38103Sbostic */ 1563*38103Sbostic 1564*38103Sbostic #define CALLSIZE 6 /* size of call instruction */ 1565*38103Sbostic 1566*38103Sbostic public beginproc(p) 1567*38103Sbostic Symbol p; 1568*38103Sbostic { 1569*38103Sbostic char save[CALLSIZE]; 1570*38103Sbostic struct { 1571*38103Sbostic short op; 1572*38103Sbostic char addr[sizeof(long)]; /* unaligned long */ 1573*38103Sbostic } call; 1574*38103Sbostic long dest; 1575*38103Sbostic 1576*38103Sbostic pc = CODESTART + 6; 1577*38103Sbostic iread(save, pc, sizeof(save)); 1578*38103Sbostic call.op = 0x4eb9; /* jsr */ 1579*38103Sbostic dest = codeloc(p) - FUNCOFFSET; 1580*38103Sbostic mov(&dest, call.addr, sizeof(call.addr)); 1581*38103Sbostic iwrite(&call, pc, sizeof(call)); 1582*38103Sbostic setreg(PROGCTR, pc); 1583*38103Sbostic pstep(process, DEFSIG); 1584*38103Sbostic iwrite(save, pc, sizeof(save)); 1585*38103Sbostic pc = reg(PROGCTR); 1586*38103Sbostic if (not isbperr()) { 1587*38103Sbostic printstatus(); 1588*38103Sbostic } 1589*38103Sbostic /* 1590*38103Sbostic * Execute link instruction so the return addr is visible. 1591*38103Sbostic */ 1592*38103Sbostic pstep(process, DEFSIG); 1593*38103Sbostic pc = reg(PROGCTR); 1594*38103Sbostic if (not isbperr()) { 1595*38103Sbostic printstatus(); 1596*38103Sbostic } 1597*38103Sbostic } 1598*38103Sbostic 1599*38103Sbostic /* 1600*38103Sbostic * Special variables for debugging the kernel. 1601*38103Sbostic */ 1602*38103Sbostic 1603*38103Sbostic public integer masterpcbb; 1604*38103Sbostic public integer slr; 1605*38103Sbostic public struct pte *sbr; 1606*38103Sbostic private struct pcb pcb; 1607*38103Sbostic 1608*38103Sbostic public getpcb () 1609*38103Sbostic { 1610*38103Sbostic integer i; 1611*38103Sbostic 1612*38103Sbostic fseek(corefile, masterpcbb & ~0x80000000, 0); 1613*38103Sbostic get(corefile, pcb); 1614*38103Sbostic pcb.pcb_p0lr &= ~AST_CLR; 1615*38103Sbostic printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", 1616*38103Sbostic pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr 1617*38103Sbostic ); 1618*38103Sbostic # ifdef sun 1619*38103Sbostic for (i = 0; i < 14; i++) { 1620*38103Sbostic setreg(i, pcb.pcb_regs.val[i]); 1621*38103Sbostic } 1622*38103Sbostic # else /* IRIS */ 1623*38103Sbostic for (i = 0; i < 14; i++) { 1624*38103Sbostic setreg(i, pcb.pcb_regs[i]); 1625*38103Sbostic } 1626*38103Sbostic # endif 1627*38103Sbostic } 1628*38103Sbostic 1629*38103Sbostic public copyregs (savreg, reg) 1630*38103Sbostic Word savreg[], reg[]; 1631*38103Sbostic { 1632*38103Sbostic reg[0] = savreg[R0]; 1633*38103Sbostic reg[1] = savreg[R1]; 1634*38103Sbostic reg[2] = savreg[R2]; 1635*38103Sbostic reg[3] = savreg[R3]; 1636*38103Sbostic reg[4] = savreg[R4]; 1637*38103Sbostic reg[5] = savreg[R5]; 1638*38103Sbostic reg[6] = savreg[R6]; 1639*38103Sbostic reg[7] = savreg[R7]; 1640*38103Sbostic reg[8] = savreg[AR0]; 1641*38103Sbostic reg[9] = savreg[AR1]; 1642*38103Sbostic reg[10] = savreg[AR2]; 1643*38103Sbostic reg[11] = savreg[AR3]; 1644*38103Sbostic reg[12] = savreg[AR4]; 1645*38103Sbostic reg[13] = savreg[AR5]; 1646*38103Sbostic reg[14] = savreg[AR6]; 1647*38103Sbostic reg[15] = savreg[AR7]; 1648*38103Sbostic reg[PROGCTR] = savreg[PC]; 1649*38103Sbostic } 1650*38103Sbostic 1651*38103Sbostic /* 1652*38103Sbostic * Map a virtual address to a physical address. 1653*38103Sbostic * XXX THIS CAN'T BE RIGHT... XXX 1654*38103Sbostic */ 1655*38103Sbostic 1656*38103Sbostic public Address vmap (addr) 1657*38103Sbostic Address addr; 1658*38103Sbostic { 1659*38103Sbostic Address r; 1660*38103Sbostic integer v, n; 1661*38103Sbostic struct pte pte; 1662*38103Sbostic 1663*38103Sbostic r = addr & ~0xc0000000; 1664*38103Sbostic v = btop(r); 1665*38103Sbostic switch (addr&0xc0000000) { 1666*38103Sbostic case 0xc0000000: 1667*38103Sbostic case 0x80000000: 1668*38103Sbostic /* 1669*38103Sbostic * In system space, so get system pte. 1670*38103Sbostic * If it is valid or reclaimable then the physical address 1671*38103Sbostic * is the combination of its page number and the page offset 1672*38103Sbostic * of the original address. 1673*38103Sbostic */ 1674*38103Sbostic if (v >= slr) { 1675*38103Sbostic error("address %x out of segment", addr); 1676*38103Sbostic } 1677*38103Sbostic r = ((long) (sbr + v)) & ~0x80000000; 1678*38103Sbostic goto simple; 1679*38103Sbostic 1680*38103Sbostic case 0x40000000: 1681*38103Sbostic /* 1682*38103Sbostic * In p1 space, must not be in shadow region. 1683*38103Sbostic */ 1684*38103Sbostic if (v < pcb.pcb_p1lr) { 1685*38103Sbostic error("address %x out of segment", addr); 1686*38103Sbostic } 1687*38103Sbostic r = (Address) (pcb.pcb_p1br + v); 1688*38103Sbostic break; 1689*38103Sbostic 1690*38103Sbostic case 0x00000000: 1691*38103Sbostic /* 1692*38103Sbostic * In p0 space, must not be off end of region. 1693*38103Sbostic */ 1694*38103Sbostic if (v >= pcb.pcb_p0lr) { 1695*38103Sbostic error("address %x out of segment", addr); 1696*38103Sbostic } 1697*38103Sbostic r = (Address) (pcb.pcb_p0br + v); 1698*38103Sbostic break; 1699*38103Sbostic 1700*38103Sbostic default: 1701*38103Sbostic /* do nothing */ 1702*38103Sbostic break; 1703*38103Sbostic } 1704*38103Sbostic /* 1705*38103Sbostic * For p0/p1 address, user-level page table should be in 1706*38103Sbostic * kernel virtual memory. Do second-level indirect by recursing. 1707*38103Sbostic */ 1708*38103Sbostic if ((r & 0x80000000) == 0) { 1709*38103Sbostic error("bad p0br or p1br in pcb"); 1710*38103Sbostic } 1711*38103Sbostic r = vmap(r); 1712*38103Sbostic simple: 1713*38103Sbostic /* 1714*38103Sbostic * "r" is now the address of the pte of the page 1715*38103Sbostic * we are interested in; get the pte and paste up the physical address. 1716*38103Sbostic */ 1717*38103Sbostic fseek(corefile, r, 0); 1718*38103Sbostic n = fread(&pte, sizeof(pte), 1, corefile); 1719*38103Sbostic if (n != 1) { 1720*38103Sbostic error("page table botch (fread at %x returns %d)", r, n); 1721*38103Sbostic } 1722*38103Sbostic if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { 1723*38103Sbostic error("page no valid or reclamable"); 1724*38103Sbostic } 1725*38103Sbostic return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum)); 1726*38103Sbostic } 1727*38103Sbostic 1728*38103Sbostic /* 1729*38103Sbostic * Extract a bit field from an integer. 1730*38103Sbostic */ 1731*38103Sbostic 1732*38103Sbostic public integer extractField (s) 1733*38103Sbostic Symbol s; 1734*38103Sbostic { 1735*38103Sbostic integer nbytes, nbits, n, r, off, len; 1736*38103Sbostic 1737*38103Sbostic off = s->symvalue.field.offset; 1738*38103Sbostic len = s->symvalue.field.length; 1739*38103Sbostic nbytes = size(s); 1740*38103Sbostic n = 0; 1741*38103Sbostic if (nbytes > sizeof(n)) { 1742*38103Sbostic printf("[bad size in extractField -- word assumed]\n"); 1743*38103Sbostic nbytes = sizeof(n); 1744*38103Sbostic } 1745*38103Sbostic popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes)); 1746*38103Sbostic nbits = nbytes * BITSPERBYTE; 1747*38103Sbostic r = n >> (nbits - ((off mod nbits) + len)); 1748*38103Sbostic r &= ((1 << len) - 1); 1749*38103Sbostic return r; 1750*38103Sbostic } 1751*38103Sbostic 1752*38103Sbostic /* 1753*38103Sbostic * Change the length of a value in memory according to a given difference 1754*38103Sbostic * in the lengths of its new and old types. 1755*38103Sbostic */ 1756*38103Sbostic 1757*38103Sbostic public loophole (oldlen, newlen) 1758*38103Sbostic integer oldlen, newlen; 1759*38103Sbostic { 1760*38103Sbostic integer i, n; 1761*38103Sbostic Stack *oldsp; 1762*38103Sbostic 1763*38103Sbostic n = newlen - oldlen; 1764*38103Sbostic oldsp = sp - oldlen; 1765*38103Sbostic if (n > 0) { 1766*38103Sbostic for (i = oldlen - 1; i >= 0; i--) { 1767*38103Sbostic oldsp[n + i] = oldsp[i]; 1768*38103Sbostic } 1769*38103Sbostic for (i = 0; i < n; i++) { 1770*38103Sbostic oldsp[i] = '\0'; 1771*38103Sbostic } 1772*38103Sbostic } else { 1773*38103Sbostic for (i = 0; i < newlen; i++) { 1774*38103Sbostic oldsp[i] = oldsp[i - n]; 1775*38103Sbostic } 1776*38103Sbostic } 1777*38103Sbostic sp += n; 1778*38103Sbostic } 1779