* solib-aix5.c (map_index_vs_section_name_okay): New function.
authorKevin Buettner <kevinb@redhat.com>
Tue, 17 Apr 2001 02:29:23 +0000 (02:29 +0000)
committerKevin Buettner <kevinb@redhat.com>
Tue, 17 Apr 2001 02:29:23 +0000 (02:29 +0000)
(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.

gdb/ChangeLog
gdb/solib-aix5.c

index c5f633038fa2b94e174855d689b846081833ac06..6d2e4b33e4386d25a1944f58b56ff228d4d71a3d 100644 (file)
@@ -1,3 +1,10 @@
+2001-04-16  Kevin Buettner  <kevinb@redhat.com>
+
+       * 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.
+
 2001-04-16  Kevin Buettner  <kevinb@redhat.com>
 
        * procfs.c (open_with_retry): New function.
index 314408ec3687b86f1459fc6e29d1bb477d7f1669..a48d4ae937ea6fef65ddc4f81fe787072544287a 100644 (file)
@@ -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;