2 * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
25 struct bin_instruction {
27 unsigned int operands[3];
38 struct bin_instruction *bin;
40 const char *operands[5];
43 unsigned int labeladdr;
44 struct statement *labelref;
51 struct list_head list;
54 struct disassembler_context {
55 /* The architecture of the input file. */
58 struct bin_instruction *code;
61 struct list_head stmt_list;
67 const char *infile_name;
68 const char *outfile_name;
71 static const char * gen_raw_code(unsigned int operand)
76 snprintf(ret, 5, "@%03X", operand);
81 static const char * disasm_mem_operand(unsigned int operand)
86 snprintf(ret, 9, "[0x%X]", operand);
91 static const char * disasm_indirect_mem_operand(unsigned int operand)
96 snprintf(ret, 12, "[0x%02X,off%u]",
97 (operand & 0x3F), ((operand >> 6) & 0x7));
102 static const char * disasm_imm_operand(unsigned int operand)
105 unsigned int signmask;
108 switch (cmdargs.arch) {
114 signmask = (1 << 10);
118 fprintf(stderr, "Internal error: disasm_imm_operand invalid arch\n");
125 if (operand & signmask)
126 operand = (operand | (~mask & 0xFFFF));
127 snprintf(ret, 7, "0x%X", operand);
132 static const char * disasm_spr_operand(unsigned int operand)
137 switch (cmdargs.arch) {
145 fprintf(stderr, "Internal error: disasm_spr_operand invalid arch\n");
150 snprintf(ret, 8, "spr%X", (operand & mask));
155 static const char * disasm_gpr_operand(unsigned int operand)
160 switch (cmdargs.arch) {
168 fprintf(stderr, "Internal error: disasm_gpr_operand invalid arch\n");
173 snprintf(ret, 5, "r%u", (operand & mask));
178 static void disasm_std_operand(struct statement *stmt,
183 unsigned int operand = stmt->u.insn.bin->operands[oper_idx];
188 switch (cmdargs.arch) {
190 if (!(operand & 0x800)) {
191 stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand);
193 } else if ((operand & 0xC00) == 0xC00) {
194 stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand);
196 } else if ((operand & 0xFC0) == 0xBC0) {
197 stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand);
199 } else if ((operand & 0xE00) == 0x800) {
200 stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand);
202 } else if ((operand & 0xE00) == 0xA00) {
203 stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand);
208 if (!(operand & 0x1000)) {
209 stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand);
211 } else if ((operand & 0x1800) == 0x1800) {
212 stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand);
214 } else if ((operand & 0x1F80) == 0x1780) {
215 stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand);
217 } else if ((operand & 0x1C00) == 0x1000) {
218 stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand);
220 } else if ((operand & 0x1C00) == 0x1400) {
221 stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand);
226 fprintf(stderr, "Internal error: disasm_std_operand invalid arch\n");
230 stmt->u.insn.operands[out_idx] = gen_raw_code(operand);
233 static void disasm_constant_opcodes(struct disassembler_context *ctx,
234 struct statement *stmt)
236 struct bin_instruction *bin = stmt->u.insn.bin;
238 switch (bin->opcode) {
240 stmt->u.insn.name = "add";
241 disasm_std_operand(stmt, 0, 0, 0);
242 disasm_std_operand(stmt, 1, 1, 0);
243 disasm_std_operand(stmt, 2, 2, 0);
246 stmt->u.insn.name = "add.";
247 disasm_std_operand(stmt, 0, 0, 0);
248 disasm_std_operand(stmt, 1, 1, 0);
249 disasm_std_operand(stmt, 2, 2, 0);
252 stmt->u.insn.name = "addc";
253 disasm_std_operand(stmt, 0, 0, 0);
254 disasm_std_operand(stmt, 1, 1, 0);
255 disasm_std_operand(stmt, 2, 2, 0);
258 stmt->u.insn.name = "addc.";
259 disasm_std_operand(stmt, 0, 0, 0);
260 disasm_std_operand(stmt, 1, 1, 0);
261 disasm_std_operand(stmt, 2, 2, 0);
264 stmt->u.insn.name = "sub";
265 disasm_std_operand(stmt, 0, 0, 0);
266 disasm_std_operand(stmt, 1, 1, 0);
267 disasm_std_operand(stmt, 2, 2, 0);
270 stmt->u.insn.name = "sub.";
271 disasm_std_operand(stmt, 0, 0, 0);
272 disasm_std_operand(stmt, 1, 1, 0);
273 disasm_std_operand(stmt, 2, 2, 0);
276 stmt->u.insn.name = "subc";
277 disasm_std_operand(stmt, 0, 0, 0);
278 disasm_std_operand(stmt, 1, 1, 0);
279 disasm_std_operand(stmt, 2, 2, 0);
282 stmt->u.insn.name = "subc.";
283 disasm_std_operand(stmt, 0, 0, 0);
284 disasm_std_operand(stmt, 1, 1, 0);
285 disasm_std_operand(stmt, 2, 2, 0);
288 stmt->u.insn.name = "sra";
289 disasm_std_operand(stmt, 0, 0, 0);
290 disasm_std_operand(stmt, 1, 1, 0);
291 disasm_std_operand(stmt, 2, 2, 0);
294 stmt->u.insn.name = "or";
295 disasm_std_operand(stmt, 0, 0, 0);
296 disasm_std_operand(stmt, 1, 1, 0);
297 disasm_std_operand(stmt, 2, 2, 0);
300 stmt->u.insn.name = "and";
301 disasm_std_operand(stmt, 0, 0, 0);
302 disasm_std_operand(stmt, 1, 1, 0);
303 disasm_std_operand(stmt, 2, 2, 0);
306 stmt->u.insn.name = "xor";
307 disasm_std_operand(stmt, 0, 0, 0);
308 disasm_std_operand(stmt, 1, 1, 0);
309 disasm_std_operand(stmt, 2, 2, 0);
312 stmt->u.insn.name = "sr";
313 disasm_std_operand(stmt, 0, 0, 0);
314 disasm_std_operand(stmt, 1, 1, 0);
315 disasm_std_operand(stmt, 2, 2, 0);
318 stmt->u.insn.name = "sl";
319 disasm_std_operand(stmt, 0, 0, 0);
320 disasm_std_operand(stmt, 1, 1, 0);
321 disasm_std_operand(stmt, 2, 2, 0);
324 stmt->u.insn.name = "rl";
325 disasm_std_operand(stmt, 0, 0, 0);
326 disasm_std_operand(stmt, 1, 1, 0);
327 disasm_std_operand(stmt, 2, 2, 0);
330 stmt->u.insn.name = "rr";
331 disasm_std_operand(stmt, 0, 0, 0);
332 disasm_std_operand(stmt, 1, 1, 0);
333 disasm_std_operand(stmt, 2, 2, 0);
336 stmt->u.insn.name = "nand";
337 disasm_std_operand(stmt, 0, 0, 0);
338 disasm_std_operand(stmt, 1, 1, 0);
339 disasm_std_operand(stmt, 2, 2, 0);
342 stmt->u.insn.name = "jand";
343 stmt->u.insn.is_labelref = 2;
344 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
345 disasm_std_operand(stmt, 0, 0, 0);
346 disasm_std_operand(stmt, 1, 1, 0);
349 stmt->u.insn.name = "jnand";
350 stmt->u.insn.is_labelref = 2;
351 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
352 disasm_std_operand(stmt, 0, 0, 0);
353 disasm_std_operand(stmt, 1, 1, 0);
356 stmt->u.insn.name = "js";
357 stmt->u.insn.is_labelref = 2;
358 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
359 disasm_std_operand(stmt, 0, 0, 0);
360 disasm_std_operand(stmt, 1, 1, 0);
363 stmt->u.insn.name = "jns";
364 stmt->u.insn.is_labelref = 2;
365 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
366 disasm_std_operand(stmt, 0, 0, 0);
367 disasm_std_operand(stmt, 1, 1, 0);
370 stmt->u.insn.name = "je";
371 stmt->u.insn.is_labelref = 2;
372 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
373 disasm_std_operand(stmt, 0, 0, 0);
374 disasm_std_operand(stmt, 1, 1, 0);
377 stmt->u.insn.name = "jne";
378 stmt->u.insn.is_labelref = 2;
379 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
380 disasm_std_operand(stmt, 0, 0, 0);
381 disasm_std_operand(stmt, 1, 1, 0);
384 stmt->u.insn.name = "jls";
385 stmt->u.insn.is_labelref = 2;
386 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
387 disasm_std_operand(stmt, 0, 0, 0);
388 disasm_std_operand(stmt, 1, 1, 0);
391 stmt->u.insn.name = "jges";
392 stmt->u.insn.is_labelref = 2;
393 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
394 disasm_std_operand(stmt, 0, 0, 0);
395 disasm_std_operand(stmt, 1, 1, 0);
398 stmt->u.insn.name = "jgs";
399 stmt->u.insn.is_labelref = 2;
400 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
401 disasm_std_operand(stmt, 0, 0, 0);
402 disasm_std_operand(stmt, 1, 1, 0);
405 stmt->u.insn.name = "jles";
406 stmt->u.insn.is_labelref = 2;
407 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
408 disasm_std_operand(stmt, 0, 0, 0);
409 disasm_std_operand(stmt, 1, 1, 0);
412 stmt->u.insn.name = "jl";
413 stmt->u.insn.is_labelref = 2;
414 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
415 disasm_std_operand(stmt, 0, 0, 0);
416 disasm_std_operand(stmt, 1, 1, 0);
419 stmt->u.insn.name = "jge";
420 stmt->u.insn.is_labelref = 2;
421 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
422 disasm_std_operand(stmt, 0, 0, 0);
423 disasm_std_operand(stmt, 1, 1, 0);
426 stmt->u.insn.name = "jg";
427 stmt->u.insn.is_labelref = 2;
428 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
429 disasm_std_operand(stmt, 0, 0, 0);
430 disasm_std_operand(stmt, 1, 1, 0);
433 stmt->u.insn.name = "jle";
434 stmt->u.insn.is_labelref = 2;
435 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
436 disasm_std_operand(stmt, 0, 0, 0);
437 disasm_std_operand(stmt, 1, 1, 0);
442 //FIXME: Broken for r15
443 stmt->u.insn.name = "call";
444 stmt->u.insn.is_labelref = 1;
445 //printf("CALL 0x%X 0x%X 0x%X\n", stmt->u.insn.bin->operands[0], stmt->u.insn.bin->operands[1], stmt->u.insn.bin->operands[2]);
446 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
448 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]);
449 stmt->u.insn.operands[0] = str;
455 stmt->u.insn.name = "ret";
457 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]);
458 stmt->u.insn.operands[0] = str;
460 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[2]);
461 stmt->u.insn.operands[2] = str;
465 unsigned int flags, mask;
467 switch (cmdargs.arch) {
475 fprintf(stderr, "Internal error: TKIP invalid arch\n");
479 flags = stmt->u.insn.bin->operands[1];
480 switch (flags & mask) {
482 stmt->u.insn.name = "tkiph";
485 stmt->u.insn.name = "tkiphs";
488 stmt->u.insn.name = "tkipl";
491 stmt->u.insn.name = "tkipls";
494 fprintf(stderr, "Invalid TKIP flags %X\n",
498 disasm_std_operand(stmt, 0, 0, 0);
499 disasm_std_operand(stmt, 2, 2, 0);
505 stmt->u.insn.name = "nap";
506 switch (cmdargs.arch) {
514 fprintf(stderr, "Internal error: NAP invalid arch\n");
517 if (stmt->u.insn.bin->operands[0] != mask) {
518 fprintf(stderr, "NAP: invalid first argument 0x%04X\n",
519 stmt->u.insn.bin->operands[0]);
521 if (stmt->u.insn.bin->operands[1] != mask) {
522 fprintf(stderr, "NAP: invalid second argument 0x%04X\n",
523 stmt->u.insn.bin->operands[1]);
525 if (stmt->u.insn.bin->operands[2] != 0) {
526 fprintf(stderr, "NAP: invalid third argument 0x%04X\n",
527 stmt->u.insn.bin->operands[2]);
532 stmt->u.insn.name = gen_raw_code(bin->opcode);
533 disasm_std_operand(stmt, 0, 0, 1);
534 disasm_std_operand(stmt, 1, 1, 1);
535 disasm_std_operand(stmt, 2, 2, 1);
540 static void disasm_opcodes(struct disassembler_context *ctx)
542 struct bin_instruction *bin;
544 struct statement *stmt;
547 for (i = 0; i < ctx->nr_insns; i++) {
548 bin = &(ctx->code[i]);
550 stmt = xmalloc(sizeof(struct statement));
551 stmt->type = STMT_INSN;
552 INIT_LIST_HEAD(&stmt->list);
553 stmt->u.insn.bin = bin;
554 stmt->u.insn.is_labelref = -1;
556 switch (bin->opcode & 0xF00) {
558 stmt->u.insn.name = "srx";
561 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
562 stmt->u.insn.operands[0] = str;
564 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
565 stmt->u.insn.operands[1] = str;
567 disasm_std_operand(stmt, 0, 2, 0);
568 disasm_std_operand(stmt, 1, 3, 0);
569 disasm_std_operand(stmt, 2, 4, 0);
572 stmt->u.insn.name = "orx";
575 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
576 stmt->u.insn.operands[0] = str;
578 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
579 stmt->u.insn.operands[1] = str;
581 disasm_std_operand(stmt, 0, 2, 0);
582 disasm_std_operand(stmt, 1, 3, 0);
583 disasm_std_operand(stmt, 2, 4, 0);
586 stmt->u.insn.name = "jzx";
589 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
590 stmt->u.insn.operands[0] = str;
592 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
593 stmt->u.insn.operands[1] = str;
595 disasm_std_operand(stmt, 0, 2, 0);
596 disasm_std_operand(stmt, 1, 3, 0);
597 stmt->u.insn.is_labelref = 4;
598 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
601 stmt->u.insn.name = "jnzx";
604 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
605 stmt->u.insn.operands[0] = str;
607 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
608 stmt->u.insn.operands[1] = str;
610 disasm_std_operand(stmt, 0, 2, 0);
611 disasm_std_operand(stmt, 1, 3, 0);
612 stmt->u.insn.is_labelref = 4;
613 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
616 stmt->u.insn.name = "jnext";
619 snprintf(str, 5, "0x%02X", (bin->opcode & 0x0FF));
620 stmt->u.insn.operands[0] = str;
622 /* We don't disassemble the first and second operand, as
623 * that always is a dummy r0 operand.
624 * disasm_std_operand(stmt, 0, 1, 0);
625 * disasm_std_operand(stmt, 1, 2, 0);
626 * stmt->u.insn.is_labelref = 3;
628 stmt->u.insn.is_labelref = 1;
629 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
632 stmt->u.insn.name = "jext";
635 snprintf(str, 5, "0x%02X", (bin->opcode & 0x0FF));
636 stmt->u.insn.operands[0] = str;
638 /* We don't disassemble the first and second operand, as
639 * that always is a dummy r0 operand.
640 * disasm_std_operand(stmt, 0, 1, 0);
641 * disasm_std_operand(stmt, 1, 2, 0);
642 * stmt->u.insn.is_labelref = 3;
644 stmt->u.insn.is_labelref = 1;
645 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
648 disasm_constant_opcodes(ctx, stmt);
652 list_add_tail(&stmt->list, &ctx->stmt_list);
656 static struct statement * get_label_at(struct disassembler_context *ctx,
659 unsigned int addrcnt = 0;
660 struct statement *stmt, *ret, *prev;
662 list_for_each_entry(stmt, &ctx->stmt_list, list) {
663 if (stmt->type != STMT_INSN)
665 if (addrcnt == addr) {
666 prev = list_entry(stmt->list.prev, struct statement, list);
667 if (prev->type == STMT_LABEL)
669 ret = xmalloc(sizeof(struct statement));
670 INIT_LIST_HEAD(&ret->list);
671 ret->type = STMT_LABEL;
672 list_add(&ret->list, &prev->list);
682 static void resolve_labels(struct disassembler_context *ctx)
684 struct statement *stmt;
685 struct statement *label;
687 unsigned int labeladdr;
688 unsigned int namecnt = 0;
690 /* Resolve label references */
691 list_for_each_entry_safe(stmt, n, &ctx->stmt_list, list) {
692 if (stmt->type != STMT_INSN)
694 if (stmt->u.insn.is_labelref == -1)
696 labeladdr = stmt->u.insn.labeladdr;
697 label = get_label_at(ctx, labeladdr);
699 fprintf(stderr, "Labeladdress %X out of bounds\n",
703 stmt->u.insn.labelref = label;
706 /* Name the labels */
707 list_for_each_entry(stmt, &ctx->stmt_list, list) {
708 if (stmt->type != STMT_LABEL)
710 stmt->u.label.name = xmalloc(20);
711 snprintf(stmt->u.label.name, 20, "L%u", namecnt);
716 static void emit_asm(struct disassembler_context *ctx)
718 struct statement *stmt;
721 unsigned int addr = 0;
723 err = open_output_file();
727 fprintf(outfile, "%%arch %u\n\n", ctx->arch);
728 list_for_each_entry(stmt, &ctx->stmt_list, list) {
729 switch (stmt->type) {
731 if (cmdargs.print_addresses)
732 fprintf(outfile, "/* %03X */", addr);
733 fprintf(outfile, "\t%s", stmt->u.insn.name);
735 for (i = 0; i < ARRAY_SIZE(stmt->u.insn.operands); i++) {
736 if (stmt->u.insn.is_labelref == i) {
737 fprintf(outfile, ", %s",
738 stmt->u.insn.labelref->u.label.name);
740 if (!stmt->u.insn.operands[i])
743 fprintf(outfile, "\t");
745 fprintf(outfile, ", ");
747 fprintf(outfile, "%s",
748 stmt->u.insn.operands[i]);
750 fprintf(outfile, "\n");
754 fprintf(outfile, "%s:\n", stmt->u.label.name);
762 static int read_input(struct disassembler_context *ctx)
764 size_t size = 0, pos = 0;
766 struct bin_instruction *code = NULL;
767 unsigned char tmp[sizeof(uint64_t)];
769 struct fw_header hdr;
772 err = open_input_file();
776 switch (cmdargs.informat) {
782 ret = fread(&hdr, 1, sizeof(hdr), infile);
783 if (ret != sizeof(hdr)) {
784 fprintf(stderr, "Corrupt input file (not fwcutter output)\n");
787 if (hdr.type != FW_TYPE_UCODE) {
788 fprintf(stderr, "Corrupt input file. Not a microcode image.\n");
791 if (hdr.ver != FW_HDR_VER) {
792 fprintf(stderr, "Invalid input file header version.\n");
801 code = xrealloc(code, size * sizeof(struct bin_instruction));
803 ret = fread(tmp, 1, sizeof(uint64_t), infile);
806 if (ret != sizeof(uint64_t)) {
807 fprintf(stderr, "Corrupt input file (not 8 byte aligned)\n");
811 switch (cmdargs.informat) {
815 codeword |= ((uint64_t)tmp[0]) << 56;
816 codeword |= ((uint64_t)tmp[1]) << 48;
817 codeword |= ((uint64_t)tmp[2]) << 40;
818 codeword |= ((uint64_t)tmp[3]) << 32;
819 codeword |= ((uint64_t)tmp[4]) << 24;
820 codeword |= ((uint64_t)tmp[5]) << 16;
821 codeword |= ((uint64_t)tmp[6]) << 8;
822 codeword |= ((uint64_t)tmp[7]);
823 codeword = ((codeword & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) |
824 ((codeword & (uint64_t)0x00000000FFFFFFFFULL) << 32);
828 codeword |= ((uint64_t)tmp[7]) << 56;
829 codeword |= ((uint64_t)tmp[6]) << 48;
830 codeword |= ((uint64_t)tmp[5]) << 40;
831 codeword |= ((uint64_t)tmp[4]) << 32;
832 codeword |= ((uint64_t)tmp[3]) << 24;
833 codeword |= ((uint64_t)tmp[2]) << 16;
834 codeword |= ((uint64_t)tmp[1]) << 8;
835 codeword |= ((uint64_t)tmp[0]);
839 switch (cmdargs.arch) {
841 if (codeword >> 48) {
842 fprintf(stderr, "Instruction format error at 0x%X (upper not clear). "
843 "Wrong input format or architecture?\n", (unsigned int)pos);
846 code[pos].opcode = (codeword >> 36) & 0xFFF;
847 code[pos].operands[2] = codeword & 0xFFF;
848 code[pos].operands[1] = (codeword >> 12) & 0xFFF;
849 code[pos].operands[0] = (codeword >> 24) & 0xFFF;
852 if (codeword >> 51) {
853 fprintf(stderr, "Instruction format error at 0x%X (upper not clear). "
854 "Wrong input format or architecture?\n", (unsigned int)pos);
857 code[pos].opcode = (codeword >> 39) & 0xFFF;
858 code[pos].operands[2] = codeword & 0x1FFF;
859 code[pos].operands[1] = (codeword >> 13) & 0x1FFF;
860 code[pos].operands[0] = (codeword >> 26) & 0x1FFF;
863 fprintf(stderr, "Internal error: read_input unknown arch %u\n",
886 static void disassemble(void)
888 struct disassembler_context ctx;
891 memset(&ctx, 0, sizeof(ctx));
892 INIT_LIST_HEAD(&ctx.stmt_list);
893 ctx.arch = cmdargs.arch;
895 err = read_input(&ctx);
898 disasm_opcodes(&ctx);
899 resolve_labels(&ctx);
903 int main(int argc, char **argv)
907 err = parse_args(argc, argv);
917 /* Lazyman simply leaks all allocated memory. */