8 #include "src/base/compiler-specific.h" 9 #include "src/globals.h" 10 #include "src/macro-assembler.h" 11 #include "src/zone/zone-containers.h" 17 :
public NON_EXPORTED_BASE(AllStatic) {
19 enum class DwarfOpcodes : byte {
26 kDefCfaRegister = 0x0d,
28 kOffsetExtendedSf = 0x11,
31 enum DwarfEncodingSpecifiers : byte {
39 static const int kLocationTag = 1;
40 static const int kLocationMask = 0x3f;
41 static const int kLocationMaskSize = 6;
43 static const int kSavedRegisterTag = 2;
44 static const int kSavedRegisterMask = 0x3f;
45 static const int kSavedRegisterMaskSize = 6;
47 static const int kFollowInitialRuleTag = 3;
48 static const int kFollowInitialRuleMask = 0x3f;
49 static const int kFollowInitialRuleMaskSize = 6;
51 static const int kProcedureAddressOffsetInFde = 2 * kInt32Size;
52 static const int kProcedureSizeOffsetInFde = 3 * kInt32Size;
54 static const int kInitialStateOffsetInCie = 19;
55 static const int kEhFrameTerminatorSize = 4;
58 static const int kCodeAlignmentFactor;
59 static const int kDataAlignmentFactor;
61 static const int kFdeVersionSize = 1;
62 static const int kFdeEncodingSpecifiersSize = 3;
64 static const int kEhFrameHdrVersion = 1;
65 static const int kEhFrameHdrSize = 20;
77 static void WriteEmptyEhFrame(std::ostream& stream);
82 void AdvanceLocation(
int pc_offset);
89 void SetBaseAddressRegister(
Register base_register);
90 void SetBaseAddressOffset(
int base_offset);
91 void IncreaseBaseAddressOffset(
int base_delta) {
92 SetBaseAddressOffset(base_offset_ + base_delta);
94 void SetBaseAddressRegisterAndOffset(
Register base_register,
int base_offset);
98 void RecordRegisterSavedToStack(
Register name,
int offset) {
99 RecordRegisterSavedToStack(RegisterToDwarfCode(name), offset);
103 void RecordRegisterNotModified(
Register name);
106 void RecordRegisterFollowsInitialRule(
Register name);
108 void Finish(
int code_size);
117 int last_pc_offset()
const {
return last_pc_offset_; }
118 Register base_register()
const {
return base_register_; }
119 int base_offset()
const {
return base_offset_; }
122 enum class InternalState { kUndefined, kInitialized, kFinalized };
124 static const uint32_t kInt32Placeholder = 0xdeadc0de;
126 void WriteSLeb128(int32_t value);
129 void WriteByte(byte value) { eh_frame_buffer_.push_back(value); }
130 void WriteOpcode(EhFrameConstants::DwarfOpcodes opcode) {
131 WriteByte(static_cast<byte>(opcode));
133 void WriteBytes(
const byte* start,
int size) {
134 eh_frame_buffer_.insert(eh_frame_buffer_.end(), start, start + size);
136 void WriteInt16(uint16_t value) {
137 WriteBytes(reinterpret_cast<const byte*>(&value),
sizeof(value));
140 WriteBytes(reinterpret_cast<const byte*>(&value),
sizeof(value));
142 void PatchInt32(
int base_offset,
uint32_t value) {
144 ReadUnalignedUInt32(reinterpret_cast<Address>(eh_frame_buffer_.data()) +
147 DCHECK_LT(base_offset + kInt32Size, eh_frame_offset());
148 WriteUnalignedUInt32(
149 reinterpret_cast<Address>(eh_frame_buffer_.data()) + base_offset,
160 void WriteFdeHeader();
164 void WriteEhFrameHdr(
int code_size);
167 void WritePaddingToAlignedSize(
int unpadded_size);
171 void RecordRegisterSavedToStack(
int register_code,
int offset);
173 int GetProcedureAddressOffset()
const {
174 return fde_offset() + EhFrameConstants::kProcedureAddressOffsetInFde;
177 int GetProcedureSizeOffset()
const {
178 return fde_offset() + EhFrameConstants::kProcedureSizeOffsetInFde;
181 int eh_frame_offset()
const {
182 return static_cast<int>(eh_frame_buffer_.size());
185 int fde_offset()
const {
return cie_size_; }
189 static int RegisterToDwarfCode(
Register name);
192 void WriteInitialStateInCie();
195 void WriteReturnAddressRegisterCode();
199 InternalState writer_state_;
210 : start_(start), next_(start), end_(end) {
211 DCHECK_LE(start, end);
215 DCHECK_EQ(next_, start_);
216 next_ += ReadUnalignedUInt32(reinterpret_cast<Address>(next_)) + kInt32Size;
219 void SkipToFdeDirectives() {
222 Skip(kDirectivesOffsetInFde);
225 void Skip(
int how_many) {
226 DCHECK_GE(how_many, 0);
228 DCHECK_LE(next_, end_);
231 uint32_t GetNextUInt32() {
return GetNextValue<uint32_t>(); }
232 uint16_t GetNextUInt16() {
return GetNextValue<uint16_t>(); }
233 byte GetNextByte() {
return GetNextValue<byte>(); }
234 EhFrameConstants::DwarfOpcodes GetNextOpcode() {
235 return static_cast<EhFrameConstants::DwarfOpcodes
>(GetNextByte());
239 int32_t GetNextSLeb128();
242 DCHECK_LE(next_, end_);
243 return next_ == end_;
246 int GetCurrentOffset()
const {
247 DCHECK_GE(next_, start_);
248 return static_cast<int>(next_ - start_);
251 int GetBufferSize() {
return static_cast<int>(end_ - start_); }
253 const void* current_address()
const {
254 return reinterpret_cast<const void*
>(next_);
258 static const int kDirectivesOffsetInFde = 4 * kInt32Size + 1;
260 static uint32_t DecodeULeb128(
const byte* encoded,
int* encoded_size);
261 static int32_t DecodeSLeb128(
const byte* encoded,
int* encoded_size);
263 template <
typename T>
266 DCHECK_LE(next_ +
sizeof(result), end_);
267 result = ReadUnalignedValue<T>(
reinterpret_cast<Address>(next_));
268 next_ +=
sizeof(result);
277 #ifdef ENABLE_DISASSEMBLER 279 class EhFrameDisassembler final {
281 EhFrameDisassembler(
const byte* start,
const byte* end)
282 : start_(start), end_(end) {
283 DCHECK_LT(start, end);
286 void DisassembleToStream(std::ostream& stream);
289 static void DumpDwarfDirectives(std::ostream& stream,
290 const byte* start,
const byte* end);
292 static const char* DwarfRegisterCodeToString(
int code);
297 DISALLOW_COPY_AND_ASSIGN(EhFrameDisassembler);
305 #endif // V8_EH_FRAME_H_