1 /* 2 * Copyright (C) 2017 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 #ifndef ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ 18 #define ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ 19 20 #if !defined(__APPLE__) 21 /* 22 * Define the DEX PC (memory address of the currently interpreted bytecode) 23 * within the CFI stream of the current function (stored in .eh_frame). 24 * This allows libunwind to detect that the frame is in the interpreter, 25 * and to resolve the memory address into human readable Java method name. 26 * The CFI instruction is recognised by the magic bytes in the expression 27 * (we push magic "DEX1" constant on the DWARF stack and drop it again). 28 * 29 * As with any other CFI opcode, the expression needs to be associated with 30 * a register. Any caller-save register will do as those are unused in CFI. 31 * Better solution would be to store the expression in Android-specific 32 * DWARF register (CFI registers don't have to correspond to real hardware 33 * registers), however, gdb handles any unknown registers very poorly. 34 * Similarly, we could also use some of the user-defined opcodes defined 35 * in the DWARF specification, but gdb doesn't support those either. 36 * 37 * The DEX PC is generally advanced in the middle of the bytecode handler, 38 * which will result in the reported DEX PC to be off by an instruction. 39 * Therefore the macro allows adding/subtracting an offset to compensate. 40 * TODO: Add the offsets to handlers to get line-accurate DEX PC reporting. 41 */ 42 #define CFI_DEFINE_DEX_PC_WITH_OFFSET(tmpReg, dexReg, dexOffset) .cfi_escape \ 43 0x16 /* DW_CFA_val_expression */, tmpReg, 0x09 /* size */, \ 44 0x0c /* DW_OP_const4u */, 0x44, 0x45, 0x58, 0x31, /* magic = "DEX1" */ \ 45 0x13 /* DW_OP_drop */, \ 46 0x92 /* DW_OP_bregx */, dexReg, (dexOffset & 0x7F) /* 1-byte SLEB128 */ 47 #else 48 // Mac OS doesn't like cfi_* directives. 49 #define CFI_DEFINE_DEX_PC_WITH_OFFSET(tmpReg, dexReg, dexOffset) 50 #endif 51 52 #endif // ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ 53