12#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM) && \
13 !defined(V8_TARGET_ARCH_ARM64) && !defined(V8_TARGET_ARCH_S390X) && \
14 !defined(V8_TARGET_ARCH_PPC64)
32#ifdef ENABLE_DISASSEMBLER
34const char* EhFrameDisassembler::DwarfRegisterCodeToString(
int) {
70 stream.write(&dummy_data[0],
sizeof(dummy_data));
79 eh_frame_buffer_(zone) {}
90 static const int kCIEIdentifier = 0;
91 static const int kCIEVersion = 3;
92 static const int kAugmentationDataSize = 2;
93 static const uint8_t kAugmentationString[] = {
'z',
'L',
'R', 0};
105 WriteBytes(&kAugmentationString[0],
sizeof(kAugmentationString));
128 int encoded_cie_size = record_end_offset - record_start_offset;
129 cie_size_ = record_end_offset - size_offset;
246 static const uint8_t
kPadding[] = {nop, nop, nop, nop, nop, nop, nop, nop};
263 }
else if (factored_delta <=
kMaxUInt8) {
310 if (factored_offset >= 0) {
384 uint8_t chunk = value & 0x7F;
386 if (value != 0) chunk |= 0x80;
388 }
while (value != 0);
392 static const int kSignBitMask = 0x40;
395 uint8_t chunk = value & 0x7F;
397 done = ((value == 0) && ((chunk & kSignBitMask) == 0)) ||
398 ((value == -1) && ((chunk & kSignBitMask) != 0));
399 if (!done) chunk |= 0x80;
423 const uint8_t* current = encoded;
429 result |= (*current & 0x7F) << shift;
431 }
while (*current++ >= 128);
434 *encoded_size =
static_cast<int>(current - encoded);
442 static const uint8_t kSignBitMask = 0x40;
444 const uint8_t* current = encoded;
452 result |= (chunk & 0x7F) << shift;
454 }
while (chunk >= 128);
457 if (chunk & kSignBitMask)
result |= (~0ull) << shift;
460 *encoded_size =
static_cast<int>(current - encoded);
465#ifdef ENABLE_DISASSEMBLER
471 explicit StreamModifiersScope(std::ostream* stream)
472 : stream_(stream),
flags_(stream->flags()) {}
473 ~StreamModifiersScope() { stream_->flags(
flags_); }
476 std::ostream* stream_;
477 std::ios::fmtflags
flags_;
483void EhFrameDisassembler::DumpDwarfDirectives(std::ostream& stream,
484 const uint8_t*
start,
485 const uint8_t*
end) {
486 StreamModifiersScope modifiers_scope(&stream);
488 EhFrameIterator eh_frame_iterator(
start,
end);
489 uint32_t offset_in_procedure = 0;
491 while (!eh_frame_iterator.Done()) {
492 stream << eh_frame_iterator.current_address() <<
" ";
494 uint8_t bytecode = eh_frame_iterator.GetNextByte();
500 offset_in_procedure +=
value;
501 stream <<
"| pc_offset=" << offset_in_procedure <<
" (delta=" << value
508 int32_t decoded_offset = eh_frame_iterator.GetNextULeb128();
510 << DwarfRegisterCodeToString(bytecode &
512 <<
" saved at base" << std::showpos
514 << std::noshowpos <<
'\n';
521 << DwarfRegisterCodeToString(bytecode &
523 <<
" follows rule in CIE\n";
530 << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128());
531 int32_t decoded_offset = eh_frame_iterator.GetNextSLeb128();
532 stream <<
" saved at base" << std::showpos
534 << std::noshowpos <<
'\n';
538 int value = eh_frame_iterator.GetNextByte() *
540 offset_in_procedure +=
value;
541 stream <<
"| pc_offset=" << offset_in_procedure <<
" (delta=" << value
546 int value = eh_frame_iterator.GetNextUInt16() *
548 offset_in_procedure +=
value;
549 stream <<
"| pc_offset=" << offset_in_procedure <<
" (delta=" << value
554 int value = eh_frame_iterator.GetNextUInt32() *
556 offset_in_procedure +=
value;
557 stream <<
"| pc_offset=" << offset_in_procedure <<
" (delta=" << value
562 uint32_t base_register = eh_frame_iterator.GetNextULeb128();
563 uint32_t base_offset = eh_frame_iterator.GetNextULeb128();
564 stream <<
"| base_register=" << DwarfRegisterCodeToString(base_register)
565 <<
", base_offset=" << base_offset <<
'\n';
569 stream <<
"| base_offset=" << eh_frame_iterator.GetNextULeb128()
574 stream <<
"| base_register="
575 << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128())
581 << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128())
582 <<
" not modified from previous frame\n";
594void EhFrameDisassembler::DisassembleToStream(std::ostream& stream) {
599 const int fde_offset = cie_size;
601 const uint8_t* cie_directives_start =
603 const uint8_t* cie_directives_end =
start_ + cie_size;
604 DCHECK_LE(cie_directives_start, cie_directives_end);
606 stream << reinterpret_cast<const void*>(
start_) <<
" .eh_frame: CIE\n";
607 DumpDwarfDirectives(stream, cie_directives_start, cie_directives_end);
609 Address procedure_offset_address =
618 uint32_t procedure_size =
621 const uint8_t* fde_start =
start_ + fde_offset;
622 stream << reinterpret_cast<const void*>(fde_start) <<
" .eh_frame: FDE\n"
623 <<
reinterpret_cast<const void*
>(procedure_offset_address)
624 <<
" | procedure_offset=" << procedure_offset <<
'\n'
625 <<
reinterpret_cast<const void*
>(procedure_size_address)
626 <<
" | procedure_size=" << procedure_size <<
'\n';
628 const int fde_directives_offset = fde_offset + 4 *
kInt32Size + 1;
630 const uint8_t* fde_directives_start =
start_ + fde_directives_offset;
633 DCHECK_LE(fde_directives_start, fde_directives_end);
635 DumpDwarfDirectives(stream, fde_directives_start, fde_directives_end);
637 const uint8_t* fde_terminator_start = fde_directives_end;
638 stream << reinterpret_cast<const void*>(fde_terminator_start)
639 <<
" .eh_frame: terminator\n";
641 const uint8_t* eh_frame_hdr_start =
643 stream << reinterpret_cast<const void*>(eh_frame_hdr_start)
644 <<
" .eh_frame_hdr\n";
static const int kLocationMask
static const int kFollowInitialRuleTag
static const int kProcedureSizeOffsetInFde
static const int kSavedRegisterMaskSize
static const int kEhFrameTerminatorSize
static const int kFdeVersionSize
static const int kInitialStateOffsetInCie
static const int kSavedRegisterTag
static const int kLocationMaskSize
static const int kLocationTag
static const int kSavedRegisterMask
static const int kFollowInitialRuleMaskSize
static const int kDataAlignmentFactor
static const int kEhFrameHdrSize
static const int kProcedureAddressOffsetInFde
static const int kCodeAlignmentFactor
static const int kEhFrameHdrVersion
static const int kFdeEncodingSpecifiersSize
static const int kFollowInitialRuleMask
static int32_t DecodeSLeb128(const uint8_t *encoded, int *encoded_size)
static uint32_t DecodeULeb128(const uint8_t *encoded, int *encoded_size)
uint32_t GetNextULeb128()
int GetProcedureAddressOffset() const
void WriteEhFrameHdr(int code_size)
void SetBaseAddressOffset(int base_offset)
void WritePaddingToAlignedSize(int unpadded_size)
void WriteBytes(const uint8_t *start, int size)
void SetBaseAddressRegisterAndOffset(Register base_register, int base_offset)
static int RegisterToDwarfCode(Register name)
void WriteOpcode(EhFrameConstants::DwarfOpcodes opcode)
void WriteSLeb128(int32_t value)
void WriteInitialStateInCie()
void WriteByte(uint8_t value)
EhFrameWriter(Zone *zone)
void WriteReturnAddressRegisterCode()
void PatchInt32(int base_offset, uint32_t value)
void WriteInt16(uint16_t value)
ZoneVector< uint8_t > eh_frame_buffer_
void Finish(int code_size)
void AdvanceLocation(int pc_offset)
int GetProcedureSizeOffset() const
void GetEhFrame(CodeDesc *desc)
int eh_frame_offset() const
void RecordRegisterNotModified(Register name)
static void WriteEmptyEhFrame(std::ostream &stream)
static const uint32_t kInt32Placeholder
InternalState writer_state_
void SetBaseAddressRegister(Register base_register)
void RecordRegisterSavedToStack(Register name, int offset)
Register base_register() const
void RecordRegisterFollowsInitialRule(Register name)
void WriteULeb128(uint32_t value)
void WriteInt32(uint32_t value)
void reserve(size_t new_cap)
const v8::base::TimeTicks end_
ZoneVector< RpoNumber > & result
static V ReadUnalignedValue(Address p)
constexpr Register no_reg
constexpr int kSystemPointerSize
#define STATIC_CONST_MEMBER_DEFINITION
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
constexpr T RoundUp(T x, intptr_t m)