110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown/*
210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * Copyright (C) 2011 The Android Open Source Project
310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown *
410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * you may not use this file except in compliance with the License.
610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * You may obtain a copy of the License at
710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown *
810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown *
1010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * Unless required by applicable law or agreed to in writing, software
1110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * See the License for the specific language governing permissions and
1410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * limitations under the License.
1510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown */
1610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
1710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown/*
1810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown * Backtracing functions for x86.
1910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown */
2010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
2110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#define LOG_TAG "Corkscrew"
2210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown//#define LOG_NDEBUG 0
2310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
2410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include "../backtrace-arch.h"
2510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include "../backtrace-helper.h"
2610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <corkscrew/ptrace.h>
2710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
2810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <stdlib.h>
2910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <signal.h>
3010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <stdbool.h>
3110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <limits.h>
3210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <errno.h>
3310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <sys/ptrace.h>
3410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown#include <cutils/log.h>
3510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
366b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes#if defined(__BIONIC__)
376b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes
385f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru#if defined(__BIONIC_HAVE_UCONTEXT_T)
395f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru
406b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes// Bionic offers the Linux kernel headers.
416b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes#include <asm/sigcontext.h>
426b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes#include <asm/ucontext.h>
436b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughestypedef struct ucontext ucontext_t;
446b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes
455f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru#else /* __BIONIC_HAVE_UCONTEXT_T */
465f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru
47b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner/* Old versions of the Android <signal.h> didn't define ucontext_t. */
48b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner
49b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turnertypedef struct {
50b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  uint32_t  gregs[32];
51b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  void*     fpregs;
52b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  uint32_t  oldmask;
53b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  uint32_t  cr2;
54b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner} mcontext_t;
55b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner
56b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turnerenum {
57b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  REG_GS = 0, REG_FS, REG_ES, REG_DS,
58b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  REG_EDI, REG_ESI, REG_EBP, REG_ESP,
59b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  REG_EBX, REG_EDX, REG_ECX, REG_EAX,
60b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  REG_TRAPNO, REG_ERR, REG_EIP, REG_CS,
61b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner  REG_EFL, REG_UESP, REG_SS
62b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner};
63b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner
6410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown/* Machine context at the time a signal was raised. */
6510484a068412613aaf3924f63a0b2f61400c7d1eJeff Browntypedef struct ucontext {
6610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    uint32_t uc_flags;
6710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    struct ucontext* uc_link;
6810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    stack_t uc_stack;
69b4ef91b97513434a13d6d84a810512315ecf4768David 'Digit' Turner    mcontext_t uc_mcontext;
7010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    uint32_t uc_sigmask;
7110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown} ucontext_t;
725f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru
735f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru#endif /* __BIONIC_HAVE_UCONTEXT_T */
745f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru
755f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru#else /* __BIONIC__ */
766b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes
776b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes// glibc has its own renaming of the Linux kernel's structures.
7871363a8075e7916c2166cbdd8a0bf5a180ed4d54Elliott Hughes#define __USE_GNU // For REG_EBP, REG_ESP, and REG_EIP.
7971363a8075e7916c2166cbdd8a0bf5a180ed4d54Elliott Hughes#include <ucontext.h>
8010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
815f83cf0bcf96fc58ca7314571ae264353cdee321Jean-Baptiste Queru#endif /* __ BIONIC__ */
826b3bab39d128947bf51deefe6a28c247cafd7baeElliott Hughes
8310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown/* Unwind state. */
8410484a068412613aaf3924f63a0b2f61400c7d1eJeff Browntypedef struct {
8510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    uint32_t ebp;
8610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    uint32_t eip;
8710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    uint32_t esp;
8810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown} unwind_state_t;
8910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
9046beebea823878218fc0f14723829d83886af978Edwin Vaneuintptr_t rewind_pc_arch(const memory_t* memory __attribute__((unused)), uintptr_t pc) {
91f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    // TODO: Implement for x86.
92f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    return pc;
93f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown}
94f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown
95f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brownstatic ssize_t unwind_backtrace_common(const memory_t* memory,
9646beebea823878218fc0f14723829d83886af978Edwin Vane        const map_info_t* map_info_list __attribute__((unused)),
9710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        unwind_state_t* state, backtrace_frame_t* backtrace,
9810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        size_t ignore_depth, size_t max_depth) {
9910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    size_t ignored_frames = 0;
10010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    size_t returned_frames = 0;
10110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
102f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    for (size_t index = 0; state->ebp && returned_frames < max_depth; index++) {
103f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown        backtrace_frame_t* frame = add_backtrace_entry(
104f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown                index ? rewind_pc_arch(memory, state->eip) : state->eip,
10510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown                backtrace, ignore_depth, max_depth,
10610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown                &ignored_frames, &returned_frames);
10710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        uint32_t next_esp = state->ebp + 8;
10810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        if (frame) {
10910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown            frame->stack_top = state->esp;
11010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown            if (state->esp < next_esp) {
11110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown                frame->stack_size = next_esp - state->esp;
11210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown            }
11310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        }
11410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        state->esp = next_esp;
115f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown        if (!try_get_word(memory, state->ebp + 4, &state->eip)
116f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown                || !try_get_word(memory, state->ebp, &state->ebp)
11710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown                || !state->eip) {
11810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown            break;
11910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        }
12010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    }
12110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
12210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    return returned_frames;
12310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown}
12410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
12546beebea823878218fc0f14723829d83886af978Edwin Vanessize_t unwind_backtrace_signal_arch(siginfo_t* siginfo __attribute__((unused)), void* sigcontext,
126f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown        const map_info_t* map_info_list,
12710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
12810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    const ucontext_t* uc = (const ucontext_t*)sigcontext;
12910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
13010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    unwind_state_t state;
13171363a8075e7916c2166cbdd8a0bf5a180ed4d54Elliott Hughes    state.ebp = uc->uc_mcontext.gregs[REG_EBP];
13271363a8075e7916c2166cbdd8a0bf5a180ed4d54Elliott Hughes    state.esp = uc->uc_mcontext.gregs[REG_ESP];
13371363a8075e7916c2166cbdd8a0bf5a180ed4d54Elliott Hughes    state.eip = uc->uc_mcontext.gregs[REG_EIP];
13410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
135f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    memory_t memory;
136f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    init_memory(&memory, map_info_list);
137f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    return unwind_backtrace_common(&memory, map_info_list,
138f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown            &state, backtrace, ignore_depth, max_depth);
13910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown}
14010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
14110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brownssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
14210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
14310484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    pt_regs_x86_t regs;
14410484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
14510484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown        return -1;
14610484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    }
14710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
14810484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    unwind_state_t state;
14910484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    state.ebp = regs.ebp;
15010484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    state.eip = regs.eip;
15110484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown    state.esp = regs.esp;
15210484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown
153f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    memory_t memory;
154f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    init_memory_ptrace(&memory, tid);
155f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    return unwind_backtrace_common(&memory, context->map_info_list,
156f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown            &state, backtrace, ignore_depth, max_depth);
15710484a068412613aaf3924f63a0b2f61400c7d1eJeff Brown}
158