• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)68 EhFrameHdr::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