From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id 531A83858D1E; Fri, 30 Sep 2022 01:15:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 531A83858D1E Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb] PR29626, Segfault when disassembling ARM code X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/master X-Git-Oldrev: 478fced3a8904bed9a99ecf9c0374a49c3ac2115 X-Git-Newrev: 4eeb0013059856b8660b4a0351589b096167b4d1 Message-Id: <20220930011559.531A83858D1E@sourceware.org> Date: Fri, 30 Sep 2022 01:15:59 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Sep 2022 01:15:59 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D4eeb00130598= 56b8660b4a0351589b096167b4d1 commit 4eeb0013059856b8660b4a0351589b096167b4d1 Author: Alan Modra Date: Fri Sep 30 10:26:30 2022 +0930 PR29626, Segfault when disassembling ARM code =20 PR 29626 * arm-dis.c (mapping_symbol_for_insn): Return false on zero symtab_size. Delete later symtab_size test. Diff: --- opcodes/arm-dis.c | 124 +++++++++++++++++++++++++++-----------------------= ---- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 684c74f7f20..caf3531ae3d 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -11865,77 +11865,75 @@ mapping_symbol_for_insn (bfd_vma pc, struct disas= semble_info *info, struct arm_private_data *private_data; =20 if (info->private_data =3D=3D NULL + || info->symtab_size =3D=3D 0 || bfd_asymbol_flavour (*info->symtab) !=3D bfd_target_elf_flavour) return false; =20 private_data =3D info->private_data; =20 /* First, look for mapping symbols. */ - if (info->symtab_size !=3D 0) - { - if (pc <=3D private_data->last_mapping_addr) - private_data->last_mapping_sym =3D -1; - - /* Start scanning at the start of the function, or wherever - we finished last time. */ - n =3D info->symtab_pos + 1; - - /* If the last stop offset is different from the current one it means = we - are disassembling a different glob of bytes. As such the optimizat= ion - would not be safe and we should start over. */ - can_use_search_opt_p - =3D private_data->last_mapping_sym >=3D 0 - && info->stop_offset =3D=3D private_data->last_stop_offset; - - if (n >=3D private_data->last_mapping_sym && can_use_search_opt_p) - n =3D private_data->last_mapping_sym; - - /* Look down while we haven't passed the location being disassembled. - The reason for this is that there's no defined order between a symb= ol - and an mapping symbol that may be at the same address. We may have= to - look at least one position ahead. */ - for (; n < info->symtab_size; n++) - { - addr =3D bfd_asymbol_value (info->symtab[n]); - if (addr > pc) - break; - if (get_map_sym_type (info, n, &type)) - { - last_sym =3D n; - found =3D true; - } - } + if (pc <=3D private_data->last_mapping_addr) + private_data->last_mapping_sym =3D -1; + + /* Start scanning at the start of the function, or wherever + we finished last time. */ + n =3D info->symtab_pos + 1; + + /* If the last stop offset is different from the current one it means we + are disassembling a different glob of bytes. As such the optimization + would not be safe and we should start over. */ + can_use_search_opt_p + =3D (private_data->last_mapping_sym >=3D 0 + && info->stop_offset =3D=3D private_data->last_stop_offset); + + if (n >=3D private_data->last_mapping_sym && can_use_search_opt_p) + n =3D private_data->last_mapping_sym; + + /* Look down while we haven't passed the location being disassembled. + The reason for this is that there's no defined order between a symbol + and an mapping symbol that may be at the same address. We may have to + look at least one position ahead. */ + for (; n < info->symtab_size; n++) + { + addr =3D bfd_asymbol_value (info->symtab[n]); + if (addr > pc) + break; + if (get_map_sym_type (info, n, &type)) + { + last_sym =3D n; + found =3D true; + } + } =20 - if (!found) - { - n =3D info->symtab_pos; - if (n >=3D private_data->last_mapping_sym && can_use_search_opt_p) - n =3D private_data->last_mapping_sym; - - /* No mapping symbol found at this address. Look backwards - for a preceeding one, but don't go pass the section start - otherwise a data section with no mapping symbol can pick up - a text mapping symbol of a preceeding section. The documentation - says section can be NULL, in which case we will seek up all the - way to the top. */ - if (info->section) - section_vma =3D info->section->vma; - - for (; n >=3D 0; n--) - { - addr =3D bfd_asymbol_value (info->symtab[n]); - if (addr < section_vma) - break; + if (!found) + { + n =3D info->symtab_pos; + if (n >=3D private_data->last_mapping_sym && can_use_search_opt_p) + n =3D private_data->last_mapping_sym; + + /* No mapping symbol found at this address. Look backwards + for a preceeding one, but don't go pass the section start + otherwise a data section with no mapping symbol can pick up + a text mapping symbol of a preceeding section. The documentation + says section can be NULL, in which case we will seek up all the + way to the top. */ + if (info->section) + section_vma =3D info->section->vma; + + for (; n >=3D 0; n--) + { + addr =3D bfd_asymbol_value (info->symtab[n]); + if (addr < section_vma) + break; =20 - if (get_map_sym_type (info, n, &type)) - { - last_sym =3D n; - found =3D true; - break; - } - } - } - } + if (get_map_sym_type (info, n, &type)) + { + last_sym =3D n; + found =3D true; + break; + } + } + } =20 /* If no mapping symbol was found, try looking up without a mapping symbol. This is done by walking up from the current PC to the nearest