buzbee | cd5b86d | 2017-10-20 14:00:52 -0700 | [diff] [blame] | 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 | |
David Srbecky | 946bb09 | 2018-03-09 17:23:01 +0000 | [diff] [blame] | 17 | #ifndef ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ |
| 18 | #define ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ |
buzbee | cd5b86d | 2017-10-20 14:00:52 -0700 | [diff] [blame] | 19 | |
David Srbecky | 64ebd81 | 2018-03-16 09:53:52 +0000 | [diff] [blame] | 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 */ |
Nicolas Geoffray | 0039182 | 2019-12-10 10:17:23 +0000 | [diff] [blame] | 47 | |
| 48 | #define CFI_DEFINE_CFA_DEREF(reg, offset, size) .cfi_escape \ |
| 49 | 0x0f /* DW_CFA_expression */, 6 /* size */, \ |
| 50 | 0x92 /* bregx */, reg, (offset & 0x7F), \ |
| 51 | 0x06 /* DW_OP_DEREF */, \ |
| 52 | 0x23 /* DW_OP_plus_uconst */, size |
David Srbecky | 64ebd81 | 2018-03-16 09:53:52 +0000 | [diff] [blame] | 53 | #else |
| 54 | // Mac OS doesn't like cfi_* directives. |
| 55 | #define CFI_DEFINE_DEX_PC_WITH_OFFSET(tmpReg, dexReg, dexOffset) |
Nicolas Geoffray | 0039182 | 2019-12-10 10:17:23 +0000 | [diff] [blame] | 56 | #define CFI_DEFINE_CFA_DEREF(reg, offset) |
David Srbecky | 64ebd81 | 2018-03-16 09:53:52 +0000 | [diff] [blame] | 57 | #endif |
buzbee | cd5b86d | 2017-10-20 14:00:52 -0700 | [diff] [blame] | 58 | |
David Srbecky | 946bb09 | 2018-03-09 17:23:01 +0000 | [diff] [blame] | 59 | #endif // ART_RUNTIME_INTERPRETER_CFI_ASM_SUPPORT_H_ |