diff options
Diffstat (limited to 'gdb/solib-irix.c')
-rw-r--r-- | gdb/solib-irix.c | 610 |
1 files changed, 0 insertions, 610 deletions
diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c deleted file mode 100644 index 00236bf7f4a..00000000000 --- a/gdb/solib-irix.c +++ /dev/null @@ -1,610 +0,0 @@ -/* Shared library support for IRIX. - Copyright (C) 1993-2014 Free Software Foundation, Inc. - - This file was created using portions of irix5-nat.c originally - contributed to GDB by Ian Lance Taylor. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "defs.h" - -#include "symtab.h" -#include "bfd.h" -/* FIXME: ezannoni/2004-02-13 Verify that the include below is - really needed. */ -#include "symfile.h" -#include "objfiles.h" -#include "gdbcore.h" -#include "target.h" -#include "inferior.h" -#include "infrun.h" -#include "gdbthread.h" - -#include "solist.h" -#include "solib.h" -#include "solib-irix.h" - - -/* Link map info to include in an allocate so_list entry. Unlike some - of the other solib backends, this (Irix) backend chooses to decode - the link map info obtained from the target and store it as (mostly) - CORE_ADDRs which need no further decoding. This is more convenient - because there are three different link map formats to worry about. - We use a single routine (fetch_lm_info) to read (and decode) the target - specific link map data. */ - -struct lm_info -{ - CORE_ADDR addr; /* address of obj_info or obj_list - struct on target (from which the - following information is obtained). */ - CORE_ADDR next; /* address of next item in list. */ - CORE_ADDR reloc_offset; /* amount to relocate by */ - CORE_ADDR pathname_addr; /* address of pathname */ - int pathname_len; /* length of pathname */ -}; - -/* It's not desirable to use the system header files to obtain the - structure of the obj_list or obj_info structs. Therefore, we use a - platform neutral representation which has been derived from the IRIX - header files. */ - -typedef struct -{ - gdb_byte b[4]; -} -gdb_int32_bytes; -typedef struct -{ - gdb_byte b[8]; -} -gdb_int64_bytes; - -/* The "old" obj_list struct. This is used with old (o32) binaries. - The ``data'' member points at a much larger and more complicated - struct which we will only refer to by offsets. See - fetch_lm_info(). */ - -struct irix_obj_list -{ - gdb_int32_bytes data; - gdb_int32_bytes next; - gdb_int32_bytes prev; -}; - -/* The ELF32 and ELF64 versions of the above struct. The oi_magic value - corresponds to the ``data'' value in the "old" struct. When this value - is 0xffffffff, the data will be in one of the following formats. The - ``oi_size'' field is used to decide which one we actually have. */ - -struct irix_elf32_obj_info -{ - gdb_int32_bytes oi_magic; - gdb_int32_bytes oi_size; - gdb_int32_bytes oi_next; - gdb_int32_bytes oi_prev; - gdb_int32_bytes oi_ehdr; - gdb_int32_bytes oi_orig_ehdr; - gdb_int32_bytes oi_pathname; - gdb_int32_bytes oi_pathname_len; -}; - -struct irix_elf64_obj_info -{ - gdb_int32_bytes oi_magic; - gdb_int32_bytes oi_size; - gdb_int64_bytes oi_next; - gdb_int64_bytes oi_prev; - gdb_int64_bytes oi_ehdr; - gdb_int64_bytes oi_orig_ehdr; - gdb_int64_bytes oi_pathname; - gdb_int32_bytes oi_pathname_len; - gdb_int32_bytes padding; -}; - -/* Union of all of the above (plus a split out magic field). */ - -union irix_obj_info -{ - gdb_int32_bytes magic; - struct irix_obj_list ol32; - struct irix_elf32_obj_info oi32; - struct irix_elf64_obj_info oi64; -}; - -/* MIPS sign extends its 32 bit addresses. We could conceivably use - extract_typed_address here, but to do so, we'd have to construct an - appropriate type. Calling extract_signed_integer seems simpler. */ - -static CORE_ADDR -extract_mips_address (void *addr, int len, enum bfd_endian byte_order) -{ - return extract_signed_integer (addr, len, byte_order); -} - -/* Fetch and return the link map data associated with ADDR. Note that - this routine automatically determines which (of three) link map - formats is in use by the target. */ - -static struct lm_info -fetch_lm_info (CORE_ADDR addr) -{ - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); - struct lm_info li; - union irix_obj_info buf; - - li.addr = addr; - - /* The smallest region that we'll need is for buf.ol32. We'll read - that first. We'll read more of the buffer later if we have to deal - with one of the other cases. (We don't want to incur a memory error - if we were to read a larger region that generates an error due to - being at the end of a page or the like.) */ - read_memory (addr, (gdb_byte *) &buf, sizeof (buf.ol32)); - - if (extract_unsigned_integer (buf.magic.b, sizeof (buf.magic), byte_order) - != 0xffffffff) - { - /* Use buf.ol32... */ - gdb_byte obj_buf[432]; - CORE_ADDR obj_addr = extract_mips_address (&buf.ol32.data, - sizeof (buf.ol32.data), - byte_order); - - li.next = extract_mips_address (&buf.ol32.next, - sizeof (buf.ol32.next), byte_order); - - read_memory (obj_addr, obj_buf, sizeof (obj_buf)); - - li.pathname_addr = extract_mips_address (&obj_buf[236], 4, byte_order); - li.pathname_len = 0; /* unknown */ - li.reloc_offset = extract_mips_address (&obj_buf[196], 4, byte_order) - - extract_mips_address (&obj_buf[248], 4, byte_order); - - } - else if (extract_unsigned_integer (buf.oi32.oi_size.b, - sizeof (buf.oi32.oi_size), byte_order) - == sizeof (buf.oi32)) - { - /* Use buf.oi32... */ - - /* Read rest of buffer. */ - read_memory (addr + sizeof (buf.ol32), - ((gdb_byte *) &buf) + sizeof (buf.ol32), - sizeof (buf.oi32) - sizeof (buf.ol32)); - - /* Fill in fields using buffer contents. */ - li.next = extract_mips_address (&buf.oi32.oi_next, - sizeof (buf.oi32.oi_next), byte_order); - li.reloc_offset = extract_mips_address (&buf.oi32.oi_ehdr, - sizeof (buf.oi32.oi_ehdr), - byte_order) - - extract_mips_address (&buf.oi32.oi_orig_ehdr, - sizeof (buf.oi32.oi_orig_ehdr), byte_order); - li.pathname_addr = extract_mips_address (&buf.oi32.oi_pathname, - sizeof (buf.oi32.oi_pathname), - byte_order); - li.pathname_len = extract_unsigned_integer (buf.oi32.oi_pathname_len.b, - sizeof (buf.oi32. - oi_pathname_len), - byte_order); - } - else if (extract_unsigned_integer (buf.oi64.oi_size.b, - sizeof (buf.oi64.oi_size), byte_order) - == sizeof (buf.oi64)) - { - /* Use buf.oi64... */ - - /* Read rest of buffer. */ - read_memory (addr + sizeof (buf.ol32), - ((gdb_byte *) &buf) + sizeof (buf.ol32), - sizeof (buf.oi64) - sizeof (buf.ol32)); - - /* Fill in fields using buffer contents. */ - li.next = extract_mips_address (&buf.oi64.oi_next, - sizeof (buf.oi64.oi_next), byte_order); - li.reloc_offset = extract_mips_address (&buf.oi64.oi_ehdr, - sizeof (buf.oi64.oi_ehdr), - byte_order) - - extract_mips_address (&buf.oi64.oi_orig_ehdr, - sizeof (buf.oi64.oi_orig_ehdr), byte_order); - li.pathname_addr = extract_mips_address (&buf.oi64.oi_pathname, - sizeof (buf.oi64.oi_pathname), - byte_order); - li.pathname_len = extract_unsigned_integer (buf.oi64.oi_pathname_len.b, - sizeof (buf.oi64. - oi_pathname_len), - byte_order); - } - else - { - error (_("Unable to fetch shared library obj_info or obj_list info.")); - } - - return li; -} - -/* The symbol which starts off the list of shared libraries. */ -#define DEBUG_BASE "__rld_obj_head" - -static CORE_ADDR debug_base; /* Base of dynamic linker structures. */ - -/* Locate the base address of dynamic linker structs. - - For both the SunOS and SVR4 shared library implementations, if the - inferior executable has been linked dynamically, there is a single - address somewhere in the inferior's data space which is the key to - locating all of the dynamic linker's runtime structures. This - address is the value of the symbol defined by the macro DEBUG_BASE. - The job of this function is to find and return that address, or to - return 0 if there is no such address (the executable is statically - linked for example). - - For SunOS, the job is almost trivial, since the dynamic linker and - all of it's structures are statically linked to the executable at - link time. Thus the symbol for the address we are looking for has - already been added to the minimal symbol table for the executable's - objfile at the time the symbol file's symbols were read, and all we - have to do is look it up there. Note that we explicitly do NOT want - to find the copies in the shared library. - - The SVR4 version is much more complicated because the dynamic linker - and it's structures are located in the shared C library, which gets - run as the executable's "interpreter" by the kernel. We have to go - to a lot more work to discover the address of DEBUG_BASE. Because - of this complexity, we cache the value we find and return that value - on subsequent invocations. Note there is no copy in the executable - symbol tables. - - Irix 5 is basically like SunOS. - - Note that we can assume nothing about the process state at the time - we need to find this address. We may be stopped on the first instruc- - tion of the interpreter (C shared library), the first instruction of - the executable itself, or somewhere else entirely (if we attached - to the process for example). */ - -static CORE_ADDR -locate_base (void) -{ - struct bound_minimal_symbol msymbol; - CORE_ADDR address = 0; - - msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile); - if ((msymbol.minsym != NULL) && (BMSYMBOL_VALUE_ADDRESS (msymbol) != 0)) - { - address = BMSYMBOL_VALUE_ADDRESS (msymbol); - } - return (address); -} - - -/* Arrange for dynamic linker to hit breakpoint. - - This functions inserts a breakpoint at the entry point of the - main executable, where all shared libraries are mapped in. */ - -static int -enable_break (void) -{ - if (symfile_objfile != NULL && has_stack_frames ()) - { - CORE_ADDR entry_point; - - if (entry_point_address_query (&entry_point)) - { - create_solib_event_breakpoint (target_gdbarch (), entry_point); - return 1; - } - } - - return 0; -} - -/* Implement the "handle_event" target_solib_ops method. */ - -static void -irix_solib_handle_event (void) -{ - /* We are now at the "mapping complete" breakpoint, we no longer - need it. Note that it is possible that we have stopped at a - location that is different from the location where we inserted - our breakpoint: On mips-irix, we can actually land in - __dbx_link(), so we should not check the PC against our - breakpoint address here. See procfs.c for more details. Note - we're being called by the bpstat handling code, and so can't - delete the breakpoint immediately. Mark it for later deletion, - which has the same effect (it'll be removed before we next resume - or if we're stopping). */ - remove_solib_event_breakpoints_at_next_stop (); - - /* The caller calls solib_add, which will add any shared libraries - that were mapped in. */ -} - -/* Implement the "create_inferior_hook" target_solib_ops method. - - For SunOS executables, this first instruction is typically the - one at "_start", or a similar text label, regardless of whether - the executable is statically or dynamically linked. The runtime - startup code takes care of dynamically linking in any shared - libraries, once gdb allows the inferior to continue. - - For SVR4 executables, this first instruction is either the first - instruction in the dynamic linker (for dynamically linked - executables) or the instruction at "start" for statically linked - executables. For dynamically linked executables, the system - first exec's /lib/libc.so.N, which contains the dynamic linker, - and starts it running. The dynamic linker maps in any needed - shared libraries, maps in the actual user executable, and then - jumps to "start" in the user executable. - - For both SunOS shared libraries, and SVR4 shared libraries, we - can arrange to cooperate with the dynamic linker to discover the - names of shared libraries that are dynamically linked, and the - base addresses to which they are linked. - - This function is responsible for discovering those names and - addresses, and saving sufficient information about them to allow - their symbols to be read at a later time. - - FIXME - - Between enable_break() and disable_break(), this code does not - properly handle hitting breakpoints which the user might have - set in the startup code or in the dynamic linker itself. Proper - handling will probably have to wait until the implementation is - changed to use the "breakpoint handler function" method. - - Also, what if child has exit()ed? Must exit loop somehow. */ - -static void -irix_solib_create_inferior_hook (int from_tty) -{ - struct inferior *inf; - struct thread_info *tp; - - inf = current_inferior (); - - /* If we are attaching to the inferior, the shared libraries - have already been mapped, so nothing more to do. */ - if (inf->attach_flag) - return; - - /* Likewise when debugging from a core file, the shared libraries - have already been mapped, so nothing more to do. */ - if (!target_can_run (¤t_target)) - return; - - if (!enable_break ()) - { - warning (_("shared library handler failed to enable breakpoint")); - return; - } - - /* The target will eventually hit the breakpoint, at which point all - of the libraries will have been mapped in and we can go groveling - around in the dynamic linker structures to find out what we need - to know about them. */ -} - -/* Implement the "current_sos" target_so_ops method. */ - -static struct so_list * -irix_current_sos (void) -{ - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); - int addr_size = gdbarch_addr_bit (target_gdbarch ()) / TARGET_CHAR_BIT; - CORE_ADDR lma; - gdb_byte addr_buf[8]; - struct so_list *head = 0; - struct so_list **link_ptr = &head; - int is_first = 1; - struct lm_info lm; - - /* Make sure we've looked up the inferior's dynamic linker's base - structure. */ - if (!debug_base) - { - debug_base = locate_base (); - - /* If we can't find the dynamic linker's base structure, this - must not be a dynamically linked executable. Hmm. */ - if (!debug_base) - return 0; - } - - read_memory (debug_base, addr_buf, addr_size); - lma = extract_mips_address (addr_buf, addr_size, byte_order); - - while (lma) - { - lm = fetch_lm_info (lma); - if (!is_first) - { - int errcode; - char *name_buf; - int name_size; - struct so_list *new - = (struct so_list *) xmalloc (sizeof (struct so_list)); - struct cleanup *old_chain = make_cleanup (xfree, new); - - memset (new, 0, sizeof (*new)); - - new->lm_info = xmalloc (sizeof (struct lm_info)); - make_cleanup (xfree, new->lm_info); - - *new->lm_info = lm; - - /* Extract this shared object's name. */ - name_size = lm.pathname_len; - if (name_size == 0) - name_size = SO_NAME_MAX_PATH_SIZE - 1; - - if (name_size >= SO_NAME_MAX_PATH_SIZE) - { - name_size = SO_NAME_MAX_PATH_SIZE - 1; - warning (_("current_sos: truncating name of " - "%d characters to only %d characters"), - lm.pathname_len, name_size); - } - - target_read_string (lm.pathname_addr, &name_buf, - name_size, &errcode); - if (errcode != 0) - warning (_("Can't read pathname for load map: %s."), - safe_strerror (errcode)); - else - { - strncpy (new->so_name, name_buf, name_size); - new->so_name[name_size] = '\0'; - xfree (name_buf); - strcpy (new->so_original_name, new->so_name); - } - - new->next = 0; - *link_ptr = new; - link_ptr = &new->next; - - discard_cleanups (old_chain); - } - is_first = 0; - lma = lm.next; - } - - return head; -} - -/* Implement the "open_symbol_file_object" target_so_ops method. - - If no open symbol file, attempt to locate and open the main symbol - file. On IRIX, this is the first link map entry. If its name is - here, we can open it. Useful when attaching to a process without - first loading its symbol file. */ - -static int -irix_open_symbol_file_object (void *from_ttyp) -{ - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); - int addr_size = gdbarch_addr_bit (target_gdbarch ()) / TARGET_CHAR_BIT; - CORE_ADDR lma; - gdb_byte addr_buf[8]; - struct lm_info lm; - struct cleanup *cleanups; - int errcode; - int from_tty = *(int *) from_ttyp; - char *filename; - - if (symfile_objfile) - if (!query (_("Attempt to reload symbols from process? "))) - return 0; - - if ((debug_base = locate_base ()) == 0) - return 0; /* failed somehow... */ - - /* First link map member should be the executable. */ - read_memory (debug_base, addr_buf, addr_size); - lma = extract_mips_address (addr_buf, addr_size, byte_order); - if (lma == 0) - return 0; /* failed somehow... */ - - lm = fetch_lm_info (lma); - - if (lm.pathname_addr == 0) - return 0; /* No filename. */ - - /* Now fetch the filename from target memory. */ - target_read_string (lm.pathname_addr, &filename, SO_NAME_MAX_PATH_SIZE - 1, - &errcode); - - if (errcode) - { - warning (_("failed to read exec filename from attached file: %s"), - safe_strerror (errcode)); - return 0; - } - - cleanups = make_cleanup (xfree, filename); - /* Have a pathname: read the symbol file. */ - symbol_file_add_main (filename, from_tty); - - do_cleanups (cleanups); - - return 1; -} - -/* Implement the "special_symbol_handling" target_so_ops method. - - For IRIX, there's nothing to do. */ - -static void -irix_special_symbol_handling (void) -{ -} - -/* Using the solist entry SO, relocate the addresses in SEC. */ - -static void -irix_relocate_section_addresses (struct so_list *so, - struct target_section *sec) -{ - sec->addr += so->lm_info->reloc_offset; - sec->endaddr += so->lm_info->reloc_offset; -} - -/* Free the lm_info struct. */ - -static void -irix_free_so (struct so_list *so) -{ - xfree (so->lm_info); -} - -/* Clear backend specific state. */ - -static void -irix_clear_solib (void) -{ - debug_base = 0; -} - -/* Return 1 if PC lies in the dynamic symbol resolution code of the - run time loader. */ -static int -irix_in_dynsym_resolve_code (CORE_ADDR pc) -{ - return 0; -} - -struct target_so_ops irix_so_ops; - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_irix_solib; - -void -_initialize_irix_solib (void) -{ - irix_so_ops.relocate_section_addresses = irix_relocate_section_addresses; - irix_so_ops.free_so = irix_free_so; - irix_so_ops.clear_solib = irix_clear_solib; - irix_so_ops.solib_create_inferior_hook = irix_solib_create_inferior_hook; - irix_so_ops.special_symbol_handling = irix_special_symbol_handling; - irix_so_ops.current_sos = irix_current_sos; - irix_so_ops.open_symbol_file_object = irix_open_symbol_file_object; - irix_so_ops.in_dynsym_resolve_code = irix_in_dynsym_resolve_code; - irix_so_ops.bfd_open = solib_bfd_open; - irix_so_ops.handle_event = irix_solib_handle_event; -} |