From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 7D614383B43A for ; Thu, 12 Aug 2021 04:24:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7D614383B43A Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-262-GSN3X0HKNE2HHa6A8zAhpg-1; Thu, 12 Aug 2021 00:24:09 -0400 X-MC-Unique: GSN3X0HKNE2HHa6A8zAhpg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4996E801A92; Thu, 12 Aug 2021 04:24:08 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.22.16.110]) by smtp.corp.redhat.com (Postfix) with ESMTP id A6F1E5D9DE; Thu, 12 Aug 2021 04:24:07 +0000 (UTC) From: Aaron Merey To: gdb-patches@sourceware.org, simon.marchi@polymtl.ca, tom@tromey.com Subject: [PATCH 1/3] gdb/solib: Refactor scan_dyntag Date: Thu, 12 Aug 2021 00:24:04 -0400 Message-Id: <20210812042406.75637-2-amerey@redhat.com> In-Reply-To: <20210812042406.75637-1-amerey@redhat.com> References: <20210812042406.75637-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2021 04:24:12 -0000 scan_dyntag is unnecessarily duplicated in solib-svr4.c and solib-dsbt.c. Move this function to solib.c and rename it to gdb_bfd_scan_elf_dyntag. Also add it to solib.h so it is included in both solib-svr4 and solib-dsbt. --- gdb/solib-dsbt.c | 104 ++--------------------------------------- gdb/solib-svr4.c | 118 ++++------------------------------------------- gdb/solib.c | 104 +++++++++++++++++++++++++++++++++++++++++ gdb/solib.h | 6 +++ 4 files changed, 122 insertions(+), 210 deletions(-) diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index 803467dd489..d7f4b252eee 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -396,106 +396,6 @@ fetch_loadmap (CORE_ADDR ldmaddr) static void dsbt_relocate_main_executable (void); static int enable_break (void); -/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is - returned and the corresponding PTR is set. */ - -static int -scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) -{ - int arch_size, step, sect_size; - long dyn_tag; - CORE_ADDR dyn_ptr, dyn_addr; - gdb_byte *bufend, *bufstart, *buf; - Elf32_External_Dyn *x_dynp_32; - Elf64_External_Dyn *x_dynp_64; - struct bfd_section *sect; - - if (abfd == NULL) - return 0; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - return 0; - - arch_size = bfd_get_arch_size (abfd); - if (arch_size == -1) - return 0; - - /* Find the start address of the .dynamic section. */ - sect = bfd_get_section_by_name (abfd, ".dynamic"); - if (sect == NULL) - return 0; - - bool found = false; - for (const target_section &target_section - : current_program_space->target_sections ()) - if (sect == target_section.the_bfd_section) - { - dyn_addr = target_section.addr; - found = true; - break; - } - if (!found) - { - /* ABFD may come from OBJFILE acting only as a symbol file without being - loaded into the target (see add_symbol_file_command). This case is - such fallback to the file VMA address without the possibility of - having the section relocated to its actual in-memory address. */ - - dyn_addr = bfd_section_vma (sect); - } - - /* Read in .dynamic from the BFD. We will get the actual value - from memory later. */ - sect_size = bfd_section_size (sect); - buf = bufstart = (gdb_byte *) alloca (sect_size); - if (!bfd_get_section_contents (abfd, sect, - buf, 0, sect_size)) - return 0; - - /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ - step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) - : sizeof (Elf64_External_Dyn); - for (bufend = buf + sect_size; - buf < bufend; - buf += step) - { - if (arch_size == 32) - { - x_dynp_32 = (Elf32_External_Dyn *) buf; - dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag); - dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr); - } - else - { - x_dynp_64 = (Elf64_External_Dyn *) buf; - dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); - dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); - } - if (dyn_tag == DT_NULL) - return 0; - if (dyn_tag == dyntag) - { - /* If requested, try to read the runtime value of this .dynamic - entry. */ - if (ptr) - { - struct type *ptr_type; - gdb_byte ptr_buf[8]; - CORE_ADDR ptr_addr; - - ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; - ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; - if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0) - dyn_ptr = extract_typed_address (ptr_buf, ptr_type); - *ptr = dyn_ptr; - } - return 1; - } - } - - return 0; -} - /* See solist.h. */ static int @@ -565,7 +465,9 @@ lm_base (void) "lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n", (unsigned int) addr); } - else if (scan_dyntag (DT_PLTGOT, current_program_space->exec_bfd (), &addr)) + else if (gdb_bfd_scan_elf_dyntag (DT_PLTGOT, + current_program_space->exec_bfd (), + &addr, NULL)) { struct int_elf32_dsbt_loadmap *ldm; diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index a8a7d1171dc..3de1bb9c7f7 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -582,109 +582,6 @@ find_program_interpreter (void) } -/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD. If DESIRED_DYNTAG is - found, 1 is returned and the corresponding PTR is set. */ - -static int -scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr, - CORE_ADDR *ptr_addr) -{ - int arch_size, step, sect_size; - long current_dyntag; - CORE_ADDR dyn_ptr, dyn_addr; - gdb_byte *bufend, *bufstart, *buf; - Elf32_External_Dyn *x_dynp_32; - Elf64_External_Dyn *x_dynp_64; - struct bfd_section *sect; - - if (abfd == NULL) - return 0; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - return 0; - - arch_size = bfd_get_arch_size (abfd); - if (arch_size == -1) - return 0; - - /* Find the start address of the .dynamic section. */ - sect = bfd_get_section_by_name (abfd, ".dynamic"); - if (sect == NULL) - return 0; - - bool found = false; - for (const target_section &target_section - : current_program_space->target_sections ()) - if (sect == target_section.the_bfd_section) - { - dyn_addr = target_section.addr; - found = true; - break; - } - if (!found) - { - /* ABFD may come from OBJFILE acting only as a symbol file without being - loaded into the target (see add_symbol_file_command). This case is - such fallback to the file VMA address without the possibility of - having the section relocated to its actual in-memory address. */ - - dyn_addr = bfd_section_vma (sect); - } - - /* Read in .dynamic from the BFD. We will get the actual value - from memory later. */ - sect_size = bfd_section_size (sect); - buf = bufstart = (gdb_byte *) alloca (sect_size); - if (!bfd_get_section_contents (abfd, sect, - buf, 0, sect_size)) - return 0; - - /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ - step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) - : sizeof (Elf64_External_Dyn); - for (bufend = buf + sect_size; - buf < bufend; - buf += step) - { - if (arch_size == 32) - { - x_dynp_32 = (Elf32_External_Dyn *) buf; - current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag); - dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr); - } - else - { - x_dynp_64 = (Elf64_External_Dyn *) buf; - current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); - dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); - } - if (current_dyntag == DT_NULL) - return 0; - if (current_dyntag == desired_dyntag) - { - /* If requested, try to read the runtime value of this .dynamic - entry. */ - if (ptr) - { - struct type *ptr_type; - gdb_byte ptr_buf[8]; - CORE_ADDR ptr_addr_1; - - ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; - ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8; - if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0) - dyn_ptr = extract_typed_address (ptr_buf, ptr_type); - *ptr = dyn_ptr; - if (ptr_addr) - *ptr_addr = dyn_addr + (buf - bufstart); - } - return 1; - } - } - - return 0; -} - /* Scan for DESIRED_DYNTAG in .dynamic section of the target's main executable, found by consulting the OS auxillary vector. If DESIRED_DYNTAG is found, 1 is returned and the corresponding PTR is set. */ @@ -768,8 +665,9 @@ elf_locate_base (void) /* Look for DT_MIPS_RLD_MAP first. MIPS executables use this instead of DT_DEBUG, although they sometimes contain an unused DT_DEBUG. */ - if (scan_dyntag (DT_MIPS_RLD_MAP, current_program_space->exec_bfd (), - &dyn_ptr, NULL) + if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP, + current_program_space->exec_bfd (), + &dyn_ptr, NULL) || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL)) { struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; @@ -787,8 +685,9 @@ elf_locate_base (void) /* Then check DT_MIPS_RLD_MAP_REL. MIPS executables now use this form because of needing to support PIE. DT_MIPS_RLD_MAP will also exist in non-PIE. */ - if (scan_dyntag (DT_MIPS_RLD_MAP_REL, current_program_space->exec_bfd (), - &dyn_ptr, &dyn_ptr_addr) + if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP_REL, + current_program_space->exec_bfd (), + &dyn_ptr, &dyn_ptr_addr) || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr)) { struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; @@ -804,7 +703,8 @@ elf_locate_base (void) } /* Find DT_DEBUG. */ - if (scan_dyntag (DT_DEBUG, current_program_space->exec_bfd (), &dyn_ptr, NULL) + if (gdb_bfd_scan_elf_dyntag (DT_DEBUG, current_program_space->exec_bfd (), + &dyn_ptr, NULL) || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL)) return dyn_ptr; @@ -3258,7 +3158,7 @@ svr4_iterate_over_objfiles_in_search_order abfd = current_objfile->obfd; if (abfd != nullptr - && scan_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1) + && gdb_bfd_scan_elf_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1) { checked_current_objfile = true; if (cb (current_objfile, cb_data) != 0) diff --git a/gdb/solib.c b/gdb/solib.c index 317f7eb485e..e30affbb7e7 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -35,6 +35,8 @@ #include "language.h" #include "gdbcmd.h" #include "completer.h" +#include "elf/external.h" +#include "elf/common.h" #include "filenames.h" /* for DOSish file names */ #include "exec.h" #include "solist.h" @@ -1481,6 +1483,108 @@ gdb_bfd_lookup_symbol_from_symtab (bfd *abfd, return symaddr; } +/* See solib.h. */ + +int +gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr, + CORE_ADDR *ptr_addr) +{ + int arch_size, step, sect_size; + long current_dyntag; + CORE_ADDR dyn_ptr, dyn_addr; + gdb_byte *bufend, *bufstart, *buf; + Elf32_External_Dyn *x_dynp_32; + Elf64_External_Dyn *x_dynp_64; + struct bfd_section *sect; + + if (abfd == NULL) + return 0; + + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) + return 0; + + arch_size = bfd_get_arch_size (abfd); + if (arch_size == -1) + return 0; + + /* Find the start address of the .dynamic section. */ + sect = bfd_get_section_by_name (abfd, ".dynamic"); + if (sect == NULL) + return 0; + + bool found = false; + for (const target_section &target_section + : current_program_space->target_sections ()) + if (sect == target_section.the_bfd_section) + { + dyn_addr = target_section.addr; + found = true; + break; + } + if (!found) + { + /* ABFD may come from OBJFILE acting only as a symbol file without being + loaded into the target (see add_symbol_file_command). This case is + such fallback to the file VMA address without the possibility of + having the section relocated to its actual in-memory address. */ + + dyn_addr = bfd_section_vma (sect); + } + + /* Read in .dynamic from the BFD. We will get the actual value + from memory later. */ + sect_size = bfd_section_size (sect); + buf = bufstart = (gdb_byte *) alloca (sect_size); + if (!bfd_get_section_contents (abfd, sect, + buf, 0, sect_size)) + return 0; + + /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ + step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) + : sizeof (Elf64_External_Dyn); + for (bufend = buf + sect_size; + buf < bufend; + buf += step) + { + if (arch_size == 32) + { + x_dynp_32 = (Elf32_External_Dyn *) buf; + current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag); + dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr); + } + else + { + x_dynp_64 = (Elf64_External_Dyn *) buf; + current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); + dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); + } + if (current_dyntag == DT_NULL) + return 0; + if (current_dyntag == desired_dyntag) + { + /* If requested, try to read the runtime value of this .dynamic + entry. */ + if (ptr) + { + struct type *ptr_type; + gdb_byte ptr_buf[8]; + CORE_ADDR ptr_addr_1; + + ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; + ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8; + if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0) + dyn_ptr = extract_typed_address (ptr_buf, ptr_type); + *ptr = dyn_ptr; + if (ptr_addr) + *ptr_addr = dyn_addr + (buf - bufstart); + } + return 1; + } + } + + return 0; +} + /* Lookup the value for a specific symbol from symbol table. Look up symbol from ABFD. MATCH_SYM is a callback function to determine whether to pick up a symbol. DATA is the input of this callback function. Return NULL diff --git a/gdb/solib.h b/gdb/solib.h index a94e9d3cd9e..c50f74e06bf 100644 --- a/gdb/solib.h +++ b/gdb/solib.h @@ -112,6 +112,12 @@ extern CORE_ADDR gdb_bfd_lookup_symbol_from_symtab (bfd *abfd, const void *), const void *data); +/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD. If DESIRED_DYNTAG is + found, 1 is returned and the corresponding PTR and PTR_ADDR are set. */ + +extern int gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, + CORE_ADDR *ptr, CORE_ADDR *ptr_addr); + /* Enable or disable optional solib event breakpoints as appropriate. */ extern void update_solib_breakpoints (void); -- 2.31.1