19e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura/* libunwind - a platform-independent unwind library 23b9fd99cb78383e0ce8cd1a31e3b824a30ef965eLassi Tuura Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY 39e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 49e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraThis file is part of libunwind. 59e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 69e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraPermission is hereby granted, free of charge, to any person obtaining 79e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraa copy of this software and associated documentation files (the 89e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura"Software"), to deal in the Software without restriction, including 99e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurawithout limitation the rights to use, copy, modify, merge, publish, 109e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuradistribute, sublicense, and/or sell copies of the Software, and to 119e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurapermit persons to whom the Software is furnished to do so, subject to 129e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurathe following conditions: 139e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 149e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraThe above copyright notice and this permission notice shall be 159e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraincluded in all copies or substantial portions of the Software. 169e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 179e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 189e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 199e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 209e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 219e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 229e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 239e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 249e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 259e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include "unwind_i.h" 269e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include "ucontext_i.h" 279e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 289e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraHIDDEN void 299e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuratdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) 309e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 319e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura struct cursor *c = (struct cursor *) dwarf_to_cursor (d); 329e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura unw_tdep_frame_t *f = &c->frame_info; 339e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 349e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" 359e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura " ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n", 369e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura d->ip, d->cfa, f->frame_type, 379e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura rs->reg[DWARF_CFA_REG_COLUMN].where, 389e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura rs->reg[DWARF_CFA_REG_COLUMN].val, 399e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura rs->reg[DWARF_CFA_OFF_COLUMN].val, 409e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura DWARF_GET_LOC(d->loc[d->ret_addr_column]), 419e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura rs->reg[RBP].where, rs->reg[RBP].val, DWARF_GET_LOC(d->loc[RBP]), 429e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura rs->reg[RSP].where, rs->reg[RSP].val, DWARF_GET_LOC(d->loc[RSP])); 439e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 449e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura /* A standard frame is defined as: 459e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura - CFA is register-relative offset off RBP or RSP; 469e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura - Return address is saved at CFA-8; 479e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura - RBP is unsaved or saved at CFA+offset, offset != -1; 489e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura - RSP is unsaved or saved at CFA+offset, offset != -1. */ 499e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (f->frame_type == UNW_X86_64_FRAME_OTHER 509e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) 519e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && (rs->reg[DWARF_CFA_REG_COLUMN].val == RBP 529e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura || rs->reg[DWARF_CFA_REG_COLUMN].val == RSP) 539e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) 549e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && DWARF_GET_LOC(d->loc[d->ret_addr_column]) == d->cfa-8 559e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && (rs->reg[RBP].where == DWARF_WHERE_UNDEF 569e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura || rs->reg[RBP].where == DWARF_WHERE_SAME 579e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura || (rs->reg[RBP].where == DWARF_WHERE_CFAREL 589e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && labs(rs->reg[RBP].val) < (1 << 14) 599e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && rs->reg[RBP].val+1 != 0)) 609e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && (rs->reg[RSP].where == DWARF_WHERE_UNDEF 619e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura || rs->reg[RSP].where == DWARF_WHERE_SAME 629e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura || (rs->reg[RSP].where == DWARF_WHERE_CFAREL 639e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && labs(rs->reg[RSP].val) < (1 << 14) 649e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura && rs->reg[RSP].val+1 != 0))) 659e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 669e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura /* Save information for a standard frame. */ 679e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura f->frame_type = UNW_X86_64_FRAME_STANDARD; 689e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura f->cfa_reg_rsp = (rs->reg[DWARF_CFA_REG_COLUMN].val == RSP); 699e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura f->cfa_reg_offset = rs->reg[DWARF_CFA_OFF_COLUMN].val; 709e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (rs->reg[RBP].where == DWARF_WHERE_CFAREL) 719e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura f->rbp_cfa_offset = rs->reg[RBP].val; 729e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (rs->reg[RSP].where == DWARF_WHERE_CFAREL) 739e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura f->rsp_cfa_offset = rs->reg[RSP].val; 749e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura Debug (4, " standard frame\n"); 759e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 769e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 771010880548589685a27b8f63ef54a3ea78e052fcArun Sharma /* Signal frame was detected via augmentation in tdep_fetch_frame() */ 789e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura else if (f->frame_type == UNW_X86_64_FRAME_SIGRETURN) 799e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 801010880548589685a27b8f63ef54a3ea78e052fcArun Sharma /* Later we are going to fish out {RBP,RSP,RIP} from sigcontext via 811010880548589685a27b8f63ef54a3ea78e052fcArun Sharma their ucontext_t offsets. Confirm DWARF info agrees with the 821010880548589685a27b8f63ef54a3ea78e052fcArun Sharma offsets we expect. */ 831010880548589685a27b8f63ef54a3ea78e052fcArun Sharma 84cf2f3d3b755d3374cc2f77973339c44c18057130Arun Sharma#ifndef NDEBUG 851010880548589685a27b8f63ef54a3ea78e052fcArun Sharma const unw_word_t uc = c->sigcontext_addr; 861010880548589685a27b8f63ef54a3ea78e052fcArun Sharma 871010880548589685a27b8f63ef54a3ea78e052fcArun Sharma assert (DWARF_GET_LOC(d->loc[RIP]) - uc == UC_MCONTEXT_GREGS_RIP); 881010880548589685a27b8f63ef54a3ea78e052fcArun Sharma assert (DWARF_GET_LOC(d->loc[RBP]) - uc == UC_MCONTEXT_GREGS_RBP); 891010880548589685a27b8f63ef54a3ea78e052fcArun Sharma assert (DWARF_GET_LOC(d->loc[RSP]) - uc == UC_MCONTEXT_GREGS_RSP); 902f328202ee19a68f4fc99d2cea169407026a70edArun Sharma#endif 911010880548589685a27b8f63ef54a3ea78e052fcArun Sharma 921010880548589685a27b8f63ef54a3ea78e052fcArun Sharma Debug (4, " sigreturn frame\n"); 939e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 949e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 959e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura /* PLT and guessed RBP-walked frames are handled in unw_step(). */ 969e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura else 97d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris /* ANDROID support update. */ 98d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris { 99d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris Debug (4, " unusual frame\n"); 100d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris } 101d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris /* End of ANDROID update. */ 1029e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 103