Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/eh-frame.cc b/src/eh-frame.cc
new file mode 100644
index 0000000..af85e0b
--- /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