/* Print a string */ void debug_print_string(const byte *chrs, ushort len) { ushort i; for ( i = 0; i < len; i++ ) dputc(chrs[i]); fflush(dstderr); }
void dprintf (const char *fmt, ...) { if (!debug_inited) return; while (*fmt) { if (*fmt != '%') { dputc(*fmt++); continue; } fmt++; } }
/* Dump a region of memory */ void debug_dump_bytes(const byte *from, const byte *to, const char *msg) { const byte *p = from; if ( from < to && msg ) dprintf1("%s:\n", msg); while ( p != to ) { const byte *q = min(p + 16, to); dprintf1("%lx:", (ulong)p); while ( p != q ) dprintf1(" %02x", *p++); dputc('\n'); } }
/****************************************************************************** * * * void RecalculateDrawWindows() * * * ******************************************************************************* * * Recalculates windowing parameters and redraws the complete screen. * If the initial window sizes are not valid, it scales them down so the * window configuration can fit on within the current screen size. * ******************************************************************************/ void RecalculateDrawWindows() { int excess; // Available number of lines int window; // Data window number UINT current; // Current data window store avail = pOut->sizeY; total = 0; if( (excess = WindowIsSizeValid()) < 0 ) AdjustToFit( -excess ); AdjustTopBottom(&pWin->r); AdjustTopBottom(&pWin->l); AdjustTopBottom(&pWin->w); AdjustTopBottom(&pWin->s); for(window=0; window<MAX_DATA; window++) AdjustTopBottom(&pWin->data[window]); AdjustTopBottom(&pWin->c); // The last one is the history window, and we will let it fill in the rest pWin->h.nLines = avail - 1; // Save one extra for the help line AdjustTopBottom(&pWin->h); // This prevent from us from calling all these drawing functions when the // debugger is not active, in which case we would not have the right memory // access set up if( deb.fRunningIce==TRUE ) { // Draw the screen dputc(DP_CLS); // Set the new history frame scroll region // Add one to the top Y to skip the header line dprint("%c%c%c", DP_SETSCROLLREGIONYY, pWin->h.Top+1+1, pWin->h.Bottom+1); RegDraw(FALSE); LocalsDraw(FALSE); WatchDraw(FALSE); StackDraw(FALSE); current = deb.nData; for(deb.nData=0; deb.nData<MAX_DATA; deb.nData++) DataDraw(FALSE, deb.dataAddr[deb.nData].offset, (deb.nData==current)); deb.nData = current; CodeDraw(FALSE); HistoryDraw(); // HistoryDraw leaves the cursor coordinates at the proper Y-coordinate } }
/* Dump a region of memory containing refs */ void debug_dump_refs(const ref *from, uint size, const char *msg) { const ref *p = from; uint count = size; if ( size && msg ) dprintf2("%s at 0x%lx:\n", msg, (ulong)from); while ( count-- ) { dprintf2("..%04x: 0x%02x ", (uint)p & 0xffff, r_type(p)); debug_dump_one_ref(p); dputc('\n'); p++; } }
/* Dump an array. */ void debug_dump_array(const ref *array) { const ref_packed *pp; unsigned int type = r_type(array); uint len; switch (type) { default: dprintf2 ("%s at 0x%lx isn't an array.\n", (type < countof(type_strings) ? type_strings[type] : "????"), (ulong)array); return; case t_oparray: /* This isn't really an array, but we'd like to see */ /* its contents anyway. */ debug_dump_array(op_array_table.value.refs + op_index(array) - op_def_count); return; case t_array: case t_mixedarray: case t_shortarray: ; } /* This "packed" loop works for all array-types. */ for ( len = r_size (array), pp = array->value.packed; len > 0; len--, pp = packed_next(pp)) { ref temp; packed_get(pp, &temp); dprintf3("..%04x%c 0x%02x ", (uint)pp & 0xffff, ((r_is_packed(pp)) ? '*' : ':'), r_type(&temp)); debug_dump_one_ref(&temp); dputc ('\n'); } }
/* Dump one ref */ void debug_dump_one_ref(const ref *p) { uint attrs = r_type_attrs(p); uint btype = r_btype(p); static const char *as = attr_print_string; const char *ap = as; #define buf_size 30 char buf[buf_size + 1]; uint plen; if ( btype >= t_next_index ) dprintf1("0x%02x?? ", btype); else dprintf1("%s ", type_strings[btype]); for ( ; *ap; ap++, attrs >>= 1 ) if ( *ap != '.' ) dputc(((attrs & 1) ? *ap : '-')); dprintf2(" 0x%04x 0x%08lx", r_size(p), *(const ulong *)&p->value); if ( obj_cvs(p, (byte *)buf, countof(buf) - 1, &plen) >= 0 && ((buf[plen] = 0), strcmp(buf, "--nostringval--")) ) dprintf1(" = %s", buf); fflush(dstderr); }
void PackWcle::decodeFixups() { upx_byte *p = oimage + soimage; iimage.dealloc(); MemBuffer tmpbuf; unsigned fixupn = unoptimizeReloc32(&p,oimage,&tmpbuf,1); MemBuffer wrkmem(8*fixupn+8); unsigned ic,jc,o,r; for (ic=0; ic<fixupn; ic++) { jc=get_le32(tmpbuf+4*ic); set_le32(wrkmem+ic*8,jc); o = soobject_table; r = get_le32(oimage+jc); virt2rela(oobject_table,&o,&r); set_le32(wrkmem+ic*8+4,OOT(o-1,my_base_address)); set_le32(oimage+jc,r); } set_le32(wrkmem+ic*8,0xFFFFFFFF); // end of 32-bit offset fixups tmpbuf.dealloc(); // selector fixups and self-relative fixups const upx_byte *selector_fixups = p; const upx_byte *selfrel_fixups = p; while (*selfrel_fixups != 0xC3) selfrel_fixups += 9; selfrel_fixups++; unsigned selectlen = ptr_diff(selfrel_fixups, selector_fixups)/9; ofixups = New(upx_byte, fixupn*9+1000+selectlen*5); upx_bytep fp = ofixups; for (ic = 1, jc = 0; ic <= opages; ic++) { // self relative fixups while ((r = get_le32(selfrel_fixups))/mps == ic-1) { fp[0] = 8; set_le16(fp+2,r & (mps-1)); o = 4+get_le32(oimage+r); set_le32(oimage+r,0); r += o; o = soobject_table; virt2rela(oobject_table,&o,&r); fp[4] = (unsigned char) o; set_le32(fp+5,r); fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0); fp += fp[1] ? 9 : 7; selfrel_fixups += 4; dputc('r',stdout); } // selector fixups while (selectlen && (r = get_le32(selector_fixups+5))/mps == ic-1) { fp[0] = 2; fp[1] = 0; set_le16(fp+2,r & (mps-1)); unsigned x = selector_fixups[1] > 0xD0 ? oh.init_ss_object : oh.init_cs_object; fp[4] = (unsigned char) x; fp += 5; selector_fixups += 9; selectlen--; dputc('s',stdout); } // 32 bit offset fixups while (get_le32(wrkmem+4*jc) < ic*mps) { if (jc > 1 && ((get_le32(wrkmem+4*(jc-2))+3) & (mps-1)) < 3) // cross page fixup? { r = get_le32(oimage+get_le32(wrkmem+4*(jc-2))); fp[0] = 7; fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0); set_le16(fp+2,get_le32(wrkmem+4*(jc-2)) | ~3); set_le32(fp+5,r); o = soobject_table; r = get_le32(wrkmem+4*(jc-1)); virt2rela(oobject_table,&o,&r); fp[4] = (unsigned char) o; fp += fp[1] ? 9 : 7; dputc('0',stdout); } o = soobject_table; r = get_le32(wrkmem+4*(jc+1)); virt2rela(oobject_table,&o,&r); r = get_le32(oimage+get_le32(wrkmem+4*jc)); fp[0] = 7; fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0); set_le16(fp+2,get_le32(wrkmem+4*jc) & (mps-1)); fp[4] = (unsigned char) o; set_le32(fp+5,r); fp += fp[1] ? 9 : 7; jc += 2; } set_le32(ofpage_table+ic,ptr_diff(fp,ofixups)); } for (ic=0; ic < FIXUP_EXTRA; ic++) *fp++ = 0; sofixups = ptr_diff(fp, ofixups); }
void PackWcle::preprocessFixups() { big_relocs = 0; unsigned ic,jc; Array(unsigned, counts, objects+2); countFixups(counts); for (ic = jc = 0; ic < objects; ic++) jc += counts[ic]; if (jc == 0) { // FIXME: implement this throwCantPack("files without relocations are not supported"); } ByteArray(rl, jc); ByteArray(srf, counts[objects+0]+1); ByteArray(slf, counts[objects+1]+1); upx_byte *selector_fixups = srf; upx_byte *selfrel_fixups = slf; unsigned rc = 0; upx_byte *fix = ifixups; for (ic = jc = 0; ic < pages; ic++) { while ((unsigned)(fix - ifixups) < get_le32(ifpage_table+ic+1)) { const int fixp2 = get_le16_signed(fix+2); unsigned value; switch (*fix) { case 2: // selector fixup if (fixp2 < 0) { // cross page selector fixup dputc('S',stdout); fix += 5; break; } dputc('s',stdout); memcpy(selector_fixups,"\x8C\xCB\x66\x89\x9D",5); // mov bx, cs ; mov [xxx+ebp], bx if (IOT(fix[4]-1,flags) & LEOF_WRITE) selector_fixups[1] = 0xDB; // ds set_le32(selector_fixups+5,jc+fixp2); selector_fixups += 9; fix += 5; break; case 5: // 16-bit offset if ((unsigned)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc) dputc('6',stdout); else throwCantPack("unsupported 16-bit offset relocation"); fix += (fix[1] & 0x10) ? 9 : 7; break; case 6: // 16:32 pointer if (fixp2 < 0) { // cross page pointer fixup dputc('P',stdout); fix += (fix[1] & 0x10) ? 9 : 7; break; } dputc('p',stdout); memcpy(iimage+jc+fixp2,fix+5,(fix[1] & 0x10) ? 4 : 2); set_le32(rl+4*rc++,jc+fixp2); set_le32(iimage+jc+fixp2,get_le32(iimage+jc+fixp2)+IOT(fix[4]-1,my_base_address)); memcpy(selector_fixups,"\x8C\xCA\x66\x89\x95",5); if (IOT(fix[4]-1,flags) & LEOF_WRITE) selector_fixups[1] = 0xDA; // ds set_le32(selector_fixups+5,jc+fixp2+4); selector_fixups += 9; fix += (fix[1] & 0x10) ? 9 : 7; break; case 7: // 32-bit offset if (fixp2 < 0) { fix += (fix[1] & 0x10) ? 9 : 7; break; } //if (memcmp(iimage+jc+fixp2,fix+5,(fix[1] & 0x10) ? 4 : 2)) // throwCantPack("illegal fixup offset"); // work around a pmwunlite bug: remove duplicated fixups // FIXME: fix the other cases too if (rc == 0 || get_le32(rl+4*rc-4) != jc+fixp2) { set_le32(rl+4*rc++,jc+fixp2); set_le32(iimage+jc+fixp2,get_le32(iimage+jc+fixp2)+IOT(fix[4]-1,my_base_address)); } fix += (fix[1] & 0x10) ? 9 : 7; break; case 8: // 32-bit self relative fixup if (fixp2 < 0) { // cross page self relative fixup dputc('R',stdout); fix += (fix[1] & 0x10) ? 9 : 7; break; } value = get_le32(fix+5); if (fix[1] == 0) value &= 0xffff; set_le32(iimage+jc+fixp2,(value+IOT(fix[4]-1,my_base_address))-jc-fixp2-4); set_le32(selfrel_fixups,jc+fixp2); selfrel_fixups += 4; dputc('r',stdout); fix += (fix[1] & 0x10) ? 9 : 7; break; default: throwCantPack("unsupported fixup record"); } } jc += mps; } // resize ifixups if it's too small if (sofixups < 1000) { delete[] ifixups; ifixups = new upx_byte[1000]; } fix = optimizeReloc32 (rl,rc,ifixups,iimage,1,&big_relocs); has_extra_code = srf != selector_fixups; // FIXME: this could be removed if has_extra_code = false // but then we'll need a flag *selector_fixups++ = 0xC3; // ret memcpy(fix,srf,selector_fixups-srf); // copy selector fixup code fix += selector_fixups-srf; memcpy(fix,slf,selfrel_fixups-slf); // copy self-relative fixup positions fix += selfrel_fixups-slf; set_le32(fix,0xFFFFFFFFUL); fix += 4; sofixups = ptr_diff(fix, ifixups); }
/* Default implementation of tile_rectangle */ int gx_default_tile_rectangle(gx_device *dev, register const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int px, int py) { /* Fill the rectangle in chunks */ int width = tile->size.x; int height = tile->size.y; int raster = tile->raster; int rwidth = tile->rep_width; int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */ (x + px) & (rwidth - 1) : (x + px) % rwidth); int ry = (y + py) % tile->rep_height; int icw = width - irx; int ch = height - ry; byte *row = tile->data + ry * raster; #define d_proc_mono (dev->procs->copy_mono) dev_proc_copy_mono((*proc_mono)); #define d_proc_color (dev->procs->copy_color) dev_proc_copy_color((*proc_color)); #define d_color_halftone\ (color0 == gx_no_color_index && color1 == gx_no_color_index) int color_halftone; #define get_color_info()\ if ( (color_halftone = d_color_halftone) ) proc_color = d_proc_color;\ else proc_mono = d_proc_mono int code; #ifdef DEBUG if ( gs_debug['t'] ) { int ptx, pty; const byte *ptp = tile->data; dprintf3("[t]tile %dx%d raster=%d;", tile->size.x, tile->size.y, tile->raster); dprintf6(" x,y=%d,%d w,h=%d,%d p=%d,%d\n", x, y, w, h, px, py); for ( pty = 0; pty < tile->size.y; pty++ ) { dprintf(" "); for ( ptx = 0; ptx < tile->raster; ptx++ ) dprintf1("%3x", *ptp++); } dputc('\n'); } #endif #define real_copy_tile(srcx, tx, ty, tw, th)\ code =\ (color_halftone ?\ (*proc_color)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th) :\ (*proc_mono)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th, color0, color1));\ gp_check_interrupts();\ if ( code < 0 ) return_error(code) #ifdef DEBUG #define copy_tile(sx, tx, ty, tw, th)\ if ( gs_debug['t'] )\ dprintf5(" copy sx=%d x=%d y=%d w=%d h=%d\n",\ sx, tx, ty, tw, th);\ real_copy_tile(sx, tx, ty, tw, th) #else #define copy_tile(sx, tx, ty, tw, th)\ real_copy_tile(sx, tx, ty, tw, th) #endif if ( icw >= w ) { /* Narrow operation */ int ey, fey, cy; if ( ch >= h ) { /* Just one (partial) tile to transfer. */ #define color_halftone d_color_halftone #define proc_color d_proc_color #define proc_mono d_proc_mono copy_tile(irx, x, y, w, h); #undef proc_mono #undef proc_color #undef color_halftone return 0; } get_color_info(); ey = y + h; fey = ey - height; copy_tile(irx, x, y, w, ch); cy = y + ch; row = tile->data; do { ch = (cy > fey ? ey - cy : height); copy_tile(irx, x, cy, w, ch); } while ( (cy += ch) < ey ); return 0; } get_color_info(); if ( ch >= h ) { /* Shallow operation */ int ex = x + w; int fex = ex - width; int cx = x + icw; copy_tile(irx, x, y, icw, h); while ( cx <= fex ) { copy_tile(0, cx, y, width, h); cx += width; } if ( cx < ex ) { copy_tile(0, cx, y, ex - cx, h); } } else { /* Full operation */ int ex = x + w, ey = y + h; int fex = ex - width, fey = ey - height; int cx, cy; for ( cy = y; ; ) { copy_tile(irx, x, cy, icw, ch); cx = x + icw; while ( cx <= fex ) { copy_tile(0, cx, cy, width, ch); cx += width; } if ( cx < ex ) { copy_tile(0, cx, cy, ex - cx, ch); } if ( (cy += ch) >= ey ) break; ch = (cy > fey ? ey - cy : height); row = tile->data; } } #undef copy_tile #undef real_copy_tile return 0; }