diff options
Diffstat (limited to 'gdb/solib.c')
-rw-r--r-- | gdb/solib.c | 148 |
1 files changed, 88 insertions, 60 deletions
diff --git a/gdb/solib.c b/gdb/solib.c index ded9faee19e..a0af4b615a3 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -445,7 +445,7 @@ solib_add_common_symbols (rtc_symp) } init_minimal_symbol_collection (); - make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0); + make_cleanup_discard_minimal_symbols (); while (rtc_symp) { @@ -710,6 +710,7 @@ elf_locate_base () CORE_ADDR dyninfo_addr; char *buf; char *bufend; + int arch_size; /* Find the start address of the .dynamic section. */ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); @@ -726,56 +727,67 @@ elf_locate_base () /* Find the DT_DEBUG entry in the the .dynamic section. For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has no DT_DEBUG entries. */ -#ifndef TARGET_ELF64 - for (bufend = buf + dyninfo_sect_size; - buf < bufend; - buf += sizeof (Elf32_External_Dyn)) - { - Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf; - long dyn_tag; - CORE_ADDR dyn_ptr; - - dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag); - if (dyn_tag == DT_NULL) - break; - else if (dyn_tag == DT_DEBUG) + + arch_size = bfd_elf_get_arch_size (exec_bfd); + if (arch_size == -1) /* failure */ + return 0; + + if (arch_size == 32) + { /* 32-bit elf */ + for (bufend = buf + dyninfo_sect_size; + buf < bufend; + buf += sizeof (Elf32_External_Dyn)) { - dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - return dyn_ptr; - } + Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf; + long dyn_tag; + CORE_ADDR dyn_ptr; + + dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag); + if (dyn_tag == DT_NULL) + break; + else if (dyn_tag == DT_DEBUG) + { + dyn_ptr = bfd_h_get_32 (exec_bfd, + (bfd_byte *) x_dynp->d_un.d_ptr); + return dyn_ptr; + } #ifdef DT_MIPS_RLD_MAP - else if (dyn_tag == DT_MIPS_RLD_MAP) - { - char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT]; - - /* DT_MIPS_RLD_MAP contains a pointer to the address - of the dynamic link structure. */ - dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf))) - return 0; - return extract_unsigned_integer (pbuf, sizeof (pbuf)); - } + else if (dyn_tag == DT_MIPS_RLD_MAP) + { + char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT]; + + /* DT_MIPS_RLD_MAP contains a pointer to the address + of the dynamic link structure. */ + dyn_ptr = bfd_h_get_32 (exec_bfd, + (bfd_byte *) x_dynp->d_un.d_ptr); + if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf))) + return 0; + return extract_unsigned_integer (pbuf, sizeof (pbuf)); + } #endif + } } -#else /* ELF64 */ - for (bufend = buf + dyninfo_sect_size; - buf < bufend; - buf += sizeof (Elf64_External_Dyn)) + else /* 64-bit elf */ { - Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf; - long dyn_tag; - CORE_ADDR dyn_ptr; - - dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag); - if (dyn_tag == DT_NULL) - break; - else if (dyn_tag == DT_DEBUG) + for (bufend = buf + dyninfo_sect_size; + buf < bufend; + buf += sizeof (Elf64_External_Dyn)) { - dyn_ptr = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - return dyn_ptr; + Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf; + long dyn_tag; + CORE_ADDR dyn_ptr; + + dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag); + if (dyn_tag == DT_NULL) + break; + else if (dyn_tag == DT_DEBUG) + { + dyn_ptr = bfd_h_get_64 (exec_bfd, + (bfd_byte *) x_dynp->d_un.d_ptr); + return dyn_ptr; + } } } -#endif /* DT_DEBUG entry not found. */ return 0; @@ -972,7 +984,7 @@ open_symbol_file_object (from_ttyp) return 0; } - make_cleanup ((make_cleanup_func) free, (void *) filename); + make_cleanup (free, filename); /* Have a pathname: read the symbol file. */ symbol_file_command (filename, *from_ttyp); @@ -1153,8 +1165,10 @@ symbol_add_stub (arg) PTR arg; { register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ - CORE_ADDR text_addr = 0; struct section_addr_info *sap; + CORE_ADDR lowest_addr = 0; + int lowest_index; + asection *lowest_sect = NULL; /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) @@ -1165,25 +1179,33 @@ symbol_add_stub (arg) /* Find the shared object's text segment. */ if (so->textsection) - text_addr = so->textsection->addr; + { + lowest_addr = so->textsection->addr; + lowest_sect = bfd_get_section_by_name (so->abfd, ".text"); + lowest_index = lowest_sect->index; + } else if (so->abfd != NULL) { - asection *lowest_sect; - - /* If we didn't find a mapped non zero sized .text section, set up - text_addr so that the relocation in symbol_file_add does no harm. */ + /* If we didn't find a mapped non zero sized .text section, set + up lowest_addr so that the relocation in symbol_file_add does + no harm. */ lowest_sect = bfd_get_section_by_name (so->abfd, ".text"); if (lowest_sect == NULL) bfd_map_over_sections (so->abfd, find_lowest_section, (PTR) &lowest_sect); if (lowest_sect) - text_addr = bfd_section_vma (so->abfd, lowest_sect) - + LM_ADDR (so); + { + lowest_addr = bfd_section_vma (so->abfd, lowest_sect) + + LM_ADDR (so); + lowest_index = lowest_sect->index; + } } sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); - sap->text_addr = text_addr; + + sap->other[lowest_index].addr = lowest_addr; + so->objfile = symbol_file_add (so->so_name, so->from_tty, sap, 0, OBJF_SHARED); free_section_addr_info (sap); @@ -1475,6 +1497,7 @@ info_sharedlibrary_command (ignore, from_tty) int header_done = 0; int addr_width; char *addr_fmt; + int arch_size; if (exec_bfd == NULL) { @@ -1482,13 +1505,18 @@ info_sharedlibrary_command (ignore, from_tty) return; } -#ifndef TARGET_ELF64 - addr_width = 8 + 4; - addr_fmt = "08l"; -#else - addr_width = 16 + 4; - addr_fmt = "016l"; -#endif + arch_size = bfd_elf_get_arch_size (exec_bfd); + /* Default to 32-bit in case of failure (non-elf). */ + if (arch_size == 32 || arch_size == -1) + { + addr_width = 8 + 4; + addr_fmt = "08l"; + } + else if (arch_size == 64) + { + addr_width = 16 + 4; + addr_fmt = "016l"; + } update_solib_list (from_tty, 0); |