Skip to content

Commit b19b4a6

Browse files
committed
Clean up E9Patch logging code.
1 parent 30f12d8 commit b19b4a6

5 files changed

Lines changed: 108 additions & 22 deletions

File tree

src/e9patch/e9api.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ static Binary *parseBinary(const Message &msg)
210210

211211
Binary *B = new Binary;
212212
B->filename = filename;
213+
B->output = nullptr;
213214
B->mode = mode;
214215
B->cursor = INTPTR_MAX;
215216

@@ -440,13 +441,14 @@ static void parseEmit(Binary *B, const Message &msg)
440441
if (dup)
441442
error("failed to parse \"emit\" message (id=%u); duplicate "
442443
"parameters detected");
444+
B->output = filename;
443445

444446
// Build trampoline entry set (b4 flush)
445447
buildEntrySet(B);
446448

447449
// Flush the queue:
448450
queueFlush(B, INTPTR_MIN);
449-
putchar('\n');
451+
log(COLOR_NONE, '\n');
450452

451453
// Create and optimize the mappings:
452454
MappingSet mappings;

src/e9patch/e9mapping.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ static Radix::Node<Key> *merge(Radix::Node<Key> *tree, Key key,
547547
// Add to existing node for key:
548548
mapping->next = node->leaf.mappings;
549549
node->leaf.mappings = mapping;
550-
putchar('+');
550+
log(COLOR_NONE, '+');
551551
return tree;
552552
}
553553

@@ -565,10 +565,10 @@ static Radix::Node<Key> *merge(Radix::Node<Key> *tree, Key key,
565565
// Leaf node is now empty, so remove it.
566566
tree = remove(tree, node->key);
567567
}
568-
printf("\33[32mM\33[0m");
568+
log(COLOR_GREEN, 'M');
569569
}
570570
else
571-
putchar('+');
571+
log(COLOR_NONE, '+');
572572

573573
// Insert a new node:
574574
tree = insert(tree, key, mapping);
@@ -590,7 +590,9 @@ static void collectMappings(Radix::Node<Key> *node, MappingSet &mappings)
590590
{
591591
std::string str;
592592
bitstring(node->key, str);
593-
printf("[\33[33m%s\33[0m]", str.c_str());
593+
log(COLOR_NONE, '[');
594+
log(COLOR_YELLOW, str.c_str());
595+
log(COLOR_NONE, ']');
594596
insertMapping(mapping, mappings);
595597
stat_num_physical_mappings++;
596598
}
@@ -652,11 +654,11 @@ void optimizeMappings(const Allocator &allocator, const size_t MAPPING_SIZE,
652654
Key key = calculateKey<Key>(allocator, MAPPING_SIZE, mapping);
653655
tree = merge(tree, key, mapping);
654656
}
655-
putchar('\n');
657+
log(COLOR_NONE, '\n');
656658

657659
mappings.clear();
658660
collectMappings(tree, mappings);
659-
putchar('\n');
661+
log(COLOR_NONE, '\n');
660662

661663
for (auto mapping: mappings)
662664
shrinkMapping(mapping, granularity);

src/e9patch/e9patch.cpp

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ bool option_loader_base_set = false;
7171
bool option_loader_phdr_set = false;
7272
bool option_loader_static_set = false;
7373
bool option_mem_rebase_set = false;
74+
bool option_log = true;
75+
int option_log_color = COLOR_NONE;
7476

