📄 solib.c
字号:
our purposes. For example, this routine is called at one point to disable breakpoints which are in shared libraries that are not currently mapped in. */intsolib_address (address) CORE_ADDR address;{ register struct so_list *so = 0; /* link map state variable */ while ((so = find_solib (so)) != NULL) { if (so -> so_name[0]) { if ((address >= (CORE_ADDR) LM_ADDR (so)) && (address < (CORE_ADDR) so -> lmend)) { return (1); } } } return (0);}/* Called by free_all_symtabs */void clear_solib(){ struct so_list *next; while (so_list_head) { if (so_list_head -> sections) { free ((PTR)so_list_head -> sections); } if (so_list_head -> so_bfd) { bfd_close (so_list_head -> so_bfd); } next = so_list_head -> next; free((PTR)so_list_head); so_list_head = next; } debug_base = 0;}/*LOCAL FUNCTION disable_break -- remove the "mapping changed" breakpointSYNOPSIS static int disable_break ()DESCRIPTION Removes the breakpoint that gets hit when the dynamic linker completes a mapping change.*/static intdisable_break (){ int status = 1;#ifndef SVR4_SHARED_LIBS int in_debugger = 0; /* Read the debugger structure from the inferior to retrieve the address of the breakpoint and the original contents of the breakpoint address. Remove the breakpoint by writing the original contents back. */ read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy)); /* Set `in_debugger' to zero now. */ write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger)); breakpoint_addr = (CORE_ADDR) debug_copy.ldd_bp_addr; write_memory (breakpoint_addr, (char *) &debug_copy.ldd_bp_inst, sizeof (debug_copy.ldd_bp_inst));#else /* SVR4_SHARED_LIBS */ /* Note that breakpoint address and original contents are in our address space, so we just need to write the original contents back. */ if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0) { status = 0; }#endif /* !SVR4_SHARED_LIBS */ /* For the SVR4 version, we always know the breakpoint address. For the SunOS version we don't know it until the above code is executed. Grumble if we are stopped anywhere besides the breakpoint address. */ if (stop_pc != breakpoint_addr) { warning ("stopped at unknown breakpoint while handling shared libraries"); } return (status);}/*LOCAL FUNCTION enable_break -- arrange for dynamic linker to hit breakpointSYNOPSIS int enable_break (void)DESCRIPTION Both the SunOS and the SVR4 dynamic linkers have, as part of their debugger interface, support for arranging for the inferior to hit a breakpoint after mapping in the shared libraries. This function enables that breakpoint. For SunOS, there is a special flag location (in_debugger) which we set to 1. When the dynamic linker sees this flag set, it will set a breakpoint at a location known only to itself, after saving the original contents of that place and the breakpoint address itself, in it's own internal structures. When we resume the inferior, it will eventually take a SIGTRAP when it runs into the breakpoint. We handle this (in a different place) by restoring the contents of the breakpointed location (which is only known after it stops), chasing around to locate the shared libraries that have been loaded, then resuming. For SVR4, the debugger interface structure contains a member (r_brk) which is statically initialized at the time the shared library is built, to the offset of a function (_r_debug_state) which is guaran- teed to be called once before mapping in a library, and again when the mapping is complete. At the time we are examining this member, it contains only the unrelocated offset of the function, so we have to do our own relocation. Later, when the dynamic linker actually runs, it relocates r_brk to be the actual address of _r_debug_state(). The debugger interface structure also contains an enumeration which is set to either RT_ADD or RT_DELETE prior to changing the mapping, depending upon whether or not the library is being mapped or unmapped, and then set to RT_CONSISTENT after the library is mapped/unmapped.*/static intenable_break (){#ifndef SVR4_SHARED_LIBS int j; int in_debugger; /* Get link_dynamic structure */ j = target_read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy)); if (j) { /* unreadable */ return (0); } /* Calc address of debugger interface structure */ debug_addr = (CORE_ADDR) dynamic_copy.ldd; /* Calc address of `in_debugger' member of debugger interface structure */ flag_addr = debug_addr + (CORE_ADDR) ((char *) &debug_copy.ldd_in_debugger - (char *) &debug_copy); /* Write a value of 1 to this member. */ in_debugger = 1; write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger));#else /* SVR4_SHARED_LIBS */#ifdef BKPT_AT_MAIN struct minimal_symbol *msymbol; msymbol = lookup_minimal_symbol ("main", symfile_objfile); if ((msymbol != NULL) && (msymbol -> address != 0)) { breakpoint_addr = msymbol -> address; } else { return (0); } if (target_insert_breakpoint (breakpoint_addr, shadow_contents) != 0) { return (0); }#else /* !BKPT_AT_MAIN */ struct symtab_and_line sal; /* Read the debugger interface structure directly. */ read_memory (debug_base, (char *) &debug_copy, sizeof (debug_copy)); /* Set breakpoint at the debugger interface stub routine that will be called just prior to each mapping change and again after the mapping change is complete. Set up the (nonexistent) handler to deal with hitting these breakpoints. (FIXME). */ warning ("'%s': line %d: missing SVR4 support code", __FILE__, __LINE__);#endif /* BKPT_AT_MAIN */#endif /* !SVR4_SHARED_LIBS */ return (1);} /* GLOBAL FUNCTION solib_create_inferior_hook -- shared library startup support SYNOPSIS void 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 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. */void solib_create_inferior_hook(){ if ((debug_base = locate_base ()) == 0) { /* Can't find the symbol or the executable is statically linked. */ return; } if (!enable_break ()) { warning ("shared library handler failed to enable breakpoint"); return; } /* Now run the target. It 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. */ clear_proceed_status (); stop_soon_quietly = 1; stop_signal = 0; do { target_resume (0, stop_signal); wait_for_inferior (); } while (stop_signal != SIGTRAP); stop_soon_quietly = 0; /* We are now either at the "mapping complete" breakpoint (or somewhere else, a condition we aren't prepared to deal with anyway), so adjust the PC as necessary after a breakpoint, disable the breakpoint, and add any shared libraries that were mapped in. */ if (DECR_PC_AFTER_BREAK) { stop_pc -= DECR_PC_AFTER_BREAK; write_register (PC_REGNUM, stop_pc); } if (!disable_break ()) { warning ("shared library handler failed to disable breakpoint"); } solib_add ((char *) 0, 0, (struct target_ops *) 0);}/*LOCAL FUNCTION special_symbol_handling -- additional shared library symbol handlingSYNOPSIS void special_symbol_handling (struct so_list *so)DESCRIPTION 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. For Suns, this consists of grunging around in the dynamic linkers structures to find symbol definitions for "common" symbols and adding them to the minimal symbol table for the corresponding objfile.*/static voidspecial_symbol_handling (so)struct so_list *so;{#ifndef SVR4_SHARED_LIBS int j; if (debug_addr == 0) { /* Get link_dynamic structure */ j = target_read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy)); if (j) { /* unreadable */ return; } /* Calc address of debugger interface structure */ /* FIXME, this needs work for cross-debugging of core files (byteorder, size, alignment, etc). */ debug_addr = (CORE_ADDR) dynamic_copy.ldd; } /* Read the debugger structure from the inferior, just to make sure we have a current copy. */ j = target_read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy)); if (j) return; /* unreadable */ /* Get common symbol definitions for the loaded object. */ if (debug_copy.ldd_cp) { solib_add_common_symbols (debug_copy.ldd_cp, so -> objfile); }#endif /* !SVR4_SHARED_LIBS */}/*LOCAL FUNCTION sharedlibrary_command -- handle command to explicitly add librarySYNOPSIS static void sharedlibrary_command (char *args, int from_tty)DESCRIPTION*/static voidsharedlibrary_command (args, from_tty)char *args;int from_tty;{ dont_repeat (); solib_add (args, from_tty, (struct target_ops *) 0);}void_initialize_solib(){ add_com ("sharedlibrary", class_files, sharedlibrary_command, "Load shared object library symbols for files matching REGEXP."); add_info ("sharedlibrary", info_sharedlibrary_command, "Status of loaded shared object libraries.");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -