| Index: src/eh-frame.cc
|
| diff --git a/src/eh-frame.cc b/src/eh-frame.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..af85e0b8d5f7143beb3c5243513a69fef0f5f919
|
| --- /dev/null
|
| +++ b/src/eh-frame.cc
|
| @@ -0,0 +1,96 @@
|
| +// Copyright 2016 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "src/eh-frame.h"
|
| +#include "src/objects-inl.h"
|
| +#include "src/objects.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +static const int DW_EH_PE_pcrel = 0x10;
|
| +static const int DW_EH_PE_datarel = 0x30;
|
| +static const int DW_EH_PE_udata4 = 0x03;
|
| +static const int DW_EH_PE_sdata4 = 0x0b;
|
| +
|
| +const int EhFrameHdr::kCIESize = 0;
|
| +
|
| +static const int kVersionSize = 1;
|
| +static const int kEncodingSpecifiersSize = 3;
|
| +
|
| +//
|
| +// In order to calculate offsets in the .eh_frame_hdr, we must know the layout
|
| +// of the DSO generated by perf inject, which is assumed to be the following:
|
| +//
|
| +// | ... | |
|
| +// +---------------+ <-- (F) --- | Larger offsets in file
|
| +// | | ^ |
|
| +// | Instructions | | .text v
|
| +// | | v
|
| +// +---------------+ <-- (E) ---
|
| +// |///////////////|
|
| +// |////Padding////|
|
| +// |///////////////|
|
| +// +---------------+ <-- (D) ---
|
| +// | | ^
|
| +// | CIE | |
|
| +// | | |
|
| +// +---------------+ <-- (C) | .eh_frame
|
| +// | | |
|
| +// | FDE | |
|
| +// | | v
|
| +// +---------------+ <-- (B) ---
|
| +// | version | ^
|
| +// +---------------+ |
|
| +// | encoding | |
|
| +// | specifiers | |
|
| +// +---------------+ <---(A) | .eh_frame_hdr
|
| +// | offset to | |
|
| +// | .eh_frame | |
|
| +// +---------------+ |
|
| +// | ... | ...
|
| +//
|
| +// (F) is aligned at a 16-byte boundary.
|
| +// (D) is aligned at a 8-byte boundary.
|
| +// (B) is aligned at a 4-byte boundary.
|
| +// (E), (C) and (A) have no alignment requirements.
|
| +//
|
| +// The distance between (A) and (B) is 4 bytes.
|
| +//
|
| +// The size of the .eh_frame is required to be a multiple of the pointer size,
|
| +// which means that (B) will be naturally aligned to a 4-byte boundary on all
|
| +// the architectures we support.
|
| +//
|
| +// Because (E) has no alignment requirements, there is padding between (E) and
|
| +// (D). (F) is aligned at a 16-byte boundary, thus to a 8-byte one as well.
|
| +//
|
| +EhFrameHdr::EhFrameHdr(Code* code) {
|
| + int code_size = code->is_crankshafted() ? code->safepoint_table_offset()
|
| + : code->instruction_size();
|
| + version_ = 1;
|
| + eh_frame_ptr_encoding_ = DW_EH_PE_sdata4 | DW_EH_PE_pcrel;
|
| + lut_size_encoding_ = DW_EH_PE_udata4;
|
| + lut_entries_encoding_ = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
|
| +
|
| + // .eh_frame pointer and LUT
|
| + if (code->has_unwinding_info()) {
|
| + DCHECK_GE(code->unwinding_info_size(), EhFrameHdr::kRecordSize);
|
| + int eh_frame_size = code->unwinding_info_size() - EhFrameHdr::kRecordSize;
|
| +
|
| + offset_to_eh_frame_ =
|
| + -(eh_frame_size + kVersionSize + kEncodingSpecifiersSize); // A -> D
|
| + lut_entries_number_ = 1;
|
| + offset_to_procedure_ = -(RoundUp(code_size, 8) + eh_frame_size); // B -> F
|
| + offset_to_fde_ = -(eh_frame_size - kCIESize); // B -> C
|
| + } else {
|
| + // Create a dummy table
|
| + offset_to_eh_frame_ = 0;
|
| + lut_entries_number_ = 0;
|
| + offset_to_procedure_ = 0;
|
| + offset_to_fde_ = 0;
|
| + }
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|