X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsolib-frv.c;h=10476f6250c94554c7ca6adef4609b34424fb018;hb=5f23a08201ed01570b34f5cff99a95fc7b9e2fdb;hp=6b6ff15fddceade5f319e9dcbbf0e56e69ea1eb4;hpb=1cf3db46a678ced9d729572de9232fab9c00350d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 6b6ff15fdd..10476f6250 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -1,5 +1,5 @@ /* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger. - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -18,7 +18,6 @@ #include "defs.h" -#include "gdb_string.h" #include "inferior.h" #include "gdbcore.h" #include "solib.h" @@ -30,9 +29,10 @@ #include "command.h" #include "gdbcmd.h" #include "elf/frv.h" +#include "gdb_bfd.h" /* Flag which indicates whether internal debug messages should be printed. */ -static int solib_frv_debug; +static unsigned int solib_frv_debug; /* FR-V pointers are four bytes wide. */ enum { FRV_PTR_SIZE = 4 }; @@ -96,6 +96,7 @@ struct int_elf32_fdpic_loadmap { static struct int_elf32_fdpic_loadmap * fetch_loadmap (CORE_ADDR ldmaddr) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); struct ext_elf32_fdpic_loadmap ext_ldmbuf_partial; struct ext_elf32_fdpic_loadmap *ext_ldmbuf; struct int_elf32_fdpic_loadmap *int_ldmbuf; @@ -112,7 +113,8 @@ fetch_loadmap (CORE_ADDR ldmaddr) /* Extract the version. */ version = extract_unsigned_integer (ext_ldmbuf_partial.version, - sizeof ext_ldmbuf_partial.version); + sizeof ext_ldmbuf_partial.version, + byte_order); if (version != 0) { /* We only handle version 0. */ @@ -121,12 +123,16 @@ fetch_loadmap (CORE_ADDR ldmaddr) /* Extract the number of segments. */ nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs, - sizeof ext_ldmbuf_partial.nsegs); + sizeof ext_ldmbuf_partial.nsegs, + byte_order); + + if (nsegs <= 0) + return NULL; /* Allocate space for the complete (external) loadmap. */ ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap) + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg); - ext_ldmbuf = xmalloc (ext_ldmbuf_size); + ext_ldmbuf = (struct ext_elf32_fdpic_loadmap *) xmalloc (ext_ldmbuf_size); /* Copy over the portion of the loadmap that's already been read. */ memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial); @@ -145,7 +151,7 @@ fetch_loadmap (CORE_ADDR ldmaddr) external loadsegs. I.e, allocate the internal loadsegs. */ int_ldmbuf_size = sizeof (struct int_elf32_fdpic_loadmap) + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg); - int_ldmbuf = xmalloc (int_ldmbuf_size); + int_ldmbuf = (struct int_elf32_fdpic_loadmap *) xmalloc (int_ldmbuf_size); /* Place extracted information in internal structs. */ int_ldmbuf->version = version; @@ -154,13 +160,16 @@ fetch_loadmap (CORE_ADDR ldmaddr) { int_ldmbuf->segs[seg].addr = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr, - sizeof (ext_ldmbuf->segs[seg].addr)); + sizeof (ext_ldmbuf->segs[seg].addr), + byte_order); int_ldmbuf->segs[seg].p_vaddr = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr, - sizeof (ext_ldmbuf->segs[seg].p_vaddr)); + sizeof (ext_ldmbuf->segs[seg].p_vaddr), + byte_order); int_ldmbuf->segs[seg].p_memsz = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz, - sizeof (ext_ldmbuf->segs[seg].p_memsz)); + sizeof (ext_ldmbuf->segs[seg].p_memsz), + byte_order); } xfree (ext_ldmbuf); @@ -191,148 +200,53 @@ struct ext_link_map ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */ }; -/* Link map info to include in an allocated so_list entry */ +/* Link map info to include in an allocated so_list entry. */ -struct lm_info +struct lm_info_frv : public lm_info_base +{ + ~lm_info_frv () { - /* The loadmap, digested into an easier to use form. */ - struct int_elf32_fdpic_loadmap *map; - /* The GOT address for this link map entry. */ - CORE_ADDR got_value; - /* The link map address, needed for frv_fetch_objfile_link_map(). */ - CORE_ADDR lm_addr; - - /* Cached dynamic symbol table and dynamic relocs initialized and - used only by find_canonical_descriptor_in_load_object(). - - Note: kevinb/2004-02-26: It appears that calls to - bfd_canonicalize_dynamic_reloc() will use the same symbols as - those supplied to the first call to this function. Therefore, - it's important to NOT free the asymbol ** data structure - supplied to the first call. Thus the caching of the dynamic - symbols (dyn_syms) is critical for correct operation. The - caching of the dynamic relocations could be dispensed with. */ - asymbol **dyn_syms; - arelent **dyn_relocs; - int dyn_reloc_count; /* number of dynamic relocs. */ - - }; + xfree (this->map); + xfree (this->dyn_syms); + xfree (this->dyn_relocs); + } + + /* The loadmap, digested into an easier to use form. */ + int_elf32_fdpic_loadmap *map = NULL; + /* The GOT address for this link map entry. */ + CORE_ADDR got_value = 0; + /* The link map address, needed for frv_fetch_objfile_link_map(). */ + CORE_ADDR lm_addr = 0; + + /* Cached dynamic symbol table and dynamic relocs initialized and + used only by find_canonical_descriptor_in_load_object(). + + Note: kevinb/2004-02-26: It appears that calls to + bfd_canonicalize_dynamic_reloc() will use the same symbols as + those supplied to the first call to this function. Therefore, + it's important to NOT free the asymbol ** data structure + supplied to the first call. Thus the caching of the dynamic + symbols (dyn_syms) is critical for correct operation. The + caching of the dynamic relocations could be dispensed with. */ + asymbol **dyn_syms = NULL; + arelent **dyn_relocs = NULL; + int dyn_reloc_count = 0; /* Number of dynamic relocs. */ +}; /* The load map, got value, etc. are not available from the chain of loaded shared objects. ``main_executable_lm_info'' provides a way to get at this information so that it doesn't need to be frequently recomputed. Initialized by frv_relocate_main_executable(). */ -static struct lm_info *main_executable_lm_info; +static lm_info_frv *main_executable_lm_info; static void frv_relocate_main_executable (void); static CORE_ADDR main_got (void); static int enable_break2 (void); -/* - - LOCAL FUNCTION - - bfd_lookup_symbol -- lookup the value for a specific symbol - - SYNOPSIS - - CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) - - DESCRIPTION - - An expensive way to lookup the value of a single symbol for - bfd's that are only temporary anyway. This is used by the - shared library support to find the address of the debugger - interface structures in the shared library. - - Note that 0 is specifically allowed as an error return (no - such symbol). - */ - -static CORE_ADDR -bfd_lookup_symbol (bfd *abfd, char *symname) -{ - long storage_needed; - asymbol *sym; - asymbol **symbol_table; - unsigned int number_of_symbols; - unsigned int i; - struct cleanup *back_to; - CORE_ADDR symaddr = 0; - - storage_needed = bfd_get_symtab_upper_bound (abfd); - - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (xfree, symbol_table); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); - - for (i = 0; i < number_of_symbols; i++) - { - sym = *symbol_table++; - if (strcmp (sym->name, symname) == 0) - { - /* Bfd symbols are section relative. */ - symaddr = sym->value + sym->section->vma; - break; - } - } - do_cleanups (back_to); - } - - if (symaddr) - return symaddr; - - /* Look for the symbol in the dynamic string table too. */ - - storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); - - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (xfree, symbol_table); - number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table); - - for (i = 0; i < number_of_symbols; i++) - { - sym = *symbol_table++; - if (strcmp (sym->name, symname) == 0) - { - /* Bfd symbols are section relative. */ - symaddr = sym->value + sym->section->vma; - break; - } - } - do_cleanups (back_to); - } - - return symaddr; -} - - -/* - - LOCAL FUNCTION - - open_symbol_file_object - - SYNOPSIS - - void open_symbol_file_object (void *from_tty) - - DESCRIPTION - - If no open symbol file, attempt to locate and open the main symbol - file. - - If FROM_TTYP dereferences to a non-zero integer, allow messages to - be printed. This parameter is a pointer rather than an int because - open_symbol_file_object() is called via catch_errors() and - catch_errors() requires a pointer argument. */ +/* Implement the "open_symbol_file_object" target_so_ops method. */ static int -open_symbol_file_object (void *from_ttyp) +open_symbol_file_object (int from_tty) { /* Unimplemented. */ return 0; @@ -355,7 +269,8 @@ static CORE_ADDR main_lm_addr = 0; static CORE_ADDR lm_base (void) { - struct minimal_symbol *got_sym; + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); + struct bound_minimal_symbol got_sym; CORE_ADDR addr; gdb_byte buf[FRV_PTR_SIZE]; @@ -373,7 +288,7 @@ lm_base (void) got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile); - if (got_sym == 0) + if (got_sym.minsym == 0) { if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, @@ -381,7 +296,7 @@ lm_base (void) return 0; } - addr = SYMBOL_VALUE_ADDRESS (got_sym) + 8; + addr = BMSYMBOL_VALUE_ADDRESS (got_sym) + 8; if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, @@ -390,7 +305,7 @@ lm_base (void) if (target_read_memory (addr, buf, sizeof buf) != 0) return 0; - lm_base_cache = extract_unsigned_integer (buf, sizeof buf); + lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order); if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, @@ -401,28 +316,12 @@ lm_base (void) } -/* LOCAL FUNCTION - - frv_current_sos -- build a list of currently loaded shared objects - - SYNOPSIS - - struct so_list *frv_current_sos () - - DESCRIPTION - - Build a list of `struct so_list' objects describing the shared - objects currently loaded in the inferior. This list does not - include an entry for the main executable file. - - Note that we only gather information directly available from the - inferior --- we don't examine any of the shared library files - themselves. The declaration of `struct so_list' says which fields - we provide values for. */ +/* Implement the "current_sos" target_so_ops method. */ static struct so_list * frv_current_sos (void) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); CORE_ADDR lm_addr, mgot; struct so_list *sos_head = NULL; struct so_list **sos_next_ptr = &sos_head; @@ -433,11 +332,11 @@ frv_current_sos (void) for details.) Note that the relocation of the main executable is also performed - by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core + by solib_create_inferior_hook(), however, in the case of core files, this hook is called too late in order to be of benefit to - SOLIB_ADD. SOLIB_ADD eventually calls this this function, + solib_add. solib_add eventually calls this this function, frv_current_sos, and also precedes the call to - SOLIB_CREATE_INFERIOR_HOOK(). (See post_create_inferior() in + solib_create_inferior_hook(). (See post_create_inferior() in infcmd.c.) */ if (main_executable_lm_info == 0 && core_bfd != NULL) frv_relocate_main_executable (); @@ -448,7 +347,7 @@ frv_current_sos (void) /* Locate the address of the first link map struct. */ lm_addr = lm_base (); - /* We have at least one link map entry. Fetch the the lot of them, + /* We have at least one link map entry. Fetch the lot of them, building the solist chain. */ while (lm_addr) { @@ -460,59 +359,66 @@ frv_current_sos (void) "current_sos: reading link_map entry at %s\n", hex_string_custom (lm_addr, 8)); - if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf)) != 0) + if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf, + sizeof (lm_buf)) != 0) { - warning (_("frv_current_sos: Unable to read link map entry. Shared object chain may be incomplete.")); + warning (_("frv_current_sos: Unable to read link map entry. " + "Shared object chain may be incomplete.")); break; } got_addr = extract_unsigned_integer (lm_buf.l_addr.got_value, - sizeof (lm_buf.l_addr.got_value)); + sizeof (lm_buf.l_addr.got_value), + byte_order); /* If the got_addr is the same as mgotr, then we're looking at the entry for the main executable. By convention, we don't include this in the list of shared objects. */ if (got_addr != mgot) { int errcode; - char *name_buf; + gdb::unique_xmalloc_ptr name_buf; struct int_elf32_fdpic_loadmap *loadmap; struct so_list *sop; CORE_ADDR addr; /* Fetch the load map address. */ addr = extract_unsigned_integer (lm_buf.l_addr.map, - sizeof lm_buf.l_addr.map); + sizeof lm_buf.l_addr.map, + byte_order); loadmap = fetch_loadmap (addr); if (loadmap == NULL) { - warning (_("frv_current_sos: Unable to fetch load map. Shared object chain may be incomplete.")); + warning (_("frv_current_sos: Unable to fetch load map. " + "Shared object chain may be incomplete.")); break; } - sop = xcalloc (1, sizeof (struct so_list)); - sop->lm_info = xcalloc (1, sizeof (struct lm_info)); - sop->lm_info->map = loadmap; - sop->lm_info->got_value = got_addr; - sop->lm_info->lm_addr = lm_addr; + sop = XCNEW (struct so_list); + lm_info_frv *li = new lm_info_frv; + sop->lm_info = li; + li->map = loadmap; + li->got_value = got_addr; + li->lm_addr = lm_addr; /* Fetch the name. */ addr = extract_unsigned_integer (lm_buf.l_name, - sizeof (lm_buf.l_name)); + sizeof (lm_buf.l_name), + byte_order); target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n", - name_buf); + name_buf.get ()); if (errcode != 0) warning (_("Can't read pathname for link map entry: %s."), safe_strerror (errcode)); else { - strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1); + strncpy (sop->so_name, name_buf.get (), + SO_NAME_MAX_PATH_SIZE - 1); sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; - xfree (name_buf); strcpy (sop->so_original_name, sop->so_name); } @@ -524,7 +430,8 @@ frv_current_sos (void) main_lm_addr = lm_addr; } - lm_addr = extract_unsigned_integer (lm_buf.l_next, sizeof (lm_buf.l_next)); + lm_addr = extract_unsigned_integer (lm_buf.l_next, + sizeof (lm_buf.l_next), byte_order); } enable_break2 (); @@ -546,13 +453,13 @@ frv_in_dynsym_resolve_code (CORE_ADDR pc) { return ((pc >= interp_text_sect_low && pc < interp_text_sect_high) || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high) - || in_plt_section (pc, NULL)); + || in_plt_section (pc)); } /* Given a loadmap and an address, return the displacement needed to relocate the address. */ -CORE_ADDR +static CORE_ADDR displacement_from_map (struct int_elf32_fdpic_loadmap *map, CORE_ADDR addr) { @@ -581,17 +488,15 @@ enable_break_failure_warning (void) "and track explicitly loaded dynamic code.")); } -/* - - LOCAL FUNCTION - - enable_break -- arrange for dynamic linker to hit breakpoint - - SYNOPSIS +/* Helper function for gdb_bfd_lookup_symbol. */ - int enable_break (void) +static int +cmp_name (const asymbol *sym, const void *data) +{ + return (strcmp (sym->name, (const char *) data) == 0); +} - DESCRIPTION +/* Arrange for dynamic linker to hit breakpoint. The dynamic linkers has, as part of its debugger interface, support for arranging for the inferior to hit a breakpoint after mapping in @@ -611,29 +516,19 @@ enable_break_failure_warning (void) using the interpreter's loadmap. Once the relocated address is known, we fetch the value (address) corresponding to r_brk and then use that value to fetch the entry point of the function - we're interested in. - - */ + we're interested in. */ -static int enable_break1_done = 0; static int enable_break2_done = 0; static int enable_break2 (void) { - int success = 0; - char **bkpt_namep; + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); asection *interp_sect; - if (!enable_break1_done || enable_break2_done) + if (enable_break2_done) return 1; - enable_break2_done = 1; - - /* First, remove all the solib event breakpoints. Their addresses - may have changed since the last time we ran the program. */ - remove_solib_event_breakpoints (); - interp_text_sect_low = interp_text_sect_high = 0; interp_plt_sect_low = interp_plt_sect_high = 0; @@ -643,10 +538,7 @@ enable_break2 (void) if (interp_sect) { unsigned int interp_sect_size; - gdb_byte *buf; - bfd *tmp_bfd = NULL; - int tmp_fd = -1; - char *tmp_pathname = NULL; + char *buf; int status; CORE_ADDR addr, interp_loadmap_addr; gdb_byte addr_buf[FRV_PTR_SIZE]; @@ -654,8 +546,8 @@ enable_break2 (void) /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ - interp_sect_size = bfd_section_size (exec_bfd, interp_sect); - buf = alloca (interp_sect_size); + interp_sect_size = bfd_section_size (interp_sect); + buf = (char *) alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); @@ -668,32 +560,27 @@ enable_break2 (void) be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ - tmp_fd = solib_open (buf, &tmp_pathname); - if (tmp_fd >= 0) - tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd); - - if (tmp_bfd == NULL) + gdb_bfd_ref_ptr tmp_bfd; + try + { + tmp_bfd = solib_bfd_open (buf); + } + catch (const gdb_exception &ex) { - enable_break_failure_warning (); - return 0; } - /* Make sure the dynamic linker is really a useful object. */ - if (!bfd_check_format (tmp_bfd, bfd_object)) + if (tmp_bfd == NULL) { - warning (_("Unable to grok dynamic linker %s as an object file"), buf); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } - status = frv_fdpic_loadmap_addresses (target_gdbarch, + status = frv_fdpic_loadmap_addresses (target_gdbarch (), &interp_loadmap_addr, 0); if (status < 0) { warning (_("Unable to determine dynamic linker loadmap address.")); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } @@ -708,93 +595,113 @@ enable_break2 (void) warning (_("Unable to load dynamic linker loadmap at address %s."), hex_string_custom (interp_loadmap_addr, 8)); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { - interp_text_sect_low - = bfd_section_vma (tmp_bfd, interp_sect); + interp_text_sect_low = bfd_section_vma (interp_sect); interp_text_sect_low += displacement_from_map (ldm, interp_text_sect_low); interp_text_sect_high - = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); + = interp_text_sect_low + bfd_section_size (interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { - interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect); + interp_plt_sect_low = bfd_section_vma (interp_sect); interp_plt_sect_low += displacement_from_map (ldm, interp_plt_sect_low); interp_plt_sect_high = - interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); + interp_plt_sect_low + bfd_section_size (interp_sect); } - addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr"); + addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name, "_dl_debug_addr"); + if (addr == 0) { - warning (_("Could not find symbol _dl_debug_addr in dynamic linker")); + warning (_("Could not find symbol _dl_debug_addr " + "in dynamic linker")); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, - "enable_break: _dl_debug_addr (prior to relocation) = %s\n", + "enable_break: _dl_debug_addr " + "(prior to relocation) = %s\n", hex_string_custom (addr, 8)); addr += displacement_from_map (ldm, addr); if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, - "enable_break: _dl_debug_addr (after relocation) = %s\n", + "enable_break: _dl_debug_addr " + "(after relocation) = %s\n", hex_string_custom (addr, 8)); /* Fetch the address of the r_debug struct. */ if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) { - warning (_("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker"), + warning (_("Unable to fetch contents of _dl_debug_addr " + "(at address %s) from dynamic linker"), hex_string_custom (addr, 8)); } - addr = extract_unsigned_integer (addr_buf, sizeof addr_buf); + addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); + + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: _dl_debug_addr[0..3] = %s\n", + hex_string_custom (addr, 8)); + + /* If it's zero, then the ldso hasn't initialized yet, and so + there are no shared libs yet loaded. */ + if (addr == 0) + { + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: ldso not yet initialized\n"); + /* Do not warn, but mark to run again. */ + return 0; + } /* Fetch the r_brk field. It's 8 bytes from the start of _dl_debug_addr. */ if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0) { - warning (_("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker"), + warning (_("Unable to fetch _dl_debug_addr->r_brk " + "(at address %s) from dynamic linker"), hex_string_custom (addr + 8, 8)); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } - addr = extract_unsigned_integer (addr_buf, sizeof addr_buf); + addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* Now fetch the function entry point. */ if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) { - warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker"), + warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point " + "(at address %s) from dynamic linker"), hex_string_custom (addr, 8)); enable_break_failure_warning (); - bfd_close (tmp_bfd); return 0; } - addr = extract_unsigned_integer (addr_buf, sizeof addr_buf); - - /* We're done with the temporary bfd. */ - bfd_close (tmp_bfd); + addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); - /* We're also done with the loadmap. */ + /* We're done with the loadmap. */ xfree (ldm); + /* Remove all the solib event breakpoints. Their addresses + may have changed since the last time we ran the program. */ + remove_solib_event_breakpoints (); + /* Now (finally!) create the solib breakpoint. */ - create_solib_event_breakpoint (addr); + create_solib_event_breakpoint (target_gdbarch (), addr); + + enable_break2_done = 1; return 1; } @@ -810,75 +717,60 @@ static int enable_break (void) { asection *interp_sect; + CORE_ADDR entry_point; - /* Remove all the solib event breakpoints. Their addresses - may have changed since the last time we ran the program. */ - remove_solib_event_breakpoints (); - - /* Check for the presence of a .interp section. If there is no - such section, the executable is statically linked. */ - - interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); - - if (interp_sect) + if (symfile_objfile == NULL) { - enable_break1_done = 1; - create_solib_event_breakpoint (symfile_objfile->ei.entry_point); - if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, - "enable_break: solib event breakpoint placed at entry point: %s\n", - hex_string_custom - (symfile_objfile->ei.entry_point, 8)); + "enable_break: No symbol file found.\n"); + return 0; } - else + + if (!entry_point_address_query (&entry_point)) { if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, - "enable_break: No .interp section found.\n"); + "enable_break: Symbol file has no entry point.\n"); + return 0; } - return 1; -} - -/* - - LOCAL FUNCTION - - special_symbol_handling -- additional shared library symbol handling - - SYNOPSIS - - void special_symbol_handling () + /* Check for the presence of a .interp section. If there is no + such section, the executable is statically linked. */ - DESCRIPTION + interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); - Once the symbols from a shared object have been loaded in the usual - way, we are called to do any system specific symbol handling that - is needed. + if (interp_sect == NULL) + { + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: No .interp section found.\n"); + return 0; + } - */ + create_solib_event_breakpoint (target_gdbarch (), entry_point); -static void -frv_special_symbol_handling (void) -{ - /* Nothing needed (yet) for FRV. */ + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: solib event breakpoint " + "placed at entry point: %s\n", + hex_string_custom (entry_point, 8)); + return 1; } static void frv_relocate_main_executable (void) { int status; - CORE_ADDR exec_addr; + CORE_ADDR exec_addr, interp_addr; struct int_elf32_fdpic_loadmap *ldm; - struct cleanup *old_chain; - struct section_offsets *new_offsets; int changed; struct obj_section *osect; - status = frv_fdpic_loadmap_addresses (target_gdbarch, 0, &exec_addr); + status = frv_fdpic_loadmap_addresses (target_gdbarch (), + &interp_addr, &exec_addr); - if (status < 0) + if (status < 0 || (exec_addr == 0 && interp_addr == 0)) { /* Not using FDPIC ABI, so do nothing. */ return; @@ -889,14 +781,11 @@ frv_relocate_main_executable (void) if (ldm == NULL) error (_("Unable to load the executable's loadmap.")); - if (main_executable_lm_info) - xfree (main_executable_lm_info); - main_executable_lm_info = xcalloc (1, sizeof (struct lm_info)); + delete main_executable_lm_info; + main_executable_lm_info = new lm_info_frv; main_executable_lm_info->map = ldm; - new_offsets = xcalloc (symfile_objfile->num_sections, - sizeof (struct section_offsets)); - old_chain = make_cleanup (xfree, new_offsets); + section_offsets new_offsets (symfile_objfile->section_offsets.size ()); changed = 0; ALL_OBJFILE_OSECTIONS (symfile_objfile, osect) @@ -905,12 +794,12 @@ frv_relocate_main_executable (void) int osect_idx; int seg; - osect_idx = osect->the_bfd_section->index; + osect_idx = osect - symfile_objfile->sections; /* Current address of section. */ addr = obj_section_addr (osect); /* Offset from where this section started. */ - offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx); + offset = symfile_objfile->section_offsets[osect_idx]; /* Original address prior to any past relocations. */ orig_addr = addr - offset; @@ -919,10 +808,10 @@ frv_relocate_main_executable (void) if (ldm->segs[seg].p_vaddr <= orig_addr && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz) { - new_offsets->offsets[osect_idx] + new_offsets[osect_idx] = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr; - if (new_offsets->offsets[osect_idx] != offset) + if (new_offsets[osect_idx] != offset) changed = 1; break; } @@ -932,37 +821,19 @@ frv_relocate_main_executable (void) if (changed) objfile_relocate (symfile_objfile, new_offsets); - do_cleanups (old_chain); - /* Now that symfile_objfile has been relocated, we can compute the GOT value and stash it away. */ main_executable_lm_info->got_value = main_got (); } -/* +/* Implement the "create_inferior_hook" target_solib_ops method. - GLOBAL FUNCTION - - frv_solib_create_inferior_hook -- shared library startup support - - SYNOPSIS - - void frv_solib_create_inferior_hook () - - DESCRIPTION - - When gdb starts up the inferior, it nurses it along (through the - shell) until it is ready to execute it's first instruction. At this - point, this function gets called via expansion of the macro - SOLIB_CREATE_INFERIOR_HOOK. - - For the FR-V shared library ABI (FDPIC), the main executable - needs to be relocated. The shared library breakpoints also need - to be enabled. - */ + For the FR-V shared library ABI (FDPIC), the main executable needs + to be relocated. The shared library breakpoints also need to be + enabled. */ static void -frv_solib_create_inferior_hook (void) +frv_solib_create_inferior_hook (int from_tty) { /* Relocate main executable. */ frv_relocate_main_executable (); @@ -979,36 +850,28 @@ static void frv_clear_solib (void) { lm_base_cache = 0; - enable_break1_done = 0; enable_break2_done = 0; main_lm_addr = 0; - if (main_executable_lm_info != 0) - { - xfree (main_executable_lm_info->map); - xfree (main_executable_lm_info->dyn_syms); - xfree (main_executable_lm_info->dyn_relocs); - xfree (main_executable_lm_info); - main_executable_lm_info = 0; - } + + delete main_executable_lm_info; + main_executable_lm_info = NULL; } static void frv_free_so (struct so_list *so) { - xfree (so->lm_info->map); - xfree (so->lm_info->dyn_syms); - xfree (so->lm_info->dyn_relocs); - xfree (so->lm_info); + lm_info_frv *li = (lm_info_frv *) so->lm_info; + + delete li; } static void frv_relocate_section_addresses (struct so_list *so, - struct section_table *sec) + struct target_section *sec) { int seg; - struct int_elf32_fdpic_loadmap *map; - - map = so->lm_info->map; + lm_info_frv *li = (lm_info_frv *) so->lm_info; + int_elf32_fdpic_loadmap *map = li->map; for (seg = 0; seg < map->nsegs; seg++) { @@ -1016,6 +879,7 @@ frv_relocate_section_addresses (struct so_list *so, && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz) { CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr; + sec->addr += displ; sec->endaddr += displ; break; @@ -1029,13 +893,14 @@ frv_relocate_section_addresses (struct so_list *so, static CORE_ADDR main_got (void) { - struct minimal_symbol *got_sym; + struct bound_minimal_symbol got_sym; - got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile); - if (got_sym == 0) + got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", + NULL, symfile_objfile); + if (got_sym.minsym == 0) return 0; - return SYMBOL_VALUE_ADDRESS (got_sym); + return BMSYMBOL_VALUE_ADDRESS (got_sym); } /* Find the global pointer for the given function address ADDR. */ @@ -1049,28 +914,27 @@ frv_fdpic_find_global_pointer (CORE_ADDR addr) while (so) { int seg; - struct int_elf32_fdpic_loadmap *map; - - map = so->lm_info->map; + lm_info_frv *li = (lm_info_frv *) so->lm_info; + int_elf32_fdpic_loadmap *map = li->map; for (seg = 0; seg < map->nsegs; seg++) { if (map->segs[seg].addr <= addr && addr < map->segs[seg].addr + map->segs[seg].p_memsz) - return so->lm_info->got_value; + return li->got_value; } so = so->next; } - /* Didn't find it it any of the shared objects. So assume it's in the + /* Didn't find it in any of the shared objects. So assume it's in the main executable. */ return main_got (); } /* Forward declarations for frv_fdpic_find_canonical_descriptor(). */ static CORE_ADDR find_canonical_descriptor_in_load_object - (CORE_ADDR, CORE_ADDR, char *, bfd *, struct lm_info *); + (CORE_ADDR, CORE_ADDR, const char *, bfd *, lm_info_frv *); /* Given a function entry point, attempt to find the canonical descriptor associated with that entry point. Return 0 if no canonical descriptor @@ -1079,13 +943,10 @@ static CORE_ADDR find_canonical_descriptor_in_load_object CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) { - char *name; + const char *name; CORE_ADDR addr; CORE_ADDR got_value; - struct int_elf32_fdpic_loadmap *ldm = 0; struct symbol *sym; - int status; - CORE_ADDR exec_loadmap_addr; /* Fetch the corresponding global pointer for the entry point. */ got_value = frv_fdpic_find_global_pointer (entry_point); @@ -1097,7 +958,7 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) if (sym == 0) name = 0; else - name = SYMBOL_LINKAGE_NAME (sym); + name = sym->linkage_name (); /* Check the main executable. */ addr = find_canonical_descriptor_in_load_object @@ -1113,8 +974,10 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) so = master_so_list (); while (so) { + lm_info_frv *li = (lm_info_frv *) so->lm_info; + addr = find_canonical_descriptor_in_load_object - (entry_point, got_value, name, so->abfd, so->lm_info); + (entry_point, got_value, name, so->abfd, li); if (addr != 0) break; @@ -1128,9 +991,10 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) static CORE_ADDR find_canonical_descriptor_in_load_object - (CORE_ADDR entry_point, CORE_ADDR got_value, char *name, bfd *abfd, - struct lm_info *lm) + (CORE_ADDR entry_point, CORE_ADDR got_value, const char *name, bfd *abfd, + lm_info_frv *lm) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); arelent *rel; unsigned int i; CORE_ADDR addr = 0; @@ -1223,18 +1087,20 @@ find_canonical_descriptor_in_load_object /* Fetch address of candidate descriptor. */ if (target_read_memory (addr, buf, sizeof buf) != 0) continue; - addr = extract_unsigned_integer (buf, sizeof buf); + addr = extract_unsigned_integer (buf, sizeof buf, byte_order); /* Check for matching entry point. */ if (target_read_memory (addr, buf, sizeof buf) != 0) continue; - if (extract_unsigned_integer (buf, sizeof buf) != entry_point) + if (extract_unsigned_integer (buf, sizeof buf, byte_order) + != entry_point) continue; /* Check for matching got value. */ if (target_read_memory (addr + 4, buf, sizeof buf) != 0) continue; - if (extract_unsigned_integer (buf, sizeof buf) != got_value) + if (extract_unsigned_integer (buf, sizeof buf, byte_order) + != got_value) continue; /* Match was successful! Exit loop. */ @@ -1254,7 +1120,7 @@ frv_fetch_objfile_link_map (struct objfile *objfile) /* Cause frv_current_sos() to be run if it hasn't been already. */ if (main_lm_addr == 0) - solib_add (0, 0, 0, 1); + solib_add (0, 0, 1); /* frv_current_sos() will set main_lm_addr for the main executable. */ if (objfile == symfile_objfile) @@ -1264,8 +1130,10 @@ frv_fetch_objfile_link_map (struct objfile *objfile) of shared libraries. */ for (so = master_so_list (); so; so = so->next) { + lm_info_frv *li = (lm_info_frv *) so->lm_info; + if (so->objfile == objfile) - return so->lm_info->lm_addr; + return li->lm_addr; } /* Not found! */ @@ -1281,18 +1149,18 @@ _initialize_frv_solib (void) frv_so_ops.free_so = frv_free_so; frv_so_ops.clear_solib = frv_clear_solib; frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook; - frv_so_ops.special_symbol_handling = frv_special_symbol_handling; frv_so_ops.current_sos = frv_current_sos; frv_so_ops.open_symbol_file_object = open_symbol_file_object; frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code; + frv_so_ops.bfd_open = solib_bfd_open; /* Debug this file's internals. */ - add_setshow_zinteger_cmd ("solib-frv", class_maintenance, - &solib_frv_debug, _("\ + add_setshow_zuinteger_cmd ("solib-frv", class_maintenance, + &solib_frv_debug, _("\ Set internal debugging of shared library code for FR-V."), _("\ Show internal debugging of shared library code for FR-V."), _("\ When non-zero, FR-V solib specific internal debugging is enabled."), - NULL, - NULL, /* FIXME: i18n: */ - &setdebuglist, &showdebuglist); + NULL, + NULL, /* FIXME: i18n: */ + &setdebuglist, &showdebuglist); }