This is the mail archive of the mailing list for the GDB project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH RFA] solib.c relocation improvements

The patch below is based on feedback from Peter Schauer regarding my
solib.c reorg patch of last weekend.  Specifically, Peter described
some additional cleanup that would be necessary for making solib.c
useful for platforms aside from the ones already using it.  I used the
following remarks from Peter as an outline for making the changes
contained in the patch:

> - This code from solib.c:solib_map_sections
>   for (p = so->sections; p < so->sections_end; p++)
>     {
>       /* Relocate the section binding addresses as recorded in the shared
>          object's file by the base address to which the object was actually
>          mapped. */
>       p->addr += TARGET_SO_LM_ADDR (so);
>       p->endaddr += TARGET_SO_LM_ADDR (so);
>       so->lmend = max (p->endaddr, so->lmend);
>       if (STREQ (p->the_bfd_section->name, ".text"))
>         {
>           so->textsection = p;
>         }
>     }
>   might be too specialized for future targets, as it assumes that all sections
>   are loaded with the same offset (perhaps I will find some time someday
>   to convert the horrible AIX shlib code to your scheme, and then we will
>   definitely need it).
>   It might be better to perform the relocation via a target_so_ops entry.
> - I am not sure if we shouldn't get rid of the TARGET_SO_LM_ADDR and
>   so->lmend crap altogether.
>   solib_address could examine so->sections.
>   info_sharedlibrary_command could put out the addresses of the textsection
>   (or of all sections, perhaps via a new `maint info sharedlibrary' command,
>   which I could have used quite often in the past).
>   The lowest section handling in symbol_add_stub is questionable anyway
>   and needs some rethinking. I put in some debug output and ran the testsuite
>   on Solaris2 and Linux x86 targets, and it seems that all the business with
>   hacking sap->other[lowest_index].addr is not needed anyway, as
>   sap->other[lowest_index].addr == lowest_addr in all test cases.
>   I no longer have a SunOS4 platform handy, so perhaps it is needed there.

I did my own examination of the lowest section handling code in
symbol_add_stub() and concluded that it was completely unnecessary. 
Here's what it was doing:

 - It finds the "lowest" section.  This is always taken to be the
   .text section if it exists.  Otherwise it is the section with the
   lowest (unrelocated) address from BFD.

   In the case of the .text section, the lowest address was taken
   to be so->textsection->addr.  Note that this is the relocated
   address of the .text section.

   In the case of one of the other sections, the lowest address is
   computed with the following expression:

     bfd_section_vma (so->abfd, lowest_sect) + TARGET_SO_LM_ADDR (so);

   I.e, it is the unrelocated address from the BFD section plus the
   address needed for relocation.  Note that this value could have
   been obtained from the shared object's section table since
   solib_map_sections() already did the same work.  (You have to
   look at build_section_table() and add_to_section_table() to
   see the bit regarding the BFD section vma though.)

   In either case, when we compute lowest_addr, it will have the same
   address as what's already in the section table.  (This was also
   verified by Peter's empirical study.  See above.)

 - A section_add_info struct is created from the shared object's
   section offsets.  This is nothing more than putting the section
   offsets into a slightly different form so that we can pass them for
   purposes of doing symbol relocations to symbol_file_add().

 - Finally, the following line...

	sap->other[lowest_index].addr = lowest_addr;

   is attempting to assign the "lowest" address that we computed
   earlier to the corresponding address in the section_addr_info

   But this code is WRONG.  lowest_index is a BFD section index
   and if you look at the way that the section_addr_info struct
   is created, you'll see that it is possible for it to be created
   in such a way that the indices won't match those of the BFD
   section indices.  (In particular, only those sections whose
   SEC_ALLOC or SEC_LOAD flags are included in these sections.)

   In order for this code to be correct, we'd need to have
   a loop which looks for the bfd section index.

   If it was correct, however, it would turn out that it isn't
   doing anything useful since the addr field is already set

I've tested these changes on i686-pc-linux-gnu,
sparc-sun-solaris2.5.1, and sparc-sun-sunos4.1.4.  No regressions. 
Also, I've implemented a backend for AIX5/IA-64 which uses the
TARGET_SO_RELOCATE_SECTION_ADDRESSES machinery for sections that are
relocated by different amounts and it works quite well.  I will add
this file to the public repository this file as soon as IBM gives
their approval.

The one change that I haven't made from Peter's remarks above is
to add a "maint info sharedlibrary" command.  I agree that this
would be useful, but Peter has sent me some other comments that
have some bearing on this issue that should be addressed first.

Okay to commit?

	Changes based on analysis from Peter Schauer:
	* solist.h (struct so_list): Remove field lmend.
	(struct target_so_ops): Remove field lm_addr.  Add field
	relocate_section_addresses.  Add comments for all fields
	in this structure
	* solib-svr4.c (svr4_relocate_section_addresses): New function.
	(_initialize_svr4_solib): Remove lm_addr initialization.  Add
	initialization for relocate_section_addresses.
	* solib.c (solib_map_sections): Invoke 
	defunct TARGET_SO_LM_ADDR to relocate the section addresses.
	Also, eliminate assignment to the lmend field since this
	field no longer exists.
	(symbol_add_stub): Remove machinery for determining the lowest
	(info_sharedlibrary_command): Print the text section starting
	and ending addresses.
	(solib_address): Don't use TARGET_SO_LM_ADDR, nor so->lmend to
	determine if an address is in a shared object.  Instead, scan
	the section table and test against the starting and ending
	addresses for each section.

Index: solib-svr4.c
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.1
diff -u -p -r1.1 solib-svr4.c
--- solib-svr4.c	2000/10/24 20:05:35	1.1
+++ solib-svr4.c	2000/10/28 22:51:30
@@ -1567,12 +1567,20 @@ svr4_free_so (struct so_list *so)
   free (so->lm_info);
+static void
+svr4_relocate_section_addresses (struct so_list *so,
+                                 struct section_table *sec)
+  sec->addr += LM_ADDR (so);
+  sec->endaddr += LM_ADDR (so);
 static struct target_so_ops svr4_so_ops;
 _initialize_svr4_solib (void)
-  svr4_so_ops.lm_addr = LM_ADDR;
+  svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
   svr4_so_ops.free_so = svr4_free_so;
   svr4_so_ops.clear_solib = svr4_clear_solib;
   svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook;
Index: solib.c
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.25
diff -u -p -r1.25 solib.c
--- solib.c	2000/10/24 20:05:35	1.25
+++ solib.c	2000/10/28 22:51:32
@@ -180,9 +180,7 @@ solib_map_sections (PTR arg)
       /* Relocate the section binding addresses as recorded in the shared
          object's file by the base address to which the object was actually
          mapped. */
-      p->addr += TARGET_SO_LM_ADDR (so);
-      p->endaddr += TARGET_SO_LM_ADDR (so);
-      so->lmend = max (p->endaddr, so->lmend);
       if (STREQ (p->the_bfd_section->name, ".text"))
 	  so->textsection = p;
@@ -248,9 +246,6 @@ symbol_add_stub (PTR arg)
   register struct so_list *so = (struct so_list *) arg;  /* catch_errs bogon */
   struct section_addr_info *sap;
-  CORE_ADDR lowest_addr = 0;
-  int lowest_index;
-  asection *lowest_sect = NULL;
   /* Have we already loaded this shared object?  */
   ALL_OBJFILES (so->objfile)
@@ -259,35 +254,9 @@ symbol_add_stub (PTR arg)
 	return 1;
-  /* Find the shared object's text segment.  */
-  if (so->textsection)
-    {
-      lowest_addr = so->textsection->addr;
-      lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
-      lowest_index = lowest_sect->index;
-    }
-  else if (so->abfd != NULL)
-    {
-      /* If we didn't find a mapped non zero sized .text section, set
-         up lowest_addr so that the relocation in symbol_file_add does
-         no harm.  */
-      lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
-      if (lowest_sect == NULL)
-	bfd_map_over_sections (so->abfd, find_lowest_section,
-			       (PTR) &lowest_sect);
-      if (lowest_sect)
-	{
-	  lowest_addr = bfd_section_vma (so->abfd, lowest_sect)
-	    + TARGET_SO_LM_ADDR (so);
-	  lowest_index = lowest_sect->index;
-	}
-    }
   sap = build_section_addr_info_from_section_table (so->sections,
-  sap->other[lowest_index].addr = lowest_addr;
   so->objfile = symbol_file_add (so->so_name, so->from_tty,
 				 sap, 0, OBJF_SHARED);
   free_section_addr_info (sap);
@@ -610,12 +579,17 @@ info_sharedlibrary_command (char *ignore
 	  printf_unfiltered ("%-*s", addr_width,
-                             local_hex_string_custom (
-			       (unsigned long) TARGET_SO_LM_ADDR (so),
-	                       addr_fmt));
+			     so->textsection != NULL 
+			       ? local_hex_string_custom (
+			           (unsigned long) so->textsection->addr,
+	                           addr_fmt)
+			       : "");
 	  printf_unfiltered ("%-*s", addr_width,
-			 local_hex_string_custom ((unsigned long) so->lmend,
-						  addr_fmt));
+			     so->textsection != NULL 
+			       ? local_hex_string_custom (
+			           (unsigned long) so->textsection->endaddr,
+	                           addr_fmt)
+			       : "");
 	  printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No");
 	  printf_unfiltered ("%s\n", so->so_name);
@@ -640,10 +614,7 @@ info_sharedlibrary_command (char *ignore
    Provides a hook for other gdb routines to discover whether or
    not a particular address is within the mapped address space of
-   a shared library.  Any address between the base mapping address
-   and the first address beyond the end of the last mapping, is
-   considered to be within the shared library address space, for
-   our purposes.
+   a shared library.
    For example, this routine is called at one point to disable
    breakpoints which are in shared libraries that are not currently
@@ -657,8 +628,13 @@ solib_address (CORE_ADDR address)
   for (so = so_list_head; so; so = so->next)
-      if (TARGET_SO_LM_ADDR (so) <= address && address < so->lmend)
-	return (so->so_name);
+      struct section_table *p;
+      for (p = so->sections; p < so->sections_end; p++)
+	{
+	  if (p->addr <= address && address < p->endaddr)
+	    return (so->so_name);
+	}
   return (0);
Index: solist.h
RCS file: /cvs/src/src/gdb/solist.h,v
retrieving revision 1.1
diff -u -p -r1.1 solist.h
--- solist.h	2000/10/24 20:05:35	1.1
+++ solist.h	2000/10/28 22:51:32
@@ -54,7 +54,6 @@ struct so_list
        are initialized when we actually add it to our symbol tables.  */
     bfd *abfd;
-    CORE_ADDR lmend;		/* upper addr bound of mapped object */
     char symbols_loaded;	/* flag: symbols read in yet? */
     char from_tty;		/* flag: print msgs? */
     struct objfile *objfile;	/* objfile for loaded lib */
@@ -65,12 +64,30 @@ struct so_list
 struct target_so_ops
-    CORE_ADDR (*lm_addr) (struct so_list *so);
+    /* Adjust the section binding addresses by the base address at
+       which the object was actually mapped.  */
+    void (*relocate_section_addresses) (struct so_list *so,
+                                        struct section_table *);
+    /* Free the the link map info and any other private data
+       structures associated with a so_list entry.  */
     void (*free_so) (struct so_list *so);
+    /* Reset or free private data structures not associated with
+       so_list entries.  */
     void (*clear_solib) (void);
+    /* Target dependent code to run after child process fork.  */
     void (*solib_create_inferior_hook) (void);
+    /* Do additional symbol handling, lookup, etc. after symbols
+       for a shared object have been loaded.  */
     void (*special_symbol_handling) (void);
+    /* Construct a list of the currently loaded shared objects.  */
     struct so_list *(*current_sos) (void);
+    /* Find, open, and read the symbols for the main executable.  */
     int (*open_symbol_file_object) (void *from_ttyp);
@@ -79,7 +96,8 @@ void free_so (struct so_list *so);
 /* FIXME: gdbarch needs to control this variable */
 extern struct target_so_ops *current_target_so_ops;
-#define TARGET_SO_LM_ADDR (current_target_so_ops->lm_addr)
+  (current_target_so_ops->relocate_section_addresses)
 #define TARGET_SO_FREE_SO (current_target_so_ops->free_so)
 #define TARGET_SO_CLEAR_SOLIB (current_target_so_ops->clear_solib)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]