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:
Markus F.X.J. Oberhumer
2022-09-11 16:03:56 +02:00
parent 4318cc22ee
commit c75d7a685d
54 changed files with 3521 additions and 1196 deletions
+44 -35
View File
@@ -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: */