On Tue, Aug 9, 2011 at 2:06 AM, Jan Kratochvil wrote: > On Tue, 09 Aug 2011 01:49:49 +0200, Paul Pluzhnikov wrote: >> --- gdbserver/linux-low.c     21 Jul 2011 23:46:12 -0000      1.173 >> +++ gdbserver/linux-low.c     8 Aug 2011 23:34:10 -0000 >> @@ -4755,6 +4755,289 @@ linux_emit_ops (void) > [...] >> +static CORE_ADDR >> +get_dynamic (const int pid, const int is_elf64) >> +{ >> +  CORE_ADDR phdr_memaddr; >> +  int num_phdr, i; >> +  unsigned char *phdr_buf; >> +  const int phdr_size = is_elf64 ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr); >> + >> + > > Two empty lines, should be one. Fixed here and elsewhere ... >> +  if (get_phdr_phnum_from_proc_auxv (pid, is_elf64, &phdr_memaddr, &num_phdr)) >> +    return 0; >> + >> +  gdb_assert (num_phdr < 100);  /* Basic sanity check.  */ >> +  phdr_buf = alloca (num_phdr * phdr_size); >> + >> +  if (linux_read_memory (phdr_memaddr, phdr_buf, num_phdr * phdr_size)) >> +    return 0; >> + >> +  for (i = 0; i < num_phdr; i++) >> +    { >> +      if (is_elf64) >> +     { >> +       Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size); >> + >> +       if (p->p_type == PT_DYNAMIC) >> +         return p->p_vaddr; > > This does not work for -fPIE -pie executables such as those on Chromebook. > One needs to relocate A_VAL as it is the in-file (0-based) address while > in-memory address is shifted by X.  X is calculated by solib-svr4.c > svr4_exec_displacement. > > One can find here X probably most easily by subtracting PT_PHDR->P_VADDR from > PHDR_MEMADDR. Done. > > There is also a bug in it in solib-svr4.c scan_dyntag_auxv >        [rfc] Use auxillary vector to retrieve .dynamic/.interp sections >        http://sourceware.org/ml/gdb-patches/2008-08/msg00360.html > but one would need to patch the code around to get the fix applicable first. > > >> +     } >> +      else >> +     { >> +       Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size); >> + >> +       if (p->p_type == PT_DYNAMIC) >> +         return p->p_vaddr; > > Here too. Ditto. >> +      /* Not checking for error because reading may stop before >> +      we've got PATH_MAX worth of characters.  */ >> +      libname[0] = '\0'; >> +      linux_read_memory (l_name, libname, sizeof (libname)); >> +      if (libname[0] != '\0') >> +     loaded_dll ((const char *) libname, l_addr); > > Unprotected against inferior string longer than PATH_MAX, this is a regression > against solib-svr4.c. Fixed. Side note: SO_NAME_MAX_PATH_SIZE == 512 in solist.h is wrong for Linux; I am surprised this hasn't bitten anyone yet. Why doesn't it use PATH_MAX ? Thanks, -- Paul Pluzhnikov 2011-08-09 Paul Pluzhnikov * solib-svr4.c (library_list_start_segment): New function. (library_list_start_library, library_list_end_library): Likewise. (library_list_start_list): Likewise. (segment_attributes, library_children): New variables. (library_attributes, library_list_children): Likewise. (library_list_attributes, library_list_elements): Likewise. (svr4_free_so): Moved to here. (svr4_free_library_list, svr4_parse_libraries): New functions. (svr4_current_sos_via_xfer_libraries): Likewise. (svr4_current_sos): Adjust. gdbserver/ChangeLog: 2011-08-09 Paul Pluzhnikov Jan Kratochvil * inferiors.c (clear_all_dlls): New function. (clear_inferiors): Move there the code from here, call it here. * linux-low.c (linux_add_process): Adjust. (get_phdr_phnum_from_proc_auxv, get_dynamic): New functions. (get_r_debug, read_one_ptr): Likewise. (struct link_map_offsets): New struct decl. (linux_refresh_libraries): New function. (struct linux_target_ops): Adjust. (struct process_info_private): New member. (handle_qxfer_libraries): Adjust. (struct target_ops): New member. * server.c (handle_qxfer_libraries): Adjust. * server.h (clear_all_dlls): New prototype. * target.h (struct target_ops): New member.