11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/diagnostics/eh-frame.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <iomanip> 81cb0ef41Sopenharmony_ci#include <ostream> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/codegen/code-desc.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM) && \ 131cb0ef41Sopenharmony_ci !defined(V8_TARGET_ARCH_ARM64) && !defined(V8_TARGET_ARCH_S390X) && \ 141cb0ef41Sopenharmony_ci !defined(V8_TARGET_ARCH_PPC64) 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// Placeholders for unsupported architectures. 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cinamespace v8 { 191cb0ef41Sopenharmony_cinamespace internal { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciconst int EhFrameConstants::kCodeAlignmentFactor = 1; 221cb0ef41Sopenharmony_ciconst int EhFrameConstants::kDataAlignmentFactor = 1; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_civoid EhFrameWriter::WriteReturnAddressRegisterCode() { UNIMPLEMENTED(); } 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_civoid EhFrameWriter::WriteInitialStateInCie() { UNIMPLEMENTED(); } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciint EhFrameWriter::RegisterToDwarfCode(Register) { 291cb0ef41Sopenharmony_ci UNIMPLEMENTED(); 301cb0ef41Sopenharmony_ci} 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciconst char* EhFrameDisassembler::DwarfRegisterCodeToString(int) { 351cb0ef41Sopenharmony_ci UNIMPLEMENTED(); 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci#endif 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci} // namespace internal 411cb0ef41Sopenharmony_ci} // namespace v8 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci#endif 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_cinamespace v8 { 461cb0ef41Sopenharmony_cinamespace internal { 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const int 491cb0ef41Sopenharmony_ci EhFrameConstants::kEhFrameTerminatorSize; 501cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const int EhFrameConstants::kEhFrameHdrVersion; 511cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const int EhFrameConstants::kEhFrameHdrSize; 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const uint32_t EhFrameWriter::kInt32Placeholder; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci// static 561cb0ef41Sopenharmony_civoid EhFrameWriter::WriteEmptyEhFrame(std::ostream& stream) { 571cb0ef41Sopenharmony_ci stream.put(EhFrameConstants::kEhFrameHdrVersion); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // .eh_frame pointer encoding specifier. 601cb0ef41Sopenharmony_ci stream.put(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci // Lookup table size encoding. 631cb0ef41Sopenharmony_ci stream.put(EhFrameConstants::kUData4); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci // Lookup table entries encoding. 661cb0ef41Sopenharmony_ci stream.put(EhFrameConstants::kSData4 | EhFrameConstants::kDataRel); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci // Dummy pointers and 0 entries in the lookup table. 691cb0ef41Sopenharmony_ci char dummy_data[EhFrameConstants::kEhFrameHdrSize - 4] = {0}; 701cb0ef41Sopenharmony_ci stream.write(&dummy_data[0], sizeof(dummy_data)); 711cb0ef41Sopenharmony_ci} 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ciEhFrameWriter::EhFrameWriter(Zone* zone) 741cb0ef41Sopenharmony_ci : cie_size_(0), 751cb0ef41Sopenharmony_ci last_pc_offset_(0), 761cb0ef41Sopenharmony_ci writer_state_(InternalState::kUndefined), 771cb0ef41Sopenharmony_ci base_register_(no_reg), 781cb0ef41Sopenharmony_ci base_offset_(0), 791cb0ef41Sopenharmony_ci eh_frame_buffer_(zone) {} 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_civoid EhFrameWriter::Initialize() { 821cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kUndefined); 831cb0ef41Sopenharmony_ci eh_frame_buffer_.reserve(128); 841cb0ef41Sopenharmony_ci writer_state_ = InternalState::kInitialized; 851cb0ef41Sopenharmony_ci WriteCie(); 861cb0ef41Sopenharmony_ci WriteFdeHeader(); 871cb0ef41Sopenharmony_ci} 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_civoid EhFrameWriter::WriteCie() { 901cb0ef41Sopenharmony_ci static const int kCIEIdentifier = 0; 911cb0ef41Sopenharmony_ci static const int kCIEVersion = 3; 921cb0ef41Sopenharmony_ci static const int kAugmentationDataSize = 2; 931cb0ef41Sopenharmony_ci static const byte kAugmentationString[] = {'z', 'L', 'R', 0}; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci // Placeholder for the size of the CIE. 961cb0ef41Sopenharmony_ci int size_offset = eh_frame_offset(); 971cb0ef41Sopenharmony_ci WriteInt32(kInt32Placeholder); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci // CIE identifier and version. 1001cb0ef41Sopenharmony_ci int record_start_offset = eh_frame_offset(); 1011cb0ef41Sopenharmony_ci WriteInt32(kCIEIdentifier); 1021cb0ef41Sopenharmony_ci WriteByte(kCIEVersion); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Augmentation data contents descriptor: LSDA and FDE encoding. 1051cb0ef41Sopenharmony_ci WriteBytes(&kAugmentationString[0], sizeof(kAugmentationString)); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci // Alignment factors. 1081cb0ef41Sopenharmony_ci WriteSLeb128(EhFrameConstants::kCodeAlignmentFactor); 1091cb0ef41Sopenharmony_ci WriteSLeb128(EhFrameConstants::kDataAlignmentFactor); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci WriteReturnAddressRegisterCode(); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci // Augmentation data. 1141cb0ef41Sopenharmony_ci WriteULeb128(kAugmentationDataSize); 1151cb0ef41Sopenharmony_ci // No language-specific data area (LSDA). 1161cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kOmit); 1171cb0ef41Sopenharmony_ci // FDE pointers encoding. 1181cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci // Write directives to build the initial state of the unwinding table. 1211cb0ef41Sopenharmony_ci DCHECK_EQ(eh_frame_offset() - size_offset, 1221cb0ef41Sopenharmony_ci EhFrameConstants::kInitialStateOffsetInCie); 1231cb0ef41Sopenharmony_ci WriteInitialStateInCie(); 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci WritePaddingToAlignedSize(eh_frame_offset() - record_start_offset); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci int record_end_offset = eh_frame_offset(); 1281cb0ef41Sopenharmony_ci int encoded_cie_size = record_end_offset - record_start_offset; 1291cb0ef41Sopenharmony_ci cie_size_ = record_end_offset - size_offset; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // Patch the size of the CIE now that we know it. 1321cb0ef41Sopenharmony_ci PatchInt32(size_offset, encoded_cie_size); 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_civoid EhFrameWriter::WriteFdeHeader() { 1361cb0ef41Sopenharmony_ci DCHECK_NE(cie_size_, 0); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci // Placeholder for size of the FDE. Will be filled in Finish(). 1391cb0ef41Sopenharmony_ci DCHECK_EQ(eh_frame_offset(), fde_offset()); 1401cb0ef41Sopenharmony_ci WriteInt32(kInt32Placeholder); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci // Backwards offset to the CIE. 1431cb0ef41Sopenharmony_ci WriteInt32(cie_size_ + kInt32Size); 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci // Placeholder for pointer to procedure. Will be filled in Finish(). 1461cb0ef41Sopenharmony_ci DCHECK_EQ(eh_frame_offset(), GetProcedureAddressOffset()); 1471cb0ef41Sopenharmony_ci WriteInt32(kInt32Placeholder); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci // Placeholder for size of the procedure. Will be filled in Finish(). 1501cb0ef41Sopenharmony_ci DCHECK_EQ(eh_frame_offset(), GetProcedureSizeOffset()); 1511cb0ef41Sopenharmony_ci WriteInt32(kInt32Placeholder); 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci // No augmentation data. 1541cb0ef41Sopenharmony_ci WriteByte(0); 1551cb0ef41Sopenharmony_ci} 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_civoid EhFrameWriter::WriteEhFrameHdr(int code_size) { 1581cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci // 1611cb0ef41Sopenharmony_ci // In order to calculate offsets in the .eh_frame_hdr, we must know the layout 1621cb0ef41Sopenharmony_ci // of the DSO generated by perf inject, which is assumed to be the following: 1631cb0ef41Sopenharmony_ci // 1641cb0ef41Sopenharmony_ci // | ... | | 1651cb0ef41Sopenharmony_ci // +---------------+ <-- (F) --- | Larger offsets in file 1661cb0ef41Sopenharmony_ci // | | ^ | 1671cb0ef41Sopenharmony_ci // | Instructions | | .text v 1681cb0ef41Sopenharmony_ci // | | v 1691cb0ef41Sopenharmony_ci // +---------------+ <-- (E) --- 1701cb0ef41Sopenharmony_ci // |///////////////| 1711cb0ef41Sopenharmony_ci // |////Padding////| 1721cb0ef41Sopenharmony_ci // |///////////////| 1731cb0ef41Sopenharmony_ci // +---------------+ <-- (D) --- 1741cb0ef41Sopenharmony_ci // | | ^ 1751cb0ef41Sopenharmony_ci // | CIE | | 1761cb0ef41Sopenharmony_ci // | | | 1771cb0ef41Sopenharmony_ci // +---------------+ <-- (C) | 1781cb0ef41Sopenharmony_ci // | | | .eh_frame 1791cb0ef41Sopenharmony_ci // | FDE | | 1801cb0ef41Sopenharmony_ci // | | | 1811cb0ef41Sopenharmony_ci // +---------------+ | 1821cb0ef41Sopenharmony_ci // | terminator | v 1831cb0ef41Sopenharmony_ci // +---------------+ <-- (B) --- 1841cb0ef41Sopenharmony_ci // | version | ^ 1851cb0ef41Sopenharmony_ci // +---------------+ | 1861cb0ef41Sopenharmony_ci // | encoding | | 1871cb0ef41Sopenharmony_ci // | specifiers | | 1881cb0ef41Sopenharmony_ci // +---------------+ <---(A) | .eh_frame_hdr 1891cb0ef41Sopenharmony_ci // | offset to | | 1901cb0ef41Sopenharmony_ci // | .eh_frame | | 1911cb0ef41Sopenharmony_ci // +---------------+ | 1921cb0ef41Sopenharmony_ci // | ... | ... 1931cb0ef41Sopenharmony_ci // 1941cb0ef41Sopenharmony_ci // (F) is aligned to a 16-byte boundary. 1951cb0ef41Sopenharmony_ci // (D) is aligned to a 8-byte boundary. 1961cb0ef41Sopenharmony_ci // (B) is aligned to a 4-byte boundary. 1971cb0ef41Sopenharmony_ci // (C), (E) and (A) have no alignment requirements. 1981cb0ef41Sopenharmony_ci // 1991cb0ef41Sopenharmony_ci // The distance between (A) and (B) is 4 bytes. 2001cb0ef41Sopenharmony_ci // 2011cb0ef41Sopenharmony_ci // The size of the FDE is required to be a multiple of the pointer size, which 2021cb0ef41Sopenharmony_ci // means that (B) will be naturally aligned to a 4-byte boundary on all the 2031cb0ef41Sopenharmony_ci // architectures we support. 2041cb0ef41Sopenharmony_ci // 2051cb0ef41Sopenharmony_ci // Because (E) has no alignment requirements, there is padding between (E) and 2061cb0ef41Sopenharmony_ci // (D). (F) is aligned at a 16-byte boundary, thus to a 8-byte one as well. 2071cb0ef41Sopenharmony_ci // 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci int eh_frame_size = eh_frame_offset(); 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kEhFrameHdrVersion); 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci // .eh_frame pointer encoding specifier. 2141cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel); 2151cb0ef41Sopenharmony_ci // Lookup table size encoding specifier. 2161cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kUData4); 2171cb0ef41Sopenharmony_ci // Lookup table entries encoding specifier. 2181cb0ef41Sopenharmony_ci WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kDataRel); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci // Pointer to .eh_frame, relative to this offset (A -> D in the diagram). 2211cb0ef41Sopenharmony_ci WriteInt32(-(eh_frame_size + EhFrameConstants::kFdeVersionSize + 2221cb0ef41Sopenharmony_ci EhFrameConstants::kFdeEncodingSpecifiersSize)); 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci // Number of entries in the LUT, one for the only routine. 2251cb0ef41Sopenharmony_ci WriteInt32(1); 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci // Pointer to the start of the routine, relative to the beginning of the 2281cb0ef41Sopenharmony_ci // .eh_frame_hdr (B -> F in the diagram). 2291cb0ef41Sopenharmony_ci WriteInt32(-(RoundUp(code_size, 8) + eh_frame_size)); 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci // Pointer to the start of the associated FDE, relative to the start of the 2321cb0ef41Sopenharmony_ci // .eh_frame_hdr (B -> C in the diagram). 2331cb0ef41Sopenharmony_ci WriteInt32(-(eh_frame_size - cie_size_)); 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci DCHECK_EQ(eh_frame_offset() - eh_frame_size, 2361cb0ef41Sopenharmony_ci EhFrameConstants::kEhFrameHdrSize); 2371cb0ef41Sopenharmony_ci} 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_civoid EhFrameWriter::WritePaddingToAlignedSize(int unpadded_size) { 2401cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 2411cb0ef41Sopenharmony_ci DCHECK_GE(unpadded_size, 0); 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci int padding_size = RoundUp(unpadded_size, kSystemPointerSize) - unpadded_size; 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci byte nop = static_cast<byte>(EhFrameConstants::DwarfOpcodes::kNop); 2461cb0ef41Sopenharmony_ci static const byte kPadding[] = {nop, nop, nop, nop, nop, nop, nop, nop}; 2471cb0ef41Sopenharmony_ci DCHECK_LE(padding_size, static_cast<int>(sizeof(kPadding))); 2481cb0ef41Sopenharmony_ci WriteBytes(&kPadding[0], padding_size); 2491cb0ef41Sopenharmony_ci} 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_civoid EhFrameWriter::AdvanceLocation(int pc_offset) { 2521cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 2531cb0ef41Sopenharmony_ci DCHECK_GE(pc_offset, last_pc_offset_); 2541cb0ef41Sopenharmony_ci uint32_t delta = pc_offset - last_pc_offset_; 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci DCHECK_EQ(delta % EhFrameConstants::kCodeAlignmentFactor, 0u); 2571cb0ef41Sopenharmony_ci uint32_t factored_delta = delta / EhFrameConstants::kCodeAlignmentFactor; 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci if (factored_delta <= EhFrameConstants::kLocationMask) { 2601cb0ef41Sopenharmony_ci WriteByte((EhFrameConstants::kLocationTag 2611cb0ef41Sopenharmony_ci << EhFrameConstants::kLocationMaskSize) | 2621cb0ef41Sopenharmony_ci (factored_delta & EhFrameConstants::kLocationMask)); 2631cb0ef41Sopenharmony_ci } else if (factored_delta <= kMaxUInt8) { 2641cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1); 2651cb0ef41Sopenharmony_ci WriteByte(factored_delta); 2661cb0ef41Sopenharmony_ci } else if (factored_delta <= kMaxUInt16) { 2671cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc2); 2681cb0ef41Sopenharmony_ci WriteInt16(factored_delta); 2691cb0ef41Sopenharmony_ci } else { 2701cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc4); 2711cb0ef41Sopenharmony_ci WriteInt32(factored_delta); 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci last_pc_offset_ = pc_offset; 2751cb0ef41Sopenharmony_ci} 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_civoid EhFrameWriter::SetBaseAddressOffset(int base_offset) { 2781cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 2791cb0ef41Sopenharmony_ci DCHECK_GE(base_offset, 0); 2801cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfaOffset); 2811cb0ef41Sopenharmony_ci WriteULeb128(base_offset); 2821cb0ef41Sopenharmony_ci base_offset_ = base_offset; 2831cb0ef41Sopenharmony_ci} 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_civoid EhFrameWriter::SetBaseAddressRegister(Register base_register) { 2861cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 2871cb0ef41Sopenharmony_ci int code = RegisterToDwarfCode(base_register); 2881cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfaRegister); 2891cb0ef41Sopenharmony_ci WriteULeb128(code); 2901cb0ef41Sopenharmony_ci base_register_ = base_register; 2911cb0ef41Sopenharmony_ci} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_civoid EhFrameWriter::SetBaseAddressRegisterAndOffset(Register base_register, 2941cb0ef41Sopenharmony_ci int base_offset) { 2951cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 2961cb0ef41Sopenharmony_ci DCHECK_GE(base_offset, 0); 2971cb0ef41Sopenharmony_ci int code = RegisterToDwarfCode(base_register); 2981cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfa); 2991cb0ef41Sopenharmony_ci WriteULeb128(code); 3001cb0ef41Sopenharmony_ci WriteULeb128(base_offset); 3011cb0ef41Sopenharmony_ci base_offset_ = base_offset; 3021cb0ef41Sopenharmony_ci base_register_ = base_register; 3031cb0ef41Sopenharmony_ci} 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_civoid EhFrameWriter::RecordRegisterSavedToStack(int dwarf_register_code, 3061cb0ef41Sopenharmony_ci int offset) { 3071cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 3081cb0ef41Sopenharmony_ci DCHECK_EQ(offset % EhFrameConstants::kDataAlignmentFactor, 0); 3091cb0ef41Sopenharmony_ci int factored_offset = offset / EhFrameConstants::kDataAlignmentFactor; 3101cb0ef41Sopenharmony_ci if (factored_offset >= 0) { 3111cb0ef41Sopenharmony_ci DCHECK_LE(dwarf_register_code, EhFrameConstants::kSavedRegisterMask); 3121cb0ef41Sopenharmony_ci WriteByte((EhFrameConstants::kSavedRegisterTag 3131cb0ef41Sopenharmony_ci << EhFrameConstants::kSavedRegisterMaskSize) | 3141cb0ef41Sopenharmony_ci (dwarf_register_code & EhFrameConstants::kSavedRegisterMask)); 3151cb0ef41Sopenharmony_ci WriteULeb128(factored_offset); 3161cb0ef41Sopenharmony_ci } else { 3171cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf); 3181cb0ef41Sopenharmony_ci WriteULeb128(dwarf_register_code); 3191cb0ef41Sopenharmony_ci WriteSLeb128(factored_offset); 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci} 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_civoid EhFrameWriter::RecordRegisterNotModified(Register name) { 3241cb0ef41Sopenharmony_ci RecordRegisterNotModified(RegisterToDwarfCode(name)); 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_civoid EhFrameWriter::RecordRegisterNotModified(int dwarf_register_code) { 3281cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 3291cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kSameValue); 3301cb0ef41Sopenharmony_ci WriteULeb128(dwarf_register_code); 3311cb0ef41Sopenharmony_ci} 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_civoid EhFrameWriter::RecordRegisterFollowsInitialRule(Register name) { 3341cb0ef41Sopenharmony_ci RecordRegisterFollowsInitialRule(RegisterToDwarfCode(name)); 3351cb0ef41Sopenharmony_ci} 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_civoid EhFrameWriter::RecordRegisterFollowsInitialRule(int dwarf_register_code) { 3381cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 3391cb0ef41Sopenharmony_ci if (dwarf_register_code <= EhFrameConstants::kFollowInitialRuleMask) { 3401cb0ef41Sopenharmony_ci WriteByte((EhFrameConstants::kFollowInitialRuleTag 3411cb0ef41Sopenharmony_ci << EhFrameConstants::kFollowInitialRuleMaskSize) | 3421cb0ef41Sopenharmony_ci (dwarf_register_code & EhFrameConstants::kFollowInitialRuleMask)); 3431cb0ef41Sopenharmony_ci } else { 3441cb0ef41Sopenharmony_ci WriteOpcode(EhFrameConstants::DwarfOpcodes::kRestoreExtended); 3451cb0ef41Sopenharmony_ci WriteULeb128(dwarf_register_code); 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci} 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_civoid EhFrameWriter::Finish(int code_size) { 3501cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kInitialized); 3511cb0ef41Sopenharmony_ci DCHECK_GE(eh_frame_offset(), cie_size_); 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_ci DCHECK_GE(eh_frame_offset(), fde_offset() + kInt32Size); 3541cb0ef41Sopenharmony_ci WritePaddingToAlignedSize(eh_frame_offset() - fde_offset() - kInt32Size); 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci // Write the size of the FDE now that we know it. 3571cb0ef41Sopenharmony_ci // The encoded size does not include the size field itself. 3581cb0ef41Sopenharmony_ci int encoded_fde_size = eh_frame_offset() - fde_offset() - kInt32Size; 3591cb0ef41Sopenharmony_ci PatchInt32(fde_offset(), encoded_fde_size); 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ci // Write size and offset to procedure. 3621cb0ef41Sopenharmony_ci PatchInt32(GetProcedureAddressOffset(), 3631cb0ef41Sopenharmony_ci -(RoundUp(code_size, 8) + GetProcedureAddressOffset())); 3641cb0ef41Sopenharmony_ci PatchInt32(GetProcedureSizeOffset(), code_size); 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci // Terminate the .eh_frame. 3671cb0ef41Sopenharmony_ci static const byte kTerminator[EhFrameConstants::kEhFrameTerminatorSize] = {0}; 3681cb0ef41Sopenharmony_ci WriteBytes(&kTerminator[0], EhFrameConstants::kEhFrameTerminatorSize); 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci WriteEhFrameHdr(code_size); 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci writer_state_ = InternalState::kFinalized; 3731cb0ef41Sopenharmony_ci} 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_civoid EhFrameWriter::GetEhFrame(CodeDesc* desc) { 3761cb0ef41Sopenharmony_ci DCHECK_EQ(writer_state_, InternalState::kFinalized); 3771cb0ef41Sopenharmony_ci desc->unwinding_info_size = static_cast<int>(eh_frame_buffer_.size()); 3781cb0ef41Sopenharmony_ci desc->unwinding_info = eh_frame_buffer_.data(); 3791cb0ef41Sopenharmony_ci} 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_civoid EhFrameWriter::WriteULeb128(uint32_t value) { 3821cb0ef41Sopenharmony_ci do { 3831cb0ef41Sopenharmony_ci byte chunk = value & 0x7F; 3841cb0ef41Sopenharmony_ci value >>= 7; 3851cb0ef41Sopenharmony_ci if (value != 0) chunk |= 0x80; 3861cb0ef41Sopenharmony_ci WriteByte(chunk); 3871cb0ef41Sopenharmony_ci } while (value != 0); 3881cb0ef41Sopenharmony_ci} 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_civoid EhFrameWriter::WriteSLeb128(int32_t value) { 3911cb0ef41Sopenharmony_ci static const int kSignBitMask = 0x40; 3921cb0ef41Sopenharmony_ci bool done; 3931cb0ef41Sopenharmony_ci do { 3941cb0ef41Sopenharmony_ci byte chunk = value & 0x7F; 3951cb0ef41Sopenharmony_ci value >>= 7; 3961cb0ef41Sopenharmony_ci done = ((value == 0) && ((chunk & kSignBitMask) == 0)) || 3971cb0ef41Sopenharmony_ci ((value == -1) && ((chunk & kSignBitMask) != 0)); 3981cb0ef41Sopenharmony_ci if (!done) chunk |= 0x80; 3991cb0ef41Sopenharmony_ci WriteByte(chunk); 4001cb0ef41Sopenharmony_ci } while (!done); 4011cb0ef41Sopenharmony_ci} 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ciuint32_t EhFrameIterator::GetNextULeb128() { 4041cb0ef41Sopenharmony_ci int size = 0; 4051cb0ef41Sopenharmony_ci uint32_t result = DecodeULeb128(next_, &size); 4061cb0ef41Sopenharmony_ci DCHECK_LE(next_ + size, end_); 4071cb0ef41Sopenharmony_ci next_ += size; 4081cb0ef41Sopenharmony_ci return result; 4091cb0ef41Sopenharmony_ci} 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ciint32_t EhFrameIterator::GetNextSLeb128() { 4121cb0ef41Sopenharmony_ci int size = 0; 4131cb0ef41Sopenharmony_ci int32_t result = DecodeSLeb128(next_, &size); 4141cb0ef41Sopenharmony_ci DCHECK_LE(next_ + size, end_); 4151cb0ef41Sopenharmony_ci next_ += size; 4161cb0ef41Sopenharmony_ci return result; 4171cb0ef41Sopenharmony_ci} 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci// static 4201cb0ef41Sopenharmony_ciuint32_t EhFrameIterator::DecodeULeb128(const byte* encoded, 4211cb0ef41Sopenharmony_ci int* encoded_size) { 4221cb0ef41Sopenharmony_ci const byte* current = encoded; 4231cb0ef41Sopenharmony_ci uint32_t result = 0; 4241cb0ef41Sopenharmony_ci int shift = 0; 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci do { 4271cb0ef41Sopenharmony_ci DCHECK_LT(shift, 8 * static_cast<int>(sizeof(result))); 4281cb0ef41Sopenharmony_ci result |= (*current & 0x7F) << shift; 4291cb0ef41Sopenharmony_ci shift += 7; 4301cb0ef41Sopenharmony_ci } while (*current++ >= 128); 4311cb0ef41Sopenharmony_ci 4321cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(encoded_size); 4331cb0ef41Sopenharmony_ci *encoded_size = static_cast<int>(current - encoded); 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci return result; 4361cb0ef41Sopenharmony_ci} 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci// static 4391cb0ef41Sopenharmony_ciint32_t EhFrameIterator::DecodeSLeb128(const byte* encoded, int* encoded_size) { 4401cb0ef41Sopenharmony_ci static const byte kSignBitMask = 0x40; 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci const byte* current = encoded; 4431cb0ef41Sopenharmony_ci int32_t result = 0; 4441cb0ef41Sopenharmony_ci int shift = 0; 4451cb0ef41Sopenharmony_ci byte chunk; 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci do { 4481cb0ef41Sopenharmony_ci chunk = *current++; 4491cb0ef41Sopenharmony_ci DCHECK_LT(shift, 8 * static_cast<int>(sizeof(result))); 4501cb0ef41Sopenharmony_ci result |= (chunk & 0x7F) << shift; 4511cb0ef41Sopenharmony_ci shift += 7; 4521cb0ef41Sopenharmony_ci } while (chunk >= 128); 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ci // Sign extend the result if the last chunk has the sign bit set. 4551cb0ef41Sopenharmony_ci if (chunk & kSignBitMask) result |= (~0ull) << shift; 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(encoded_size); 4581cb0ef41Sopenharmony_ci *encoded_size = static_cast<int>(current - encoded); 4591cb0ef41Sopenharmony_ci 4601cb0ef41Sopenharmony_ci return result; 4611cb0ef41Sopenharmony_ci} 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_cinamespace { 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ciclass V8_NODISCARD StreamModifiersScope final { 4681cb0ef41Sopenharmony_ci public: 4691cb0ef41Sopenharmony_ci explicit StreamModifiersScope(std::ostream* stream) 4701cb0ef41Sopenharmony_ci : stream_(stream), flags_(stream->flags()) {} 4711cb0ef41Sopenharmony_ci ~StreamModifiersScope() { stream_->flags(flags_); } 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_ci private: 4741cb0ef41Sopenharmony_ci std::ostream* stream_; 4751cb0ef41Sopenharmony_ci std::ios::fmtflags flags_; 4761cb0ef41Sopenharmony_ci}; 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci} // namespace 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci// static 4811cb0ef41Sopenharmony_civoid EhFrameDisassembler::DumpDwarfDirectives(std::ostream& stream, 4821cb0ef41Sopenharmony_ci const byte* start, 4831cb0ef41Sopenharmony_ci const byte* end) { 4841cb0ef41Sopenharmony_ci StreamModifiersScope modifiers_scope(&stream); 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci EhFrameIterator eh_frame_iterator(start, end); 4871cb0ef41Sopenharmony_ci uint32_t offset_in_procedure = 0; 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci while (!eh_frame_iterator.Done()) { 4901cb0ef41Sopenharmony_ci stream << eh_frame_iterator.current_address() << " "; 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci byte bytecode = eh_frame_iterator.GetNextByte(); 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci if (((bytecode >> EhFrameConstants::kLocationMaskSize) & 0xFF) == 4951cb0ef41Sopenharmony_ci EhFrameConstants::kLocationTag) { 4961cb0ef41Sopenharmony_ci int value = (bytecode & EhFrameConstants::kLocationMask) * 4971cb0ef41Sopenharmony_ci EhFrameConstants::kCodeAlignmentFactor; 4981cb0ef41Sopenharmony_ci offset_in_procedure += value; 4991cb0ef41Sopenharmony_ci stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value 5001cb0ef41Sopenharmony_ci << ")\n"; 5011cb0ef41Sopenharmony_ci continue; 5021cb0ef41Sopenharmony_ci } 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ci if (((bytecode >> EhFrameConstants::kSavedRegisterMaskSize) & 0xFF) == 5051cb0ef41Sopenharmony_ci EhFrameConstants::kSavedRegisterTag) { 5061cb0ef41Sopenharmony_ci int32_t decoded_offset = eh_frame_iterator.GetNextULeb128(); 5071cb0ef41Sopenharmony_ci stream << "| " 5081cb0ef41Sopenharmony_ci << DwarfRegisterCodeToString(bytecode & 5091cb0ef41Sopenharmony_ci EhFrameConstants::kLocationMask) 5101cb0ef41Sopenharmony_ci << " saved at base" << std::showpos 5111cb0ef41Sopenharmony_ci << decoded_offset * EhFrameConstants::kDataAlignmentFactor 5121cb0ef41Sopenharmony_ci << std::noshowpos << '\n'; 5131cb0ef41Sopenharmony_ci continue; 5141cb0ef41Sopenharmony_ci } 5151cb0ef41Sopenharmony_ci 5161cb0ef41Sopenharmony_ci if (((bytecode >> EhFrameConstants::kFollowInitialRuleMaskSize) & 0xFF) == 5171cb0ef41Sopenharmony_ci EhFrameConstants::kFollowInitialRuleTag) { 5181cb0ef41Sopenharmony_ci stream << "| " 5191cb0ef41Sopenharmony_ci << DwarfRegisterCodeToString(bytecode & 5201cb0ef41Sopenharmony_ci EhFrameConstants::kLocationMask) 5211cb0ef41Sopenharmony_ci << " follows rule in CIE\n"; 5221cb0ef41Sopenharmony_ci continue; 5231cb0ef41Sopenharmony_ci } 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci switch (static_cast<EhFrameConstants::DwarfOpcodes>(bytecode)) { 5261cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf: { 5271cb0ef41Sopenharmony_ci stream << "| " 5281cb0ef41Sopenharmony_ci << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128()); 5291cb0ef41Sopenharmony_ci int32_t decoded_offset = eh_frame_iterator.GetNextSLeb128(); 5301cb0ef41Sopenharmony_ci stream << " saved at base" << std::showpos 5311cb0ef41Sopenharmony_ci << decoded_offset * EhFrameConstants::kDataAlignmentFactor 5321cb0ef41Sopenharmony_ci << std::noshowpos << '\n'; 5331cb0ef41Sopenharmony_ci break; 5341cb0ef41Sopenharmony_ci } 5351cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kAdvanceLoc1: { 5361cb0ef41Sopenharmony_ci int value = eh_frame_iterator.GetNextByte() * 5371cb0ef41Sopenharmony_ci EhFrameConstants::kCodeAlignmentFactor; 5381cb0ef41Sopenharmony_ci offset_in_procedure += value; 5391cb0ef41Sopenharmony_ci stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value 5401cb0ef41Sopenharmony_ci << ")\n"; 5411cb0ef41Sopenharmony_ci break; 5421cb0ef41Sopenharmony_ci } 5431cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kAdvanceLoc2: { 5441cb0ef41Sopenharmony_ci int value = eh_frame_iterator.GetNextUInt16() * 5451cb0ef41Sopenharmony_ci EhFrameConstants::kCodeAlignmentFactor; 5461cb0ef41Sopenharmony_ci offset_in_procedure += value; 5471cb0ef41Sopenharmony_ci stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value 5481cb0ef41Sopenharmony_ci << ")\n"; 5491cb0ef41Sopenharmony_ci break; 5501cb0ef41Sopenharmony_ci } 5511cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kAdvanceLoc4: { 5521cb0ef41Sopenharmony_ci int value = eh_frame_iterator.GetNextUInt32() * 5531cb0ef41Sopenharmony_ci EhFrameConstants::kCodeAlignmentFactor; 5541cb0ef41Sopenharmony_ci offset_in_procedure += value; 5551cb0ef41Sopenharmony_ci stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value 5561cb0ef41Sopenharmony_ci << ")\n"; 5571cb0ef41Sopenharmony_ci break; 5581cb0ef41Sopenharmony_ci } 5591cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kDefCfa: { 5601cb0ef41Sopenharmony_ci uint32_t base_register = eh_frame_iterator.GetNextULeb128(); 5611cb0ef41Sopenharmony_ci uint32_t base_offset = eh_frame_iterator.GetNextULeb128(); 5621cb0ef41Sopenharmony_ci stream << "| base_register=" << DwarfRegisterCodeToString(base_register) 5631cb0ef41Sopenharmony_ci << ", base_offset=" << base_offset << '\n'; 5641cb0ef41Sopenharmony_ci break; 5651cb0ef41Sopenharmony_ci } 5661cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kDefCfaOffset: { 5671cb0ef41Sopenharmony_ci stream << "| base_offset=" << eh_frame_iterator.GetNextULeb128() 5681cb0ef41Sopenharmony_ci << '\n'; 5691cb0ef41Sopenharmony_ci break; 5701cb0ef41Sopenharmony_ci } 5711cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kDefCfaRegister: { 5721cb0ef41Sopenharmony_ci stream << "| base_register=" 5731cb0ef41Sopenharmony_ci << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128()) 5741cb0ef41Sopenharmony_ci << '\n'; 5751cb0ef41Sopenharmony_ci break; 5761cb0ef41Sopenharmony_ci } 5771cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kSameValue: { 5781cb0ef41Sopenharmony_ci stream << "| " 5791cb0ef41Sopenharmony_ci << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128()) 5801cb0ef41Sopenharmony_ci << " not modified from previous frame\n"; 5811cb0ef41Sopenharmony_ci break; 5821cb0ef41Sopenharmony_ci } 5831cb0ef41Sopenharmony_ci case EhFrameConstants::DwarfOpcodes::kNop: 5841cb0ef41Sopenharmony_ci stream << "| nop\n"; 5851cb0ef41Sopenharmony_ci break; 5861cb0ef41Sopenharmony_ci default: 5871cb0ef41Sopenharmony_ci UNREACHABLE(); 5881cb0ef41Sopenharmony_ci } 5891cb0ef41Sopenharmony_ci } 5901cb0ef41Sopenharmony_ci} 5911cb0ef41Sopenharmony_ci 5921cb0ef41Sopenharmony_civoid EhFrameDisassembler::DisassembleToStream(std::ostream& stream) { 5931cb0ef41Sopenharmony_ci // The encoded CIE size does not include the size field itself. 5941cb0ef41Sopenharmony_ci const int cie_size = 5951cb0ef41Sopenharmony_ci base::ReadUnalignedValue<uint32_t>(reinterpret_cast<Address>(start_)) + 5961cb0ef41Sopenharmony_ci kInt32Size; 5971cb0ef41Sopenharmony_ci const int fde_offset = cie_size; 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci const byte* cie_directives_start = 6001cb0ef41Sopenharmony_ci start_ + EhFrameConstants::kInitialStateOffsetInCie; 6011cb0ef41Sopenharmony_ci const byte* cie_directives_end = start_ + cie_size; 6021cb0ef41Sopenharmony_ci DCHECK_LE(cie_directives_start, cie_directives_end); 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci stream << reinterpret_cast<const void*>(start_) << " .eh_frame: CIE\n"; 6051cb0ef41Sopenharmony_ci DumpDwarfDirectives(stream, cie_directives_start, cie_directives_end); 6061cb0ef41Sopenharmony_ci 6071cb0ef41Sopenharmony_ci Address procedure_offset_address = 6081cb0ef41Sopenharmony_ci reinterpret_cast<Address>(start_) + fde_offset + 6091cb0ef41Sopenharmony_ci EhFrameConstants::kProcedureAddressOffsetInFde; 6101cb0ef41Sopenharmony_ci int32_t procedure_offset = 6111cb0ef41Sopenharmony_ci base::ReadUnalignedValue<int32_t>(procedure_offset_address); 6121cb0ef41Sopenharmony_ci 6131cb0ef41Sopenharmony_ci Address procedure_size_address = reinterpret_cast<Address>(start_) + 6141cb0ef41Sopenharmony_ci fde_offset + 6151cb0ef41Sopenharmony_ci EhFrameConstants::kProcedureSizeOffsetInFde; 6161cb0ef41Sopenharmony_ci uint32_t procedure_size = 6171cb0ef41Sopenharmony_ci base::ReadUnalignedValue<uint32_t>(procedure_size_address); 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ci const byte* fde_start = start_ + fde_offset; 6201cb0ef41Sopenharmony_ci stream << reinterpret_cast<const void*>(fde_start) << " .eh_frame: FDE\n" 6211cb0ef41Sopenharmony_ci << reinterpret_cast<const void*>(procedure_offset_address) 6221cb0ef41Sopenharmony_ci << " | procedure_offset=" << procedure_offset << '\n' 6231cb0ef41Sopenharmony_ci << reinterpret_cast<const void*>(procedure_size_address) 6241cb0ef41Sopenharmony_ci << " | procedure_size=" << procedure_size << '\n'; 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci const int fde_directives_offset = fde_offset + 4 * kInt32Size + 1; 6271cb0ef41Sopenharmony_ci 6281cb0ef41Sopenharmony_ci const byte* fde_directives_start = start_ + fde_directives_offset; 6291cb0ef41Sopenharmony_ci const byte* fde_directives_end = end_ - EhFrameConstants::kEhFrameHdrSize - 6301cb0ef41Sopenharmony_ci EhFrameConstants::kEhFrameTerminatorSize; 6311cb0ef41Sopenharmony_ci DCHECK_LE(fde_directives_start, fde_directives_end); 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_ci DumpDwarfDirectives(stream, fde_directives_start, fde_directives_end); 6341cb0ef41Sopenharmony_ci 6351cb0ef41Sopenharmony_ci const byte* fde_terminator_start = fde_directives_end; 6361cb0ef41Sopenharmony_ci stream << reinterpret_cast<const void*>(fde_terminator_start) 6371cb0ef41Sopenharmony_ci << " .eh_frame: terminator\n"; 6381cb0ef41Sopenharmony_ci 6391cb0ef41Sopenharmony_ci const byte* eh_frame_hdr_start = 6401cb0ef41Sopenharmony_ci fde_terminator_start + EhFrameConstants::kEhFrameTerminatorSize; 6411cb0ef41Sopenharmony_ci stream << reinterpret_cast<const void*>(eh_frame_hdr_start) 6421cb0ef41Sopenharmony_ci << " .eh_frame_hdr\n"; 6431cb0ef41Sopenharmony_ci} 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci#endif 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci} // namespace internal 6481cb0ef41Sopenharmony_ci} // namespace v8 649