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