7577
/*
7678
* Global statistics.
@@ -142,6 +144,33 @@ void debugImpl(const char *msg, ...)
142144
putc('\n', stderr);
143145
}
144146

147+
/*
148+
* Print logging information.
149+
*/
150+
void logSetColor(int color)
151+
{
152+
option_log_color = color;
153+
if (!option_is_tty || !option_log)
154+
return;
155+
switch (color)
156+
{
157+
case COLOR_NONE:
158+
fputs("\33[0m", stdout); break;
159+
case COLOR_RED:
160+
fputs("\33[31m", stdout); break;
161+
case COLOR_GREEN:
162+
fputs("\33[32m", stdout); break;
163+
case COLOR_BLUE:
164+
fputs("\33[34m", stdout); break;
165+
case COLOR_CYAN:
166+
fputs("\33[36m", stdout); break;
167+
case COLOR_MAGENTA:
168+
fputs("\33[35m", stdout); break;
169+
case COLOR_YELLOW:
170+
fputs("\33[33m", stdout); break;
171+
}
172+
}
173+
145174
/*
146175
* Parse an integer from an optarg.
147176
*/
@@ -236,8 +265,9 @@ static void usage(FILE *stream, const char *progname)
236265
"\t\tRewrite the binary in one batch rather than incrementally.\n"
237266
"\t\tDefault: false (disabled)\n"
238267
"\n"
239-
"\t--debug\n"
240-
"\t\tEnable debug log messages.\n"
268+
"\t--debug[=false]\n"
269+
"\t\tEnable [disable] debug log messages.\n"
270+
"\t\tDefault: false (disabled)\n"
241271
"\n"
242272
"\t--help, -h\n"
243273
"\t\tPrint this help message.\n"
@@ -272,6 +302,10 @@ static void usage(FILE *stream, const char *progname)
272302
"\t\tOnly relevant for ELF binaries.\n"
273303
"\t\tDefault: false (disabled)\n"
274304
"\n"
305+
"\t--log=[false]\n"
306+
"\t\tEnable [disable] log output.\n"
307+
"\t\tDefault: true (enabled)\n"
308+
"\n"
275309
"\t--mem-granularity=SIZE\n"
276310
"\t\tSet SIZE to be the granularity used for the physical page\n"
277311
"\t\tgrouping memory optimization. Higher values result in\n"
@@ -347,6 +381,7 @@ enum Option
347381
OPTION_LOADER_BASE,
348382
OPTION_LOADER_PHDR,
349383
OPTION_LOADER_STATIC,
384+
OPTION_LOG,
350385
OPTION_MEM_GRANULARITY,
351386
OPTION_MEM_LB,
352387
OPTION_MEM_MAPPING_SIZE,
@@ -392,12 +427,13 @@ void parseOptions(char * const argv[], bool api)
392427
{"Oprologue-size", req_arg, nullptr, OPTION_OPROLOGUE_SIZE},
393428
{"Oscratch-stack", opt_arg, nullptr, OPTION_OSCRATCH_STACK},
394429
{"batch", opt_arg, nullptr, OPTION_BATCH},
395-
{"debug", no_arg, nullptr, OPTION_DEBUG},
430+
{"debug", opt_arg, nullptr, OPTION_DEBUG},
396431
{"help", no_arg, nullptr, OPTION_HELP},
397432
{"input", req_arg, nullptr, OPTION_INPUT},
398433
{"loader-base", req_arg, nullptr, OPTION_LOADER_BASE},
399434
{"loader-phdr", req_arg, nullptr, OPTION_LOADER_PHDR},
400435
{"loader-static", opt_arg, nullptr, OPTION_LOADER_STATIC},
436+
{"log", opt_arg, nullptr, OPTION_LOG},
401437
{"mem-granularity", req_arg, nullptr, OPTION_MEM_GRANULARITY},
402438
{"mem-lb", req_arg, nullptr, OPTION_MEM_LB},
403439
{"mem-mapping-size", req_arg, nullptr, OPTION_MEM_MAPPING_SIZE},
@@ -441,7 +477,7 @@ void parseOptions(char * const argv[], bool api)
441477
option_batch = parseBoolOptArg("--batch", optarg);
442478
break;
443479
case OPTION_DEBUG:
444-
option_debug = true;
480+
option_debug = parseBoolOptArg("--debug", optarg);
445481
break;
446482
case 'h':
447483
case OPTION_HELP:
@@ -547,6 +583,9 @@ void parseOptions(char * const argv[], bool api)
547583
option_loader_static =
548584
parseBoolOptArg("--loader-static", optarg);
549585
break;
586+
case OPTION_LOG:
587+
option_log = parseBoolOptArg("--log", optarg);
588+
break;
550589
case OPTION_MEM_GRANULARITY:
551590
option_mem_granularity = parseIntOptArg("--mem-granularity",
552591
optarg, INTPTR_MIN, INTPTR_MAX);
@@ -619,11 +658,6 @@ extern "C"
619658
int realMain(int argc, char **argv)
620659
{
621660
option_is_tty = (isatty(STDERR_FILENO) != 0);
622-
if (getenv("E9PATCH_TTY") != nullptr)
623-
option_is_tty = true;
624-
if (getenv("E9PATCH_DEBUG") != nullptr)
625-
option_debug = true;
626-
627661
parseOptions(argv);
628662

629663
if (option_input != "-")
@@ -642,7 +676,7 @@ int realMain(int argc, char **argv)
642676
}
643677
if (isatty(STDIN_FILENO))
644678
warning("reading JSON-RPC from a terminal (this is probably not "
645-
"what you want, please use an E9PATCH frontend instead!)");
679+
"what you want, please use E9Tool instead!)");
646680

647681
Binary *B = nullptr;
648682
Message msg;
@@ -696,9 +730,11 @@ int realMain(int argc, char **argv)
696730
mode_str = "Windows PE dynamic link library"; break;
697731
}
698732

