[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 (&sect, 0, sizeof (struct section_64));
                             memcpy (&sect, offset, sizeof (struct section_64));
                             baton->compact_unwind_start = baton->mach_header_start + sect.offset;
                         }
                         else
                         {
                             struct section sect;
+                            memset (&sect, 0, sizeof (struct section));
                             memcpy (&sect, 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 (&sect, 0, sizeof (struct section_64));
                             memcpy (&sect, offset, sizeof (struct section_64));
                             baton->eh_section_file_address = sect.addr;
                         }
                         else
                         {
                             struct section sect;
+                            memset (&sect, 0, sizeof (struct section));
                             memcpy (&sect, 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 (&sect, 0, sizeof (struct section_64));
                             memcpy (&sect, 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 (&sect, 0, sizeof (struct section));
                             memcpy (&sect, 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