X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsolib-frv.c;h=16455bef03f4801406a9f93599a8534f4090259a;hb=c378eb4eaae2baecb17b41ba928daf9dc74b1aab;hp=a8ef73ba45fc18ee247ef7fe0cf4fa4136b4ee67;hpb=9bc7b6c67c89b58420df6e016c5c66fc41aa699d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index a8ef73ba45..16455bef03 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -1,5 +1,6 @@ /* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger. - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. This file is part of GDB. @@ -97,6 +98,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; @@ -113,7 +115,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. */ @@ -122,7 +125,8 @@ 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; @@ -158,13 +162,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); @@ -195,7 +202,7 @@ 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 { @@ -218,7 +225,7 @@ struct lm_info caching of the dynamic relocations could be dispensed with. */ asymbol **dyn_syms; arelent **dyn_relocs; - int dyn_reloc_count; /* number of dynamic relocs. */ + int dyn_reloc_count; /* Number of dynamic relocs. */ }; @@ -277,7 +284,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname) sym = *symbol_table++; if (strcmp (sym->name, symname) == 0) { - /* Bfd symbols are section relative. */ + /* Bfd symbols are section relative. */ symaddr = sym->value + sym->section->vma; break; } @@ -303,7 +310,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname) sym = *symbol_table++; if (strcmp (sym->name, symname) == 0) { - /* Bfd symbols are section relative. */ + /* Bfd symbols are section relative. */ symaddr = sym->value + sym->section->vma; break; } @@ -333,7 +340,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname) 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. */ + catch_errors() requires a pointer argument. */ static int open_symbol_file_object (void *from_ttyp) @@ -359,6 +366,7 @@ static CORE_ADDR main_lm_addr = 0; static CORE_ADDR lm_base (void) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); struct minimal_symbol *got_sym; CORE_ADDR addr; gdb_byte buf[FRV_PTR_SIZE]; @@ -394,7 +402,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, @@ -427,6 +435,7 @@ lm_base (void) 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; @@ -464,15 +473,18 @@ 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. */ @@ -486,11 +498,13 @@ frv_current_sos (void) /* 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; } @@ -501,7 +515,8 @@ frv_current_sos (void) sop->lm_info->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); @@ -528,7 +543,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 (); @@ -556,7 +572,7 @@ frv_in_dynsym_resolve_code (CORE_ADDR 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) { @@ -619,25 +635,19 @@ enable_break_failure_warning (void) */ -static int enable_break1_done = 0; static int enable_break2_done = 0; static int enable_break2 (void) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); int success = 0; char **bkpt_namep; 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; @@ -732,7 +742,8 @@ enable_break2 (void) addr = bfd_lookup_symbol (tmp_bfd, "_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; @@ -740,46 +751,67 @@ enable_break2 (void) 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); + addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); @@ -787,8 +819,14 @@ enable_break2 (void) /* We're also 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; } @@ -805,33 +843,44 @@ enable_break (void) { asection *interp_sect; - /* Remove all the solib event breakpoints. Their addresses - may have changed since the last time we ran the program. */ - remove_solib_event_breakpoints (); + if (symfile_objfile == NULL) + { + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: No symbol file found.\n"); + return 0; + } + + if (!symfile_objfile->ei.entry_point_p) + { + if (solib_frv_debug) + fprintf_unfiltered (gdb_stdlog, + "enable_break: Symbol file has no entry point.\n"); + return 0; + } /* 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 (interp_sect == 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)); - } - else - { - if (solib_frv_debug) - fprintf_unfiltered (gdb_stdlog, - "enable_break: No .interp section found.\n"); + "enable_break: No .interp section found.\n"); + return 0; } + create_solib_event_breakpoint (target_gdbarch, + 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)); return 1; } @@ -856,7 +905,7 @@ enable_break (void) static void frv_special_symbol_handling (void) { - /* Nothing needed (yet) for FRV. */ + /* Nothing needed (yet) for FRV. */ } static void @@ -957,7 +1006,7 @@ frv_relocate_main_executable (void) */ static void -frv_solib_create_inferior_hook (void) +frv_solib_create_inferior_hook (int from_tty) { /* Relocate main executable. */ frv_relocate_main_executable (); @@ -974,7 +1023,6 @@ 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) @@ -998,7 +1046,7 @@ frv_free_so (struct so_list *so) 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; @@ -1011,6 +1059,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; @@ -1026,7 +1075,8 @@ main_got (void) { struct minimal_symbol *got_sym; - got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile); + got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", + NULL, symfile_objfile); if (got_sym == 0) return 0; @@ -1126,6 +1176,7 @@ find_canonical_descriptor_in_load_object (CORE_ADDR entry_point, CORE_ADDR got_value, char *name, bfd *abfd, struct lm_info *lm) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); arelent *rel; unsigned int i; CORE_ADDR addr = 0; @@ -1218,18 +1269,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. */ @@ -1269,6 +1322,9 @@ frv_fetch_objfile_link_map (struct objfile *objfile) struct target_so_ops frv_so_ops; +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_frv_solib; + void _initialize_frv_solib (void) { @@ -1280,6 +1336,7 @@ _initialize_frv_solib (void) 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,