From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 77681 invoked by alias); 26 Jun 2015 12:45:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 77657 invoked by uid 89); 26 Jun 2015 12:45:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 26 Jun 2015 12:45:27 +0000 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 19ED84E92F150; Fri, 26 Jun 2015 13:45:21 +0100 (IST) Received: from LEMAIL01.le.imgtec.org (192.168.152.62) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 26 Jun 2015 13:45:23 +0100 Received: from LEMAIL01.le.imgtec.org ([fe80::5ae:ee16:f4b9:cda9]) by LEMAIL01.le.imgtec.org ([fe80::5ae:ee16:f4b9:cda9%17]) with mapi id 14.03.0210.002; Fri, 26 Jun 2015 13:45:23 +0100 From: Matthew Fortune To: "gdb-patches@sourceware.org" CC: Joseph Myers Subject: RE: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb) Date: Fri, 26 Jun 2015 12:45:00 -0000 Message-ID: <6D39441BF12EF246A7ABCE6654B02353211AFAAB@LEMAIL01.le.imgtec.org> References: <6D39441BF12EF246A7ABCE6654B02353211760FA@LEMAIL01.le.imgtec.org> In-Reply-To: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-SW-Source: 2015-06/txt/msg00563.txt.bz2 Joseph Myers writes: > On Tue, 23 Jun 2015, Matthew Fortune wrote: >=20 > > Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled > > unless the host's elf.h header has the new tag defined in it. For > > cross compiled GDB this may mean hacking the solib-svr4.c file to > > define the macro until such time as distributions update glibc. >=20 > That doesn't make any sense to me. Hosts (e.g. MinGW) may not have > elf.h at all. GDB should get these definitions from the #include > "elf/mips.h" > already in solib-svr4.c (i.e. from toplevel's include/elf/mips.h). And > so there should be no #ifdefs there. Updated version below to match the name of the new tag as committed to binutils and removed the #ifdefs from solib-svr4.c. binutils commit: a5499fa Add support for DT_MIPS_RLD_MAP_REL. OK to commit? Thanks, Matthew This tag allows debugging of MIPS position independent executables and provides access to shared library information. gdb/gdbserver/ * linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL. gdb/ * solib-svr4.c (read_program_header): Add base_addr argument to report the runtime address of the segment. (find_program_interpreter): Update read_program_header call to pass a NULL pointer for the new argument. (scan_dyntag): Add ptr_addr argument to report the runtime address of the tag payload. (scan_dyntag_auxv): Likewise and use thew new base_addr argument of read_program_header to get the base address of the dynamic segment. (elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and read_program_header. (elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL. --- gdb/ChangeLog | 14 +++++++++++ gdb/gdbserver/ChangeLog | 4 +++ gdb/gdbserver/linux-low.c | 30 +++++++++++++++++++--- gdb/solib-svr4.c | 63 +++++++++++++++++++++++++++++++++++--------= ---- 4 files changed, 91 insertions(+), 20 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 659f9b7..766c02f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2015-06-26 Matthew Fortune + + * solib-svr4.c (read_program_header): Add base_addr argument to + report the runtime address of the segment. + (find_program_interpreter): Update read_program_header call to pass + a NULL pointer for the new argument. + (scan_dyntag): Add ptr_addr argument to report the runtime address + of the tag payload. + (scan_dyntag_auxv): Likewise and use thew new base_addr argument of + read_program_header to get the base address of the dynamic segment. + (elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and + read_program_header. + (elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL. + 2015-06-25 Gary Benson =20 * solib.c (solib_find_1): Set local variable sysroot to NULL if diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 2528f0f..6e37863 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,7 @@ +2015-06-26 Matthew Fortune + + * linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL. + 2015-06-24 Gary Benson =20 * linux-i386-ipa.c (stdint.h): Do not include. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 3774d17..ed18e24 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -6102,14 +6102,15 @@ get_r_debug (const int pid, const int is_elf64) if (is_elf64) { Elf64_Dyn *const dyn =3D (Elf64_Dyn *) buf; -#ifdef DT_MIPS_RLD_MAP +#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL union { Elf64_Xword map; unsigned char buf[sizeof (Elf64_Xword)]; } rld_map; - +#endif +#ifdef DT_MIPS_RLD_MAP if (dyn->d_tag =3D=3D DT_MIPS_RLD_MAP) { if (linux_read_memory (dyn->d_un.d_val, @@ -6119,6 +6120,16 @@ get_r_debug (const int pid, const int is_elf64) break; } #endif /* DT_MIPS_RLD_MAP */ +#ifdef DT_MIPS_RLD_MAP_REL + if (dyn->d_tag =3D=3D DT_MIPS_RLD_MAP_REL) + { + if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr, + rld_map.buf, sizeof (rld_map.buf)) =3D=3D 0) + return rld_map.map; + else + break; + } +#endif /* DT_MIPS_RLD_MAP_REL */ =20 if (dyn->d_tag =3D=3D DT_DEBUG && map =3D=3D -1) map =3D dyn->d_un.d_val; @@ -6129,14 +6140,15 @@ get_r_debug (const int pid, const int is_elf64) else { Elf32_Dyn *const dyn =3D (Elf32_Dyn *) buf; -#ifdef DT_MIPS_RLD_MAP +#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL union { Elf32_Word map; unsigned char buf[sizeof (Elf32_Word)]; } rld_map; - +#endif +#ifdef DT_MIPS_RLD_MAP if (dyn->d_tag =3D=3D DT_MIPS_RLD_MAP) { if (linux_read_memory (dyn->d_un.d_val, @@ -6146,6 +6158,16 @@ get_r_debug (const int pid, const int is_elf64) break; } #endif /* DT_MIPS_RLD_MAP */ +#ifdef DT_MIPS_RLD_MAP_REL + if (dyn->d_tag =3D=3D DT_MIPS_RLD_MAP_REL) + { + if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr, + rld_map.buf, sizeof (rld_map.buf)) =3D=3D 0) + return rld_map.map; + else + break; + } +#endif /* DT_MIPS_RLD_MAP_REL */ =20 if (dyn->d_tag =3D=3D DT_DEBUG && map =3D=3D -1) map =3D dyn->d_un.d_val; diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 909dfb7..a71fb82 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -443,10 +443,12 @@ static int match_main (const char *); Return a pointer to allocated memory holding the program header content= s, or NULL on failure. If sucessful, and unless P_SECT_SIZE is NULL, the size of those contents is returned to P_SECT_SIZE. Likewise, the target - architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE. */ + architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and + the base address of the section is returned in BASE_ADDR. */ =20 static gdb_byte * -read_program_header (int type, int *p_sect_size, int *p_arch_size) +read_program_header (int type, int *p_sect_size, int *p_arch_size, + CORE_ADDR *base_addr) { enum bfd_endian byte_order =3D gdbarch_byte_order (target_gdbarch ()); CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr =3D 0; @@ -576,6 +578,8 @@ read_program_header (int type, int *p_sect_size, int *p= _arch_size) *p_arch_size =3D arch_size; if (p_sect_size) *p_sect_size =3D sect_size; + if (base_addr) + *base_addr =3D sect_addr; =20 return buf; } @@ -605,7 +609,7 @@ find_program_interpreter (void) =20 /* If we didn't find it, use the target auxillary vector. */ if (!buf) - buf =3D read_program_header (PT_INTERP, NULL, NULL); + buf =3D read_program_header (PT_INTERP, NULL, NULL, NULL); =20 return (char *) buf; } @@ -615,7 +619,8 @@ find_program_interpreter (void) found, 1 is returned and the corresponding PTR is set. */ =20 static int -scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr) +scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr, + CORE_ADDR *ptr_addr) { int arch_size, step, sect_size; long current_dyntag; @@ -695,13 +700,15 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, COR= E_ADDR *ptr) { struct type *ptr_type; gdb_byte ptr_buf[8]; - CORE_ADDR ptr_addr; + CORE_ADDR ptr_addr_1; =20 ptr_type =3D builtin_type (target_gdbarch ())->builtin_data_ptr; - ptr_addr =3D dyn_addr + (buf - bufstart) + arch_size / 8; - if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) =3D=3D 0) + ptr_addr_1 =3D dyn_addr + (buf - bufstart) + arch_size / 8; + if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) =3D=3D 0) dyn_ptr =3D extract_typed_address (ptr_buf, ptr_type); *ptr =3D dyn_ptr; + if (ptr_addr) + *ptr_addr =3D dyn_addr + (buf - bufstart); } return 1; } @@ -715,16 +722,19 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, COR= E_ADDR *ptr) is returned and the corresponding PTR is set. */ =20 static int -scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr) +scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr, + CORE_ADDR *ptr_addr) { enum bfd_endian byte_order =3D gdbarch_byte_order (target_gdbarch ()); int sect_size, arch_size, step; long current_dyntag; CORE_ADDR dyn_ptr; + CORE_ADDR base_addr; gdb_byte *bufend, *bufstart, *buf; =20 /* Read in .dynamic section. */ - buf =3D bufstart =3D read_program_header (PT_DYNAMIC, §_size, &arch_= size); + buf =3D bufstart =3D read_program_header (PT_DYNAMIC, §_size, &arch_= size, + &base_addr); if (!buf) return 0; =20 @@ -761,6 +771,9 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *= ptr) if (ptr) *ptr =3D dyn_ptr; =20 + if (ptr_addr) + *ptr_addr =3D base_addr + buf - bufstart; + xfree (bufstart); return 1; } @@ -786,13 +799,13 @@ static CORE_ADDR elf_locate_base (void) { struct bound_minimal_symbol msymbol; - CORE_ADDR dyn_ptr; + CORE_ADDR dyn_ptr, dyn_ptr_addr; =20 /* 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, exec_bfd, &dyn_ptr) - || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr)) + if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL) + || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL)) { struct type *ptr_type =3D builtin_type (target_gdbarch ())->builtin_= data_ptr; gdb_byte *pbuf; @@ -806,9 +819,27 @@ elf_locate_base (void) return extract_typed_address (pbuf, ptr_type); } =20 + /* 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, exec_bfd, &dyn_ptr, &dyn_ptr_addr) + || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr)) + { + struct type *ptr_type =3D builtin_type (target_gdbarch ())->builtin_= data_ptr; + gdb_byte *pbuf; + int pbuf_size =3D TYPE_LENGTH (ptr_type); + + pbuf =3D alloca (pbuf_size); + /* DT_MIPS_RLD_MAP_REL contains an offset from the address of the + DT slot to the address of the dynamic link structure. */ + if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size)) + return 0; + return extract_typed_address (pbuf, ptr_type); + } + /* Find DT_DEBUG. */ - if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr) - || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr)) + if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL) + || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL)) return dyn_ptr; =20 /* This may be a static executable. Look for the symbol @@ -2607,7 +2638,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp) gdb_byte *buf, *buf2; int arch_size; =20 - buf =3D read_program_header (-1, &phdrs_size, &arch_size); + buf =3D read_program_header (-1, &phdrs_size, &arch_size, NULL); buf2 =3D read_program_headers_from_bfd (exec_bfd, &phdrs2_size); if (buf !=3D NULL && buf2 !=3D NULL) { @@ -3228,7 +3259,7 @@ elf_lookup_lib_symbol (struct objfile *objfile, abfd =3D objfile->obfd; } =20 - if (abfd =3D=3D NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) !=3D 1) + if (abfd =3D=3D NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) !=3D= 1) return NULL; =20 return lookup_global_symbol_from_objfile (objfile, name, domain); --=20 2.2.1