699-
printf("\n\n-----------------------------------------------\n");
733+
log(COLOR_NONE, '\n');
734+
printf("-----------------------------------------------\n");
735+
printf("mode = %s\n", mode_str);
700736
printf("input_binary = %s\n", B->filename);
701-
printf("input_mode = %s\n", mode_str);
737+
printf("output_binary = %s\n", B->output);
702738
printf("num_patched = %zu / %zu (%s%s%%)\n",
703739
stat_num_patched, stat_num_total, (approx? "~": ""),
704740
percent);
@@ -749,7 +785,7 @@ int realMain(int argc, char **argv)
749785
"\t(1) raising the limit, e.g.:\n"
750786
"\t sudo sysctl -w vm.max_map_count=%zu\n"
751787
"\t(2) rewriting the binary with a larger mapping size\n"
752-
"\t (see the `--mem-mapping-size' option).",
788+
"\t (see the `--size' option).",
753789
stat_num_virtual_mappings,
754790
((ssize_t)stat_num_virtual_mappings >= MAX_MAPPINGS?
755791
"exceeds": "may exceed"),
@@ -838,3 +874,19 @@ asm (
838874
".Lskip:\n"
839875
);
840876

877+
#ifndef NDEBUG
878+
/*
879+
* ASAN options.
880+
*/
881+
extern "C"
882+
{
883+
/*
884+
* E9Patch deliberately leaks memory & leaves it to the OS to clean-up.
885+
*/
886+
const char *__asan_default_options()
887+
{
888+
return "detect_leaks=0";
889+
}
890+
}
891+
#endif
892+

src/e9patch/e9patch.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ struct Binary
481481
{
482482
const char *filename; // The binary's path.
483483
size_t size; // The binary's size.
484+
const char *output; // The rewritten binary's path.
484485
union
485486
{
486487
ElfInfo elf; // ELF information.
@@ -559,6 +560,8 @@ extern bool option_loader_base_set;
559560
extern bool option_loader_phdr_set;
560561
extern bool option_loader_static_set;
561562
extern bool option_mem_rebase_set;
563+
extern bool option_log;
564+
extern int option_log_color;
562565

563566
/*
564567
* Special values for option_mem_rebase.
@@ -567,6 +570,17 @@ extern bool option_mem_rebase_set;
567570
#define OPTION_REBASE_AUTO -1
568571
#define OPTION_REBASE_RANDOM -2
569572

573+
/*
574+
* Log colors.
575+
*/
576+
#define COLOR_NONE 0
577+
#define COLOR_RED 1
578+
#define COLOR_GREEN 2
579+
#define COLOR_BLUE 3
580+
#define COLOR_CYAN 4
581+
#define COLOR_MAGENTA 5
582+
#define COLOR_YELLOW 6
583+
570584
/*
571585
* Global statistics.
572586
*/
@@ -588,12 +602,28 @@ extern void parseOptions(char * const argv[], bool api = false);
588602
extern void NO_RETURN error(const char *msg, ...);
589603
extern void warning(const char *msg, ...);
590604
extern void debugImpl(const char *msg, ...);
605+
extern void logSetColor(int color);
606+
607+
static inline void logImpl(char c)
608+
{
609+
putchar(c);
610+
}
611+
static inline void logImpl(const char *s)
612+
{
613+
fputs(s, stdout);
614+
}
591615

592616
#define debug(msg, ...) \
593617
do { \
594618
if (__builtin_expect(option_debug, false)) \
595619
debugImpl((msg), ##__VA_ARGS__); \
596620
} while (false)
621+
#define log(color, msg, ...) \
622+
do { \
623+
if (!option_log) break; \
624+
if ((color) != option_log_color) logSetColor(color); \
625+
logImpl(msg, ##__VA_ARGS__); \
626+
} while (false)
597627

598628
#define ADDRESS_FORMAT "%s%s0x%lx"
599629
#define ADDRESS(p) \

src/e9patch/e9tactics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ bool patch(Binary &B, Instr *I, const Trampoline *T)
756756
{
757757
debug("failed to patch instruction at address 0x%lx (%zu)", I->addr,
758758
I->size);
759-
printf("\33[31mX\33[0m");
759+
log(COLOR_RED, 'X');
760760
return false; // Failed :(
761761
}
762762

@@ -774,7 +774,7 @@ bool patch(Binary &B, Instr *I, const Trampoline *T)
774774
ADDRESS(entry), ADDRESS(lb), ADDRESS(ub),
775775
(ssize_t)(entry - lb));
776776
}
777-
printf("\33[32m.\33[0m");
777+
log(COLOR_GREEN, '.');
778778
return true; // Success!
779779
}
780780

0 commit comments

Comments
 (0)