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, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits