35 if (prel31 & (1 << 30))
36 res |= 0xffffffff80000000ULL;
42 : file_address(f), address(a), data(d) {}
78 uint16_t offset)
const {
79 uint32_t value = data[offset / 4];
81 value = llvm::byteswap<uint32_t>(value);
82 return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
86 uint16_t max_offset)
const {
89 while (offset < max_offset) {
91 result |= (uint64_t)(
byte & 0x7f) << shift;
92 if ((
byte & 0x80) == 0)
108 uint16_t byte_count = 0;
109 uint16_t byte_offset = 0;
110 if (data[0] & 0x80000000) {
111 switch ((data[0] >> 24) & 0x0f) {
118 byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
126 byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
132 std::vector<std::pair<uint32_t, int32_t>>
135 while (byte_offset < byte_count) {
137 if ((byte1 & 0xc0) == 0x00) {
140 vsp += ((byte1 & 0x3f) << 2) + 4;
141 }
else if ((byte1 & 0xc0) == 0x40) {
144 vsp -= ((byte1 & 0x3f) << 2) + 4;
145 }
else if ((byte1 & 0xf0) == 0x80) {
146 if (byte_offset >= byte_count)
150 if (byte1 == 0x80 && byte2 == 0) {
158 uint16_t regs = ((byte1 & 0x0f) << 8) | byte2;
159 for (uint8_t i = 0; i < 12; ++i) {
160 if (regs & (1 << i)) {
161 register_offsets.emplace_back(
dwarf_r4 + i, vsp);
166 }
else if ((byte1 & 0xff) == 0x9d) {
170 }
else if ((byte1 & 0xff) == 0x9f) {
174 }
else if ((byte1 & 0xf0) == 0x90) {
177 vsp_reg =
dwarf_r0 + (byte1 & 0x0f);
178 }
else if ((byte1 & 0xf8) == 0xa0) {
181 uint8_t n = byte1 & 0x7;
182 for (uint8_t i = 0; i <= n; ++i) {
183 register_offsets.emplace_back(
dwarf_r4 + i, vsp);
186 }
else if ((byte1 & 0xf8) == 0xa8) {
189 uint8_t n = byte1 & 0x7;
190 for (uint8_t i = 0; i <= n; ++i) {
191 register_offsets.emplace_back(
dwarf_r4 + i, vsp);
195 register_offsets.emplace_back(
dwarf_lr, vsp);
197 }
else if ((byte1 & 0xff) == 0xb0) {
201 }
else if ((byte1 & 0xff) == 0xb1) {
202 if (byte_offset >= byte_count)
206 if ((byte2 & 0xff) == 0x00) {
210 }
else if ((byte2 & 0xf0) == 0x00) {
213 for (uint8_t i = 0; i < 4; ++i) {
214 if (byte2 & (1 << i)) {
215 register_offsets.emplace_back(
dwarf_r0 + i, vsp);
224 }
else if ((byte1 & 0xff) == 0xb2) {
227 uint64_t uleb128 =
GetULEB128(data, byte_offset, byte_count);
228 vsp += 0x204 + (uleb128 << 2);
229 }
else if ((byte1 & 0xff) == 0xb3) {
233 if (byte_offset >= byte_count)
237 uint8_t s = (byte2 & 0xf0) >> 4;
238 uint8_t c = (byte2 & 0x0f) >> 0;
239 for (uint8_t i = 0; i <= c; ++i) {
240 register_offsets.emplace_back(
dwarf_d0 + s + i, vsp);
244 }
else if ((byte1 & 0xfc) == 0xb4) {
248 }
else if ((byte1 & 0xf8) == 0xb8) {
252 uint8_t n = byte1 & 0x07;
253 for (uint8_t i = 0; i <= n; ++i) {
254 register_offsets.emplace_back(
dwarf_d8 + i, vsp);
258 }
else if ((byte1 & 0xf8) == 0xc0) {
275 }
else if ((byte1 & 0xff) == 0xc8) {
279 if (byte_offset >= byte_count)
283 uint8_t s = (byte2 & 0xf0) >> 4;
284 uint8_t c = (byte2 & 0x0f) >> 0;
285 for (uint8_t i = 0; i <= c; ++i) {
286 register_offsets.emplace_back(
dwarf_d16 + s + i, vsp);
289 }
else if ((byte1 & 0xff) == 0xc9) {
293 if (byte_offset >= byte_count)
297 uint8_t s = (byte2 & 0xf0) >> 4;
298 uint8_t c = (byte2 & 0x0f) >> 0;
299 for (uint8_t i = 0; i <= c; ++i) {
300 register_offsets.emplace_back(
dwarf_d0 + s + i, vsp);
303 }
else if ((byte1 & 0xf8) == 0xc8) {
307 }
else if ((byte1 & 0xf8) == 0xd0) {
311 uint8_t n = byte1 & 0x07;
312 for (uint8_t i = 0; i <= n; ++i) {
313 register_offsets.emplace_back(
dwarf_d8 + i, vsp);
316 }
else if ((byte1 & 0xc0) == 0xc0) {
326 row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
328 bool have_location_for_pc =
false;
329 for (
const auto &offset : register_offsets) {
330 have_location_for_pc |= offset.first ==
dwarf_pc;
331 row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp,
335 if (!have_location_for_pc) {
337 if (row->GetRegisterInfo(
dwarf_lr, lr_location))
338 row->SetRegisterInfo(
dwarf_pc, lr_location);
364 if (it->data & 0x80000000)
365 return (
const uint8_t *)&it->data;
static addr_t Prel31ToAddr(uint32_t prel31)
A section + offset based address class.
lldb::addr_t GetFileAddress() const
Get the file address.
bool GetUnwindPlan(Target &target, const Address &addr, UnwindPlan &unwind_plan)
const lldb::ByteOrder m_byte_order
const uint8_t * GetExceptionHandlingTableEntry(const Address &addr)
ArmUnwindInfo(ObjectFile &objfile, lldb::SectionSP &arm_exidx, lldb::SectionSP &arm_extab)
lldb::SectionSP m_arm_extab_sp
uint64_t GetULEB128(const uint32_t *data, uint16_t &offset, uint16_t max_offset) const
std::vector< ArmExidxEntry > m_exidx_entries
DataExtractor m_arm_exidx_data
uint8_t GetByteAtOffset(const uint32_t *data, uint16_t offset) const
DataExtractor m_arm_extab_data
lldb::SectionSP m_arm_exidx_sp
A plug-in interface definition class for object file parsers.
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void AppendRow(const RowSP &row_sp)
std::shared_ptr< Row > RowSP
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Section > SectionSP
@ eRegisterKindDWARF
the register numbers seen DWARF
ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d)
bool operator<(const ArmExidxEntry &other) const