1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

avoid copying (faster for same instruction size)

committer: jreiser <jreiser> 958949861 +0000
This commit is contained in:
John Reiser 2000-05-21 22:57:41 +00:00
parent 6bb104b39f
commit f443210ded

View File

@ -49,14 +49,14 @@
#undef xwrite #undef xwrite
struct Extent { struct Extent {
size_t size; // must be first to match size[0] uncompressed size int size; // must be first to match size[0] uncompressed size
char *buf; char *buf;
}; };
static void static void
xread(struct Extent *const x, char *const buf, size_t const count) xread(struct Extent *const x, char *const buf, size_t const count)
{ {
if (x->size < count) { if (x->size < (int)count) {
exit(127); exit(127);
} }
#if 0 //{ #if 0 //{
@ -81,7 +81,7 @@ xread(struct Extent *const x, char *const buf, size_t const count)
} }
#if 1 #if 1
static __inline__ int xwrite(int fd, const void *buf, int count) static int xwrite(int fd, const void *buf, int count)
{ {
// note: we can assert(count > 0); // note: we can assert(count > 0);
do { do {
@ -126,6 +126,17 @@ static char *upx_itoa(char *buf, unsigned long v)
return buf; return buf;
} }
static uint32_t ascii5(uint32_t r, unsigned k, char *p)
{
do {
unsigned char d = r % 32;
if (d >= 26) d += '0' - 'Z' - 1;
*--p += d;
r /= 32;
} while (--k > 0);
return r;
}
#if defined(__i386__) #if defined(__i386__)
# define SET2(p, c0, c1) \ # define SET2(p, c0, c1) \
@ -246,19 +257,9 @@ void upx_main(
// Protect against Denial-of-Service attacks. // Protect against Denial-of-Service attacks.
{ {
char *p = tmpname_buf + sizeof(tmpname_buf) - 1; char *p = tmpname_buf + sizeof(tmpname_buf) - 1;
uint32_t r;
// Compute the last 4 characters (20 bits) from getpid(). // Compute the last 4 characters (20 bits) from getpid().
{ uint32_t r = ascii5((uint32_t)pid, 4, p); p-=4;
unsigned k = 4;
r = (uint32_t) pid;
do {
unsigned char d = r % 32;
if (d >= 26) d += '0' - 'Z' - 1;
*--p += d;
r /= 32;
} while (--k > 0);
}
// Provide 4 random bytes from our program id. // Provide 4 random bytes from our program id.
r ^= header.p_progid; r ^= header.p_progid;
@ -280,15 +281,7 @@ void upx_main(
#endif #endif
} }
// Compute 7 more characters from the 32 random bits. // Compute 7 more characters from the 32 random bits.
{ ascii5(r, 7, p);
unsigned k = 7;
do {
unsigned char d = r % 32;
if (d >= 26) d += '0' - 'Z' - 1;
*--p += d;
r /= 32;
} while (--k > 0);
}
} }
// Just in case, remove the file. // Just in case, remove the file.
@ -358,24 +351,21 @@ void upx_main(
// assert(h.sz_unc > 0 && h.sz_unc <= blocksize); // assert(h.sz_unc > 0 && h.sz_unc <= blocksize);
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize); // assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
// Read compressed block. header.p_filesize -= h.sz_unc;
i = header.p_blocksize + OVERHEAD - h.sz_cpr; if (h.sz_cpr < h.sz_unc) { // Decompress block.
xread(&xi, buf+i, h.sz_cpr);
// Decompress block.
if (h.sz_cpr < h.sz_unc)
{
// in-place decompression
nrv_uint out_len; nrv_uint out_len;
i = (*f_decompress)(buf+i, h.sz_cpr, buf, &out_len); i = (*f_decompress)(xi.buf, h.sz_cpr, buf, &out_len);
if (i != 0 || out_len != (nrv_uint)h.sz_unc) if (i != 0 || out_len != (nrv_uint)h.sz_unc)
goto error; goto error;
// i == 0 now i = xwrite(fdo, buf, h.sz_unc);
} }
else { // Incompressible block
i = xwrite(fdo, xi.buf, h.sz_unc);
}
xi.buf += h.sz_cpr;
xi.size -= h.sz_cpr;
// Write uncompressed block. if (xi.size < 0 || i != 0) {
if (xwrite(fdo, buf+i, h.sz_unc) != 0)
{
// error exit is here in the middle to keep the jumps short. // error exit is here in the middle to keep the jumps short.
error: error:
(void) unlink(tmpname); (void) unlink(tmpname);
@ -385,7 +375,6 @@ void upx_main(
for (;;) for (;;)
(void) exit(127); (void) exit(127);
} }
header.p_filesize -= h.sz_unc;
// We will never touch these pages again. // We will never touch these pages again.
i = (PAGE_MASK & (unsigned)xi.buf) - (unsigned)next_unmap; i = (PAGE_MASK & (unsigned)xi.buf) - (unsigned)next_unmap;