1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <inttypes.h> 5 #include <assert.h> 6 #include "trace_reader.h" 7 #include "armdis.h" 8 #include "parse_options.h" 9 10 typedef TraceReader<> TraceReaderType; 11 12 #include "parse_options-inl.h" 13 14 static const uint32_t kOffsetThreshold = 0x100000; 15 static uint64_t startTime = 0; 16 17 void Usage(const char *program) 18 { 19 fprintf(stderr, 20 "Usage: %s [options] [-- -s start_time] trace_file elf_file\n", 21 program); 22 OptionsUsage(); 23 } 24 25 26 bool localParseOptions(int argc, char **argv) 27 { 28 bool err = false; 29 while (!err) { 30 int opt = getopt(argc, argv, "+s:"); 31 if (opt == -1) 32 break; 33 switch (opt) { 34 case 's': 35 startTime = strtoull(optarg, NULL, 0); 36 break; 37 default: 38 err = true; 39 break; 40 } 41 } 42 return err; 43 } 44 45 int main(int argc, char **argv) { 46 // Parse the options 47 ParseOptions(argc, argv); 48 localParseOptions(argc, argv); 49 if (argc - optind != 2) { 50 Usage(argv[0]); 51 exit(1); 52 } 53 54 char *trace_filename = argv[optind++]; 55 char *elf_file = argv[optind++]; 56 TraceReader<> *trace = new TraceReader<>; 57 trace->Open(trace_filename); 58 trace->SetDemangle(demangle); 59 trace->ReadKernelSymbols(elf_file); 60 trace->SetRoot(root); 61 62 while (1) { 63 symbol_type *sym; 64 char buf[1024]; 65 BBEvent event; 66 BBEvent ignored; 67 68 if (GetNextValidEvent(trace, &event, &ignored, &sym)) 69 break; 70 #if 0 71 fprintf(stderr, "t%llu bb %lld %d\n", 72 event.time, event.bb_num, event.num_insns); 73 #endif 74 75 uint32_t *insns = event.insns; 76 uint32_t addr = event.bb_addr; 77 uint32_t offset = addr - sym->addr - sym->region->base_addr; 78 symbol_type *vm_sym = sym->vm_sym; 79 const char *vm_name = NULL; 80 if (vm_sym != NULL) { 81 vm_name = vm_sym->name; 82 offset = addr - vm_sym->addr - vm_sym->region->base_addr; 83 } 84 #if 0 85 if (strcmp(sym->name, "(unknown)") == 0 || offset > kOffsetThreshold) { 86 ProcessState *process = trace->GetCurrentProcess(); 87 ProcessState *manager = process->addr_manager; 88 for (int ii = 0; ii < manager->nregions; ++ii) { 89 printf(" %2d: %08x - %08x base: %08x offset: %u nsyms: %4d flags: 0x%x %s\n", 90 ii, 91 manager->regions[ii]->vstart, 92 manager->regions[ii]->vend, 93 manager->regions[ii]->base_addr, 94 manager->regions[ii]->file_offset, 95 manager->regions[ii]->nsymbols, 96 manager->regions[ii]->flags, 97 manager->regions[ii]->path); 98 int nsymbols = manager->regions[ii]->nsymbols; 99 for (int jj = 0; jj < 10 && jj < nsymbols; ++jj) { 100 printf(" %08x %s\n", 101 manager->regions[ii]->symbols[jj].addr, 102 manager->regions[ii]->symbols[jj].name); 103 } 104 } 105 } 106 #endif 107 #if 1 108 for (int ii = 0; ii < event.num_insns; ++ii) { 109 uint64_t sim_time = trace->ReadInsnTime(event.time); 110 if (sim_time < startTime) 111 continue; 112 113 uint32_t insn = insns[ii]; 114 char *disasm; 115 int bytes; 116 if (vm_name != NULL) { 117 sprintf(buf, "%s+%02x: %s", vm_name, offset, sym->name); 118 } else { 119 sprintf(buf, "%s+%02x", sym->name, offset); 120 } 121 122 if (insn_is_thumb(insn)) { 123 bytes = 2; 124 insn = insn_unwrap_thumb(insn); 125 126 // thumb_pair is true if this is the first of a pair of 127 // thumb instructions (BL or BLX). 128 bool thumb_pair = ((insn & 0xf800) == 0xf000); 129 130 // Get the next thumb instruction (if any) because we may need 131 // it for the case where insn is BL or BLX. 132 uint32_t insn2 = 0; 133 if (thumb_pair && (ii + 1 < event.num_insns)) { 134 insn2 = insns[ii + 1]; 135 insn2 = insn_unwrap_thumb(insn2); 136 bytes = 4; 137 ii += 1; 138 } 139 disasm = disasm_insn_thumb(addr, insn, insn2, NULL); 140 if (thumb_pair) { 141 printf("%llu p%-4d %08x %04x %04x %-30s %s\n", 142 sim_time, event.pid, addr, insn, insn2, buf, disasm); 143 } else { 144 printf("%llu p%-4d %08x %04x %-30s %s\n", 145 sim_time, event.pid, addr, insn, buf, disasm); 146 } 147 } else { 148 bytes = 4; 149 disasm = Arm::disasm(addr, insn, NULL); 150 printf("%llu p%-4d %08x %08x %-30s %s\n", 151 sim_time, event.pid, addr, insn, buf, disasm); 152 } 153 //printf("t%llu \t%08x\n", sim_time, addr); 154 addr += bytes; 155 offset += bytes; 156 } 157 #endif 158 #if 0 159 assert(offset < kOffsetThreshold); 160 #endif 161 } 162 163 delete trace; 164 return 0; 165 } 166