diff -rup binutils-2.29.1/binutils/dwarf.c binutils-2.29.1-new/binutils/dwarf.c --- binutils-2.29.1/binutils/dwarf.c 2017-09-14 02:30:59.000000000 -0700 +++ binutils-2.29.1-new/binutils/dwarf.c 2017-12-05 16:42:59.548836797 -0800 @@ -6225,7 +6225,7 @@ typedef struct Frame_Chunk int data_factor; dwarf_vma pc_begin; dwarf_vma pc_range; - int cfa_reg; + unsigned int cfa_reg; dwarf_vma cfa_offset; unsigned int ra; unsigned char fde_encoding; @@ -6568,13 +6568,13 @@ frame_display_row (Frame_Chunk *fc, int static unsigned char * read_cie (unsigned char *start, unsigned char *end, Frame_Chunk **p_cie, int *p_version, - unsigned long *p_aug_len, unsigned char **p_aug) + bfd_size_type *p_aug_len, unsigned char **p_aug) { int version; Frame_Chunk *fc; unsigned int length_return; unsigned char *augmentation_data = NULL; - unsigned long augmentation_data_len = 0; + bfd_size_type augmentation_data_len = 0; * p_cie = NULL; /* PR 17512: file: 001-228113-0.004. */ @@ -6643,14 +6643,15 @@ read_cie (unsigned char *start, unsigned { READ_ULEB (augmentation_data_len); augmentation_data = start; - start += augmentation_data_len; /* PR 17512: file: 11042-2589-0.004. */ - if (start > end) + if (augmentation_data_len > (bfd_size_type) (end - start)) { - warn (_("Augmentation data too long: %#lx, expected at most %#lx\n"), - augmentation_data_len, (long)((end - start) + augmentation_data_len)); + warn (_("Augmentation data too long: 0x%s, expected at most %#lx\n"), + dwarf_vmatoa ("x", augmentation_data_len), + (unsigned long) (end - start)); return end; } + start += augmentation_data_len; } if (augmentation_data_len) @@ -6663,14 +6664,7 @@ read_cie (unsigned char *start, unsigned q = augmentation_data; qend = q + augmentation_data_len; - /* PR 17531: file: 015adfaa. */ - if (qend < q) - { - warn (_("Negative augmentation data length: 0x%lx"), augmentation_data_len); - augmentation_data_len = 0; - } - - while (p < end && q < augmentation_data + augmentation_data_len) + while (p < end && q < qend) { if (*p == 'L') q++; @@ -6699,6 +6693,31 @@ read_cie (unsigned char *start, unsigned return start; } +/* Prints out the contents on the augmentation data array. + If do_wide is not enabled, then formats the output to fit into 80 columns. */ + +static void +display_augmentation_data (const unsigned char * data, const bfd_size_type len) +{ + bfd_size_type i; + + i = printf (_(" Augmentation data: ")); + + if (do_wide || len < ((80 - i) / 3)) + for (i = 0; i < len; ++i) + printf (" %02x", data[i]); + else + { + for (i = 0; i < len; ++i) + { + if (i % (80 / 3) == 0) + putchar ('\n'); + printf (" %02x", data[i]); + } + } + putchar ('\n'); +} + static int display_debug_frames (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED) @@ -6727,7 +6746,7 @@ display_debug_frames (struct dwarf_secti Frame_Chunk *cie; int need_col_headers = 1; unsigned char *augmentation_data = NULL; - unsigned long augmentation_data_len = 0; + bfd_size_type augmentation_data_len = 0; unsigned int encoded_ptr_size = saved_eh_addr_size; unsigned int offset_size; unsigned int initial_length_size; @@ -6821,16 +6840,8 @@ display_debug_frames (struct dwarf_secti printf (" Return address column: %d\n", fc->ra); if (augmentation_data_len) - { - unsigned long i; + display_augmentation_data (augmentation_data, augmentation_data_len); - printf (" Augmentation data: "); - for (i = 0; i < augmentation_data_len; ++i) - /* FIXME: If do_wide is FALSE, then we should - add carriage returns at 80 columns... */ - printf (" %02x", augmentation_data[i]); - putchar ('\n'); - } putchar ('\n'); } } @@ -6986,11 +6997,13 @@ display_debug_frames (struct dwarf_secti READ_ULEB (augmentation_data_len); augmentation_data = start; start += augmentation_data_len; - /* PR 17512: file: 722-8446-0.004. */ - if (start >= end || ((signed long) augmentation_data_len) < 0) + /* PR 17512 file: 722-8446-0.004 and PR 22386. */ + if (start >= end + || ((bfd_signed_vma) augmentation_data_len) < 0 + || augmentation_data > start) { - warn (_("Corrupt augmentation data length: %lx\n"), - augmentation_data_len); + warn (_("Corrupt augmentation data length: 0x%s\n"), + dwarf_vmatoa ("x", augmentation_data_len)); start = end; augmentation_data = NULL; augmentation_data_len = 0; @@ -7012,12 +7025,7 @@ display_debug_frames (struct dwarf_secti if (! do_debug_frames_interp && augmentation_data_len) { - unsigned long i; - - printf (" Augmentation data: "); - for (i = 0; i < augmentation_data_len; ++i) - printf (" %02x", augmentation_data[i]); - putchar ('\n'); + display_augmentation_data (augmentation_data, augmentation_data_len); putchar ('\n'); } } @@ -7449,7 +7457,7 @@ display_debug_frames (struct dwarf_secti break; case DW_CFA_def_cfa: - READ_SLEB (fc->cfa_reg); + READ_ULEB (fc->cfa_reg); READ_ULEB (fc->cfa_offset); fc->cfa_exp = 0; if (! do_debug_frames_interp) @@ -7458,7 +7466,7 @@ display_debug_frames (struct dwarf_secti break; case DW_CFA_def_cfa_register: - READ_SLEB (fc->cfa_reg); + READ_ULEB (fc->cfa_reg); fc->cfa_exp = 0; if (! do_debug_frames_interp) printf (" DW_CFA_def_cfa_register: %s\n", @@ -7577,7 +7585,7 @@ display_debug_frames (struct dwarf_secti break; case DW_CFA_def_cfa_sf: - READ_SLEB (fc->cfa_reg); + READ_ULEB (fc->cfa_reg); READ_ULEB (fc->cfa_offset); fc->cfa_offset = fc->cfa_offset * fc->data_factor; fc->cfa_exp = 0;