X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsolib-som.c;h=1ac83e15c37912e1613092a6592d104418c0a78d;hb=d62d0f5fc2156db337ac3cbbc3c05ca76565dbd3;hp=247ada36645ac601f50666f7c822b08917a8c05c;hpb=9b254dd1ce46c19dde1dde5b8d1e22e862dfacce;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-som.c b/gdb/solib-som.c index 247ada3664..1ac83e15c3 100644 --- a/gdb/solib-som.c +++ b/gdb/solib-som.c @@ -1,6 +1,7 @@ /* Handle SOM shared libraries. - Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of GDB. @@ -29,6 +30,10 @@ #include "hppa-tdep.h" #include "solist.h" #include "solib.h" +#include "solib-som.h" + +#include +#include #undef SOLIB_SOM_DBG @@ -107,7 +112,7 @@ dld_cache; static void som_relocate_section_addresses (struct so_list *so, - struct section_table *sec) + struct target_section *sec) { flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section); @@ -125,6 +130,38 @@ som_relocate_section_addresses (struct so_list *so, ; } +/* Get HP-UX major release number. Returns zero if the + release is not known. */ + +static int +get_hpux_major_release (void) +{ + static int hpux_major_release = -1; + + if (hpux_major_release == -1) + { + struct utsname x; + char *p; + + uname (&x); + p = strchr (x.release, '.'); + hpux_major_release = p ? atoi (p + 1) : 0; + } + + return hpux_major_release; +} + +/* DL header flag defines. */ +#define SHLIB_TEXT_PRIVATE_ENABLE 0x4000 + +/* The DL header is documented in . We are only interested + in the flags field to determine whether the executable wants shared + libraries mapped private. */ +struct { + short junk[37]; + short flags; +} dl_header; + /* This hook gets called just before the first instruction in the inferior process is executed. @@ -146,18 +183,15 @@ som_relocate_section_addresses (struct so_list *so, means running until the "_start" is called. */ static void -som_solib_create_inferior_hook (void) +som_solib_create_inferior_hook (int from_tty) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); struct minimal_symbol *msymbol; unsigned int dld_flags, status, have_endo; asection *shlib_info; char buf[4]; CORE_ADDR anaddr; - /* First, 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) return; @@ -170,6 +204,10 @@ som_solib_create_inferior_hook (void) if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) return; + /* Read the DL header. */ + bfd_get_section_contents (symfile_objfile->obfd, shlib_info, + (char *) &dl_header, 0, sizeof (dl_header)); + have_endo = 0; /* Slam the pid of the process into __d_pid. @@ -182,7 +220,7 @@ som_solib_create_inferior_hook (void) goto keep_going; anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); + store_unsigned_integer (buf, 4, byte_order, PIDGET (inferior_ptid)); status = target_write_memory (anaddr, buf, 4); if (status != 0) { @@ -225,7 +263,7 @@ GDB will be unable to track shl_load/shl_unload calls")); anaddr = SYMBOL_VALUE (msymbol); dld_cache.hook_stub.address = anaddr; } - store_unsigned_integer (buf, 4, anaddr); + store_unsigned_integer (buf, 4, byte_order, anaddr); msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile); if (msymbol == NULL) @@ -250,7 +288,8 @@ Suggest linking with /opt/langtools/lib/end.o.\n\ GDB will be unable to track shl_load/shl_unload calls")); goto keep_going; } - create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); + create_solib_event_breakpoint (target_gdbarch, + SYMBOL_VALUE_ADDRESS (msymbol)); /* We have all the support usually found in end.o, so we can track shl_load and shl_unload calls. */ @@ -272,13 +311,27 @@ keep_going: status = target_read_memory (anaddr, buf, 4); if (status != 0) error (_("Unable to read __dld_flags.")); - dld_flags = extract_unsigned_integer (buf, 4); + dld_flags = extract_unsigned_integer (buf, 4, byte_order); + + /* If the libraries were not mapped private on HP-UX 11 and later, warn + the user. On HP-UX 10 and earlier, there is no easy way to specify + that shared libraries should be privately mapped. So, we just force + private mapping. */ + if (get_hpux_major_release () >= 11 + && (dl_header.flags & SHLIB_TEXT_PRIVATE_ENABLE) == 0 + && (dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) + warning + (_("Private mapping of shared library text was not specified\n" + "by the executable; setting a breakpoint in a shared library which\n" + "is not privately mapped will not work. See the HP-UX 11i v3 chatr\n" + "manpage for methods to privately map shared library text.")); /* Turn on the flags we care about. */ - dld_flags |= DLD_FLAGS_MAPPRIVATE; + if (get_hpux_major_release () < 11) + dld_flags |= DLD_FLAGS_MAPPRIVATE; if (have_endo) dld_flags |= DLD_FLAGS_HOOKVALID; - store_unsigned_integer (buf, 4, dld_flags); + store_unsigned_integer (buf, 4, byte_order, dld_flags); status = target_write_memory (anaddr, buf, 4); if (status != 0) error (_("Unable to write __dld_flags.")); @@ -299,7 +352,7 @@ keep_going: anaddr = SYMBOL_VALUE_ADDRESS (msymbol); /* Make the breakpoint at "_start" a shared library event breakpoint. */ - create_solib_event_breakpoint (anaddr); + create_solib_event_breakpoint (target_gdbarch, anaddr); clear_symtab_users (); } @@ -338,7 +391,7 @@ som_solib_desire_dynamic_linker_symbols (void) objfile); if (dld_msymbol != NULL) { - if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) + if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) { u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) @@ -377,7 +430,7 @@ som_solib_desire_dynamic_linker_symbols (void) objfile); if (dld_msymbol != NULL) { - if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) + if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) { u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) @@ -472,6 +525,7 @@ struct dld_list { static CORE_ADDR link_map_start (void) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); struct minimal_symbol *sym; CORE_ADDR addr; char buf[4]; @@ -482,16 +536,10 @@ link_map_start (void) error (_("Unable to find __dld_flags symbol in object file.")); addr = SYMBOL_VALUE_ADDRESS (sym); read_memory (addr, buf, 4); - dld_flags = extract_unsigned_integer (buf, 4); + dld_flags = extract_unsigned_integer (buf, 4, byte_order); if ((dld_flags & DLD_FLAGS_LISTVALID) == 0) error (_("__dld_list is not valid according to __dld_flags.")); - /* If the libraries were not mapped private, warn the user. */ - if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) - warning (_("The shared libraries were not privately mapped; setting a\n" - "breakpoint in a shared library will not work until you rerun the " - "program.\n")); - sym = lookup_minimal_symbol ("__dld_list", NULL, NULL); if (!sym) { @@ -509,12 +557,12 @@ link_map_start (void) addr = SYMBOL_VALUE_ADDRESS (sym); read_memory (addr, buf, 4); - addr = extract_unsigned_integer (buf, 4); + addr = extract_unsigned_integer (buf, 4, byte_order); if (addr == 0) return 0; read_memory (addr, buf, 4); - return extract_unsigned_integer (buf, 4); + return extract_unsigned_integer (buf, 4, byte_order); } /* Does this so's name match the main binary? */ @@ -527,6 +575,7 @@ match_main (const char *name) static struct so_list * som_current_sos (void) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); CORE_ADDR lm; struct so_list *head = 0; struct so_list **link_ptr = &head; @@ -551,7 +600,7 @@ som_current_sos (void) read_memory (lm, (gdb_byte *)&dbuf, sizeof (struct dld_list)); addr = extract_unsigned_integer ((gdb_byte *)&dbuf.name, - sizeof (dbuf.name)); + sizeof (dbuf.name), byte_order); target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (errcode != 0) warning (_("Can't read pathname for load map: %s."), @@ -572,7 +621,8 @@ som_current_sos (void) lmi->lm_addr = lm; #define EXTRACT(_fld) \ - extract_unsigned_integer ((gdb_byte *)&dbuf._fld, sizeof (dbuf._fld)); + extract_unsigned_integer ((gdb_byte *)&dbuf._fld, \ + sizeof (dbuf._fld), byte_order); lmi->text_addr = EXTRACT (text_addr); tmp = EXTRACT (info); @@ -587,31 +637,32 @@ som_current_sos (void) lmi->got_value = EXTRACT (got_value); tmp = EXTRACT (tsd_start_addr_ptr); read_memory (tmp, tsdbuf, 4); - lmi->tsd_start_addr = extract_unsigned_integer (tsdbuf, 4); + lmi->tsd_start_addr + = extract_unsigned_integer (tsdbuf, 4, byte_order); #ifdef SOLIB_SOM_DBG - printf ("\n+ library \"%s\" is described at 0x%s\n", new->so_name, - paddr_nz (lm)); + printf ("\n+ library \"%s\" is described at %s\n", new->so_name, + paddress (target_gdbarch, lm)); printf (" 'version' is %d\n", new->lm_info->struct_version); printf (" 'bind_mode' is %d\n", new->lm_info->bind_mode); printf (" 'library_version' is %d\n", new->lm_info->library_version); - printf (" 'text_addr' is 0x%s\n", - paddr_nz (new->lm_info->text_addr)); - printf (" 'text_link_addr' is 0x%s\n", - paddr_nz (new->lm_info->text_link_addr)); - printf (" 'text_end' is 0x%s\n", - paddr_nz (new->lm_info->text_end)); - printf (" 'data_start' is 0x%s\n", - paddr_nz (new->lm_info->data_start)); - printf (" 'bss_start' is 0x%s\n", - paddr_nz (new->lm_info->bss_start)); - printf (" 'data_end' is 0x%s\n", - paddr_nz (new->lm_info->data_end)); - printf (" 'got_value' is %s\n", - paddr_nz (new->lm_info->got_value)); - printf (" 'tsd_start_addr' is 0x%s\n", - paddr_nz (new->lm_info->tsd_start_addr)); + printf (" 'text_addr' is %s\n", + paddress (target_gdbarch, new->lm_info->text_addr)); + printf (" 'text_link_addr' is %s\n", + paddress (target_gdbarch, new->lm_info->text_link_addr)); + printf (" 'text_end' is %s\n", + paddress (target_gdbarch, new->lm_info->text_end)); + printf (" 'data_start' is %s\n", + paddress (target_gdbarch, new->lm_info->data_start)); + printf (" 'bss_start' is %s\n", + paddress (target_gdbarch, new->lm_info->bss_start)); + printf (" 'data_end' is %s\n", + paddress (target_gdbarch, new->lm_info->data_end)); + printf (" 'got_value' is %s\n", + paddress (target_gdbarch, new->lm_info->got_value)); + printf (" 'tsd_start_addr' is %s\n", + paddress (target_gdbarch, new->lm_info->tsd_start_addr)); #endif new->addr_low = lmi->text_addr; @@ -641,6 +692,7 @@ som_current_sos (void) static int som_open_symbol_file_object (void *from_ttyp) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); CORE_ADDR lm, l_name; char *filename; int errcode; @@ -648,7 +700,7 @@ som_open_symbol_file_object (void *from_ttyp) char buf[4]; if (symfile_objfile) - if (!query ("Attempt to reload symbols from process? ")) + if (!query (_("Attempt to reload symbols from process? "))) return 0; /* First link map member should be the executable. */ @@ -660,7 +712,7 @@ som_open_symbol_file_object (void *from_ttyp) /* Convert the address to host format. Assume that the address is unsigned. */ - l_name = extract_unsigned_integer (buf, 4); + l_name = extract_unsigned_integer (buf, 4, byte_order); if (l_name == 0) return 0; /* No filename. */ @@ -757,9 +809,11 @@ _initialize_som_solib (void) som_so_ops.current_sos = som_current_sos; som_so_ops.open_symbol_file_object = som_open_symbol_file_object; som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code; + som_so_ops.bfd_open = solib_bfd_open; } -void som_solib_select (struct gdbarch *gdbarch) +void +som_solib_select (struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); set_solib_ops (gdbarch, &som_so_ops);