new DPRINTF
modified: stub/src/amd64-darwin.macho-main.c
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
#include "include/darwin.h"
|
||||
|
||||
#ifndef DEBUG /*{*/
|
||||
#define DEBUG 0
|
||||
#define DEBUG 1
|
||||
#endif /*}*/
|
||||
|
||||
/*************************************************************************
|
||||
@@ -45,136 +45,44 @@
|
||||
// it at an address different from it load address: there must be no
|
||||
// static data, and no string constants.
|
||||
|
||||
#if !DEBUG /*{*/
|
||||
#define DPRINTF(a) /* empty: no debug drivel */
|
||||
#define DEBUG_STRCON(name, value) /* empty */
|
||||
#else /*}{ DEBUG */
|
||||
extern int write(int, void const *, size_t);
|
||||
#if 0
|
||||
#include "stdarg.h"
|
||||
#else
|
||||
#define va_arg __builtin_va_arg
|
||||
#define va_end __builtin_va_end
|
||||
#define va_list __builtin_va_list
|
||||
#define va_start __builtin_va_start
|
||||
#endif
|
||||
#if !DEBUG //{
|
||||
#define DPRINTF(fmt, args...) /*empty*/
|
||||
#else //}{
|
||||
// DPRINTF is defined as an expression using "({ ... })"
|
||||
// so that DPRINTF can be invoked inside an expression,
|
||||
// and then followed by a comma to ignore the return value.
|
||||
// The only complication is that percent and backslash
|
||||
// must be doubled in the format string, because the format
|
||||
// string is processd twice: once at compile-time by 'asm'
|
||||
// to produce the assembled value, and once at runtime to use it.
|
||||
#if defined(__powerpc__) //{
|
||||
#define DPRINTF(fmt, args...) ({ \
|
||||
char const *r_fmt; \
|
||||
asm("bl 0f; .string \"" fmt "\"; .balign 4; 0: mflr %0" \
|
||||
/*out*/ : "=r"(r_fmt) \
|
||||
/* in*/ : \
|
||||
/*und*/ : "lr"); \
|
||||
dprintf(r_fmt, args); \
|
||||
})
|
||||
#elif defined(__x86_64) //}{
|
||||
#define DPRINTF(fmt, args...) ({ \
|
||||
char const *r_fmt; \
|
||||
asm("call 0f; .asciz \"" fmt "\"; 0: pop %0" \
|
||||
/*out*/ : "=r"(r_fmt) ); \
|
||||
dprintf(r_fmt, args); \
|
||||
})
|
||||
#elif defined(__aarch64__) //}{
|
||||
#define DPRINTF(fmt, args...) ({ \
|
||||
char const *r_fmt; \
|
||||
asm("bl 0f; .string \"" fmt "\"; .balign 4; 0: mov %0,x30" \
|
||||
/*out*/ : "=r"(r_fmt) \
|
||||
/* in*/ : \
|
||||
/*und*/ : "x30"); \
|
||||
dprintf(r_fmt, args); \
|
||||
})
|
||||
#endif //}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) /*{*/
|
||||
#define PIC_STRING(value, var) \
|
||||
__asm__ __volatile__ ( \
|
||||
"call 0f; .asciz \"" value "\"; \
|
||||
0: pop %0;" : "=r"(var) : \
|
||||
)
|
||||
#elif defined(__arm__) /*}{*/
|
||||
#define PIC_STRING(value, var) \
|
||||
__asm__ __volatile__ ( \
|
||||
"mov %0,pc; b 0f; \
|
||||
.asciz \"" value "\"; .balign 4; \
|
||||
0: " : "=r"(var) \
|
||||
)
|
||||
#elif defined(__mips__) /*}{*/
|
||||
#define PIC_STRING(value, var) \
|
||||
__asm__ __volatile__ ( \
|
||||
".set noreorder; bal 0f; move %0,$31; .set reorder; \
|
||||
.asciz \"" value "\"; .balign 4; \
|
||||
0: " \
|
||||
: "=r"(var) : : "ra" \
|
||||
)
|
||||
#endif /*}*/
|
||||
|
||||
|
||||
#define DEBUG_STRCON(name, strcon) \
|
||||
static char const *name(void) { \
|
||||
register char const *rv; PIC_STRING(strcon, rv); \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef __arm__ /*{*/
|
||||
extern unsigned div10(unsigned);
|
||||
#else /*}{*/
|
||||
static unsigned
|
||||
div10(unsigned x)
|
||||
{
|
||||
return x / 10u;
|
||||
}
|
||||
#endif /*}*/
|
||||
|
||||
static int
|
||||
unsimal(unsigned x, char *ptr, int n)
|
||||
{
|
||||
if (10<=x) {
|
||||
unsigned const q = div10(x);
|
||||
x -= 10 * q;
|
||||
n = unsimal(q, ptr, n);
|
||||
}
|
||||
ptr[n] = '0' + x;
|
||||
return 1+ n;
|
||||
}
|
||||
|
||||
static int
|
||||
decimal(int x, char *ptr, int n)
|
||||
{
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
ptr[n++] = '-';
|
||||
}
|
||||
return unsimal(x, ptr, n);
|
||||
}
|
||||
|
||||
DEBUG_STRCON(STR_hex, "0123456789abcdef");
|
||||
|
||||
static int
|
||||
heximal(unsigned long x, char *ptr, int n)
|
||||
{
|
||||
if (16<=x) {
|
||||
n = heximal(x>>4, ptr, n);
|
||||
x &= 0xf;
|
||||
}
|
||||
ptr[n] = STR_hex()[x];
|
||||
return 1+ n;
|
||||
}
|
||||
|
||||
|
||||
#define DPRINTF(a) dprintf a
|
||||
|
||||
static int
|
||||
dprintf(char const *fmt, ...)
|
||||
{
|
||||
char c;
|
||||
int n= 0;
|
||||
char *ptr;
|
||||
char buf[20];
|
||||
va_list va; va_start(va, fmt);
|
||||
ptr= &buf[0];
|
||||
while (0!=(c= *fmt++)) if ('%'!=c) goto literal;
|
||||
else switch (c= *fmt++) {
|
||||
default: {
|
||||
literal:
|
||||
n+= write(2, fmt-1, 1);
|
||||
} break;
|
||||
case 0: goto done; /* early */
|
||||
case 'u': {
|
||||
n+= write(2, buf, unsimal(va_arg(va, unsigned), buf, 0));
|
||||
} break;
|
||||
case 'd': {
|
||||
n+= write(2, buf, decimal(va_arg(va, int), buf, 0));
|
||||
} break;
|
||||
case 'p': {
|
||||
buf[0] = '0';
|
||||
buf[1] = 'x';
|
||||
n+= write(2, buf, heximal((unsigned long)va_arg(va, void *), buf, 2));
|
||||
} break;
|
||||
case 'x': {
|
||||
buf[0] = '0';
|
||||
buf[1] = 'x';
|
||||
n+= write(2, buf, heximal(va_arg(va, int), buf, 2));
|
||||
} break;
|
||||
}
|
||||
done:
|
||||
va_end(va);
|
||||
return n;
|
||||
}
|
||||
static int dprintf(char const *fmt, ...); // forward
|
||||
#endif /*}*/
|
||||
|
||||
|
||||
@@ -187,17 +95,15 @@ typedef struct {
|
||||
void *buf;
|
||||
} Extent;
|
||||
|
||||
DEBUG_STRCON(STR_xread, "xread %%p(%%x %%p) %%p %%x\\n")
|
||||
DEBUG_STRCON(STR_xreadfail, "xreadfail %%p(%%x %%p) %%p %%x\\n")
|
||||
|
||||
static void
|
||||
xread(Extent *x, void *buf, size_t count)
|
||||
{
|
||||
unsigned char *p=x->buf, *q=buf;
|
||||
size_t j;
|
||||
DPRINTF((STR_xread(), x, x->size, x->buf, buf, count));
|
||||
DPRINTF("xread %%p(%%x %%p) %%p %%x\\n", x, x->size, x->buf, buf, count);
|
||||
if (x->size < count) {
|
||||
DPRINTF((STR_xreadfail(), x, x->size, x->buf, buf, count));
|
||||
DPRINTF("xreadfail %%p(%%x %%p) %%p %%x\\n",
|
||||
x, x->size, x->buf, buf, count);
|
||||
exit(127);
|
||||
}
|
||||
for (j = count; 0!=j--; ++p, ++q) {
|
||||
@@ -217,12 +123,11 @@ xread(Extent *x, void *buf, size_t count)
|
||||
#define err_exit(a) goto error
|
||||
#else //}{ save debugging time
|
||||
#define ERR_LAB /*empty*/
|
||||
DEBUG_STRCON(STR_exit, "err_exit %%x\\n");
|
||||
|
||||
static void
|
||||
err_exit(int a)
|
||||
{
|
||||
DPRINTF((STR_exit(), a));
|
||||
DPRINTF("err_exit %%x\\n", a);
|
||||
(void)a; // debugging convenience
|
||||
exit(127);
|
||||
}
|
||||
@@ -263,11 +168,7 @@ typedef void f_unfilter(
|
||||
);
|
||||
typedef int f_expand(
|
||||
const nrv_byte *, nrv_uint,
|
||||
nrv_byte *, nrv_uint *, unsigned );
|
||||
|
||||
DEBUG_STRCON(STR_unpackExtent,
|
||||
"unpackExtent in=%%p(%%x %%p) out=%%p(%%x %%p) %%p %%p\\n");
|
||||
DEBUG_STRCON(STR_err5, "sz_cpr=%%x sz_unc=%%x xo->size=%%x\\n");
|
||||
nrv_byte *, size_t *, unsigned );
|
||||
|
||||
static void
|
||||
unpackExtent(
|
||||
@@ -277,8 +178,8 @@ unpackExtent(
|
||||
f_unfilter *f_unf
|
||||
)
|
||||
{
|
||||
DPRINTF((STR_unpackExtent(),
|
||||
xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, f_unf));
|
||||
DPRINTF("unpackExtent in=%%p(%%x %%p) out=%%p(%%x %%p) %%p %%p\\n",
|
||||
xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, f_unf);
|
||||
while (xo->size) {
|
||||
struct b_info h;
|
||||
// Note: if h.sz_unc == h.sz_cpr then the block was not
|
||||
@@ -299,7 +200,8 @@ ERR_LAB
|
||||
}
|
||||
if (h.sz_cpr > h.sz_unc
|
||||
|| h.sz_unc > xo->size ) {
|
||||
DPRINTF((STR_err5(), h.sz_cpr, h.sz_unc, xo->size));
|
||||
DPRINTF("sz_cpr=%%x sz_unc=%%x xo->size=%%x\\n",
|
||||
h.sz_cpr, h.sz_unc, xo->size);
|
||||
err_exit(5);
|
||||
}
|
||||
// Now we have:
|
||||
@@ -308,7 +210,7 @@ ERR_LAB
|
||||
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
|
||||
|
||||
if (h.sz_cpr < h.sz_unc) { // Decompress block
|
||||
nrv_uint out_len = h.sz_unc; // EOF for lzma
|
||||
size_t out_len = h.sz_unc; // EOF for lzma
|
||||
int const j = (*f_decompress)(xi->buf, h.sz_cpr,
|
||||
xo->buf, &out_len, h.b_method);
|
||||
if (j != 0 || out_len != (nrv_uint)h.sz_unc)
|
||||
@@ -471,11 +373,7 @@ extern void *mmap(void *, size_t, unsigned, unsigned, int, off_t_upx_stub);
|
||||
ssize_t pread(int, void *, size_t, off_t_upx_stub);
|
||||
extern void bswap(void *, unsigned);
|
||||
|
||||
DEBUG_STRCON(STR_mmap,
|
||||
"mmap addr=%%p len=%%p prot=%%x flags=%%x fd=%%d off=%%p\\n");
|
||||
DEBUG_STRCON(STR_do_xmap,
|
||||
"do_xmap fdi=%%x mhdr=%%p xi=%%p(%%x %%p) f_unf=%%p\\n")
|
||||
|
||||
// FIXME: must reserve convex hull of pages; must reloc PIE
|
||||
static Mach_AMD64_thread_state const *
|
||||
do_xmap(
|
||||
Mach_header64 const *const mhdr,
|
||||
@@ -491,8 +389,8 @@ do_xmap(
|
||||
Mach_AMD64_thread_state const *entry = 0;
|
||||
unsigned j;
|
||||
|
||||
DPRINTF((STR_do_xmap(),
|
||||
fdi, mhdr, xi, (xi? xi->size: 0), (xi? xi->buf: 0), f_unf));
|
||||
DPRINTF("do_xmap fdi=%%x mhdr=%%p xi=%%p(%%x %%p) f_unf=%%p\\n",
|
||||
fdi, mhdr, xi, (xi? xi->size: 0), (xi? xi->buf: 0), f_unf);
|
||||
|
||||
for ( j=0; j < mhdr->ncmds; ++j,
|
||||
(sc = (Mach_segment_command const *)(sc->cmdsize + (void const *)sc))
|
||||
@@ -514,7 +412,8 @@ do_xmap(
|
||||
int const fdm = ((0==sc->filesize) ? MAP_ANON_FD : fdi);
|
||||
off_t_upx_stub const offset = sc->fileoff + fat_offset;
|
||||
|
||||
DPRINTF((STR_mmap(), addr, mlen3, prot, flags, fdm, offset));
|
||||
DPRINTF("mmap addr=%%p len=%%p prot=%%x flags=%%x fd=%%d off=%%p\\n",
|
||||
addr, mlen3, prot, flags, fdm, offset);
|
||||
if (addr != mmap(addr, mlen3, prot, flags, fdm, offset)) {
|
||||
err_exit(8);
|
||||
}
|
||||
@@ -562,14 +461,10 @@ ERR_LAB
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// upx_main - called by our entry code
|
||||
// upx_main - called by our unfolded entry code
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
DEBUG_STRCON(STR_upx_main,
|
||||
"upx_main szc=%%x f_dec=%%p f_unf=%%p "
|
||||
" xo=%%p(%%x %%p) xi=%%p(%%x %%p) mhdrpp=%%p\\n")
|
||||
|
||||
Mach_AMD64_thread_state const *
|
||||
upx_main(
|
||||
struct l_info const *const li,
|
||||
@@ -590,9 +485,10 @@ upx_main(
|
||||
xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc;
|
||||
xi0 = xi;
|
||||
|
||||
DPRINTF((STR_upx_main(),
|
||||
DPRINTF("upx_main szc=%%x f_dec=%%p f_unf=%%p "
|
||||
" xo=%%p(%%x %%p) xi=%%p(%%x %%p) mhdrpp=%%p mhdrp=%%p\\n",
|
||||
sz_compressed, f_decompress, f_unf, &xo, xo.size, xo.buf,
|
||||
&xi, xi.size, xi.buf, mhdrpp));
|
||||
&xi, xi.size, xi.buf, mhdrpp, *mhdrpp);
|
||||
|
||||
// Uncompress Macho headers
|
||||
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
|
||||
@@ -643,4 +539,113 @@ ERR_LAB
|
||||
return entry;
|
||||
}
|
||||
|
||||
#if DEBUG //{
|
||||
|
||||
static int
|
||||
unsimal(unsigned x, char *ptr, int n)
|
||||
{
|
||||
unsigned m = 10;
|
||||
while (10 <= (x / m)) m *= 10;
|
||||
while (10 <= x) {
|
||||
unsigned d = x / m;
|
||||
x -= m * d;
|
||||
m /= 10;
|
||||
ptr[n++] = '0' + d;
|
||||
}
|
||||
ptr[n++] = '0' + x;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
decimal(int x, char *ptr, int n)
|
||||
{
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
ptr[n++] = '-';
|
||||
}
|
||||
return unsimal(x, ptr, n);
|
||||
}
|
||||
|
||||
static int
|
||||
heximal(unsigned long x, char *ptr, int n)
|
||||
{
|
||||
unsigned j = -1+ 2*sizeof(unsigned long);
|
||||
unsigned long m = 0xful << (4 * j);
|
||||
for (; j; --j, m >>= 4) { // omit leading 0 digits
|
||||
if (m & x) break;
|
||||
}
|
||||
for (; m; --j, m >>= 4) {
|
||||
unsigned d = 0xf & (x >> (4 * j));
|
||||
ptr[n++] = ((10<=d) ? ('a' - 10) : '0') + d;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#define va_arg __builtin_va_arg
|
||||
#define va_end __builtin_va_end
|
||||
#define va_list __builtin_va_list
|
||||
#define va_start __builtin_va_start
|
||||
|
||||
static int
|
||||
dprintf(char const *fmt, ...)
|
||||
{
|
||||
int n= 0;
|
||||
char const *literal = 0; // NULL
|
||||
char buf[24]; // ~0ull == 18446744073709551615 ==> 20 chars
|
||||
va_list va; va_start(va, fmt);
|
||||
for (;;) {
|
||||
char c = *fmt++;
|
||||
if (!c) { // end of fmt
|
||||
if (literal) {
|
||||
goto finish;
|
||||
}
|
||||
break; // goto done
|
||||
}
|
||||
if ('%'!=c) {
|
||||
if (!literal) {
|
||||
literal = fmt; // 1 beyond start of literal
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// '%' == c
|
||||
if (literal) {
|
||||
finish:
|
||||
n += write(2, -1+ literal, fmt - literal);
|
||||
literal = 0; // NULL
|
||||
if (!c) { // fmt already ended
|
||||
break; // goto done
|
||||
}
|
||||
}
|
||||
switch (c= *fmt++) { // deficiency: does not handle _long_
|
||||
default: { // un-implemented conversion
|
||||
n+= write(2, -1+ fmt, 1);
|
||||
} break;
|
||||
case 0: { // fmt ends with "%\0" ==> ignore
|
||||
goto done;
|
||||
} break;
|
||||
case 'u': {
|
||||
n+= write(2, buf, unsimal(va_arg(va, unsigned), buf, 0));
|
||||
} break;
|
||||
case 'd': {
|
||||
n+= write(2, buf, decimal(va_arg(va, int), buf, 0));
|
||||
} break;
|
||||
case 'p': {
|
||||
buf[0] = '0';
|
||||
buf[1] = 'x';
|
||||
n+= write(2, buf, heximal((unsigned long)va_arg(va, void *), buf, 2));
|
||||
} break;
|
||||
case 'x': {
|
||||
buf[0] = '0';
|
||||
buf[1] = 'x';
|
||||
n+= write(2, buf, heximal(va_arg(va, int), buf, 2));
|
||||
} break;
|
||||
} // 'switch'
|
||||
}
|
||||
done:
|
||||
va_end(va);
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif //}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
Reference in New Issue
Block a user