]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/elfread.c
* coffread.c (coff_sym_fns): Add default_symfile_segments.
[thirdparty/binutils-gdb.git] / gdb / elfread.c
index a80b8f0854823879289c3818a5c94b54e0a2a1eb..7b84ede6c7165f329f12667307e587b4c3a2f8e1 100644 (file)
@@ -26,6 +26,8 @@
 #include "bfd.h"
 #include "gdb_string.h"
 #include "elf-bfd.h"
+#include "elf/common.h"
+#include "elf/internal.h"
 #include "elf/mips.h"
 #include "symtab.h"
 #include "symfile.h"
@@ -51,6 +53,76 @@ struct elfinfo
 
 static void free_elfinfo (void *);
 
+/* Locate the segments in ABFD.  */
+
+static struct symfile_segment_data *
+elf_symfile_segments (bfd *abfd)
+{
+  Elf_Internal_Phdr *phdrs, **segments;
+  long phdrs_size;
+  int num_phdrs, num_segments, num_sections, i;
+  asection *sect;
+  struct symfile_segment_data *data;
+
+  phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
+  if (phdrs_size == -1)
+    return NULL;
+
+  phdrs = alloca (phdrs_size);
+  num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
+  if (num_phdrs == -1)
+    return NULL;
+
+  num_segments = 0;
+  segments = alloca (sizeof (Elf_Internal_Phdr *) * num_phdrs);
+  for (i = 0; i < num_phdrs; i++)
+    if (phdrs[i].p_type == PT_LOAD)
+      segments[num_segments++] = &phdrs[i];
+
+  if (num_segments == 0)
+    return NULL;
+
+  data = XZALLOC (struct symfile_segment_data);
+  data->num_segments = num_segments;
+  data->segment_bases = XCALLOC (num_segments, CORE_ADDR);
+  data->segment_sizes = XCALLOC (num_segments, CORE_ADDR);
+
+  for (i = 0; i < num_segments; i++)
+    {
+      data->segment_bases[i] = segments[i]->p_vaddr;
+      data->segment_sizes[i] = segments[i]->p_memsz;
+    }
+
+  num_sections = bfd_count_sections (abfd);
+  data->segment_info = XCALLOC (num_sections, int);
+
+  for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+    {
+      int j;
+      CORE_ADDR vma;
+
+      if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+       continue;
+
+      vma = bfd_get_section_vma (abfd, sect);
+
+      for (j = 0; j < num_segments; j++)
+       if (segments[j]->p_memsz > 0
+           && vma >= segments[j]->p_vaddr
+           && vma < segments[j]->p_vaddr + segments[j]->p_memsz)
+         {
+           data->segment_info[i] = j + 1;
+           break;
+         }
+
+      if (bfd_get_section_size (sect) > 0 && j == num_segments)
+       warning (_("Loadable segment \"%s\" outside of ELF segments"),
+                bfd_section_name (abfd, sect));
+    }
+
+  return data;
+}
+
 /* We are called once per section from elf_symfile_read.  We
    need to examine each section we are passed, check to see
    if it is something we are interested in processing, and
@@ -96,7 +168,7 @@ record_minimal_symbol (char *name, CORE_ADDR address,
                       asection *bfd_section, struct objfile *objfile)
 {
   if (ms_type == mst_text || ms_type == mst_file_text)
-    address = SMASH_TEXT_ADDRESS (address);
+    address = gdbarch_smash_text_address (current_gdbarch, address);
 
   return prim_record_minimal_symbol_and_info
     (name, address, ms_type, NULL, bfd_section->index, bfd_section, objfile);
@@ -410,7 +482,7 @@ elf_symtab_read (struct objfile *objfile, int dynamic,
          if (msym != NULL)
            msym->filename = filesymname;
 #endif
-         ELF_MAKE_MSYMBOL_SPECIAL (sym, msym);
+         gdbarch_elf_make_msymbol_special (current_gdbarch, sym, msym);
        }
     }
 }
@@ -741,6 +813,8 @@ static struct sym_fns elf_sym_fns =
   elf_symfile_read,            /* sym_read: read a symbol file into symtab */
   elf_symfile_finish,          /* sym_finish: finished with file, cleanup */
   default_symfile_offsets,     /* sym_offsets:  Translate ext. to int. relocation */
+  elf_symfile_segments,                /* sym_segments: Get segment information from
+                                  a file.  */
   NULL                         /* next: pointer to next struct sym_fns */
 };