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:
parent
6bb104b39f
commit
f443210ded
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user