1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Backtracing functions for x86. 19 */ 20 21 #define LOG_TAG "Corkscrew" 22 //#define LOG_NDEBUG 0 23 24 #include "../backtrace-arch.h" 25 #include "../backtrace-helper.h" 26 #include "../ptrace-arch.h" 27 #include <corkscrew/ptrace.h> 28 #include "dwarf.h" 29 30 #include <stdlib.h> 31 #include <signal.h> 32 #include <stdbool.h> 33 #include <limits.h> 34 #include <errno.h> 35 #include <string.h> 36 #include <sys/ptrace.h> 37 #include <cutils/log.h> 38 39 #if defined(__BIONIC__) 40 41 #if defined(__BIONIC_HAVE_UCONTEXT_T) 42 43 // Bionic offers the Linux kernel headers. 44 #include <asm/sigcontext.h> 45 #include <asm/ucontext.h> 46 typedef struct ucontext ucontext_t; 47 48 #else /* __BIONIC_HAVE_UCONTEXT_T */ 49 50 /* Old versions of the Android <signal.h> didn't define ucontext_t. */ 51 52 typedef struct { 53 uint32_t gregs[32]; 54 void* fpregs; 55 uint32_t oldmask; 56 uint32_t cr2; 57 } mcontext_t; 58 59 enum { 60 REG_GS = 0, REG_FS, REG_ES, REG_DS, 61 REG_EDI, REG_ESI, REG_EBP, REG_ESP, 62 REG_EBX, REG_EDX, REG_ECX, REG_EAX, 63 REG_TRAPNO, REG_ERR, REG_EIP, REG_CS, 64 REG_EFL, REG_UESP, REG_SS 65 }; 66 67 /* Machine context at the time a signal was raised. */ 68 typedef struct ucontext { 69 uint32_t uc_flags; 70 struct ucontext* uc_link; 71 stack_t uc_stack; 72 mcontext_t uc_mcontext; 73 uint32_t uc_sigmask; 74 } ucontext_t; 75 76 #endif /* __BIONIC_HAVE_UCONTEXT_T */ 77 78 #else /* __BIONIC__ */ 79 80 // glibc has its own renaming of the Linux kernel's structures. 81 #define __USE_GNU // For REG_EBP, REG_ESP, and REG_EIP. 82 #include <ucontext.h> 83 84 #endif /* __ BIONIC__ */ 85 86 /* Unwind state. */ 87 typedef struct { 88 uint32_t reg[DWARF_REGISTERS]; 89 } unwind_state_t; 90 91 typedef struct { 92 backtrace_frame_t* backtrace; 93 size_t ignore_depth; 94 size_t max_depth; 95 size_t ignored_frames; 96 size_t returned_frames; 97 memory_t memory; 98 } backtrace_state_t; 99 100 uintptr_t rewind_pc_arch(const memory_t* memory __attribute__((unused)), uintptr_t pc) { 101 /* TODO: x86 instructions are 1-16 bytes, to define exact size of previous instruction 102 we have to disassemble from the function entry point up to pc. 103 Returning pc-1 is probably enough for now, the only drawback is that 104 it points somewhere between the first byte of instruction we are looking for and 105 the first byte of the next instruction. */ 106 107 return pc-1; 108 /* TODO: We should adjust that for the signal frames and return pc for them instead of pc-1. 109 To recognize signal frames we should read cie_info property. */ 110 } 111 112 /* Read byte through 4 byte cache. Usually we read byte by byte and updating cursor. */ 113 static bool try_get_byte(const memory_t* memory, uintptr_t ptr, uint8_t* out_value, uint32_t* cursor) { 114 static uintptr_t lastptr; 115 static uint32_t buf; 116 117 ptr += *cursor; 118 119 if (ptr < lastptr || lastptr + 3 < ptr) { 120 lastptr = (ptr >> 2) << 2; 121 if (!try_get_word(memory, lastptr, &buf)) { 122 return false; 123 } 124 } 125 *out_value = (uint8_t)((buf >> ((ptr & 3) * 8)) & 0xff); 126 ++*cursor; 127 return true; 128 } 129 130 /* Getting X bytes. 4 is maximum for now. */ 131 static bool try_get_xbytes(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t bytes, uint32_t* cursor) { 132 uint32_t data = 0; 133 if (bytes > 4) { 134 ALOGE("can't read more than 4 bytes, trying to read %d", bytes); 135 return false; 136 } 137 for (int i = 0; i < bytes; i++) { 138 uint8_t buf; 139 if (!try_get_byte(memory, ptr, &buf, cursor)) { 140 return false; 141 } 142 data |= (uint32_t)buf << (i * 8); 143 } 144 *out_value = data; 145 return true; 146 } 147 148 /* Reads signed/unsigned LEB128 encoded data. From 1 to 4 bytes. */ 149 static bool try_get_leb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor, bool sign_extend) { 150 uint8_t buf = 0; 151 uint32_t val = 0; 152 uint8_t c = 0; 153 do { 154 if (!try_get_byte(memory, ptr, &buf, cursor)) { 155 return false; 156 } 157 val |= ((uint32_t)buf & 0x7f) << (c * 7); 158 c++; 159 } while (buf & 0x80 && (c * 7) <= 32); 160 if (c * 7 > 32) { 161 ALOGE("%s: data exceeds expected 4 bytes maximum", __FUNCTION__); 162 return false; 163 } 164 if (sign_extend) { 165 if (buf & 0x40) { 166 val |= ((uint32_t)-1 << (c * 7)); 167 } 168 } 169 *out_value = val; 170 return true; 171 } 172 173 /* Reads signed LEB128 encoded data. From 1 to 4 bytes. */ 174 static bool try_get_sleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) { 175 return try_get_leb128(memory, ptr, out_value, cursor, true); 176 } 177 178 /* Reads unsigned LEB128 encoded data. From 1 to 4 bytes. */ 179 static bool try_get_uleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) { 180 return try_get_leb128(memory, ptr, out_value, cursor, false); 181 } 182 183 /* Getting data encoded by dwarf encodings. */ 184 static bool read_dwarf(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t encoding, uint32_t* cursor) { 185 uint32_t data = 0; 186 bool issigned = true; 187 uintptr_t addr = ptr + *cursor; 188 /* Lower 4 bits is data type/size */ 189 /* TODO: add more encodings if it becomes necessary */ 190 switch (encoding & 0xf) { 191 case DW_EH_PE_absptr: 192 if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) { 193 return false; 194 } 195 *out_value = data; 196 return true; 197 case DW_EH_PE_udata4: 198 issigned = false; 199 case DW_EH_PE_sdata4: 200 if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) { 201 return false; 202 } 203 break; 204 default: 205 ALOGE("unrecognized dwarf lower part encoding: 0x%x", encoding); 206 return false; 207 } 208 /* Higher 4 bits is modifier */ 209 /* TODO: add more encodings if it becomes necessary */ 210 switch (encoding & 0xf0) { 211 case 0: 212 *out_value = data; 213 break; 214 case DW_EH_PE_pcrel: 215 if (issigned) { 216 *out_value = addr + (int32_t)data; 217 } else { 218 *out_value = addr + data; 219 } 220 break; 221 /* Assuming ptr is correct base to calculate datarel */ 222 case DW_EH_PE_datarel: 223 if (issigned) { 224 *out_value = ptr + (int32_t)data; 225 } else { 226 *out_value = ptr + data; 227 } 228 break; 229 default: 230 ALOGE("unrecognized dwarf higher part encoding: 0x%x", encoding); 231 return false; 232 } 233 return true; 234 } 235 236 /* Having PC find corresponding FDE by reading .eh_frame_hdr section data. */ 237 static uintptr_t find_fde(const memory_t* memory, 238 const map_info_t* map_info_list, uintptr_t pc) { 239 if (!pc) { 240 ALOGV("find_fde: pc is zero, no eh_frame"); 241 return 0; 242 } 243 const map_info_t* mi = find_map_info(map_info_list, pc); 244 if (!mi) { 245 ALOGV("find_fde: no map info for pc:0x%x", pc); 246 return 0; 247 } 248 const map_info_data_t* midata = mi->data; 249 if (!midata) { 250 ALOGV("find_fde: no eh_frame_hdr for map: start=0x%x, end=0x%x", mi->start, mi->end); 251 return 0; 252 } 253 254 eh_frame_hdr_info_t eh_hdr_info; 255 memset(&eh_hdr_info, 0, sizeof(eh_frame_hdr_info_t)); 256 257 /* Getting the first word of eh_frame_hdr: 258 1st byte is version; 259 2nd byte is encoding of pointer to eh_frames; 260 3rd byte is encoding of count of FDEs in lookup table; 261 4th byte is encoding of lookup table entries. 262 */ 263 uintptr_t eh_frame_hdr = midata->eh_frame_hdr; 264 uint32_t c = 0; 265 if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.version, &c)) return 0; 266 if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr_enc, &c)) return 0; 267 if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_count_enc, &c)) return 0; 268 if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_table_enc, &c)) return 0; 269 270 /* TODO: 3rd byte can be DW_EH_PE_omit, that means no lookup table available and we should 271 try to parse eh_frame instead. Not sure how often it may occur, skipping now. 272 */ 273 if (eh_hdr_info.version != 1) { 274 ALOGV("find_fde: eh_frame_hdr version %d is not supported", eh_hdr_info.version); 275 return 0; 276 } 277 /* Getting the data: 278 2nd word is eh_frame pointer (normally not used, because lookup table has all we need); 279 3rd word is count of FDEs in the lookup table; 280 starting from 4 word there is FDE lookup table (pairs of PC and FDE pointer) sorted by PC; 281 */ 282 if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr, eh_hdr_info.eh_frame_ptr_enc, &c)) return 0; 283 if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.fde_count, eh_hdr_info.fde_count_enc, &c)) return 0; 284 ALOGV("find_fde: found %d FDEs", eh_hdr_info.fde_count); 285 286 int32_t low = 0; 287 int32_t high = eh_hdr_info.fde_count; 288 uintptr_t start = 0; 289 uintptr_t fde = 0; 290 /* eh_frame_hdr + c points to lookup table at this point. */ 291 while (low <= high) { 292 uint32_t mid = (high + low)/2; 293 uint32_t entry = c + mid * 8; 294 if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &entry)) return 0; 295 if (pc <= start) { 296 high = mid - 1; 297 } else { 298 low = mid + 1; 299 } 300 } 301 /* Value found is at high. */ 302 if (high < 0) { 303 ALOGV("find_fde: pc %x is out of FDE bounds: %x", pc, start); 304 return 0; 305 } 306 c += high * 8; 307 if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &c)) return 0; 308 if (!read_dwarf(memory, eh_frame_hdr, &fde, eh_hdr_info.fde_table_enc, &c)) return 0; 309 ALOGV("pc 0x%x, ENTRY %d: start=0x%x, fde=0x%x", pc, high, start, fde); 310 return fde; 311 } 312 313 /* Execute single dwarf instruction and update dwarf state accordingly. */ 314 static bool execute_dwarf(const memory_t* memory, uintptr_t ptr, cie_info_t* cie_info, 315 dwarf_state_t* dstate, uint32_t* cursor, 316 dwarf_state_t* stack, uint8_t* stack_ptr) { 317 uint8_t inst; 318 uint8_t op = 0; 319 320 if (!try_get_byte(memory, ptr, &inst, cursor)) { 321 return false; 322 } 323 ALOGV("DW_CFA inst: 0x%x", inst); 324 325 /* For some instructions upper 2 bits is opcode and lower 6 bits is operand. See dwarf-2.0 7.23. */ 326 if (inst & 0xc0) { 327 op = inst & 0x3f; 328 inst &= 0xc0; 329 } 330 331 switch ((dwarf_CFA)inst) { 332 uint32_t reg = 0; 333 uint32_t offset = 0; 334 case DW_CFA_advance_loc: 335 dstate->loc += op * cie_info->code_align; 336 ALOGV("DW_CFA_advance_loc: %d to 0x%x", op, dstate->loc); 337 break; 338 case DW_CFA_offset: 339 if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false; 340 dstate->regs[op].rule = 'o'; 341 dstate->regs[op].value = offset * cie_info->data_align; 342 ALOGV("DW_CFA_offset: r%d = o(%d)", op, dstate->regs[op].value); 343 break; 344 case DW_CFA_restore: 345 dstate->regs[op].rule = stack->regs[op].rule; 346 dstate->regs[op].value = stack->regs[op].value; 347 ALOGV("DW_CFA_restore: r%d = %c(%d)", op, dstate->regs[op].rule, dstate->regs[op].value); 348 break; 349 case DW_CFA_nop: 350 break; 351 case DW_CFA_set_loc: // probably we don't have it on x86. 352 if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false; 353 if (offset < dstate->loc) { 354 ALOGE("DW_CFA_set_loc: attempt to move location backward"); 355 return false; 356 } 357 dstate->loc = offset * cie_info->code_align; 358 ALOGV("DW_CFA_set_loc: %d to 0x%x", offset * cie_info->code_align, dstate->loc); 359 break; 360 case DW_CFA_advance_loc1: 361 if (!try_get_byte(memory, ptr, (uint8_t*)&offset, cursor)) return false; 362 dstate->loc += (uint8_t)offset * cie_info->code_align; 363 ALOGV("DW_CFA_advance_loc1: %d to 0x%x", (uint8_t)offset * cie_info->code_align, dstate->loc); 364 break; 365 case DW_CFA_advance_loc2: 366 if (!try_get_xbytes(memory, ptr, &offset, 2, cursor)) return false; 367 dstate->loc += (uint16_t)offset * cie_info->code_align; 368 ALOGV("DW_CFA_advance_loc2: %d to 0x%x", (uint16_t)offset * cie_info->code_align, dstate->loc); 369 break; 370 case DW_CFA_advance_loc4: 371 if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false; 372 dstate->loc += offset * cie_info->code_align; 373 ALOGV("DW_CFA_advance_loc4: %d to 0x%x", offset * cie_info->code_align, dstate->loc); 374 break; 375 case DW_CFA_offset_extended: // probably we don't have it on x86. 376 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 377 if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false; 378 if (reg > DWARF_REGISTERS) { 379 ALOGE("DW_CFA_offset_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS); 380 return false; 381 } 382 dstate->regs[reg].rule = 'o'; 383 dstate->regs[reg].value = offset * cie_info->data_align; 384 ALOGV("DW_CFA_offset_extended: r%d = o(%d)", reg, dstate->regs[reg].value); 385 break; 386 case DW_CFA_restore_extended: // probably we don't have it on x86. 387 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 388 dstate->regs[reg].rule = stack->regs[reg].rule; 389 dstate->regs[reg].value = stack->regs[reg].value; 390 if (reg > DWARF_REGISTERS) { 391 ALOGE("DW_CFA_restore_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS); 392 return false; 393 } 394 ALOGV("DW_CFA_restore: r%d = %c(%d)", reg, dstate->regs[reg].rule, dstate->regs[reg].value); 395 break; 396 case DW_CFA_undefined: // probably we don't have it on x86. 397 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 398 dstate->regs[reg].rule = 'u'; 399 dstate->regs[reg].value = 0; 400 if (reg > DWARF_REGISTERS) { 401 ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS); 402 return false; 403 } 404 ALOGV("DW_CFA_undefined: r%d", reg); 405 break; 406 case DW_CFA_same_value: // probably we don't have it on x86. 407 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 408 dstate->regs[reg].rule = 's'; 409 dstate->regs[reg].value = 0; 410 if (reg > DWARF_REGISTERS) { 411 ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS); 412 return false; 413 } 414 ALOGV("DW_CFA_same_value: r%d", reg); 415 break; 416 case DW_CFA_register: // probably we don't have it on x86. 417 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 418 /* that's new register actually, not offset */ 419 if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false; 420 if (reg > DWARF_REGISTERS || offset > DWARF_REGISTERS) { 421 ALOGE("DW_CFA_register: r%d or r%d exceeds supported number of registers (%d)", reg, offset, DWARF_REGISTERS); 422 return false; 423 } 424 dstate->regs[reg].rule = 'r'; 425 dstate->regs[reg].value = offset; 426 ALOGV("DW_CFA_register: r%d = r(%d)", reg, dstate->regs[reg].value); 427 break; 428 case DW_CFA_remember_state: 429 if (*stack_ptr == DWARF_STATES_STACK) { 430 ALOGE("DW_CFA_remember_state: states stack overflow %d", *stack_ptr); 431 return false; 432 } 433 stack[(*stack_ptr)++] = *dstate; 434 ALOGV("DW_CFA_remember_state: stacktop moves to %d", *stack_ptr); 435 break; 436 case DW_CFA_restore_state: 437 /* We have CIE state saved at 0 position. It's not supposed to be taken 438 by DW_CFA_restore_state. */ 439 if (*stack_ptr == 1) { 440 ALOGE("DW_CFA_restore_state: states stack is empty"); 441 return false; 442 } 443 /* Don't touch location on restore. */ 444 uintptr_t saveloc = dstate->loc; 445 *dstate = stack[--*stack_ptr]; 446 dstate->loc = saveloc; 447 ALOGV("DW_CFA_restore_state: stacktop moves to %d", *stack_ptr); 448 break; 449 case DW_CFA_def_cfa: 450 if (!try_get_uleb128(memory, ptr, ®, cursor)) return false; 451 if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false; 452 dstate->cfa_reg = reg; 453 dstate->cfa_off = offset; 454 ALOGV("DW_CFA_def_cfa: %x(r%d)", offset, reg); 455 break; 456 case DW_CFA_def_cfa_register: 457 if (!try_get_uleb128(memory, ptr, ®, cursor)) { 458 return false; 459 } 460 dstate->cfa_reg = reg; 461 ALOGV("DW_CFA_def_cfa_register: r%d", reg); 462 break; 463 case DW_CFA_def_cfa_offset: 464 if (!try_get_uleb128(memory, ptr, &offset, cursor)) { 465 return false; 466 } 467 dstate->cfa_off = offset; 468 ALOGV("DW_CFA_def_cfa_offset: %x", offset); 469 break; 470 default: 471 ALOGE("unrecognized DW_CFA_* instruction: 0x%x", inst); 472 return false; 473 } 474 return true; 475 } 476 477 /* Restoring particular register value based on dwarf state. */ 478 static bool get_old_register_value(const memory_t* memory, uint32_t cfa, 479 dwarf_state_t* dstate, uint8_t reg, 480 unwind_state_t* state, unwind_state_t* newstate) { 481 uint32_t addr; 482 switch (dstate->regs[reg].rule) { 483 case 0: 484 /* We don't have dstate updated for this register, so assuming value kept the same. 485 Normally we should look into state and return current value as the old one 486 but we don't have all registers in state to handle this properly */ 487 ALOGV("get_old_register_value: value of r%d is the same", reg); 488 // for ESP if it's not updated by dwarf rule we assume it's equal to CFA 489 if (reg == DWARF_ESP) { 490 ALOGV("get_old_register_value: adjusting esp to CFA: 0x%x", cfa); 491 newstate->reg[reg] = cfa; 492 } else { 493 newstate->reg[reg] = state->reg[reg]; 494 } 495 break; 496 case 'o': 497 addr = cfa + (int32_t)dstate->regs[reg].value; 498 if (!try_get_word(memory, addr, &newstate->reg[reg])) { 499 ALOGE("get_old_register_value: can't read from 0x%x", addr); 500 return false; 501 } 502 ALOGV("get_old_register_value: r%d at 0x%x is 0x%x", reg, addr, newstate->reg[reg]); 503 break; 504 case 'r': 505 /* We don't have all registers in state so don't even try to look at 'r' */ 506 ALOGE("get_old_register_value: register lookup not implemented yet"); 507 break; 508 default: 509 ALOGE("get_old_register_value: unexpected rule:%c value:%d for register %d", 510 dstate->regs[reg].rule, (int32_t)dstate->regs[reg].value, reg); 511 return false; 512 } 513 return true; 514 } 515 516 /* Updaing state based on dwarf state. */ 517 static bool update_state(const memory_t* memory, unwind_state_t* state, 518 dwarf_state_t* dstate, cie_info_t* cie_info) { 519 unwind_state_t newstate; 520 /* We can restore more registers here if we need them. Meanwile doing minimal work here. */ 521 /* Getting CFA. */ 522 uintptr_t cfa = 0; 523 if (dstate->cfa_reg == DWARF_ESP) { 524 cfa = state->reg[DWARF_ESP] + dstate->cfa_off; 525 } else if (dstate->cfa_reg == DWARF_EBP) { 526 cfa = state->reg[DWARF_EBP] + dstate->cfa_off; 527 } else { 528 ALOGE("update_state: unexpected CFA register: %d", dstate->cfa_reg); 529 return false; 530 } 531 ALOGV("update_state: new CFA: 0x%x", cfa); 532 /* Getting EIP. */ 533 if (!get_old_register_value(memory, cfa, dstate, DWARF_EIP, state, &newstate)) return false; 534 /* Getting EBP. */ 535 if (!get_old_register_value(memory, cfa, dstate, DWARF_EBP, state, &newstate)) return false; 536 /* Getting ESP. */ 537 if (!get_old_register_value(memory, cfa, dstate, DWARF_ESP, state, &newstate)) return false; 538 539 ALOGV("update_state: IP: 0x%x; restore IP: 0x%x", state->reg[DWARF_EIP], newstate.reg[DWARF_EIP]); 540 ALOGV("update_state: EBP: 0x%x; restore EBP: 0x%x", state->reg[DWARF_EBP], newstate.reg[DWARF_EBP]); 541 ALOGV("update_state: ESP: 0x%x; restore ESP: 0x%x", state->reg[DWARF_ESP], newstate.reg[DWARF_ESP]); 542 *state = newstate; 543 return true; 544 } 545 546 /* Execute CIE and FDE instructions for FDE found with find_fde. */ 547 static bool execute_fde(const memory_t* memory, 548 const map_info_t* map_info_list, 549 uintptr_t fde, 550 unwind_state_t* state) { 551 uint32_t fde_length = 0; 552 uint32_t cie_length = 0; 553 uintptr_t cie = 0; 554 uintptr_t cie_offset = 0; 555 cie_info_t cie_i; 556 cie_info_t* cie_info = &cie_i; 557 fde_info_t fde_i; 558 fde_info_t* fde_info = &fde_i; 559 dwarf_state_t dwarf_state; 560 dwarf_state_t* dstate = &dwarf_state; 561 dwarf_state_t stack[DWARF_STATES_STACK]; 562 uint8_t stack_ptr = 0; 563 564 memset(dstate, 0, sizeof(dwarf_state_t)); 565 memset(cie_info, 0, sizeof(cie_info_t)); 566 memset(fde_info, 0, sizeof(fde_info_t)); 567 568 /* Read common CIE or FDE area: 569 1st word is length; 570 2nd word is ID: 0 for CIE, CIE pointer for FDE. 571 */ 572 if (!try_get_word(memory, fde, &fde_length)) { 573 return false; 574 } 575 if ((int32_t)fde_length == -1) { 576 ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet"); 577 return false; 578 } 579 if (!try_get_word(memory, fde + 4, &cie_offset)) { 580 return false; 581 } 582 if (cie_offset == 0) { 583 /* This is CIE. We shouldn't be here normally. */ 584 cie = fde; 585 cie_length = fde_length; 586 } else { 587 /* Find CIE. */ 588 /* Positive cie_offset goes backward from current field. */ 589 cie = fde + 4 - cie_offset; 590 if (!try_get_word(memory, cie, &cie_length)) { 591 return false; 592 } 593 if ((int32_t)cie_length == -1) { 594 ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet"); 595 return false; 596 } 597 if (!try_get_word(memory, cie + 4, &cie_offset)) { 598 return false; 599 } 600 if (cie_offset != 0) { 601 ALOGV("execute_fde: can't find CIE"); 602 return false; 603 } 604 } 605 ALOGV("execute_fde: FDE length: %d", fde_length); 606 ALOGV("execute_fde: CIE pointer: %x", cie); 607 ALOGV("execute_fde: CIE length: %d", cie_length); 608 609 /* Read CIE: 610 Augmentation independent: 611 1st byte is version; 612 next x bytes is /0 terminated augmentation string; 613 next x bytes is unsigned LEB128 encoded code alignment factor; 614 next x bytes is signed LEB128 encoded data alignment factor; 615 next 1 (CIE version 1) or x (CIE version 3 unsigned LEB128) bytes is return register column; 616 Augmentation dependent: 617 if 'z' next x bytes is unsigned LEB128 encoded augmentation data size; 618 if 'L' next 1 byte is LSDA encoding; 619 if 'R' next 1 byte is FDE encoding; 620 if 'S' CIE represents signal handler stack frame; 621 if 'P' next 1 byte is personality encoding folowed by personality function pointer; 622 Next x bytes is CIE program. 623 */ 624 625 uint32_t c = 8; 626 if (!try_get_byte(memory, cie, &cie_info->version, &c)) { 627 return false; 628 } 629 ALOGV("execute_fde: CIE version: %d", cie_info->version); 630 uint8_t ch; 631 do { 632 if (!try_get_byte(memory, cie, &ch, &c)) { 633 return false; 634 } 635 switch (ch) { 636 case '\0': break; 637 case 'z': cie_info->aug_z = 1; break; 638 case 'L': cie_info->aug_L = 1; break; 639 case 'R': cie_info->aug_R = 1; break; 640 case 'S': cie_info->aug_S = 1; break; 641 case 'P': cie_info->aug_P = 1; break; 642 default: 643 ALOGV("execute_fde: Unrecognized CIE augmentation char: '%c'", ch); 644 return false; 645 break; 646 } 647 } while (ch); 648 if (!try_get_uleb128(memory, cie, &cie_info->code_align, &c)) { 649 return false; 650 } 651 if (!try_get_sleb128(memory, cie, &cie_info->data_align, &c)) { 652 return false; 653 } 654 if (cie_info->version >= 3) { 655 if (!try_get_uleb128(memory, cie, &cie_info->reg, &c)) { 656 return false; 657 } 658 } else { 659 if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->reg, &c)) { 660 return false; 661 } 662 } 663 ALOGV("execute_fde: CIE code alignment factor: %d", cie_info->code_align); 664 ALOGV("execute_fde: CIE data alignment factor: %d", cie_info->data_align); 665 if (cie_info->aug_z) { 666 if (!try_get_uleb128(memory, cie, &cie_info->aug_z, &c)) { 667 return false; 668 } 669 } 670 if (cie_info->aug_L) { 671 if (!try_get_byte(memory, cie, &cie_info->aug_L, &c)) { 672 return false; 673 } 674 } else { 675 /* Default encoding. */ 676 cie_info->aug_L = DW_EH_PE_absptr; 677 } 678 if (cie_info->aug_R) { 679 if (!try_get_byte(memory, cie, &cie_info->aug_R, &c)) { 680 return false; 681 } 682 } else { 683 /* Default encoding. */ 684 cie_info->aug_R = DW_EH_PE_absptr; 685 } 686 if (cie_info->aug_P) { 687 /* Get encoding of personality routine pointer. We don't use it now. */ 688 if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->aug_P, &c)) { 689 return false; 690 } 691 /* Get routine pointer. */ 692 if (!read_dwarf(memory, cie, &cie_info->aug_P, (uint8_t)cie_info->aug_P, &c)) { 693 return false; 694 } 695 } 696 /* CIE program. */ 697 /* Length field itself (4 bytes) is not included into length. */ 698 stack[0] = *dstate; 699 stack_ptr = 1; 700 while (c < cie_length + 4) { 701 if (!execute_dwarf(memory, cie, cie_info, dstate, &c, stack, &stack_ptr)) { 702 return false; 703 } 704 } 705 706 /* We went directly to CIE. Normally it shouldn't occur. */ 707 if (cie == fde) return true; 708 709 /* Go back to FDE. */ 710 c = 8; 711 /* Read FDE: 712 Augmentation independent: 713 next x bytes (encoded as specified in CIE) is FDE starting address; 714 next x bytes (encoded as specified in CIE) is FDE number of instructions covered; 715 Augmentation dependent: 716 if 'z' next x bytes is unsigned LEB128 encoded augmentation data size; 717 if 'L' next x bytes is LSDA pointer (encoded as specified in CIE); 718 Next x bytes is FDE program. 719 */ 720 if (!read_dwarf(memory, fde, &fde_info->start, (uint8_t)cie_info->aug_R, &c)) { 721 return false; 722 } 723 dstate->loc = fde_info->start; 724 ALOGV("execute_fde: FDE start: %x", dstate->loc); 725 if (!read_dwarf(memory, fde, &fde_info->length, 0, &c)) { 726 return false; 727 } 728 ALOGV("execute_fde: FDE length: %x", fde_info->length); 729 if (cie_info->aug_z) { 730 if (!try_get_uleb128(memory, fde, &fde_info->aug_z, &c)) { 731 return false; 732 } 733 } 734 if (cie_info->aug_L && cie_info->aug_L != DW_EH_PE_omit) { 735 if (!read_dwarf(memory, fde, &fde_info->aug_L, cie_info->aug_L, &c)) { 736 return false; 737 } 738 } 739 /* FDE program. */ 740 /* Length field itself (4 bytes) is not included into length. */ 741 /* Save CIE state as 0 element of stack. Used by DW_CFA_restore. */ 742 stack[0] = *dstate; 743 stack_ptr = 1; 744 while (c < fde_length + 4 && state->reg[DWARF_EIP] >= dstate->loc) { 745 if (!execute_dwarf(memory, fde, cie_info, dstate, &c, stack, &stack_ptr)) { 746 return false; 747 } 748 ALOGV("IP: %x, LOC: %x", state->reg[DWARF_EIP], dstate->loc); 749 } 750 751 return update_state(memory, state, dstate, cie_info); 752 } 753 754 static ssize_t unwind_backtrace_common(const memory_t* memory, 755 const map_info_t* map_info_list, 756 unwind_state_t* state, backtrace_frame_t* backtrace, 757 size_t ignore_depth, size_t max_depth) { 758 759 size_t ignored_frames = 0; 760 size_t returned_frames = 0; 761 762 ALOGV("Unwinding tid: %d", memory->tid); 763 ALOGV("IP: %x", state->reg[DWARF_EIP]); 764 ALOGV("BP: %x", state->reg[DWARF_EBP]); 765 ALOGV("SP: %x", state->reg[DWARF_ESP]); 766 767 for (size_t index = 0; returned_frames < max_depth; index++) { 768 uintptr_t fde = find_fde(memory, map_info_list, state->reg[DWARF_EIP]); 769 /* FDE is not found, it may happen if stack is corrupted or calling wrong adress. 770 Getting return address from stack. 771 */ 772 if (!fde) { 773 uint32_t ip; 774 ALOGV("trying to restore registers from stack"); 775 if (!try_get_word(memory, state->reg[DWARF_EBP] + 4, &ip) || 776 ip == state->reg[DWARF_EIP]) { 777 ALOGV("can't get IP from stack"); 778 break; 779 } 780 /* We've been able to get IP from stack so recording the frame before continue. */ 781 backtrace_frame_t* frame = add_backtrace_entry( 782 index ? rewind_pc_arch(memory, state->reg[DWARF_EIP]) : state->reg[DWARF_EIP], 783 backtrace, ignore_depth, max_depth, 784 &ignored_frames, &returned_frames); 785 state->reg[DWARF_EIP] = ip; 786 state->reg[DWARF_ESP] = state->reg[DWARF_EBP] + 8; 787 if (!try_get_word(memory, state->reg[DWARF_EBP], &state->reg[DWARF_EBP])) { 788 ALOGV("can't get EBP from stack"); 789 break; 790 } 791 ALOGV("restore IP: %x", state->reg[DWARF_EIP]); 792 ALOGV("restore BP: %x", state->reg[DWARF_EBP]); 793 ALOGV("restore SP: %x", state->reg[DWARF_ESP]); 794 continue; 795 } 796 backtrace_frame_t* frame = add_backtrace_entry( 797 index ? rewind_pc_arch(memory, state->reg[DWARF_EIP]) : state->reg[DWARF_EIP], 798 backtrace, ignore_depth, max_depth, 799 &ignored_frames, &returned_frames); 800 801 uint32_t stack_top = state->reg[DWARF_ESP]; 802 803 if (!execute_fde(memory, map_info_list, fde, state)) break; 804 805 if (frame) { 806 frame->stack_top = stack_top; 807 if (stack_top < state->reg[DWARF_ESP]) { 808 frame->stack_size = state->reg[DWARF_ESP] - stack_top; 809 } 810 } 811 ALOGV("Stack: 0x%x ... 0x%x - %d bytes", frame->stack_top, state->reg[DWARF_ESP], frame->stack_size); 812 } 813 return returned_frames; 814 } 815 816 ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo __attribute__((unused)), void* sigcontext, 817 const map_info_t* map_info_list, 818 backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { 819 const ucontext_t* uc = (const ucontext_t*)sigcontext; 820 821 unwind_state_t state; 822 state.reg[DWARF_EBP] = uc->uc_mcontext.gregs[REG_EBP]; 823 state.reg[DWARF_ESP] = uc->uc_mcontext.gregs[REG_ESP]; 824 state.reg[DWARF_EIP] = uc->uc_mcontext.gregs[REG_EIP]; 825 826 memory_t memory; 827 init_memory(&memory, map_info_list); 828 return unwind_backtrace_common(&memory, map_info_list, 829 &state, backtrace, ignore_depth, max_depth); 830 } 831 832 ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context, 833 backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { 834 pt_regs_x86_t regs; 835 if (ptrace(PTRACE_GETREGS, tid, 0, ®s)) { 836 return -1; 837 } 838 839 unwind_state_t state; 840 state.reg[DWARF_EBP] = regs.ebp; 841 state.reg[DWARF_EIP] = regs.eip; 842 state.reg[DWARF_ESP] = regs.esp; 843 844 memory_t memory; 845 init_memory_ptrace(&memory, tid); 846 return unwind_backtrace_common(&memory, context->map_info_list, 847 &state, backtrace, ignore_depth, max_depth); 848 } 849