[Lldb-commits] [lldb] r271774 - Add armv7 compact unwind printing to the compact-unwind-dumper.c tool
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 3 21:10:15 PDT 2016
Author: jmolenda
Date: Fri Jun 3 23:10:15 2016
New Revision: 271774
URL: http://llvm.org/viewvc/llvm-project?rev=271774&view=rev
Log:
Add armv7 compact unwind printing to the compact-unwind-dumper.c tool
as a prototype for adding armv7 compact unwind reading to lldb.
Modified:
lldb/trunk/tools/compact-unwind/compact-unwind-dumper.c
Modified: lldb/trunk/tools/compact-unwind/compact-unwind-dumper.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/compact-unwind/compact-unwind-dumper.c?rev=271774&r1=271773&r2=271774&view=diff
==============================================================================
--- lldb/trunk/tools/compact-unwind/compact-unwind-dumper.c (original)
+++ lldb/trunk/tools/compact-unwind/compact-unwind-dumper.c Fri Jun 3 23:10:15 2016
@@ -35,6 +35,28 @@ enum {
UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
+enum {
+ UNWIND_ARM_MODE_MASK = 0x0F000000,
+ UNWIND_ARM_MODE_FRAME = 0x01000000,
+ UNWIND_ARM_MODE_FRAME_D = 0x02000000,
+ UNWIND_ARM_MODE_DWARF = 0x04000000,
+
+ UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
+
+ UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
+
+ UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
+
+ UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
+
+ UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+};
#define EXTRACT_BITS(value, mask) \
( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
@@ -218,12 +240,14 @@ scan_macho_load_commands (struct baton *
if (is_64bit)
{
struct section_64 sect;
+ memset (§, 0, sizeof (struct section_64));
memcpy (§, offset, sizeof (struct section_64));
baton->compact_unwind_start = baton->mach_header_start + sect.offset;
}
else
{
struct section sect;
+ memset (§, 0, sizeof (struct section));
memcpy (§, offset, sizeof (struct section));
baton->compact_unwind_start = baton->mach_header_start + sect.offset;
}
@@ -233,12 +257,14 @@ scan_macho_load_commands (struct baton *
if (is_64bit)
{
struct section_64 sect;
+ memset (§, 0, sizeof (struct section_64));
memcpy (§, offset, sizeof (struct section_64));
baton->eh_section_file_address = sect.addr;
}
else
{
struct section sect;
+ memset (§, 0, sizeof (struct section));
memcpy (§, offset, sizeof (struct section));
baton->eh_section_file_address = sect.addr;
}
@@ -248,6 +274,7 @@ scan_macho_load_commands (struct baton *
if (is_64bit)
{
struct section_64 sect;
+ memset (§, 0, sizeof (struct section_64));
memcpy (§, offset, sizeof (struct section_64));
baton->text_section_vmaddr = sect.addr;
baton->text_section_file_offset = sect.offset;
@@ -255,6 +282,7 @@ scan_macho_load_commands (struct baton *
else
{
struct section sect;
+ memset (§, 0, sizeof (struct section));
memcpy (§, offset, sizeof (struct section));
baton->text_section_vmaddr = sect.addr;
}
@@ -305,6 +333,7 @@ scan_macho_load_commands (struct baton *
for (int i = 0; i < local_syms_count; i++)
{
struct nlist_64 nlist;
+ memset (&nlist, 0, sizeof (struct nlist_64));
if (is_64bit)
{
memcpy (&nlist, local_syms + (i * nlist_size), sizeof (struct nlist_64));
@@ -312,6 +341,7 @@ scan_macho_load_commands (struct baton *
else
{
struct nlist nlist_32;
+ memset (&nlist_32, 0, sizeof (struct nlist));
memcpy (&nlist_32, local_syms + (i * nlist_size), sizeof (struct nlist));
nlist.n_un.n_strx = nlist_32.n_un.n_strx;
nlist.n_type = nlist_32.n_type;
@@ -326,6 +356,8 @@ scan_macho_load_commands (struct baton *
&& nlist.n_value != baton->text_segment_vmaddr)
{
baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
baton->symbols_count++;
}
@@ -334,6 +366,7 @@ scan_macho_load_commands (struct baton *
for (int i = 0; i < exported_syms_count; i++)
{
struct nlist_64 nlist;
+ memset (&nlist, 0, sizeof (struct nlist_64));
if (is_64bit)
{
memcpy (&nlist, exported_syms + (i * nlist_size), sizeof (struct nlist_64));
@@ -355,6 +388,8 @@ scan_macho_load_commands (struct baton *
&& nlist.n_value != baton->text_segment_vmaddr)
{
baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
baton->symbols_count++;
}
@@ -410,6 +445,8 @@ scan_macho_load_commands (struct baton *
{
struct symbol search_key;
search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
if (sym == NULL)
unnamed_functions_to_add++;
@@ -423,6 +460,8 @@ scan_macho_load_commands (struct baton *
{
struct symbol search_key;
search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
if (sym == NULL)
{
@@ -1045,6 +1084,159 @@ print_encoding_arm64 (struct baton baton
}
}
+void
+print_encoding_armv7 (struct baton baton, uint8_t *function_start, uint32_t encoding)
+{
+ const int wordsize = 4;
+ int mode = encoding & UNWIND_ARM_MODE_MASK;
+ switch (mode)
+ {
+ case UNWIND_ARM_MODE_FRAME_D:
+ case UNWIND_ARM_MODE_FRAME:
+ {
+ int stack_adjust = EXTRACT_BITS (mode, UNWIND_ARM_FRAME_STACK_ADJUST_MASK);
+
+ printf ("frame func: CFA is fp+%d ", (2 * wordsize) + stack_adjust);
+ int cfa_offset = -stack_adjust;
+
+ cfa_offset -= wordsize;
+ printf (" pc=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf (" fp=[CFA%d]", cfa_offset);
+
+ uint32_t saved_register_bits = encoding & 0xff;
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6)
+ {
+ cfa_offset -= wordsize;
+ printf (" r6=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5)
+ {
+ cfa_offset -= wordsize;
+ printf (" r5=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4)
+ {
+ cfa_offset -= wordsize;
+ printf (" r4=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12)
+ {
+ cfa_offset -= wordsize;
+ printf (" r12=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11)
+ {
+ cfa_offset -= wordsize;
+ printf (" r11=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10)
+ {
+ cfa_offset -= wordsize;
+ printf (" r10=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9)
+ {
+ cfa_offset -= wordsize;
+ printf (" r9=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8)
+ {
+ cfa_offset -= wordsize;
+ printf (" r8=[CFA%d]", cfa_offset);
+ }
+
+ if (mode & UNWIND_ARM_MODE_FRAME_D)
+ {
+ uint32_t d_reg_bits = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
+ switch (d_reg_bits)
+ {
+ case 0:
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 1:
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 2:
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 3:
+ // vpush {d14}
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf (" d14=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf (" d8=[CFA%d]", cfa_offset);
+ break;
+ case 4:
+ // vpush {d14}
+ // vpush {d12}
+ // sp = (sp - 24) & (-16);
+ // vst {d8, d9, d10}
+ printf (" d14, d12, d10, d9, d8");
+ break;
+ case 5:
+ // vpush {d14}
+ // sp = (sp - 40) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12}
+ printf (" d14, d11, d10, d9, d8, d12");
+ break;
+ case 6:
+ // sp = (sp - 56) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14}
+ printf (" d11, d10, d9, d8, d14, d13, d12");
+ break;
+ case 7:
+ // sp = (sp - 64) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14, d15}
+ printf (" d11, d10, d9, d8, d15, d14, d13, d12");
+ break;
+ }
+ }
+ }
+ break;
+
+ case UNWIND_ARM_MODE_DWARF:
+ {
+ uint32_t dwarf_offset = encoding & UNWIND_ARM_DWARF_SECTION_OFFSET;
+ printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ }
+ break;
+
+ case 0:
+ {
+ printf (" no unwind information");
+ }
+ break;
+ }
+}
+
+
void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encoding)
@@ -1062,6 +1254,10 @@ void print_encoding (struct baton baton,
{
print_encoding_arm64 (baton, function_start, encoding);
}
+ else if (baton.cputype == CPU_TYPE_ARM)
+ {
+ print_encoding_armv7 (baton, function_start, encoding);
+ }
else
{
printf (" -- unsupported encoding arch -- ");
@@ -1084,6 +1280,9 @@ print_function_encoding (struct baton ba
uint64_t file_address = baton.first_level_index_entry.functionOffset + entry_func_offset + baton.text_segment_vmaddr;
+ if (baton.cputype == CPU_TYPE_ARM)
+ file_address = file_address & ~1;
+
printf (" func [%d] offset %d (file addr 0x%" PRIx64 ")%s, encoding is 0x%x",
idx, entry_func_offset,
file_address,
More information about the lldb-commits
mailing list