[commit] Fix MIPS shared library support, symbolic lookup

Daniel Jacobowitz drow@false.org
Wed Aug 22 14:25:00 GMT 2007


There were two problems with the DT_SYMBOLIC patch.  The one I
noticed was that it checks all of .dynamic for DT_DEBUG before
checking anywhere for DT_MIPS_RLD_MAP; the old code would process
DT_MIPS_RLD_MAP in preference if it came first.  DT_DEBUG is
present but NULL on mips-linux, so this change meant shared libraries
were never found.

The other problem was that it caused all of .dynamic to be read at
every global symbol lookup.  I haven't completely fixed that, but I
did stop it from reading from the target; it still reads from the BFD.
We should probably cache this information instead.

Tested on mips64-linux and committed.

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-22  Daniel Jacobowitz  <dan@codesourcery.com>

	* solib-svr4.c (scan_dyntag): Only read target memory when necessary.
	Fix formatting.
	(elf_locate_base): Look for DT_MIPS_RLD_MAP first.  Expand comments.
	(elf_lookup_lib_symbol): Fix formatting.

Index: solib-svr4.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gdb/solib-svr4.c,v
retrieving revision 1.73
diff -u -p -r1.73 solib-svr4.c
--- solib-svr4.c	10 Aug 2007 20:42:45 -0000	1.73
+++ solib-svr4.c	22 Aug 2007 13:35:10 -0000
@@ -354,7 +354,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE
   int arch_size, step, sect_size;
   long dyn_tag;
   CORE_ADDR dyn_ptr, dyn_addr;
-  gdb_byte *bufend, *buf;
+  gdb_byte *bufend, *bufstart, *buf;
   Elf32_External_Dyn *x_dynp_32;
   Elf64_External_Dyn *x_dynp_64;
   struct bfd_section *sect;
@@ -371,16 +371,13 @@ scan_dyntag (int dyntag, bfd *abfd, CORE
     return 0;
   dyn_addr = bfd_section_vma (abfd, sect);
 
-  /* Read in .dynamic section, silently ignore errors.  */
+  /* Read in .dynamic from the BFD.  We will get the actual value
+     from memory later.  */
   sect_size = bfd_section_size (abfd, sect);
-  buf = alloca (sect_size);
-  if (target_read_memory (dyn_addr, buf, sect_size))
-    {
-      /* If target_read_memory fails, try reading the BFD file.  */
-      if (!bfd_get_section_contents (abfd, sect,
-				     buf, 0, sect_size))
-	return 0;
-    }
+  buf = bufstart = 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)
@@ -395,7 +392,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE
 	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
+    else
       {
 	x_dynp_64 = (Elf64_External_Dyn *) buf;
 	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
@@ -405,9 +402,20 @@ scan_dyntag (int dyntag, bfd *abfd, CORE
        return 0;
      if (dyn_tag == dyntag)
        {
+	 /* If requested, try to read the runtime value of this .dynamic
+	    entry.  */
 	 if (ptr)
-	   *ptr = dyn_ptr;
-         return 1;
+	   {
+	     gdb_byte ptr_buf[8];
+	     CORE_ADDR ptr_addr;
+
+	     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,
+						builtin_type_void_data_ptr);
+	     *ptr = dyn_ptr;
+	   }
+	 return 1;
        }
   }
 
@@ -445,11 +453,9 @@ elf_locate_base (void)
   struct minimal_symbol *msymbol;
   CORE_ADDR dyn_ptr;
 
-  /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
-    return dyn_ptr;
-
-  /* Find DT_MIPS_RLD_MAP.  */
+  /* 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))
     {
       gdb_byte *pbuf;
@@ -462,6 +468,10 @@ elf_locate_base (void)
       return extract_typed_address (pbuf, builtin_type_void_data_ptr);
     }
 
+  /* Find DT_DEBUG.  */
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
+    return dyn_ptr;
+
   /* This may be a static executable.  Look for the symbol
      conventionally named _r_debug, as a last resort.  */
   msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
@@ -1549,7 +1559,7 @@ elf_lookup_lib_symbol (const struct objf
      || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
     return NULL;
 
-  return  lookup_global_symbol_from_objfile
+  return lookup_global_symbol_from_objfile
 		(objfile, name, linkage_name, domain, symtab);
 }
 



More information about the Gdb-patches mailing list