1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/eh-frame.h" 6 #include "src/objects-inl.h" 7 #include "src/objects.h" 8 9 namespace v8 { 10 namespace internal { 11 12 static const int DW_EH_PE_pcrel = 0x10; 13 static const int DW_EH_PE_datarel = 0x30; 14 static const int DW_EH_PE_udata4 = 0x03; 15 static const int DW_EH_PE_sdata4 = 0x0b; 16 17 const int EhFrameHdr::kCIESize = 0; 18 19 static const int kVersionSize = 1; 20 static const int kEncodingSpecifiersSize = 3; 21 22 // 23 // In order to calculate offsets in the .eh_frame_hdr, we must know the layout 24 // of the DSO generated by perf inject, which is assumed to be the following: 25 // 26 // | ... | | 27 // +---------------+ <-- (F) --- | Larger offsets in file 28 // | | ^ | 29 // | Instructions | | .text v 30 // | | v 31 // +---------------+ <-- (E) --- 32 // |///////////////| 33 // |////Padding////| 34 // |///////////////| 35 // +---------------+ <-- (D) --- 36 // | | ^ 37 // | CIE | | 38 // | | | 39 // +---------------+ <-- (C) | .eh_frame 40 // | | | 41 // | FDE | | 42 // | | v 43 // +---------------+ <-- (B) --- 44 // | version | ^ 45 // +---------------+ | 46 // | encoding | | 47 // | specifiers | | 48 // +---------------+ <---(A) | .eh_frame_hdr 49 // | offset to | | 50 // | .eh_frame | | 51 // +---------------+ | 52 // | ... | ... 53 // 54 // (F) is aligned at a 16-byte boundary. 55 // (D) is aligned at a 8-byte boundary. 56 // (B) is aligned at a 4-byte boundary. 57 // (E), (C) and (A) have no alignment requirements. 58 // 59 // The distance between (A) and (B) is 4 bytes. 60 // 61 // The size of the .eh_frame is required to be a multiple of the pointer size, 62 // which means that (B) will be naturally aligned to a 4-byte boundary on all 63 // the architectures we support. 64 // 65 // Because (E) has no alignment requirements, there is padding between (E) and 66 // (D). (F) is aligned at a 16-byte boundary, thus to a 8-byte one as well. 67 // EhFrameHdr(Code * code)68EhFrameHdr::EhFrameHdr(Code* code) { 69 int code_size = code->is_crankshafted() ? code->safepoint_table_offset() 70 : code->instruction_size(); 71 version_ = 1; 72 eh_frame_ptr_encoding_ = DW_EH_PE_sdata4 | DW_EH_PE_pcrel; 73 lut_size_encoding_ = DW_EH_PE_udata4; 74 lut_entries_encoding_ = DW_EH_PE_sdata4 | DW_EH_PE_datarel; 75 76 // .eh_frame pointer and LUT 77 if (code->has_unwinding_info()) { 78 DCHECK_GE(code->unwinding_info_size(), EhFrameHdr::kRecordSize); 79 int eh_frame_size = code->unwinding_info_size() - EhFrameHdr::kRecordSize; 80 81 offset_to_eh_frame_ = 82 -(eh_frame_size + kVersionSize + kEncodingSpecifiersSize); // A -> D 83 lut_entries_number_ = 1; 84 offset_to_procedure_ = -(RoundUp(code_size, 8) + eh_frame_size); // B -> F 85 offset_to_fde_ = -(eh_frame_size - kCIESize); // B -> C 86 } else { 87 // Create a dummy table 88 offset_to_eh_frame_ = 0; 89 lut_entries_number_ = 0; 90 offset_to_procedure_ = 0; 91 offset_to_fde_ = 0; 92 } 93 } 94 95 } // namespace internal 96 } // namespace v8 97