aboutsummaryrefslogtreecommitdiff
path: root/gdb/solib-svr4.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2010-01-14 20:48:26 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2010-01-14 20:48:26 +0000
commitb8040f198caee93044ccfc5aacaa0c3244057b0a (patch)
tree377164e5942eca841914b8e2169f7962d72e3275 /gdb/solib-svr4.c
parenta2a7d12cfc7afce610d6f2c45e7f8883668c9c56 (diff)
downloadgdb-b8040f198caee93044ccfc5aacaa0c3244057b0a.zip
gdb-b8040f198caee93044ccfc5aacaa0c3244057b0a.tar.gz
gdb-b8040f198caee93044ccfc5aacaa0c3244057b0a.tar.bz2
gdb/
* solib-svr4.c (svr4_relocate_main_executable): Move the static exec code part to ... (svr4_static_exec_displacement): ... a new function. (svr4_exec_displacement): New function. (svr4_relocate_main_executable): Call svr4_exec_displacement. Allocate new_offsets using alloca now. Remove variable old_chain and changed. Call objfile_relocate unconditionally now. gdb/testsuite/ * gdb.base/break-interp.exp: New file.
Diffstat (limited to 'gdb/solib-svr4.c')
-rw-r--r--gdb/solib-svr4.c184
1 files changed, 96 insertions, 88 deletions
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 00e16b0..3ad067a 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1535,111 +1535,119 @@ svr4_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.
+/* 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.
- 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. */
+ [ 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. ]
+ */
-static void
-svr4_relocate_main_executable (void)
+static CORE_ADDR
+svr4_static_exec_displacement (void)
{
asection *interp_sect;
struct regcache *regcache
= get_thread_arch_regcache (inferior_ptid, target_gdbarch);
CORE_ADDR pc = regcache_read_pc (regcache);
- /* 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
&& (exec_entry_point (exec_bfd, &exec_ops) != pc))
+ return pc - exec_entry_point (exec_bfd, &exec_ops);
+
+ return 0;
+}
+
+/* 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. */
+
+static CORE_ADDR
+svr4_exec_displacement (void)
+{
+ int found;
+ CORE_ADDR entry_point;
+
+ if (exec_bfd == NULL)
+ return 0;
+
+ if (target_auxv_search (&current_target, AT_ENTRY, &entry_point) == 1)
+ return entry_point - exec_entry_point (exec_bfd, &current_target);
+
+ return svr4_static_exec_displacement ();
+}
+
+/* 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 AT_ENTRY of AUXV and if they are
+ different, the main executable is relocated by the proper amount. */
+
+static void
+svr4_relocate_main_executable (void)
+{
+ CORE_ADDR displacement = svr4_exec_displacement ();
+
+ /* Even if DISPLACEMENT is 0 still try to relocate it as this is a new
+ difference of in-memory vs. in-file addresses and we could already
+ relocate the executable at this function to improper address before. */
+
+ if (symfile_objfile)
{
- 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 - exec_entry_point (exec_bfd, &exec_ops);
- changed = 0;
-
- new_offsets = xcalloc (symfile_objfile->num_sections,
- sizeof (struct section_offsets));
- old_chain = make_cleanup (xfree, new_offsets);
+ int i;
- for (i = 0; i < symfile_objfile->num_sections; i++)
- {
- if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
- changed = 1;
- new_offsets->offsets[i] = displacement;
- }
+ new_offsets = alloca (symfile_objfile->num_sections
+ * sizeof (*new_offsets));
- if (changed)
- objfile_relocate (symfile_objfile, new_offsets);
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ new_offsets->offsets[i] = displacement;
- do_cleanups (old_chain);
+ objfile_relocate (symfile_objfile, new_offsets);
}
}