From 67f101eece4327a7c9e13f257fe76f8082a5e336 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 4 Apr 2016 12:53:33 +0100 Subject: [PATCH] Ignore DWARF debug information with a version of 0 - assume that it is padding. PR 19872 bfd * dwarf2.c (parse_comp_unit): Skip warning about unrecognised version number if the version is zero. bin * dwarf.c (display_debug_aranges): Skip warning about unrecognised version number if the version is zero. --- bfd/ChangeLog | 6 ++ bfd/dwarf2.c | 34 ++++---- binutils/ChangeLog | 6 ++ binutils/dwarf.c | 7 +- ld/emultempl/pe.em | 92 +++++++++++----------- ld/pe-dll.c | 3 + sim/aarch64/simulator.c | 201 +++++++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 276 insertions(+), 73 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9b87780..42d112f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-04-04 Nick Clifton + + PR 19872 + * dwarf2.c (parse_comp_unit): Skip warning about unrecognised + version number if the version is zero. + 2016-04-01 Alan Modra PR 19886 diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index addfbf5..33370ac 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -2757,11 +2757,18 @@ parse_comp_unit (struct dwarf2_debug *stash, if (version != 2 && version != 3 && version != 4) { - (*_bfd_error_handler) - (_("Dwarf Error: found dwarf version '%u', this reader" - " only handles version 2, 3 and 4 information."), version); - bfd_set_error (bfd_error_bad_value); - return 0; + /* PR 19872: A version number of 0 probably means that there is padding + at the end of the .debug_info section. Gold puts it there when + performing an incremental link, for example. So do not generate + an error, just return a NULL. */ + if (version) + { + (*_bfd_error_handler) + (_("Dwarf Error: found dwarf version '%u', this reader" + " only handles version 2, 3 and 4 information."), version); + bfd_set_error (bfd_error_bad_value); + } + return NULL; } if (addr_size > sizeof (bfd_vma)) @@ -2772,7 +2779,7 @@ parse_comp_unit (struct dwarf2_debug *stash, addr_size, (unsigned int) sizeof (bfd_vma)); bfd_set_error (bfd_error_bad_value); - return 0; + return NULL; } if (addr_size != 2 && addr_size != 4 && addr_size != 8) @@ -2781,22 +2788,23 @@ parse_comp_unit (struct dwarf2_debug *stash, ("Dwarf Error: found address size '%u', this reader" " can only handle address sizes '2', '4' and '8'.", addr_size); bfd_set_error (bfd_error_bad_value); - return 0; + return NULL; } /* Read the abbrevs for this compilation unit into a table. */ abbrevs = read_abbrevs (abfd, abbrev_offset, stash); if (! abbrevs) - return 0; + return NULL; abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, end_ptr); info_ptr += bytes_read; if (! abbrev_number) { - (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."), - abbrev_number); - bfd_set_error (bfd_error_bad_value); - return 0; + /* PR 19872: An abbrev number of 0 probably means that there is padding + at the end of the .debug_abbrev section. Gold puts it there when + performing an incremental link, for example. So do not generate + an error, just return a NULL. */ + return NULL; } abbrev = lookup_abbrev (abbrev_number, abbrevs); @@ -2805,7 +2813,7 @@ parse_comp_unit (struct dwarf2_debug *stash, (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); bfd_set_error (bfd_error_bad_value); - return 0; + return NULL; } amt = sizeof (struct comp_unit); diff --git a/binutils/ChangeLog b/binutils/ChangeLog index ad58eb9..b4f5286 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2016-04-04 Nick Clifton + + PR 19872 + * dwarf.c (display_debug_aranges): Skip warning about unrecognised + version number if the version is zero. + 2016-03-29 Alan Modra * readelf.c (get_data): Use BFD_VMA_FMT to print bfd_size_type vars. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 086df4b..80f6b87 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -4910,7 +4910,12 @@ display_debug_aranges (struct dwarf_section *section, if (arange.ar_version != 2 && arange.ar_version != 3) { - warn (_("Only DWARF 2 and 3 aranges are currently supported.\n")); + /* PR 19872: A version number of 0 probably means that there is + padding at the end of the .debug_aranges section. Gold puts + it there when performing an incremental link, for example. + So do not generate a warning in this case. */ + if (arange.ar_version) + warn (_("Only DWARF 2 and 3 aranges are currently supported.\n")); break; } diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index bf146f6..c13fa4d 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -1059,10 +1059,38 @@ pe_undef_cdecl_match (struct bfd_link_hash_entry *h, void *inf) return TRUE; } +/* Change UNDEF to a defined symbol, taking data from SYM. */ + +static void +change_undef (struct bfd_link_hash_entry * undef, + struct bfd_link_hash_entry * sym) +{ + static bfd_boolean gave_warning_message = FALSE; + + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, sym->root.string); + + if (! gave_warning_message) + { + einfo (_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo (_("Use --disable-stdcall-fixup to disable these fixups\n")); + gave_warning_message = TRUE; + } + } + + /* PR 19803: Make sure that the linked symbol is not garbage collected. */ + lang_add_gc_name (sym->root.string); +} + static void pe_fixup_stdcalls (void) { - static int gave_warning_message = 0; struct bfd_link_hash_entry *undef, *sym; if (pe_dll_extra_pe_debug) @@ -1071,69 +1099,39 @@ pe_fixup_stdcalls (void) for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next) if (undef->type == bfd_link_hash_undefined) { - char* at = strchr (undef->root.string, '@'); - int lead_at = (*undef->root.string == '@'); + const char * name = undef->root.string; + char * at; + int lead_at = (*name == '@'); + if (lead_at) - at = strchr (undef->root.string + 1, '@'); + at = strchr (name + 1, '@'); + else + at = strchr (name, '@'); if (at || lead_at) { /* The symbol is a stdcall symbol, so let's look for a cdecl symbol with the same name and resolve to that. */ - char *cname = xstrdup (undef->root.string); + char *cname = xstrdup (name); if (lead_at) *cname = '_'; - at = strchr (cname, '@'); - if (at) - *at = 0; - sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1); + if (at) + * strchr (cname, '@') = 0; + sym = bfd_link_hash_lookup (link_info.hash, cname, FALSE, FALSE, TRUE); if (sym && sym->type == bfd_link_hash_defined) - { - undef->type = bfd_link_hash_defined; - undef->u.def.value = sym->u.def.value; - undef->u.def.section = sym->u.def.section; - - if (pe_enable_stdcall_fixup == -1) - { - einfo (_("Warning: resolving %s by linking to %s\n"), - undef->root.string, cname); - if (! gave_warning_message) - { - gave_warning_message = 1; - einfo (_("Use --enable-stdcall-fixup to disable these warnings\n")); - einfo (_("Use --disable-stdcall-fixup to disable these fixups\n")); - } - } - } + change_undef (undef, sym); } else { /* The symbol is a cdecl symbol, so we look for stdcall symbols - which means scanning the whole symbol table. */ - pe_undef_found_sym = 0; + pe_undef_found_sym = NULL; bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match, - (char *) undef->root.string); - sym = pe_undef_found_sym; - if (sym) - { - undef->type = bfd_link_hash_defined; - undef->u.def.value = sym->u.def.value; - undef->u.def.section = sym->u.def.section; - - if (pe_enable_stdcall_fixup == -1) - { - einfo (_("Warning: resolving %s by linking to %s\n"), - undef->root.string, sym->root.string); - if (! gave_warning_message) - { - gave_warning_message = 1; - einfo (_("Use --enable-stdcall-fixup to disable these warnings\n")); - einfo (_("Use --disable-stdcall-fixup to disable these fixups\n")); - } - } - } + (char *) name); + if (pe_undef_found_sym) + change_undef (undef, pe_undef_found_sym); } } } diff --git a/ld/pe-dll.c b/ld/pe-dll.c index a280647..1f176ec 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -905,6 +905,9 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * { *name = '_'; strcpy (name + 1, int_name); + + /* PR 19803: The alias must be preserved as well. */ + lang_add_gc_name (xstrdup (name)); } else strcpy (name, int_name); diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c index b4c8654..70e15c3 100644 --- a/sim/aarch64/simulator.c +++ b/sim/aarch64/simulator.c @@ -5322,6 +5322,90 @@ do_vec_FCVTZS (sim_cpu *cpu) } static void +do_vec_REV64 (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half + instr[29,24] = 00 1110 + instr[23,22] = size + instr[21,10] = 10 0000 0000 10 + instr[9,5] = Rn + instr[4,0] = Rd. */ + + unsigned rn = INSTR (9, 5); + unsigned rd = INSTR (4, 0); + unsigned size = INSTR (23, 22); + unsigned full = INSTR (30, 30); + unsigned i; + FRegister val; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 10, 0x802); + + switch (size) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + val.b[i ^ 0x7] = aarch64_get_vec_u8 (cpu, rn, i); + break; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + val.h[i ^ 0x3] = aarch64_get_vec_u16 (cpu, rn, i); + break; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + val.w[i ^ 0x1] = aarch64_get_vec_u32 (cpu, rn, i); + break; + + case 3: + HALT_UNALLOC; + } + + aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]); + if (full) + aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]); +} + +static void +do_vec_REV16 (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half + instr[29,24] = 00 1110 + instr[23,22] = size + instr[21,10] = 10 0000 0001 10 + instr[9,5] = Rn + instr[4,0] = Rd. */ + + unsigned rn = INSTR (9, 5); + unsigned rd = INSTR (4, 0); + unsigned size = INSTR (23, 22); + unsigned full = INSTR (30, 30); + unsigned i; + FRegister val; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 10, 0x806); + + switch (size) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + val.b[i ^ 0x1] = aarch64_get_vec_u8 (cpu, rn, i); + break; + + default: + HALT_UNALLOC; + } + + aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]); + if (full) + aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]); +} + +static void do_vec_op1 (sim_cpu *cpu) { /* instr[31] = 0 @@ -5389,6 +5473,9 @@ do_vec_op1 (sim_cpu *cpu) switch (INSTR (15, 10)) { + case 0x02: do_vec_REV64 (cpu); return; + case 0x06: do_vec_REV16 (cpu); return; + case 0x07: switch (INSTR (23, 21)) { @@ -6442,6 +6529,89 @@ do_vec_MOV_element (sim_cpu *cpu) } static void +do_vec_REV32 (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half + instr[29,24] = 10 1110 + instr[23,22] = size + instr[21,10] = 10 0000 0000 10 + instr[9,5] = Rn + instr[4,0] = Rd. */ + + unsigned rn = INSTR (9, 5); + unsigned rd = INSTR (4, 0); + unsigned size = INSTR (23, 22); + unsigned full = INSTR (30, 30); + unsigned i; + FRegister val; + + NYI_assert (29, 24, 0x2E); + NYI_assert (21, 10, 0x802); + + switch (size) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + val.b[i ^ 0x3] = aarch64_get_vec_u8 (cpu, rn, i); + break; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + val.h[i ^ 0x1] = aarch64_get_vec_u16 (cpu, rn, i); + break; + + default: + HALT_UNALLOC; + } + + aarch64_set_vec_u64 (cpu, rd, 0, val.v[0]); + if (full) + aarch64_set_vec_u64 (cpu, rd, 1, val.v[1]); +} + +static void +do_vec_EXT (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half + instr[29,21] = 10 1110 000 + instr[20,16] = Vm + instr[15] = 0 + instr[14,11] = source index + instr[10] = 0 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = INSTR (20, 16); + unsigned vn = INSTR (9, 5); + unsigned vd = INSTR (4, 0); + unsigned src_index = INSTR (14, 11); + unsigned full = INSTR (30, 30); + unsigned i; + unsigned j; + FRegister val; + + NYI_assert (31, 21, 0x370); + NYI_assert (15, 15, 0); + NYI_assert (10, 10, 0); + + if (!full && (src_index & 0x8)) + HALT_UNALLOC; + + j = 0; + + for (i = src_index; i < (full ? 16 : 8); i++) + val.b[j ++] = aarch64_get_vec_u8 (cpu, vn, i); + for (i = 0; i < src_index; i++) + val.b[j ++] = aarch64_get_vec_u8 (cpu, vm, i); + + aarch64_set_vec_u64 (cpu, vd, 0, val.v[0]); + if (full) + aarch64_set_vec_u64 (cpu, vd, 1, val.v[1]); +} + +static void dexAdvSIMD0 (sim_cpu *cpu) { /* instr [28,25] = 0 111. */ @@ -6484,22 +6654,15 @@ dexAdvSIMD0 (sim_cpu *cpu) case 0x0E: do_vec_op1 (cpu); return; case 0x0F: do_vec_op2 (cpu); return; - case 0x2f: - switch (INSTR (15, 10)) - { - case 0x01: do_vec_SSHR_USHR (cpu); return; - case 0x10: - case 0x12: do_vec_mls_indexed (cpu); return; - case 0x29: do_vec_xtl (cpu); return; - default: - HALT_NYI; - } - case 0x2E: if (INSTR (21, 21) == 1) { switch (INSTR (15, 10)) { + case 0x02: + do_vec_REV32 (cpu); + return; + case 0x07: switch (INSTR (23, 22)) { @@ -6550,7 +6713,10 @@ dexAdvSIMD0 (sim_cpu *cpu) if (INSTR (31, 21) == 0x370) { - do_vec_MOV_element (cpu); + if (INSTR (10, 10)) + do_vec_MOV_element (cpu); + else + do_vec_EXT (cpu); return; } @@ -6568,6 +6734,17 @@ dexAdvSIMD0 (sim_cpu *cpu) } break; + case 0x2f: + switch (INSTR (15, 10)) + { + case 0x01: do_vec_SSHR_USHR (cpu); return; + case 0x10: + case 0x12: do_vec_mls_indexed (cpu); return; + case 0x29: do_vec_xtl (cpu); return; + default: + HALT_NYI; + } + default: break; } -- 2.7.4