new DPRINTF

modified:   stub/src/amd64-darwin.macho-main.c
This commit is contained in:
John Reiser
2017-12-12 10:52:47 -08:00
parent 34646f1c6a
commit 3385264eb2
+166 -161
View File
@@ -34,7 +34,7 @@
#include "include/darwin.h" #include "include/darwin.h"
#ifndef DEBUG /*{*/ #ifndef DEBUG /*{*/
#define DEBUG 0 #define DEBUG 1
#endif /*}*/ #endif /*}*/
/************************************************************************* /*************************************************************************
@@ -45,136 +45,44 @@
// it at an address different from it load address: there must be no // it at an address different from it load address: there must be no
// static data, and no string constants. // static data, and no string constants.
#if !DEBUG /*{*/ #if !DEBUG //{
#define DPRINTF(a) /* empty: no debug drivel */ #define DPRINTF(fmt, args...) /*empty*/
#define DEBUG_STRCON(name, value) /* empty */ #else //}{
#else /*}{ DEBUG */ // DPRINTF is defined as an expression using "({ ... })"
extern int write(int, void const *, size_t); // so that DPRINTF can be invoked inside an expression,
#if 0 // and then followed by a comma to ignore the return value.
#include "stdarg.h" // The only complication is that percent and backslash
#else // must be doubled in the format string, because the format
#define va_arg __builtin_va_arg // string is processd twice: once at compile-time by 'asm'
#define va_end __builtin_va_end // to produce the assembled value, and once at runtime to use it.
#define va_list __builtin_va_list #if defined(__powerpc__) //{
#define va_start __builtin_va_start #define DPRINTF(fmt, args...) ({ \
#endif 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__) /*{*/ static int dprintf(char const *fmt, ...); // forward
#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;
}
#endif /*}*/ #endif /*}*/
@@ -187,17 +95,15 @@ typedef struct {
void *buf; void *buf;
} Extent; } 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 static void
xread(Extent *x, void *buf, size_t count) xread(Extent *x, void *buf, size_t count)
{ {
unsigned char *p=x->buf, *q=buf; unsigned char *p=x->buf, *q=buf;
size_t j; 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) { 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); exit(127);
} }
for (j = count; 0!=j--; ++p, ++q) { 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 #define err_exit(a) goto error
#else //}{ save debugging time #else //}{ save debugging time
#define ERR_LAB /*empty*/ #define ERR_LAB /*empty*/
DEBUG_STRCON(STR_exit, "err_exit %%x\\n");
static void static void
err_exit(int a) err_exit(int a)
{ {
DPRINTF((STR_exit(), a)); DPRINTF("err_exit %%x\\n", a);
(void)a; // debugging convenience (void)a; // debugging convenience
exit(127); exit(127);
} }
@@ -263,11 +168,7 @@ typedef void f_unfilter(
); );
typedef int f_expand( typedef int f_expand(
const nrv_byte *, nrv_uint, const nrv_byte *, nrv_uint,
nrv_byte *, nrv_uint *, unsigned ); nrv_byte *, size_t *, 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");
static void static void
unpackExtent( unpackExtent(
@@ -277,8 +178,8 @@ unpackExtent(
f_unfilter *f_unf f_unfilter *f_unf
) )
{ {
DPRINTF((STR_unpackExtent(), 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)); xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, f_unf);
while (xo->size) { while (xo->size) {
struct b_info h; struct b_info h;
// Note: if h.sz_unc == h.sz_cpr then the block was not // 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 if (h.sz_cpr > h.sz_unc
|| h.sz_unc > xo->size ) { || 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); err_exit(5);
} }
// Now we have: // Now we have:
@@ -308,7 +210,7 @@ ERR_LAB
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize); // assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
if (h.sz_cpr < h.sz_unc) { // Decompress block 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, int const j = (*f_decompress)(xi->buf, h.sz_cpr,
xo->buf, &out_len, h.b_method); xo->buf, &out_len, h.b_method);
if (j != 0 || out_len != (nrv_uint)h.sz_unc) 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); ssize_t pread(int, void *, size_t, off_t_upx_stub);
extern void bswap(void *, unsigned); extern void bswap(void *, unsigned);
DEBUG_STRCON(STR_mmap, // FIXME: must reserve convex hull of pages; must reloc PIE
"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")
static Mach_AMD64_thread_state const * static Mach_AMD64_thread_state const *
do_xmap( do_xmap(
Mach_header64 const *const mhdr, Mach_header64 const *const mhdr,
@@ -491,8 +389,8 @@ do_xmap(
Mach_AMD64_thread_state const *entry = 0; Mach_AMD64_thread_state const *entry = 0;
unsigned j; unsigned j;
DPRINTF((STR_do_xmap(), 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)); fdi, mhdr, xi, (xi? xi->size: 0), (xi? xi->buf: 0), f_unf);
for ( j=0; j < mhdr->ncmds; ++j, for ( j=0; j < mhdr->ncmds; ++j,
(sc = (Mach_segment_command const *)(sc->cmdsize + (void const *)sc)) (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); int const fdm = ((0==sc->filesize) ? MAP_ANON_FD : fdi);
off_t_upx_stub const offset = sc->fileoff + fat_offset; 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)) { if (addr != mmap(addr, mlen3, prot, flags, fdm, offset)) {
err_exit(8); 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 * Mach_AMD64_thread_state const *
upx_main( upx_main(
struct l_info const *const li, struct l_info const *const li,
@@ -590,9 +485,10 @@ upx_main(
xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc; xo.size = ((struct b_info const *)(void const *)xi.buf)->sz_unc;
xi0 = xi; 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, 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 // Uncompress Macho headers
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered? unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
@@ -643,4 +539,113 @@ ERR_LAB
return entry; 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: */ /* vim:set ts=4 sw=4 et: */