src: major cleanups, introduce new eXtended Span class
- initial minimally invasive eXtended Span implementation - rename ptr_diff to ptr_diff_bytes - move some files to util subdir - lots of cleanups - start using the new checked pointers - this needs some real-world testing
This commit is contained in:
+44
-35
@@ -176,7 +176,7 @@ void PackWcle::encodeEntryTable()
|
||||
//if (Opt_debug) printf("%d entries encoded.\n",n);
|
||||
UNUSED(n);
|
||||
|
||||
soentries = ptr_diff(p, ientries) + 1;
|
||||
soentries = ptr_udiff_bytes(p, ientries) + 1;
|
||||
oentries = ientries;
|
||||
ientries = nullptr;
|
||||
}
|
||||
@@ -290,12 +290,13 @@ void PackWcle::preprocessFixups()
|
||||
throwCantPack("files without relocations are not supported");
|
||||
}
|
||||
|
||||
ByteArray(rl, jc);
|
||||
MemBuffer rl_membuf(jc);
|
||||
ByteArray(srf, counts[objects+0]+1);
|
||||
ByteArray(slf, counts[objects+1]+1);
|
||||
|
||||
upx_byte *selector_fixups = srf;
|
||||
upx_byte *selfrel_fixups = slf;
|
||||
SPAN_S_VAR(upx_byte, rl, rl_membuf);
|
||||
SPAN_S_VAR(upx_byte, selector_fixups, srf_membuf);
|
||||
SPAN_S_VAR(upx_byte, selfrel_fixups, slf_membuf);
|
||||
unsigned rc = 0;
|
||||
|
||||
upx_byte *fix = ifixups;
|
||||
@@ -399,20 +400,20 @@ void PackWcle::preprocessFixups()
|
||||
delete[] ifixups;
|
||||
ifixups = new upx_byte[1000];
|
||||
}
|
||||
fix = optimizeReloc32 (rl,rc,ifixups,iimage,file_size,1,&big_relocs);
|
||||
has_extra_code = srf != selector_fixups;
|
||||
fix = ifixups + optimizeReloc32 (rl,rc,ifixups,iimage,file_size,1,&big_relocs);
|
||||
has_extra_code = ptr_udiff_bytes(selector_fixups, srf) != 0;
|
||||
// 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,srf,ptr_udiff_bytes(selector_fixups, srf)); // copy selector fixup code
|
||||
fix += ptr_udiff_bytes(selector_fixups, srf);
|
||||
|
||||
memcpy(fix,slf,selfrel_fixups-slf); // copy self-relative fixup positions
|
||||
fix += selfrel_fixups-slf;
|
||||
memcpy(fix,slf,ptr_udiff_bytes(selfrel_fixups,slf)); // copy self-relative fixup positions
|
||||
fix += ptr_udiff_bytes(selfrel_fixups, slf);
|
||||
set_le32(fix,0xFFFFFFFFUL);
|
||||
fix += 4;
|
||||
|
||||
sofixups = ptr_diff(fix, ifixups);
|
||||
sofixups = ptr_udiff(fix, ifixups);
|
||||
}
|
||||
|
||||
|
||||
@@ -427,7 +428,8 @@ void PackWcle::encodeImage(Filter *ft)
|
||||
|
||||
delete[] ifixups; ifixups = nullptr;
|
||||
|
||||
oimage.allocForCompression(isize, RESERVED+512);
|
||||
mb_oimage.allocForCompression(isize, RESERVED+512);
|
||||
oimage = mb_oimage;
|
||||
// prepare packheader
|
||||
ph.u_len = isize;
|
||||
// prepare filter [already done]
|
||||
@@ -435,7 +437,7 @@ void PackWcle::encodeImage(Filter *ft)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||
compressWithFilters(ibuf, isize,
|
||||
oimage + RESERVED,
|
||||
raw_bytes(oimage + RESERVED, mb_oimage.getSize() - RESERVED),
|
||||
ibuf + ft->addvalue, ft->buf_len,
|
||||
nullptr, 0,
|
||||
ft, 512, &cconf, 0);
|
||||
@@ -473,7 +475,7 @@ void PackWcle::pack(OutputFile *fo)
|
||||
readNonResidentNames();
|
||||
|
||||
// if (find_le32(iimage,20,get_le32("UPX ")) >= 0)
|
||||
if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0)
|
||||
if (find_le32(raw_bytes(iimage, soimage) ,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
|
||||
if (ih.init_ss_object != objects)
|
||||
@@ -556,14 +558,14 @@ void PackWcle::pack(OutputFile *fo)
|
||||
writeFile(fo, opt->watcom_le.le);
|
||||
|
||||
// verify
|
||||
verifyOverlappingDecompression(oimage + e_len, oimage.getSize() - e_len);
|
||||
verifyOverlappingDecompression(mb_oimage + e_len, mb_oimage.getSize() - e_len);
|
||||
|
||||
// copy the overlay
|
||||
const unsigned overlaystart = ih.data_pages_offset + exe_offset
|
||||
+ getImageSize();
|
||||
const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length;
|
||||
checkOverlay(overlay);
|
||||
copyOverlay(fo, overlay, &oimage);
|
||||
copyOverlay(fo, overlay, mb_oimage);
|
||||
|
||||
// finally check the compression ratio
|
||||
if (!checkFinalCompressionRatio(fo))
|
||||
@@ -577,12 +579,14 @@ void PackWcle::pack(OutputFile *fo)
|
||||
|
||||
void PackWcle::decodeFixups()
|
||||
{
|
||||
upx_byte *p = oimage + soimage;
|
||||
SPAN_P_VAR(upx_byte, p, oimage + soimage);
|
||||
// assert(p.raw_size_in_bytes() == mb_oimage.getSize()); // Span sanity check
|
||||
|
||||
iimage.dealloc();
|
||||
mb_iimage.dealloc();
|
||||
iimage = nullptr;
|
||||
|
||||
MemBuffer tmpbuf;
|
||||
unsigned const fixupn = unoptimizeReloc32(&p,oimage,&tmpbuf,1);
|
||||
unsigned const fixupn = unoptimizeReloc32(p,oimage,tmpbuf,true);
|
||||
|
||||
MemBuffer wrkmem(8*fixupn+8);
|
||||
unsigned ic,jc,o,r;
|
||||
@@ -600,10 +604,10 @@ void PackWcle::decodeFixups()
|
||||
tmpbuf.dealloc();
|
||||
|
||||
// selector fixups then self-relative fixups
|
||||
const upx_byte *selector_fixups = p;
|
||||
SPAN_P_VAR(const upx_byte, selector_fixups, p);
|
||||
|
||||
// Find selfrel_fixups by skipping over selector_fixups.
|
||||
const upx_byte *q = selector_fixups;
|
||||
SPAN_P_VAR(const upx_byte, q, selector_fixups);
|
||||
// The code is a subroutine that ends in RET (0xC3).
|
||||
while (*q != 0xC3) {
|
||||
// Defend against tampered selector_fixups; see PackWcle::preprocessFixups().
|
||||
@@ -622,20 +626,21 @@ void PackWcle::decodeFixups()
|
||||
}
|
||||
// Guard against run-away.
|
||||
static unsigned char const blank[9] = {0};
|
||||
if (q > (oimage + ph.u_len - sizeof(blank)) // catastrophic worst case
|
||||
if (ptr_diff_bytes(oimage + ph.u_len - sizeof(blank), raw_bytes(q,0)) < 0 // catastrophic worst case
|
||||
|| !memcmp(blank, q, sizeof(blank)) // no-good early warning
|
||||
) {
|
||||
char msg[50]; snprintf(msg, sizeof(msg),
|
||||
"bad selector_fixups +%#zx", q - selector_fixups);
|
||||
"bad selector_fixups %d", ptr_diff_bytes(q, selector_fixups));
|
||||
throwCantPack(msg);
|
||||
}
|
||||
q += 9;
|
||||
}
|
||||
unsigned selectlen = ptr_diff(q, selector_fixups)/9;
|
||||
const upx_byte *selfrel_fixups = 1+ q; // Skip the 0xC3
|
||||
unsigned selectlen = ptr_udiff_bytes(q, selector_fixups)/9;
|
||||
SPAN_P_VAR(const upx_byte, selfrel_fixups, q + 1); // Skip the 0xC3
|
||||
|
||||
ofixups = New(upx_byte, fixupn*9+1000+selectlen*5);
|
||||
upx_bytep fp = ofixups;
|
||||
const unsigned fbytes = fixupn*9+1000+selectlen*5;
|
||||
ofixups = New(upx_byte, fbytes);
|
||||
SPAN_S_VAR(upx_byte, fp, ofixups, fbytes, ofixups);
|
||||
|
||||
for (ic = 1, jc = 0; ic <= opages; ic++)
|
||||
{
|
||||
@@ -698,11 +703,11 @@ void PackWcle::decodeFixups()
|
||||
fp += fp[1] ? 9 : 7;
|
||||
jc += 2;
|
||||
}
|
||||
set_le32(ofpage_table+ic,ptr_diff(fp,ofixups));
|
||||
set_le32(ofpage_table+ic,ptr_udiff_bytes(fp,ofixups));
|
||||
}
|
||||
for (ic=0; ic < FIXUP_EXTRA; ic++)
|
||||
*fp++ = 0;
|
||||
sofixups = ptr_diff(fp, ofixups);
|
||||
sofixups = ptr_udiff_bytes(fp, ofixups);
|
||||
}
|
||||
|
||||
|
||||
@@ -751,7 +756,8 @@ void PackWcle::decodeObjectTable()
|
||||
|
||||
void PackWcle::decodeImage()
|
||||
{
|
||||
oimage.allocForUncompression(ph.u_len);
|
||||
mb_oimage.allocForUncompression(ph.u_len);
|
||||
oimage = mb_oimage;
|
||||
|
||||
decompress(iimage + ph.buf_offset + ph.getPackHeaderSize(),oimage);
|
||||
soimage = get_le32(oimage + ph.u_len - 5);
|
||||
@@ -762,11 +768,13 @@ void PackWcle::decodeImage()
|
||||
|
||||
void PackWcle::decodeEntryTable()
|
||||
{
|
||||
unsigned count,object,r;
|
||||
upx_byte *p = ientries;
|
||||
unsigned count,object,n,r;
|
||||
SPAN_S_VAR(upx_byte, p, ientries, soentries);
|
||||
n = 0;
|
||||
while (*p)
|
||||
{
|
||||
count = *p;
|
||||
n += count;
|
||||
if (p[1] == 0) // unused bundle
|
||||
p += 2;
|
||||
else if (p[1] == 3) // 32-bit offset bundle
|
||||
@@ -787,8 +795,9 @@ void PackWcle::decodeEntryTable()
|
||||
}
|
||||
|
||||
//if (Opt_debug) printf("\n%d entries decoded.\n",n);
|
||||
UNUSED(n);
|
||||
|
||||
soentries = ptr_diff(p, ientries) + 1;
|
||||
soentries = ptr_udiff_bytes(p, ientries) + 1;
|
||||
oentries = ientries;
|
||||
ientries = nullptr;
|
||||
}
|
||||
@@ -852,7 +861,7 @@ void PackWcle::unpack(OutputFile *fo)
|
||||
ft.cto = (unsigned char) ph.filter_cto;
|
||||
if (ph.version < 11)
|
||||
ft.cto = (unsigned char) (get_le32(oimage+ph.u_len-9) >> 24);
|
||||
ft.unfilter(oimage+text_vaddr, text_size);
|
||||
ft.unfilter(raw_bytes(oimage+text_vaddr, text_size), text_size);
|
||||
}
|
||||
|
||||
decodeFixupPageTable();
|
||||
@@ -878,7 +887,7 @@ void PackWcle::unpack(OutputFile *fo)
|
||||
+ getImageSize();
|
||||
const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length;
|
||||
checkOverlay(overlay);
|
||||
copyOverlay(fo, overlay, &oimage);
|
||||
copyOverlay(fo, overlay, mb_oimage);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
Reference in New Issue
Block a user