This is the mail archive of the gdb-patches@sources.redhat.com 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]
Other format: [Raw text]

[PATCH/RFA] Don't relocate SunOS-style a.out dynamic executables


Since I was curious whether our SunOS-style a.out shared library
support still worked, I fired up my virtual VAX[1] and installed
NetBSD 1.5.2 on it.  Alas, GDB didn't quite work, and indeed the
solib-sunos.c code is to blame.  Some debugging revealed that the code
was relocating the main executable over two bytes.  If you know a bit
about the VAX and look at the code it is pretty easy to see why.  VAX
functions start at an offset of two bytes from the function's address.
The code in sunos-solib.c:sunos_relocate_main_executable() compares
the PC with the entry point as recorded in the executable.  Since
these differ by two bytes, the code relocates the main executable over
those two bytes.  

The easiest way to solve the problem would be to rip out the code that
tries to relocate the executable.  AFAIK SunOS-style a.out executable
aren't relocatable.  This code is probably just a leftover from when
the SunOS code was split out of the SVR4 code.  Is that right?

If so, I'd like to apply the attached patch.

Mark

[1] The Computer History Simulation Project provides a pretty good VAX
    simulator as part of the SIMH package that runs NetBSD, OpenBSD,
    Ultrix and many other OS'es.  See http://simh.trailing-edge.com.


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>
 
	* solib-sunos.c (sunos_relocate_main_executable): Remove function.
	(sunos_solib_create_inferior_hook): Don't call
	sunos_relocate_main_executable.

	* infptrace.c: Remove #ifdef'ed out inclusion of gdb_stat.h.
	Reorder includes.
	(fetch_register, store_register): Remove prototypes.
	(child_resume): Reorganize code and comments such that it is
	grouped a bit more logically.
	(attach): Explicitly compare errno against 0.
	(detach): Likewise.  Use perror_with_name instead of
	print_sys_errmsg.

	* Makefile.in (infptrace.o): Update dependencies.

Index: solib-sunos.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-sunos.c,v
retrieving revision 1.14
diff -u -p -r1.14 solib-sunos.c
--- solib-sunos.c 9 Feb 2004 23:50:55 -0000 1.14
+++ solib-sunos.c 22 Aug 2004 18:35:00 -0000
@@ -643,112 +643,6 @@ sunos_special_symbol_handling (void)
     }
 }
 
-/* Relocate the main executable.  This function should be called upon
-   stopping the inferior process at the entry point to the program. 
-   The entry point from BFD is compared to the PC and if they are
-   different, the main executable is relocated by the proper amount. 
-   
-   As written it will only attempt to relocate executables which
-   lack interpreter sections.  It seems likely that only dynamic
-   linker executables will get relocated, though it should work
-   properly for a position-independent static executable as well.  */
-
-static void
-sunos_relocate_main_executable (void)
-{
-  asection *interp_sect;
-  CORE_ADDR pc = read_pc ();
-
-  /* Decide if the objfile needs to be relocated.  As indicated above,
-     we will only be here when execution is stopped at the beginning
-     of the program.  Relocation is necessary if the address at which
-     we are presently stopped differs from the start address stored in
-     the executable AND there's no interpreter section.  The condition
-     regarding the interpreter section is very important because if
-     there *is* an interpreter section, execution will begin there
-     instead.  When there is an interpreter section, the start address
-     is (presumably) used by the interpreter at some point to start
-     execution of the program.
-
-     If there is an interpreter, it is normal for it to be set to an
-     arbitrary address at the outset.  The job of finding it is
-     handled in enable_break().
-
-     So, to summarize, relocations are necessary when there is no
-     interpreter section and the start address obtained from the
-     executable is different from the address at which GDB is
-     currently stopped.
-     
-     [ The astute reader will note that we also test to make sure that
-       the executable in question has the DYNAMIC flag set.  It is my
-       opinion that this test is unnecessary (undesirable even).  It
-       was added to avoid inadvertent relocation of an executable
-       whose e_type member in the ELF header is not ET_DYN.  There may
-       be a time in the future when it is desirable to do relocations
-       on other types of files as well in which case this condition
-       should either be removed or modified to accomodate the new file
-       type.  (E.g, an ET_EXEC executable which has been built to be
-       position-independent could safely be relocated by the OS if
-       desired.  It is true that this violates the ABI, but the ABI
-       has been known to be bent from time to time.)  - Kevin, Nov 2000. ]
-     */
-
-  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
-  if (interp_sect == NULL 
-      && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
-      && bfd_get_start_address (exec_bfd) != pc)
-    {
-      struct cleanup *old_chain;
-      struct section_offsets *new_offsets;
-      int i, changed;
-      CORE_ADDR displacement;
-      
-      /* It is necessary to relocate the objfile.  The amount to
-	 relocate by is simply the address at which we are stopped
-	 minus the starting address from the executable.
-
-	 We relocate all of the sections by the same amount.  This
-	 behavior is mandated by recent editions of the System V ABI. 
-	 According to the System V Application Binary Interface,
-	 Edition 4.1, page 5-5:
-
-	   ...  Though the system chooses virtual addresses for
-	   individual processes, it maintains the segments' relative
-	   positions.  Because position-independent code uses relative
-	   addressesing between segments, the difference between
-	   virtual addresses in memory must match the difference
-	   between virtual addresses in the file.  The difference
-	   between the virtual address of any segment in memory and
-	   the corresponding virtual address in the file is thus a
-	   single constant value for any one executable or shared
-	   object in a given process.  This difference is the base
-	   address.  One use of the base address is to relocate the
-	   memory image of the program during dynamic linking.
-
-	 The same language also appears in Edition 4.0 of the System V
-	 ABI and is left unspecified in some of the earlier editions.  */
-
-      displacement = pc - bfd_get_start_address (exec_bfd);
-      changed = 0;
-
-      new_offsets = xcalloc (symfile_objfile->num_sections,
-			     sizeof (struct section_offsets));
-      old_chain = make_cleanup (xfree, new_offsets);
-
-      for (i = 0; i < symfile_objfile->num_sections; i++)
-	{
-	  if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
-	    changed = 1;
-	  new_offsets->offsets[i] = displacement;
-	}
-
-      if (changed)
-	objfile_relocate (symfile_objfile, new_offsets);
-
-      do_cleanups (old_chain);
-    }
-}
-
 /*
 
    GLOBAL FUNCTION
@@ -804,9 +698,6 @@ sunos_relocate_main_executable (void)
 static void
 sunos_solib_create_inferior_hook (void)
 {
-  /* Relocate the main executable if necessary.  */
-  sunos_relocate_main_executable ();
-
   if ((debug_base = locate_base ()) == 0)
     {
       /* Can't find the symbol or the executable is statically linked. */


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