[gdb] Handle .TOC. sections during gdb-compile for rs6000 target.
authorWill Schmidt <will_schmidt@vnet.ibm.com>
Thu, 5 Aug 2021 17:46:32 +0000 (12:46 -0500)
committerWill Schmidt <will_schmidt@vnet.ibm.com>
Thu, 5 Aug 2021 17:46:32 +0000 (12:46 -0500)
[gdb] Handle .TOC. sections during gdb-compile for rs6000 target.

  When we encounter a .TOC. symbol in the object we are loading,
we need to associate this with the .toc section in order to
properly resolve other symbols in the object.  IF a .toc section
is not found, iterate the sections until we find one with the
SEC_ALLOC flag.  If that also fails, fall back to using
the *ABS* section, pointed to by bfd_abs_section_ptr.

gdb/compile/compile-object-load.c

index 1c512801bcdfa355b8253116a1df8d0420a16cd7..a25eb6142c7e2fae4b01b27c6225d034e31754d9 100644 (file)
@@ -722,6 +722,47 @@ compile_object_load (const compile_file_names &file_names,
          sym->value = 0;
          continue;
        }
+      if (strcmp (sym->name, ".TOC.") == 0)
+       {
+         /* Handle the .TOC. symbol as the linker would do.  Set the .TOC.
+            sections value to 0x8000 (see bfd/elf64-ppc.c TOC_BASE_OFF);
+            point the symbol section at the ".toc" section;
+            and pass the toc->vma value into bfd_set_gp_value().
+            If the .toc section is not found, use the first section
+            with the SEC_ALLOC flag set.  In the unlikely case that
+            we still do not have a section identified, fall back to using
+            the "*ABS*" section.  */
+         asection *toc_fallback = bfd_get_section_by_name(abfd.get(), ".toc");
+         if (toc_fallback == NULL)
+           {
+             for (asection *tsect = abfd->sections; tsect != nullptr;
+                  tsect = tsect->next)
+                {
+                   if (bfd_section_flags (tsect) & SEC_ALLOC)
+                      {
+                         toc_fallback = tsect;
+                         break;
+                      }
+                }
+           }
+
+         if (toc_fallback == NULL)
+           /*  If we've gotten here, we have not found a section usable
+               as a backup for the .toc section.  In this case, use the
+               absolute (*ABS*) section.  */
+            toc_fallback = bfd_abs_section_ptr;
+
+         sym->section = toc_fallback;
+         sym->value = 0x8000;
+         bfd_set_gp_value(abfd.get(), toc_fallback->vma);
+         if (compile_debug)
+           fprintf_unfiltered (gdb_stdlog,
+                               "Connectiong ELF symbol \"%s\" to the .toc section (%s)\n",
+                               sym->name,
+                               paddress (target_gdbarch (), sym->value));
+         continue;
+       }
+
       bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
       switch (bmsym.minsym == NULL
              ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))