blob: af85e0b8d5f7143beb3c5243513a69fef0f5f919 [file] [log] [blame]
Ben Murdoch61f157c2016-09-16 13:49:30 +01001// 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
9namespace v8 {
10namespace internal {
11
12static const int DW_EH_PE_pcrel = 0x10;
13static const int DW_EH_PE_datarel = 0x30;
14static const int DW_EH_PE_udata4 = 0x03;
15static const int DW_EH_PE_sdata4 = 0x0b;
16
17const int EhFrameHdr::kCIESize = 0;
18
19static const int kVersionSize = 1;
20static 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//
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