Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <elf.h> | |
| 9 #include <inttypes.h> | |
| 10 #include <stdio.h> | 8 #include <stdio.h> |
| 11 #include <stdlib.h> | 9 #include <stdlib.h> |
| 12 #include <string.h> | 10 #include <string.h> |
| 13 #include "decoder.h" | |
| 14 | 11 |
| 15 #undef TRUE | 12 #include "native_client/src/include/elf32.h" |
| 16 #define TRUE 1 | 13 #include "native_client/src/include/elf64.h" |
| 14 #include "native_client/src/shared/platform/nacl_check.h" | |
| 15 #include "native_client/src/shared/utils/types.h" | |
| 16 #include "native_client/src/trusted/validator_ragel/unreviewed/decoder.h" | |
| 17 | 17 |
| 18 #undef FALSE | 18 /* This is a copy of NaClLog_Function from shared/platform/nacl_log.c to avoid |
| 19 #define FALSE 0 | 19 * linking in code in NaCl shared code in the unreviewed/Makefile and be able to |
| 20 * use CHECK(). | |
| 21 | |
| 22 * TODO(khim): remove the copy of NaClLog_Function implementation as soon as | |
| 23 *unreviewed/Makefile is eliminated. | |
|
pasko-google - do not use
2012/04/10 09:32:41
add space after *
khim
2012/04/10 12:29:38
Done.
| |
| 24 */ | |
| 25 void NaClLog_Function(int detail_level, char const *fmt, ...) { | |
| 26 va_list ap; | |
| 27 | |
| 28 UNREFERENCED_PARAMETER(detail_level); | |
| 29 va_start(ap, fmt); | |
| 30 vfprintf(stderr, fmt, ap); | |
| 31 exit(1); | |
| 32 } | |
| 20 | 33 |
| 21 static void CheckBounds(unsigned char *data, size_t data_size, | 34 static void CheckBounds(unsigned char *data, size_t data_size, |
| 22 void *ptr, size_t inside_size) { | 35 void *ptr, size_t inside_size) { |
| 23 assert(data <= (unsigned char *) ptr); | 36 CHECK(data <= (unsigned char *) ptr); |
| 24 assert((unsigned char *) ptr + inside_size <= data + data_size); | 37 CHECK((unsigned char *) ptr + inside_size <= data + data_size); |
| 25 } | 38 } |
| 26 | 39 |
| 27 void ReadFile(const char *filename, uint8_t **result, size_t *result_size) { | 40 void ReadImage(const char *filename, uint8_t **result, size_t *result_size) { |
| 28 FILE *fp; | 41 FILE *fp; |
| 29 uint8_t *data; | 42 uint8_t *data; |
| 30 size_t file_size; | 43 size_t file_size; |
| 31 size_t got; | 44 size_t got; |
| 32 | 45 |
| 33 fp = fopen(filename, "rb"); | 46 fp = fopen(filename, "rb"); |
| 34 if (fp == NULL) { | 47 if (fp == NULL) { |
| 35 fprintf(stderr, "Failed to open input file: %s\n", filename); | 48 fprintf(stderr, "Failed to open input file: %s\n", filename); |
| 36 exit(1); | 49 exit(1); |
| 37 } | 50 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 const char *instruction_name; | 82 const char *instruction_name; |
| 70 unsigned char operands_count; | 83 unsigned char operands_count; |
| 71 const uint8_t *p; | 84 const uint8_t *p; |
| 72 char delimeter = ' '; | 85 char delimeter = ' '; |
| 73 int print_rip = FALSE; | 86 int print_rip = FALSE; |
| 74 int rex_bits = 0; | 87 int rex_bits = 0; |
| 75 int maybe_rex_bits = 0; | 88 int maybe_rex_bits = 0; |
| 76 int show_name_suffix = FALSE; | 89 int show_name_suffix = FALSE; |
| 77 int empty_rex_prefix_ok = FALSE; | 90 int empty_rex_prefix_ok = FALSE; |
| 78 #define print_name(x) (printf((x)), shown_name += strlen((x))) | 91 #define print_name(x) (printf((x)), shown_name += strlen((x))) |
| 79 int shown_name = 0; | 92 size_t shown_name = 0; |
| 80 int i, operand_type; | 93 int i, operand_type; |
| 81 | 94 |
| 82 /* "fwait" is nasty: any number of them will be included in other X87 | 95 /* "fwait" is nasty: any number of them will be included in other X87 |
| 83 instructions ("fclex", "finit", "fstcw", "fstsw", "fsave" have two | 96 instructions ("fclex", "finit", "fstcw", "fstsw", "fsave" have two |
| 84 names, other instructions are unchanged) - but if after them we see | 97 names, other instructions are unchanged) - but if after them we see |
| 85 regular instruction then we must print all them. This convoluted | 98 regular instruction then we must print all them. This convoluted |
| 86 logic is not needed when we don't print anything so decoder does | 99 logic is not needed when we don't print anything so decoder does |
| 87 not include it. */ | 100 not include it. */ |
| 88 if ((end == begin + 1) && (begin[0] == 0x9b)) { | 101 if ((end == begin + 1) && (begin[0] == 0x9b)) { |
| 89 if (!(((struct DecodeState *)userdata)->fwait)) { | 102 if (!(((struct DecodeState *)userdata)->fwait)) { |
| 90 ((struct DecodeState *)userdata)->fwait = begin; | 103 ((struct DecodeState *)userdata)->fwait = begin; |
| 91 } | 104 } |
| 92 return; | 105 return; |
| 93 } else if (((struct DecodeState *)userdata)->fwait) { | 106 } else if (((struct DecodeState *)userdata)->fwait) { |
| 94 if ((begin[0] < 0xd8) || (begin[0] > 0xdf)) { | 107 if ((begin[0] < 0xd8) || (begin[0] > 0xdf)) { |
| 95 while ((((struct DecodeState *)userdata)->fwait) < begin) { | 108 while ((((struct DecodeState *)userdata)->fwait) < begin) { |
| 96 printf("%*zx:\t \tfwait\n", | 109 printf("%*lx:\t \tfwait\n", |
| 97 ((struct DecodeState *)userdata)->width, | 110 ((struct DecodeState *)userdata)->width, |
| 98 ((((struct DecodeState *)userdata)->fwait++) - | 111 (long)((((struct DecodeState *)userdata)->fwait++) - |
| 99 (((struct DecodeState *)userdata)->offset))); | 112 (((struct DecodeState *)userdata)->offset))); |
| 100 } | 113 } |
| 101 } else { | 114 } else { |
| 102 begin = ((struct DecodeState *)userdata)->fwait; | 115 begin = ((struct DecodeState *)userdata)->fwait; |
| 103 } | 116 } |
| 104 ((struct DecodeState *)userdata)->fwait = FALSE; | 117 ((struct DecodeState *)userdata)->fwait = FALSE; |
| 105 } | 118 } |
| 106 printf("%*zx:\t", ((struct DecodeState *)userdata)->width, | 119 printf("%*lx:\t", ((struct DecodeState *)userdata)->width, |
| 107 (begin - (((struct DecodeState *)userdata)->offset))); | 120 (long)(begin - (((struct DecodeState *)userdata)->offset))); |
| 108 for (p = begin; p < begin + 7; ++p) { | 121 for (p = begin; p < begin + 7; ++p) { |
| 109 if (p >= end) { | 122 if (p >= end) { |
| 110 printf(" "); | 123 printf(" "); |
| 111 } else { | 124 } else { |
| 112 printf("%02x ", *p); | 125 printf("%02x ", *p); |
| 113 } | 126 } |
| 114 } | 127 } |
| 115 printf("\t"); | 128 printf("\t"); |
| 116 instruction_name = instruction->name; | 129 instruction_name = instruction->name; |
| 117 operands_count = instruction->operands_count; | 130 operands_count = instruction->operands_count; |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 instruction->operands[i].name -= 8; | 536 instruction->operands[i].name -= 8; |
| 524 --rex_bits; | 537 --rex_bits; |
| 525 } | 538 } |
| 526 } | 539 } |
| 527 } | 540 } |
| 528 } | 541 } |
| 529 } else if (instruction->operands[i].name == REG_RM) { | 542 } else if (instruction->operands[i].name == REG_RM) { |
| 530 if ((instruction->rm.base >= REG_R8) && | 543 if ((instruction->rm.base >= REG_R8) && |
| 531 (instruction->rm.base <= REG_R15)) { | 544 (instruction->rm.base <= REG_R15)) { |
| 532 ++rex_bits; | 545 ++rex_bits; |
| 533 } else if ((instruction->rm.base == REG_NONE) || | 546 } else if ((instruction->rm.base == NO_REG) || |
| 534 (instruction->rm.base == REG_RIP)) { | 547 (instruction->rm.base == REG_RIP)) { |
| 535 ++maybe_rex_bits; | 548 ++maybe_rex_bits; |
| 536 } | 549 } |
| 537 if ((instruction->rm.index >= REG_R8) && | 550 if ((instruction->rm.index >= REG_R8) && |
| 538 (instruction->rm.index <= REG_R15)) { | 551 (instruction->rm.index <= REG_R15)) { |
| 539 ++rex_bits; | 552 ++rex_bits; |
| 540 } | 553 } |
| 541 } | 554 } |
| 542 } | 555 } |
| 543 } | 556 } |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 769 ++shown_name; | 782 ++shown_name; |
| 770 } | 783 } |
| 771 } | 784 } |
| 772 if (!strcmp(instruction_name, "mov")) { | 785 if (!strcmp(instruction_name, "mov")) { |
| 773 if ((instruction->operands[1].name == REG_IMM) && | 786 if ((instruction->operands[1].name == REG_IMM) && |
| 774 (instruction->operands[1].type == OperandSize64bit)) { | 787 (instruction->operands[1].type == OperandSize64bit)) { |
| 775 print_name("abs"); | 788 print_name("abs"); |
| 776 } | 789 } |
| 777 } | 790 } |
| 778 { | 791 { |
| 792 size_t i; | |
| 779 /* Print branch hint suffixes for conditional jump instructions (Jcc). */ | 793 /* Print branch hint suffixes for conditional jump instructions (Jcc). */ |
| 780 const char* jcc_jumps[] = { | 794 const char* jcc_jumps[] = { |
| 781 "ja", "jae", "jbe", "jb", "je", "jg", "jge", "jle", | 795 "ja", "jae", "jbe", "jb", "je", "jg", "jge", "jle", |
| 782 "jl", "jne", "jno", "jnp", "jns", "jo", "jp", "js", NULL}; | 796 "jl", "jne", "jno", "jnp", "jns", "jo", "jp", "js", NULL}; |
| 783 for (int i = 0; jcc_jumps[i] != NULL; ++i) { | 797 for (i = 0; jcc_jumps[i] != NULL; ++i) { |
| 784 if (!strcmp(instruction_name, jcc_jumps[i])) { | 798 if (!strcmp(instruction_name, jcc_jumps[i])) { |
| 785 if (instruction->prefix.branch_not_taken) { | 799 if (instruction->prefix.branch_not_taken) { |
| 786 print_name(",pn"); | 800 print_name(",pn"); |
| 787 } else if (instruction->prefix.branch_taken) { | 801 } else if (instruction->prefix.branch_taken) { |
| 788 print_name(",pt"); | 802 print_name(",pt"); |
| 789 } | 803 } |
| 790 break; | 804 break; |
| 791 } | 805 } |
| 792 } | 806 } |
| 793 } | 807 } |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 case OperandDebugRegister: printf("%%db15"); break; | 1156 case OperandDebugRegister: printf("%%db15"); break; |
| 1143 default: assert(FALSE); | 1157 default: assert(FALSE); |
| 1144 } | 1158 } |
| 1145 break; | 1159 break; |
| 1146 case REG_ST: | 1160 case REG_ST: |
| 1147 assert(operand_type == OperandST); | 1161 assert(operand_type == OperandST); |
| 1148 printf("%%st"); | 1162 printf("%%st"); |
| 1149 break; | 1163 break; |
| 1150 case REG_RM: { | 1164 case REG_RM: { |
| 1151 if (instruction->rm.offset) { | 1165 if (instruction->rm.offset) { |
| 1152 printf("0x%"PRIx64, instruction->rm.offset); | 1166 printf("0x%"NACL_PRIx64, instruction->rm.offset); |
| 1153 } | 1167 } |
| 1154 if (((struct DecodeState *)userdata)->ia32_mode) { | 1168 if (((struct DecodeState *)userdata)->ia32_mode) { |
| 1155 if ((instruction->rm.base != REG_NONE) || | 1169 if ((instruction->rm.base != NO_REG) || |
| 1156 (instruction->rm.index != REG_NONE) || | 1170 (instruction->rm.index != NO_REG) || |
| 1157 (instruction->rm.scale != 0)) { | 1171 (instruction->rm.scale != 0)) { |
| 1158 printf("("); | 1172 printf("("); |
| 1159 } | 1173 } |
| 1160 switch (instruction->rm.base) { | 1174 switch (instruction->rm.base) { |
| 1161 case REG_RAX: printf("%%eax"); break; | 1175 case REG_RAX: printf("%%eax"); break; |
| 1162 case REG_RCX: printf("%%ecx"); break; | 1176 case REG_RCX: printf("%%ecx"); break; |
| 1163 case REG_RDX: printf("%%edx"); break; | 1177 case REG_RDX: printf("%%edx"); break; |
| 1164 case REG_RBX: printf("%%ebx"); break; | 1178 case REG_RBX: printf("%%ebx"); break; |
| 1165 case REG_RSP: printf("%%esp"); break; | 1179 case REG_RSP: printf("%%esp"); break; |
| 1166 case REG_RBP: printf("%%ebp"); break; | 1180 case REG_RBP: printf("%%ebp"); break; |
| 1167 case REG_RSI: printf("%%esi"); break; | 1181 case REG_RSI: printf("%%esi"); break; |
| 1168 case REG_RDI: printf("%%edi"); break; | 1182 case REG_RDI: printf("%%edi"); break; |
| 1169 case REG_NONE: break; | 1183 case NO_REG: break; |
| 1170 case REG_R8: | 1184 case REG_R8: |
| 1171 case REG_R9: | 1185 case REG_R9: |
| 1172 case REG_R10: | 1186 case REG_R10: |
| 1173 case REG_R11: | 1187 case REG_R11: |
| 1174 case REG_R12: | 1188 case REG_R12: |
| 1175 case REG_R13: | 1189 case REG_R13: |
| 1176 case REG_R14: | 1190 case REG_R14: |
| 1177 case REG_R15: | 1191 case REG_R15: |
| 1178 case REG_RIP: | 1192 case REG_RIP: |
| 1179 case REG_RM: | 1193 case REG_RM: |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1194 case REG_RDX: printf(",%%edx,%d",1<<instruction->rm.scale); break; | 1208 case REG_RDX: printf(",%%edx,%d",1<<instruction->rm.scale); break; |
| 1195 case REG_RBX: printf(",%%ebx,%d",1<<instruction->rm.scale); break; | 1209 case REG_RBX: printf(",%%ebx,%d",1<<instruction->rm.scale); break; |
| 1196 case REG_RSP: printf(",%%esp,%d",1<<instruction->rm.scale); break; | 1210 case REG_RSP: printf(",%%esp,%d",1<<instruction->rm.scale); break; |
| 1197 case REG_RBP: printf(",%%ebp,%d",1<<instruction->rm.scale); break; | 1211 case REG_RBP: printf(",%%ebp,%d",1<<instruction->rm.scale); break; |
| 1198 case REG_RSI: printf(",%%esi,%d",1<<instruction->rm.scale); break; | 1212 case REG_RSI: printf(",%%esi,%d",1<<instruction->rm.scale); break; |
| 1199 case REG_RDI: printf(",%%edi,%d",1<<instruction->rm.scale); break; | 1213 case REG_RDI: printf(",%%edi,%d",1<<instruction->rm.scale); break; |
| 1200 case REG_RIZ: if ((instruction->rm.base != REG_RSP) || | 1214 case REG_RIZ: if ((instruction->rm.base != REG_RSP) || |
| 1201 (instruction->rm.scale != 0)) | 1215 (instruction->rm.scale != 0)) |
| 1202 printf(",%%eiz,%d",1<<instruction->rm.scale); | 1216 printf(",%%eiz,%d",1<<instruction->rm.scale); |
| 1203 break; | 1217 break; |
| 1204 case REG_NONE: break; | 1218 case NO_REG: break; |
| 1205 case REG_R8: | 1219 case REG_R8: |
| 1206 case REG_R9: | 1220 case REG_R9: |
| 1207 case REG_R10: | 1221 case REG_R10: |
| 1208 case REG_R11: | 1222 case REG_R11: |
| 1209 case REG_R12: | 1223 case REG_R12: |
| 1210 case REG_R13: | 1224 case REG_R13: |
| 1211 case REG_R14: | 1225 case REG_R14: |
| 1212 case REG_R15: | 1226 case REG_R15: |
| 1213 case REG_RM: | 1227 case REG_RM: |
| 1214 case REG_RIP: | 1228 case REG_RIP: |
| 1215 case REG_IMM: | 1229 case REG_IMM: |
| 1216 case REG_IMM2: | 1230 case REG_IMM2: |
| 1217 case REG_DS_RBX: | 1231 case REG_DS_RBX: |
| 1218 case REG_ES_RDI: | 1232 case REG_ES_RDI: |
| 1219 case REG_DS_RSI: | 1233 case REG_DS_RSI: |
| 1220 case REG_PORT_DX: | 1234 case REG_PORT_DX: |
| 1221 case REG_ST: | 1235 case REG_ST: |
| 1222 case JMP_TO: | 1236 case JMP_TO: |
| 1223 assert(FALSE); | 1237 assert(FALSE); |
| 1224 } | 1238 } |
| 1225 if ((instruction->rm.base != REG_NONE) || | 1239 if ((instruction->rm.base != NO_REG) || |
| 1226 (instruction->rm.index != REG_NONE) || | 1240 (instruction->rm.index != NO_REG) || |
| 1227 (instruction->rm.scale != 0)) { | 1241 (instruction->rm.scale != 0)) { |
| 1228 printf(")"); | 1242 printf(")"); |
| 1229 } | 1243 } |
| 1230 } else { | 1244 } else { |
| 1231 if ((instruction->rm.base != REG_NONE) || | 1245 if ((instruction->rm.base != NO_REG) || |
| 1232 (instruction->rm.index != REG_RIZ) || | 1246 (instruction->rm.index != REG_RIZ) || |
| 1233 (instruction->rm.scale != 0)) { | 1247 (instruction->rm.scale != 0)) { |
| 1234 printf("("); | 1248 printf("("); |
| 1235 } | 1249 } |
| 1236 switch (instruction->rm.base) { | 1250 switch (instruction->rm.base) { |
| 1237 case REG_RAX: printf("%%rax"); break; | 1251 case REG_RAX: printf("%%rax"); break; |
| 1238 case REG_RCX: printf("%%rcx"); break; | 1252 case REG_RCX: printf("%%rcx"); break; |
| 1239 case REG_RDX: printf("%%rdx"); break; | 1253 case REG_RDX: printf("%%rdx"); break; |
| 1240 case REG_RBX: printf("%%rbx"); break; | 1254 case REG_RBX: printf("%%rbx"); break; |
| 1241 case REG_RSP: printf("%%rsp"); break; | 1255 case REG_RSP: printf("%%rsp"); break; |
| 1242 case REG_RBP: printf("%%rbp"); break; | 1256 case REG_RBP: printf("%%rbp"); break; |
| 1243 case REG_RSI: printf("%%rsi"); break; | 1257 case REG_RSI: printf("%%rsi"); break; |
| 1244 case REG_RDI: printf("%%rdi"); break; | 1258 case REG_RDI: printf("%%rdi"); break; |
| 1245 case REG_R8: printf("%%r8"); break; | 1259 case REG_R8: printf("%%r8"); break; |
| 1246 case REG_R9: printf("%%r9"); break; | 1260 case REG_R9: printf("%%r9"); break; |
| 1247 case REG_R10: printf("%%r10"); break; | 1261 case REG_R10: printf("%%r10"); break; |
| 1248 case REG_R11: printf("%%r11"); break; | 1262 case REG_R11: printf("%%r11"); break; |
| 1249 case REG_R12: printf("%%r12"); break; | 1263 case REG_R12: printf("%%r12"); break; |
| 1250 case REG_R13: printf("%%r13"); break; | 1264 case REG_R13: printf("%%r13"); break; |
| 1251 case REG_R14: printf("%%r14"); break; | 1265 case REG_R14: printf("%%r14"); break; |
| 1252 case REG_R15: printf("%%r15"); break; | 1266 case REG_R15: printf("%%r15"); break; |
| 1253 case REG_RIP: printf("%%rip"); print_rip = TRUE; break; | 1267 case REG_RIP: printf("%%rip"); print_rip = TRUE; break; |
| 1254 case REG_NONE: break; | 1268 case NO_REG: break; |
| 1255 case REG_RM: | 1269 case REG_RM: |
| 1256 case REG_RIZ: | 1270 case REG_RIZ: |
| 1257 case REG_IMM: | 1271 case REG_IMM: |
| 1258 case REG_IMM2: | 1272 case REG_IMM2: |
| 1259 case REG_DS_RBX: | 1273 case REG_DS_RBX: |
| 1260 case REG_ES_RDI: | 1274 case REG_ES_RDI: |
| 1261 case REG_DS_RSI: | 1275 case REG_DS_RSI: |
| 1262 case REG_PORT_DX: | 1276 case REG_PORT_DX: |
| 1263 case REG_ST: | 1277 case REG_ST: |
| 1264 case JMP_TO: | 1278 case JMP_TO: |
| 1265 assert(FALSE); | 1279 assert(FALSE); |
| 1266 } | 1280 } |
| 1267 switch (instruction->rm.index) { | 1281 switch (instruction->rm.index) { |
| 1268 case REG_RAX: printf(",%%rax,%d",1<<instruction->rm.scale); break; | 1282 case REG_RAX: printf(",%%rax,%d",1<<instruction->rm.scale); break; |
| 1269 case REG_RCX: printf(",%%rcx,%d",1<<instruction->rm.scale); break; | 1283 case REG_RCX: printf(",%%rcx,%d",1<<instruction->rm.scale); break; |
| 1270 case REG_RDX: printf(",%%rdx,%d",1<<instruction->rm.scale); break; | 1284 case REG_RDX: printf(",%%rdx,%d",1<<instruction->rm.scale); break; |
| 1271 case REG_RBX: printf(",%%rbx,%d",1<<instruction->rm.scale); break; | 1285 case REG_RBX: printf(",%%rbx,%d",1<<instruction->rm.scale); break; |
| 1272 case REG_RSP: printf(",%%rsp,%d",1<<instruction->rm.scale); break; | 1286 case REG_RSP: printf(",%%rsp,%d",1<<instruction->rm.scale); break; |
| 1273 case REG_RBP: printf(",%%rbp,%d",1<<instruction->rm.scale); break; | 1287 case REG_RBP: printf(",%%rbp,%d",1<<instruction->rm.scale); break; |
| 1274 case REG_RSI: printf(",%%rsi,%d",1<<instruction->rm.scale); break; | 1288 case REG_RSI: printf(",%%rsi,%d",1<<instruction->rm.scale); break; |
| 1275 case REG_RDI: printf(",%%rdi,%d",1<<instruction->rm.scale); break; | 1289 case REG_RDI: printf(",%%rdi,%d",1<<instruction->rm.scale); break; |
| 1276 case REG_R8: printf(",%%r8,%d",1<<instruction->rm.scale); break; | 1290 case REG_R8: printf(",%%r8,%d",1<<instruction->rm.scale); break; |
| 1277 case REG_R9: printf(",%%r9,%d",1<<instruction->rm.scale); break; | 1291 case REG_R9: printf(",%%r9,%d",1<<instruction->rm.scale); break; |
| 1278 case REG_R10: printf(",%%r10,%d",1<<instruction->rm.scale); break; | 1292 case REG_R10: printf(",%%r10,%d",1<<instruction->rm.scale); break; |
| 1279 case REG_R11: printf(",%%r11,%d",1<<instruction->rm.scale); break; | 1293 case REG_R11: printf(",%%r11,%d",1<<instruction->rm.scale); break; |
| 1280 case REG_R12: printf(",%%r12,%d",1<<instruction->rm.scale); break; | 1294 case REG_R12: printf(",%%r12,%d",1<<instruction->rm.scale); break; |
| 1281 case REG_R13: printf(",%%r13,%d",1<<instruction->rm.scale); break; | 1295 case REG_R13: printf(",%%r13,%d",1<<instruction->rm.scale); break; |
| 1282 case REG_R14: printf(",%%r14,%d",1<<instruction->rm.scale); break; | 1296 case REG_R14: printf(",%%r14,%d",1<<instruction->rm.scale); break; |
| 1283 case REG_R15: printf(",%%r15,%d",1<<instruction->rm.scale); break; | 1297 case REG_R15: printf(",%%r15,%d",1<<instruction->rm.scale); break; |
| 1284 case REG_RIZ: if (((instruction->rm.base != REG_NONE) && | 1298 case REG_RIZ: if (((instruction->rm.base != NO_REG) && |
| 1285 (instruction->rm.base != REG_RSP) && | 1299 (instruction->rm.base != REG_RSP) && |
| 1286 (instruction->rm.base != REG_R12)) || | 1300 (instruction->rm.base != REG_R12)) || |
| 1287 (instruction->rm.scale != 0)) | 1301 (instruction->rm.scale != 0)) |
| 1288 printf(",%%riz,%d",1<<instruction->rm.scale); | 1302 printf(",%%riz,%d",1<<instruction->rm.scale); |
| 1289 break; | 1303 break; |
| 1290 case REG_NONE: break; | 1304 case NO_REG: break; |
| 1291 case REG_RM: | 1305 case REG_RM: |
| 1292 case REG_RIP: | 1306 case REG_RIP: |
| 1293 case REG_IMM: | 1307 case REG_IMM: |
| 1294 case REG_IMM2: | 1308 case REG_IMM2: |
| 1295 case REG_DS_RBX: | 1309 case REG_DS_RBX: |
| 1296 case REG_ES_RDI: | 1310 case REG_ES_RDI: |
| 1297 case REG_DS_RSI: | 1311 case REG_DS_RSI: |
| 1298 case REG_PORT_DX: | 1312 case REG_PORT_DX: |
| 1299 case REG_ST: | 1313 case REG_ST: |
| 1300 case JMP_TO: | 1314 case JMP_TO: |
| 1301 assert(FALSE); | 1315 assert(FALSE); |
| 1302 } | 1316 } |
| 1303 if ((instruction->rm.base != REG_NONE) || | 1317 if ((instruction->rm.base != NO_REG) || |
| 1304 (instruction->rm.index != REG_RIZ) || | 1318 (instruction->rm.index != REG_RIZ) || |
| 1305 (instruction->rm.scale != 0)) { | 1319 (instruction->rm.scale != 0)) { |
| 1306 printf(")"); | 1320 printf(")"); |
| 1307 } | 1321 } |
| 1308 } | 1322 } |
| 1309 } | 1323 } |
| 1310 break; | 1324 break; |
| 1311 case REG_IMM: { | 1325 case REG_IMM: { |
| 1312 printf("$0x%"PRIx64,instruction->imm[0]); | 1326 printf("$0x%"NACL_PRIx64,instruction->imm[0]); |
| 1313 break; | 1327 break; |
| 1314 } | 1328 } |
| 1315 case REG_IMM2: { | 1329 case REG_IMM2: { |
| 1316 printf("$0x%"PRIx64,instruction->imm[1]); | 1330 printf("$0x%"NACL_PRIx64,instruction->imm[1]); |
| 1317 break; | 1331 break; |
| 1318 } | 1332 } |
| 1319 case REG_PORT_DX: printf("(%%dx)"); break; | 1333 case REG_PORT_DX: printf("(%%dx)"); break; |
| 1320 case REG_DS_RBX: if (((struct DecodeState *)userdata)->ia32_mode) { | 1334 case REG_DS_RBX: if (((struct DecodeState *)userdata)->ia32_mode) { |
| 1321 printf("%%ds:(%%ebx)"); | 1335 printf("%%ds:(%%ebx)"); |
| 1322 } else { | 1336 } else { |
| 1323 printf("%%ds:(%%rbx)"); | 1337 printf("%%ds:(%%rbx)"); |
| 1324 } | 1338 } |
| 1325 break; | 1339 break; |
| 1326 case REG_ES_RDI: if (((struct DecodeState *)userdata)->ia32_mode) { | 1340 case REG_ES_RDI: if (((struct DecodeState *)userdata)->ia32_mode) { |
| 1327 printf("%%es:(%%edi)"); | 1341 printf("%%es:(%%edi)"); |
| 1328 } else { | 1342 } else { |
| 1329 printf("%%es:(%%rdi)"); | 1343 printf("%%es:(%%rdi)"); |
| 1330 } | 1344 } |
| 1331 break; | 1345 break; |
| 1332 case REG_DS_RSI: if (((struct DecodeState *)userdata)->ia32_mode) { | 1346 case REG_DS_RSI: if (((struct DecodeState *)userdata)->ia32_mode) { |
| 1333 printf("%%ds:(%%esi)"); | 1347 printf("%%ds:(%%esi)"); |
| 1334 } else { | 1348 } else { |
| 1335 printf("%%ds:(%%rsi)"); | 1349 printf("%%ds:(%%rsi)"); |
| 1336 } | 1350 } |
| 1337 break; | 1351 break; |
| 1338 case JMP_TO: if (instruction->operands[0].type == OperandSize16bit) | 1352 case JMP_TO: if (instruction->operands[0].type == OperandSize16bit) |
| 1339 printf("0x%zx", ((end + instruction->rm.offset - | 1353 printf("0x%lx", (long)((end + instruction->rm.offset - |
| 1340 (((struct DecodeState *)userdata)->offset)) & 0xffff)); | 1354 (((struct DecodeState *)userdata)->offset)) & 0xffff)); |
| 1341 else | 1355 else |
| 1342 printf("0x%zx", (end + instruction->rm.offset - | 1356 printf("0x%lx", (long)(end + instruction->rm.offset - |
| 1343 (((struct DecodeState *)userdata)->offset))); | 1357 (((struct DecodeState *)userdata)->offset))); |
| 1344 break; | 1358 break; |
| 1345 case REG_RIP: | 1359 case REG_RIP: |
| 1346 case REG_RIZ: | 1360 case REG_RIZ: |
| 1347 case REG_NONE: | 1361 case NO_REG: |
| 1348 assert(FALSE); | 1362 assert(FALSE); |
| 1349 } | 1363 } |
| 1350 delimeter = ','; | 1364 delimeter = ','; |
| 1351 } | 1365 } |
| 1352 if (print_rip) { | 1366 if (print_rip) { |
| 1353 printf(" # 0x%8"PRIx64, | 1367 printf(" # 0x%8"NACL_PRIx64, |
| 1354 (uint64_t) (end + instruction->rm.offset - | 1368 (uint64_t) (end + instruction->rm.offset - |
| 1355 (((struct DecodeState *)userdata)->offset))); | 1369 (((struct DecodeState *)userdata)->offset))); |
| 1356 } | 1370 } |
| 1357 printf("\n"); | 1371 printf("\n"); |
| 1358 begin += 7; | 1372 begin += 7; |
| 1359 while (begin < end) { | 1373 while (begin < end) { |
| 1360 printf("%*"PRIx64":\t", ((struct DecodeState *)userdata)->width, | 1374 printf("%*"NACL_PRIx64":\t", ((struct DecodeState *)userdata)->width, |
| 1361 (uint64_t) (begin - (((struct DecodeState *)userdata)->offset))); | 1375 (uint64_t) (begin - (((struct DecodeState *)userdata)->offset))); |
| 1362 for (p = begin; p < begin + 7; ++p) { | 1376 for (p = begin; p < begin + 7; ++p) { |
| 1363 if (p >= end) { | 1377 if (p >= end) { |
| 1364 printf("\n"); | 1378 printf("\n"); |
| 1365 return; | 1379 return; |
| 1366 } else { | 1380 } else { |
| 1367 printf("%02x ", *p); | 1381 printf("%02x ", *p); |
| 1368 } | 1382 } |
| 1369 } | 1383 } |
| 1370 if (p >= end) { | 1384 if (p >= end) { |
| 1371 printf("\n"); | 1385 printf("\n"); |
| 1372 return; | 1386 return; |
| 1373 } | 1387 } |
| 1374 begin += 7; | 1388 begin += 7; |
| 1375 } | 1389 } |
| 1376 } | 1390 } |
| 1377 | 1391 |
| 1378 void ProcessError (const uint8_t *ptr, void *userdata) { | 1392 void ProcessError (const uint8_t *ptr, void *userdata) { |
| 1379 printf("rejected at %"PRIx64" (byte 0x%02"PRIx32")\n", | 1393 printf("rejected at %"NACL_PRIx64" (byte 0x%02"NACL_PRIx32")\n", |
| 1380 (uint64_t) (ptr - (((struct DecodeState *)userdata)->offset)), | 1394 (uint64_t) (ptr - (((struct DecodeState *)userdata)->offset)), |
| 1381 *ptr); | 1395 *ptr); |
| 1382 } | 1396 } |
| 1383 | 1397 |
| 1384 int DecodeFile(const char *filename, int repeat_count) { | 1398 int DecodeFile(const char *filename, int repeat_count) { |
| 1385 size_t data_size; | 1399 size_t data_size; |
| 1386 uint8_t *data; | 1400 uint8_t *data; |
| 1387 int count; | 1401 int count; |
| 1388 | 1402 |
| 1389 ReadFile(filename, &data, &data_size); | 1403 ReadImage(filename, &data, &data_size); |
| 1390 if (data[4] == 1) { | 1404 if (data[4] == 1) { |
| 1391 for (count = 0; count < repeat_count; ++count) { | 1405 for (count = 0; count < repeat_count; ++count) { |
| 1392 Elf32_Ehdr *header; | 1406 Elf32_Ehdr *header; |
| 1393 int index; | 1407 int index; |
| 1394 | 1408 |
| 1395 header = (Elf32_Ehdr *) data; | 1409 header = (Elf32_Ehdr *) data; |
| 1396 CheckBounds(data, data_size, header, sizeof(*header)); | 1410 CheckBounds(data, data_size, header, sizeof(*header)); |
| 1397 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0); | 1411 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0); |
| 1398 | 1412 |
| 1399 for (index = 0; index < header->e_shnum; ++index) { | 1413 for (index = 0; index < header->e_shnum; ++index) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1416 state.width = 12; | 1430 state.width = 12; |
| 1417 } | 1431 } |
| 1418 CheckBounds(data, data_size, | 1432 CheckBounds(data, data_size, |
| 1419 data + section->sh_offset, section->sh_size); | 1433 data + section->sh_offset, section->sh_size); |
| 1420 res = DecodeChunkIA32(data + section->sh_offset, section->sh_size, | 1434 res = DecodeChunkIA32(data + section->sh_offset, section->sh_size, |
| 1421 ProcessInstruction, ProcessError, &state); | 1435 ProcessInstruction, ProcessError, &state); |
| 1422 if (res != 0) { | 1436 if (res != 0) { |
| 1423 return res; | 1437 return res; |
| 1424 } else if (state.fwait) { | 1438 } else if (state.fwait) { |
| 1425 while (state.fwait < data + section->sh_offset + section->sh_size) { | 1439 while (state.fwait < data + section->sh_offset + section->sh_size) { |
| 1426 printf("%*zx:\t9b \tfwait\n", | 1440 printf("%*lx:\t9b \tfwait\n", |
| 1427 state.width, (state.fwait++ - state.offset)); | 1441 state.width, (long)(state.fwait++ - state.offset)); |
| 1428 } | 1442 } |
| 1429 } | 1443 } |
| 1430 } | 1444 } |
| 1431 } | 1445 } |
| 1432 } | 1446 } |
| 1433 } else if (data[4] == 2) { | 1447 } else if (data[4] == 2) { |
| 1434 for (count = 0; count < repeat_count; ++count) { | 1448 for (count = 0; count < repeat_count; ++count) { |
| 1435 Elf64_Ehdr *header; | 1449 Elf64_Ehdr *header; |
| 1436 int index; | 1450 int index; |
| 1437 | 1451 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1454 if (section->sh_size <= 0xfff) { | 1468 if (section->sh_size <= 0xfff) { |
| 1455 state.width = 4; | 1469 state.width = 4; |
| 1456 } else if (section->sh_size <= 0xfffffff) { | 1470 } else if (section->sh_size <= 0xfffffff) { |
| 1457 state.width = 8; | 1471 state.width = 8; |
| 1458 } else if (section->sh_size <= 0xfffffffffffLL) { | 1472 } else if (section->sh_size <= 0xfffffffffffLL) { |
| 1459 state.width = 12; | 1473 state.width = 12; |
| 1460 } else { | 1474 } else { |
| 1461 state.width = 16; | 1475 state.width = 16; |
| 1462 } | 1476 } |
| 1463 CheckBounds(data, data_size, | 1477 CheckBounds(data, data_size, |
| 1464 data + section->sh_offset, section->sh_size); | 1478 data + section->sh_offset, (size_t)section->sh_size); |
| 1465 res = DecodeChunkAMD64(data + section->sh_offset, section->sh_size, | 1479 res = DecodeChunkAMD64(data + section->sh_offset, |
| 1466 ProcessInstruction, ProcessError, &state); | 1480 (size_t)section->sh_size, ProcessInstruction, ProcessError, &state); |
|
pasko-google - do not use
2012/04/10 09:32:41
should be either shifted by 4 from the previous li
khim
2012/04/10 12:29:38
This will create additional useless line. Shift it
| |
| 1467 if (res != 0) { | 1481 if (res != 0) { |
| 1468 return res; | 1482 return res; |
| 1469 } else if (state.fwait) { | 1483 } else if (state.fwait) { |
| 1470 while (state.fwait < data + section->sh_offset + section->sh_size) { | 1484 while (state.fwait < data + section->sh_offset + section->sh_size) { |
| 1471 printf("%*zx:\t9b \tfwait\n", | 1485 printf("%*lx:\t9b \tfwait\n", |
| 1472 state.width, (state.fwait++ - state.offset)); | 1486 state.width, (long)(state.fwait++ - state.offset)); |
| 1473 } | 1487 } |
| 1474 } | 1488 } |
| 1475 } | 1489 } |
| 1476 } | 1490 } |
| 1477 } | 1491 } |
| 1478 } else { | 1492 } else { |
| 1479 printf("Unknown ELF class: %s\n", filename); | 1493 printf("Unknown ELF class: %s\n", filename); |
| 1480 exit(1); | 1494 exit(1); |
| 1481 } | 1495 } |
| 1482 return 0; | 1496 return 0; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1494 for (index = initial_index; index < argc; ++index) { | 1508 for (index = initial_index; index < argc; ++index) { |
| 1495 const char *filename = argv[index]; | 1509 const char *filename = argv[index]; |
| 1496 int rc = DecodeFile(filename, repeat_count); | 1510 int rc = DecodeFile(filename, repeat_count); |
| 1497 if (rc != 0) { | 1511 if (rc != 0) { |
| 1498 printf("file '%s' can not be fully decoded\n", filename); | 1512 printf("file '%s' can not be fully decoded\n", filename); |
| 1499 return 1; | 1513 return 1; |
| 1500 } | 1514 } |
| 1501 } | 1515 } |
| 1502 return 0; | 1516 return 0; |
| 1503 } | 1517 } |
| OLD | NEW |