summaryrefslogtreecommitdiff
path: root/gdb/solib-aix5.c
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2001-04-17 02:29:23 +0000
committerKevin Buettner <kevinb@redhat.com>2001-04-17 02:29:23 +0000
commitd15da51a594382737fc4739da332de6995d9e1a8 (patch)
tree7ac1232c33af392f9bfff3a7501f2489b7fc84f0 /gdb/solib-aix5.c
parente103cd4491dc27cb989ec0138b1bf96dc2bb37e6 (diff)
downloadgdb-d15da51a594382737fc4739da332de6995d9e1a8.tar.gz
* solib-aix5.c (map_index_vs_section_name_okay): New function.
(aix5_relocate_main_executable): Don't use file offsets for determining corresponding sections and map file entries. Call map_index_vs_section_name_okay() to do this instead.
Diffstat (limited to 'gdb/solib-aix5.c')
-rw-r--r--gdb/solib-aix5.c131
1 files changed, 129 insertions, 2 deletions
diff --git a/gdb/solib-aix5.c b/gdb/solib-aix5.c
index 314408ec368..a48d4ae937e 100644
--- a/gdb/solib-aix5.c
+++ b/gdb/solib-aix5.c
@@ -562,6 +562,133 @@ aix5_special_symbol_handling (void)
/* Nothing needed (yet) for AIX5. */
}
+/* On AIX5, the /proc/PID/map information is used to determine
+ the relocation offsets needed for relocating the main executable.
+ There is no problem determining which map entries correspond
+ to the main executable, because these will have the MA_MAINEXEC
+ flag set. The tricky part is determining which sections correspond
+ to which map entries. To date, the following approaches have
+ been tried:
+
+ - Use the MA_WRITE attribute of pr_mflags to distinguish the read-only
+ mapping from the read/write mapping. (This assumes that there are
+ only two mappings for the main executable.) All writable sections
+ are associated with the read/write mapping and all non-writable
+ sections are associated with the read-only mapping.
+
+ This approach worked quite well until we came across executables
+ which didn't have a read-only mapping. Both mappings had the
+ same attributes represented in pr_mflags and it was impossible
+ to tell them apart.
+
+ - Use the pr_off field (which represents the offset into the
+ executable) to determine the section-to-mapping relationship.
+ Unfortunately, this approach doesn't work either, because the
+ offset value contained in the mapping is rounded down by some
+ moderately large power-of-2 value (4096 is a typical value).
+ A small (e.g. "Hello World") program will appear to have all
+ of its sections belonging to both mappings.
+
+ Also, the following approach has been considered, but dismissed:
+
+ - The section vma values typically look (something) like
+ 0x00000001xxxxxxxx or 0x00000002xxxxxxxx. Furthermore, the
+ 0x00000001xxxxxxxx values always belong to one mapping and
+ the 0x00000002xxxxxxxx values always belong to the other.
+ Thus it seems conceivable that GDB could use the bit patterns
+ in the upper portion (for some definition of "upper") in a
+ section's vma to help determine the section-to-mapping
+ relationship.
+
+ This approach was dismissed because there is nothing to prevent
+ the linker from lumping the section vmas together in one large
+ contiguous space and still expecting the dynamic linker to
+ separate them and relocate them independently. Also, different
+ linkers have been observed to use different patterns for the
+ upper portions of the vma addresses and it isn't clear what the
+ mask ought to be for distinguishing these patterns.
+
+ The current (admittedly inelegant) approach uses a lookup
+ table which associates section names with the map index that
+ they're permitted to be in. This is inelegant because we are
+ making the following assumptions:
+
+ 1) There will only be two mappings.
+ 2) The relevant (i.e. main executable) mappings will always appear
+ in the same order in the map file.
+ 3) The sections named in the table will always belong to the
+ indicated mapping.
+ 4) The table completely enumerates all possible section names.
+
+ IMO, any of these deficiencies alone will normally be sufficient
+ to disqualify this approach, but I haven't been able to think of
+ a better way to do it.
+
+ map_index_vs_section_name_okay() is a predicate which returns
+ true iff the section name NAME is associated with the map index
+ IDX in its builtin table. Of course, there's no guarantee that
+ this association is actually valid... */
+
+static int
+map_index_vs_section_name_okay (int idx, const char *name)
+{
+ static struct
+ {
+ char *name;
+ int idx;
+ } okay[] =
+ {
+ { ".interp", 0 },
+ { ".hash", 0 },
+ { ".dynsym", 0 },
+ { ".dynstr", 0 },
+ { ".rela.text", 0 },
+ { ".rela.rodata", 0 },
+ { ".rela.data", 0 },
+ { ".rela.ctors", 0 },
+ { ".rela.dtors", 0 },
+ { ".rela.got", 0 },
+ { ".rela.sdata", 0 },
+ { ".rela.IA_64.pltoff", 0 },
+ { ".rel.data", 0 },
+ { ".rel.sdata", 0 },
+ { ".rel.got", 0 },
+ { ".rel.AIX.pfdesc", 0 },
+ { ".rel.IA_64.pltoff", 0 },
+ { ".dynamic", 0 },
+ { ".init", 0 },
+ { ".plt", 0 },
+ { ".text", 0 },
+ { ".fini", 0 },
+ { ".rodata", 0 },
+ { ".IA_64.unwind_info", 0 },
+ { ".IA_64.unwind", 0 },
+ { ".AIX.mustrel", 0 },
+
+ { ".data", 1 },
+ { ".ctors", 1 },
+ { ".dtors", 1 },
+ { ".got", 1 },
+ { ".dynamic", 1},
+ { ".sdata", 1 },
+ { ".IA_64.pltoff", 1 },
+ { ".sbss", 1 },
+ { ".bss", 1 },
+ { ".AIX.pfdesc", 1 }
+ };
+ int i;
+
+ for (i = 0; i < sizeof (okay) / sizeof (okay[0]); i++)
+ {
+ if (strcmp (name, okay[i].name) == 0)
+ return idx == okay[i].idx;
+ }
+
+ warning ("solib-aix5.c: Ignoring section %s when relocating the executable\n",
+ name);
+ return 0;
+}
+
#define SECTMAPMASK (~ (CORE_ADDR) 0x03ffffff)
static void
@@ -608,8 +735,8 @@ aix5_relocate_main_executable (void)
if (flags & SEC_ALLOC)
{
file_ptr filepos = sect->the_bfd_section->filepos;
- if (mapping->offset <= filepos
- && filepos <= mapping->offset + mapping->size)
+ if (map_index_vs_section_name_okay (i,
+ bfd_get_section_name (obfd, sect->the_bfd_section)))
{
int idx = sect->the_bfd_section->index;