Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Unified Diff: src/eh-frame.h

Issue 2023503002: Reland Implement .eh_frame writer and disassembler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@eh-frame-base
Patch Set: SaveRegisterToStack => RegisterSavedToStack. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/crankshaft/lithium.cc ('k') | src/eh-frame.cc » ('j') | src/eh-frame.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/eh-frame.h
diff --git a/src/eh-frame.h b/src/eh-frame.h
index 75781acb502ee8f420e93b240e7515e6e9f7348d..151deb67c4a529b0845e1a499a662f87a865852b 100644
--- a/src/eh-frame.h
+++ b/src/eh-frame.h
@@ -5,19 +5,175 @@
#ifndef V8_EH_FRAME_H_
#define V8_EH_FRAME_H_
-#include <cstdint>
+#include "src/macro-assembler.h"
namespace v8 {
namespace internal {
-class Code;
+class EhFrameWriter {
+ public:
+ enum DwarfOpcodes : byte {
rmcilroy 2016/07/05 10:56:12 enum class please
Stefano Sanfilippo 2016/07/05 16:02:13 Done.
+ kNop = 0x00,
+ kAdvanceLoc1 = 0x02,
+ kAdvanceLoc2 = 0x03,
+ kAdvanceLoc4 = 0x04,
+ kSameValue = 0x08,
+ kDefCfa = 0x0c,
+ kDefCfaRegister = 0x0d,
+ kDefCfaOffset = 0x0e,
+ kOffsetExtendedSf = 0x11,
+ };
+
+ enum DwarfEncodingSpecifiers : byte {
rmcilroy 2016/07/05 10:56:13 ditto
Stefano Sanfilippo 2016/07/05 16:02:14 These need to be | combinable though, static_cast<
rmcilroy 2016/07/06 13:59:30 OK, enum is fine in that case.
+ kUData4 = 0x03,
+ kSData4 = 0x0b,
+ kPcRel = 0x10,
+ kDataRel = 0x30,
+ kOmit = 0xff,
+ };
+
+ static const uint32_t kInt32Placeholder = 0xdeadc0de;
+
+ static const int kLocationTag = 1;
+ static const int kSavedRegisterTag = 2;
rmcilroy 2016/07/05 10:56:13 Move SavedRegisterTag below the location mask / ma
Stefano Sanfilippo 2016/07/05 16:02:13 Done.
+ static const int kLocationMask = 0x3f;
+ static const int kLocationMaskSize = 6;
+ static const int kSavedRegisterMask = 0x3f;
+ static const int kSavedRegisterMaskSize = 6;
+
+ static const int kProcedureAddressOffsetInFde = 2 * kInt32Size;
+ static const int kProcedureSizeOffsetInFde = 3 * kInt32Size;
+ static const int kTerminatorSize = 4;
rmcilroy 2016/07/05 10:56:12 kFdeTerminatorSize ? also put in it's own block (
Stefano Sanfilippo 2016/07/05 16:02:13 Done the moving. About the name, the terminator te
rmcilroy 2016/07/06 13:59:30 SGTM
+
+ static const int kInitialStateOffsetInCIE = 19;
+
+ static const int kDataAlignmentFactor;
rmcilroy 2016/07/05 10:56:13 This should all be private, none ofthese fields or
Stefano Sanfilippo 2016/07/05 16:02:14 The encoding specifiers are used in the EhFrameHdr
rmcilroy 2016/07/06 13:59:30 These shouldn't be part of EhFrameWriter in that c
Stefano Sanfilippo 2016/07/06 16:54:49 As discussed, I have uploaded a patchset with the
+
+ EhFrameWriter();
+
+ void AdvanceLocation(int pc_offset);
+
+ // The <base_address> is the one to which all <offset>s in SaveRegisterToStack
+ // directives are relative. It is given by <base_register> + <base_offset>.
+ void SetBaseAddressRegister(Register base_register);
+ void SetBaseAddressOffset(int base_offset);
+ void IncreaseBaseAddressOffset(int base_delta) {
+ SetBaseAddressOffset(base_offset_ + base_delta);
+ }
+ void SetBaseAddressRegisterAndOffset(Register base_register, int base_offset);
+
+ // Offset relative to <base address>, positive offsets go in the direction
+ // of stack growth (downwards on all architectures we support).
+ void RegisterSavedToStack(Register name, int offset) {
+ RegisterSavedToStack(RegisterToDwarfCode(name), offset);
+ }
+
+ void RegisterSavedToStack(Register name) {
+ RegisterSavedToStack(name, base_offset_);
+ }
+
+ void RegisterIsValid(Register name);
+
+ void Finish(int code_size);
+
+ // Remember to call Finish() before GetEhFrame().
+ //
+ // The EhFrameWriter instance owns the buffer pointed by
+ // CodeDesc::unwinding_info, and must outlive any use of the CodeDesc.
+ void GetEhFrame(CodeDesc* desc);
+
+ int last_pc_offset() const { return last_pc_offset_; }
+ Register base_register() const { return base_register_; }
+ int base_offset() const { return base_offset_; }
+
+#ifdef ENABLE_DISASSEMBLER
+ static void DisassembleToStream(std::ostream& stream, // NOLINT
+ const byte* start, const byte* end);
+#endif
+
+ protected:
rmcilroy 2016/07/05 10:56:13 This should all be private - you've already made E
Stefano Sanfilippo 2016/07/05 16:02:14 Done.
+ static uint32_t DecodeULEB128(const byte* encoded, int* encoded_size);
+
rmcilroy 2016/07/05 10:56:13 nit - remove newline (and group common blocks (e.g
Stefano Sanfilippo 2016/07/05 16:02:13 Done.
+ static int32_t DecodeSLEB128(const byte* encoded, int* encoded_size);
+
+ void WriteByte(byte value) { eh_frame_buffer_.push_back(value); }
+
+ void WriteBytes(const byte* start, int size) {
+ eh_frame_buffer_.insert(eh_frame_buffer_.end(), start, start + size);
+ }
+
+ void WriteInt16(uint16_t value) {
+ WriteBytes(reinterpret_cast<const byte*>(&value), sizeof(value));
+ }
+
+ void WriteInt32(uint32_t value) {
+ WriteBytes(reinterpret_cast<const byte*>(&value), sizeof(value));
+ }
+
+ void WriteSLEB128(int32_t value);
+
+ void WriteULEB128(uint32_t value);
+
+ void PatchInt32(int base_offset, uint32_t value) {
+ DCHECK_EQ(ReadUnalignedUInt32(eh_frame_buffer_.data() + base_offset),
+ kInt32Placeholder);
+ DCHECK_LT(base_offset + kInt32Size, eh_frame_offset());
+ WriteUnalignedUInt32(eh_frame_buffer_.data() + base_offset, value);
+ }
+
+ void WriteFDEHeader();
rmcilroy 2016/07/05 10:56:13 Short comments for these more complex functions
Stefano Sanfilippo 2016/07/05 16:02:13 Done.
rmcilroy 2016/07/06 13:59:30 Still no comments?
Stefano Sanfilippo 2016/07/06 16:54:49 Sorry, they came in a later patchset.
+
+ void WriteCIE();
+
+ void WriteInitialState();
rmcilroy 2016/07/05 10:56:13 WriteInitialStateInCIE ?
Stefano Sanfilippo 2016/07/05 16:02:14 Done.
+
+ void WriteReturnAddressRegisterCode();
rmcilroy 2016/07/05 10:56:13 This should just be "Register GetReturnAddressRegi
Stefano Sanfilippo 2016/07/05 16:02:14 The problem is that x64 rip is a pseudoregister wi
+
+ void Align();
rmcilroy 2016/07/05 10:56:13 WritePaddingTo8ByteAlign
Stefano Sanfilippo 2016/07/05 16:02:13 Done.
+
+ // Internal version that directly accepts a DWARF register code, needed for
+ // handling pseudoregisters on some platforms, such as x64.
+ void RegisterSavedToStack(int register_code, int offset);
+
+ int eh_frame_offset() const {
+ return static_cast<int>(eh_frame_buffer_.size());
+ }
+
+ int fde_offset() const { return cie_size_; }
+
+ int procedure_address_offset() const {
+ return fde_offset() + kProcedureAddressOffsetInFde;
+ }
+
+ int procedure_size_offset() const {
+ return fde_offset() + kProcedureSizeOffsetInFde;
+ }
+
+ private:
+#ifdef ENABLE_DISASSEMBLER
+ static void DumpDWARFDirectives(std::ostream& stream, // NOLINT
+ const byte* begin, const byte* end);
+#endif
+
+ static const char* DwarfRegisterCodeToString(int code);
+ static int RegisterToDwarfCode(Register name);
+
+ int last_pc_offset_;
+ bool eh_frame_finalised_;
+ Register base_register_;
+ int base_offset_;
+ std::vector<byte> eh_frame_buffer_;
+ int cie_size_;
rmcilroy 2016/07/05 10:56:13 nit - move cie_size_ to be first field
Stefano Sanfilippo 2016/07/05 16:02:14 Done.
+
+ friend class EhFrameWriterInternals; // For unit tests.
rmcilroy 2016/07/05 10:56:13 Rename this class to EhFrameWriteTest and remove c
Stefano Sanfilippo 2016/07/05 16:02:14 Removed the friend altogether, since the internals
+};
class EhFrameHdr final {
public:
static const int kRecordSize = 20;
- static const int kCIESize;
- explicit EhFrameHdr(Code* code);
+ EhFrameHdr(int code_size, int eh_frame_size, int cie_size);
+ static EhFrameHdr CreateEmptyHeader();
int32_t offset_to_eh_frame() const { return offset_to_eh_frame_; }
uint32_t lut_entries_number() const { return lut_entries_number_; }
@@ -25,6 +181,10 @@ class EhFrameHdr final {
int32_t offset_to_fde() const { return offset_to_fde_; }
private:
+ static const int kEhFrameHdrVersion = 1;
+
+ EhFrameHdr() {}
+
uint8_t version_;
uint8_t eh_frame_ptr_encoding_;
uint8_t lut_size_encoding_;
« no previous file with comments | « src/crankshaft/lithium.cc ('k') | src/eh-frame.cc » ('j') | src/eh-frame.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698