diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-06-18 15:46:38 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-06-18 15:46:38 +0000 |
commit | 31d99776c73d6fca13163da59c852b0fa99f89b8 (patch) | |
tree | 4dace09d40a34a22c8a02adcc688ae8c991973bb /gdb/elfread.c | |
parent | d856f2ddfa3d037987610ecc0edbf75f31296971 (diff) | |
download | gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.zip gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.tar.gz gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.tar.bz2 |
* coffread.c (coff_sym_fns): Add default_symfile_segments.
* dbxread.c (start_psymtab): Check HAVE_ELF.
(aout_sym_fns): Likewise.
* elfread.c (elf_symfile_segments): New.
(elf_sym_fns): Add elf_symfile_segments.
* mipsread.c (ecoff_sym_fns): Add default_symfile_segments.
* remote.c (get_offsets): Use symfile_map_offsets_to_segments.
Skip if there is no symfile_objfile. Handle TextSeg and DataSeg.
* somread.c (som_sym_fns): Use default_symfile_segments.
* symfile.c (find_sym_fns): Take a BFD and return the sym_fns.
(init_objfile_sect_indices): Call symfile_find_segment_sections.
(default_symfile_segments): New function.
(syms_from_objfile): Update call to find_sym_fns.
(symfile_get_segment_data, free_symfile_segment_data): New.
(symfile_map_offsets_to_segments): New.
(symfile_find_segment_sections): New.
* symfile.h (struct symfile_segment_data): New.
(struct sym_fns): Add sym_segments.
(default_symfile_segments, symfile_get_segment_data)
(free_symfile_segment_data): New prototypes.
(symfile_map_offsets_to_segments): Likewise.
* xcoffread.c (xcoff_sym_fns): Add default_symfile_segments.
* Makefile.in (COMMON_OBS): Remove elfread.o.
(elf_internal_h): New.
(elfread.o): Update.
* configure.ac: Add elfread.o to COMMON_OBS if bfd/elf.o was
compiled.
* config.in, configure: Regenerated.
* NEWS: Mention qOffsets changes.
* gdb.texinfo (General Query Packets): Document qOffsets changes.
* Makefile.def: Add dependency from configure-gdb to all-bfd.
* Makefile.in: Regenerated.
Diffstat (limited to 'gdb/elfread.c')
-rw-r--r-- | gdb/elfread.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/gdb/elfread.c b/gdb/elfread.c index ea28d7c..7b84ede 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -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 @@ -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 */ }; |