mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-16 07:27:56 +00:00
Add code for relocating dynamic executables.
This commit is contained in:
parent
ef5c4bfce0
commit
e2a44558ad
@ -1,3 +1,10 @@
|
||||
2000-11-09 Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
Changes based on a patch from Ulrich Drepper:
|
||||
* solib-svr4.c (svr4_relocate_main_executable): New function.
|
||||
(svr4_solib_create_inferior_hook): Call
|
||||
svr4_relocate_main_executable.
|
||||
|
||||
2000-11-09 J.T. Conklin <jtc@redback.com>
|
||||
|
||||
* config/i386/nbsd.mh: Remove solib.o, solib-svr4.o from NATDEPFILES.
|
||||
|
111
gdb/solib-svr4.c
111
gdb/solib-svr4.c
@ -1437,6 +1437,112 @@ svr4_special_symbol_handling (void)
|
||||
#endif /* !SVR4_SHARED_LIBS */
|
||||
}
|
||||
|
||||
/* 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
|
||||
svr4_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 (sizeof (struct section_offsets),
|
||||
symfile_objfile->num_sections);
|
||||
old_chain = make_cleanup (free, 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
|
||||
@ -1489,9 +1595,12 @@ svr4_special_symbol_handling (void)
|
||||
Also, what if child has exit()ed? Must exit loop somehow.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
svr4_solib_create_inferior_hook (void)
|
||||
{
|
||||
/* Relocate the main executable if necessary. */
|
||||
svr4_relocate_main_executable ();
|
||||
|
||||
/* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
|
||||
yet. In fact, in the case of a SunOS4 executable being run on
|
||||
Solaris, we can't get it yet. current_sos will get it when it needs
|
||||
|
Loading…
x
Reference in New Issue
Block a user