📄 solib.c
字号:
{ bfd_close (interp_bfd); return (0); } /* Eureka! We found the symbol. But now we may need to relocate it by the base address. If the symbol's value is less than the base address of the shared library, then it hasn't yet been relocated by the dynamic linker, and we have to do it ourself. FIXME: Note that we make the assumption that the first segment that corresponds to the shared library has the base address to which the library was relocated. */ if (address < baseaddr) { address += baseaddr; } debug_base = address; bfd_close (interp_bfd); return (1);}#endif/*LOCAL FUNCTION locate_base -- locate the base address of dynamic linker structsSYNOPSIS CORE_ADDR locate_base (void)DESCRIPTION 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. 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_ADDRlocate_base (){#ifndef SVR4_SHARED_LIBS struct minimal_symbol *msymbol; CORE_ADDR address = 0; /* For SunOS, we want to limit the search for DEBUG_BASE to the executable being debugged, since there is a duplicate named symbol in the shared library. We don't want the shared library versions. */ msymbol = lookup_minimal_symbol (DEBUG_BASE, symfile_objfile); if ((msymbol != NULL) && (msymbol -> address != 0)) { address = msymbol -> address; } return (address);#else /* SVR4_SHARED_LIBS */ /* Check to see if we have a currently valid address, and if so, avoid doing all this work again and just return the cached address. If we have no cached address, ask the /proc support interface to iterate over the list of mapped address segments, calling look_for_base() for each segment. When we are done, we will have either found the base address or not. */ if (debug_base == 0) { proc_iterate_over_mappings (look_for_base); } return (debug_base);#endif /* !SVR4_SHARED_LIBS */}static struct link_map *first_link_map_member (){ struct link_map *lm = NULL;#ifndef SVR4_SHARED_LIBS read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy)); if (dynamic_copy.ld_version >= 2) { /* It is a version that we can deal with, so read in the secondary structure and find the address of the link map list from it. */ read_memory ((CORE_ADDR) dynamic_copy.ld_un.ld_2, (char *) &ld_2_copy, sizeof (struct link_dynamic_2)); lm = ld_2_copy.ld_loaded; }#else /* SVR4_SHARED_LIBS */ read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug)); lm = debug_copy.r_map;#endif /* !SVR4_SHARED_LIBS */ return (lm);}/*LOCAL FUNCTION find_solib -- step through list of shared objectsSYNOPSIS struct so_list *find_solib (struct so_list *so_list_ptr)DESCRIPTION This module contains the routine which finds the names of any loaded "images" in the current process. The argument in must be NULL on the first call, and then the returned value must be passed in on subsequent calls. This provides the capability to "step" down the list of loaded objects. On the last object, a NULL value is returned. The arg and return value are "struct link_map" pointers, as defined in <link.h>. */static struct so_list *find_solib (so_list_ptr) struct so_list *so_list_ptr; /* Last lm or NULL for first one */{ struct so_list *so_list_next = NULL; struct link_map *lm = NULL; struct so_list *new; if (so_list_ptr == NULL) { /* We are setting up for a new scan through the loaded images. */ if ((so_list_next = so_list_head) == NULL) { /* We have not already read in the dynamic linking structures from the inferior, lookup the address of the base structure. */ debug_base = locate_base (); if (debug_base > 0) { /* Read the base structure in and find the address of the first link map list member. */ lm = first_link_map_member (); } } } else { /* We have been called before, and are in the process of walking the shared library list. Advance to the next shared object. */ if ((lm = LM_NEXT (so_list_ptr)) == NULL) { /* We have hit the end of the list, so check to see if any were added, but be quiet if we can't read from the target any more. */ int status = target_read_memory ((CORE_ADDR) so_list_ptr -> lmaddr, (char *) &(so_list_ptr -> lm), sizeof (struct link_map)); if (status == 0) { lm = LM_NEXT (so_list_ptr); } else { lm = NULL; } } so_list_next = so_list_ptr -> next; } if ((so_list_next == NULL) && (lm != NULL)) { /* Get next link map structure from inferior image and build a local abbreviated load_map structure */ new = (struct so_list *) xmalloc (sizeof (struct so_list)); memset ((char *) new, 0, sizeof (struct so_list)); new -> lmaddr = lm; /* Add the new node as the next node in the list, or as the root node if this is the first one. */ if (so_list_ptr != NULL) { so_list_ptr -> next = new; } else { so_list_head = new; } so_list_next = new; read_memory ((CORE_ADDR) lm, (char *) &(new -> lm), sizeof (struct link_map)); /* For the SVR4 version, there is one entry that has no name (for the inferior executable) since it is not a shared object. */ if (LM_NAME (new) != 0) { if (!target_read_string((CORE_ADDR) LM_NAME (new), new -> so_name, MAX_PATH_SIZE - 1)) error ("find_solib: Can't read pathname for load map\n"); new -> so_name[MAX_PATH_SIZE - 1] = 0; solib_map_sections (new); } } return (so_list_next);}/* A small stub to get us past the arg-passing pinhole of catch_errors. */static intsymbol_add_stub (arg) char *arg;{ register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ so -> objfile = symbol_file_add (so -> so_name, so -> from_tty, (unsigned int) so -> textsection -> addr, 0, 0, 0); return (1);}/*GLOBAL FUNCTION solib_add -- add a shared library file to the symtab and section listSYNOPSIS void solib_add (char *arg_string, int from_tty, struct target_ops *target)DESCRIPTION*/voidsolib_add (arg_string, from_tty, target) char *arg_string; int from_tty; struct target_ops *target;{ register struct so_list *so = NULL; /* link map state variable */ char *re_err; int count; int old; if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) { error ("Invalid regexp: %s", re_err); } /* Getting new symbols may change our opinion about what is frameless. */ reinit_frame_cache (); while ((so = find_solib (so)) != NULL) { if (so -> so_name[0] && re_exec (so -> so_name)) { if (so -> symbols_loaded) { if (from_tty) { printf ("Symbols already loaded for %s\n", so -> so_name); } } else { catch_errors (symbol_add_stub, (char *) so, "Error while reading shared library symbols:\n"); special_symbol_handling (so); so -> symbols_loaded = 1; so -> from_tty = from_tty; } } } /* Now add the shared library sections to the section table of the specified target, if any. */ if (target) { /* Count how many new section_table entries there are. */ so = NULL; count = 0; while ((so = find_solib (so)) != NULL) { if (so -> so_name[0]) { count += so -> sections_end - so -> sections; } } if (count) { /* Reallocate the target's section table including the new size. */ if (target -> to_sections) { old = target -> to_sections_end - target -> to_sections; target -> to_sections = (struct section_table *) realloc ((char *)target -> to_sections, (sizeof (struct section_table)) * (count + old)); } else { old = 0; target -> to_sections = (struct section_table *) malloc ((sizeof (struct section_table)) * count); } target -> to_sections_end = target -> to_sections + (count + old); /* Add these section table entries to the target's table. */ while ((so = find_solib (so)) != NULL) { if (so -> so_name[0]) { count = so -> sections_end - so -> sections; memcpy ((char *) (target -> to_sections + old), so -> sections, (sizeof (struct section_table)) * count); old += count; } } } }}/*LOCAL FUNCTION info_sharedlibrary_command -- code for "info sharedlibrary"SYNOPSIS static void info_sharedlibrary_command ()DESCRIPTION Walk through the shared library list and print information about each attached library.*/static voidinfo_sharedlibrary_command (ignore, from_tty) char *ignore; int from_tty;{ register struct so_list *so = NULL; /* link map state variable */ int header_done = 0; if (exec_bfd == NULL) { printf ("No exec file.\n"); return; } while ((so = find_solib (so)) != NULL) { if (so -> so_name[0]) { if (!header_done) { printf("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read", "Shared Object Library"); header_done++; } printf ("%-12s", local_hex_string_custom ((int) LM_ADDR (so), "08")); printf ("%-12s", local_hex_string_custom (so -> lmend, "08")); printf ("%-12s", so -> symbols_loaded ? "Yes" : "No"); printf ("%s\n", so -> so_name); } } if (so_list_head == NULL) { printf ("No shared libraries loaded at this time.\n"); }}/*GLOBAL FUNCTION solib_address -- check to see if an address is in a shared libSYNOPSIS int solib_address (CORE_ADDR address)DESCRIPTION Provides a hook for other gdb routines to discover whether or not a particular address is within the mapped address space of a shared library. Any address between the base mapping address and the first address beyond the end of the last mapping, is considered to be within the shared library address space, for
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -