diff options
Diffstat (limited to 'gdb/solib.c')
-rw-r--r-- | gdb/solib.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/gdb/solib.c b/gdb/solib.c new file mode 100644 index 0000000..ab9336f --- /dev/null +++ b/gdb/solib.c @@ -0,0 +1,245 @@ +/* Copyright (C) 1990 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB 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 1, or (at your option) +any later version. + +GDB 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 GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* +** symbol definitions +*/ +#include <sys/types.h> +#include <string.h> +#include <link.h> +#include "defs.h" +#include "param.h" +#include "symtab.h" +#include "gdbcore.h" +#include "command.h" + +/* +** local data declarations +*/ +#define MAX_PATH_SIZE 256 +struct so_list { + struct link_map inferior_lm; /* inferior link map */ + struct link_map *inferior_lm_add; + long ld_text; + char inferior_so_name[MAX_PATH_SIZE]; /* Shared Object Library Name */ + struct so_list *next; /* Next Structure */ + int symbols_loaded; +}; + +static struct so_list *so_list_head = 0; + +/*=======================================================================*/ + +/* find_solib +** +**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>. +** +** NOTE: This only works under SunOS4.0. +*/ + +struct so_list *find_solib(so_list_ptr) +struct so_list *so_list_ptr; /* so_list_head position ptr */ +{ +struct so_list *so_list_next = 0; +CORE_ADDR inferior_dynamic_ptr = 0; +struct link_map *inferior_lm = 0; +struct link_dynamic inferior_dynamic_cpy; +struct link_dynamic_2 inferior_ld_2_cpy; +struct so_list *new; +int i; + + if (!so_list_ptr) { + if (!(so_list_next = so_list_head)) { + for (i = 0; i < misc_function_count; i++) { + if (!strcmp (misc_function_vector[i].name, "_DYNAMIC")) { + inferior_dynamic_ptr = misc_function_vector[i].address; + break; + } + } + if (inferior_dynamic_ptr) { + read_memory(inferior_dynamic_ptr, &inferior_dynamic_cpy, sizeof(struct link_dynamic)); + if (inferior_dynamic_cpy.ld_version == 3) { + read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2, + &inferior_ld_2_cpy, + sizeof(struct link_dynamic_2)); + inferior_lm = inferior_ld_2_cpy.ld_loaded; + } + } + } + } else { + /* + ** Advance to next local abbreviated load_map structure + */ + if (!(inferior_lm = so_list_ptr->inferior_lm.lm_next)) { + /* + ** See if any were added + */ + read_memory((CORE_ADDR)so_list_ptr->inferior_lm_add, + &so_list_ptr->inferior_lm, + sizeof(struct link_map)); + inferior_lm = so_list_ptr->inferior_lm.lm_next; + } + so_list_next = so_list_ptr->next; + } + if ((!so_list_next) && inferior_lm) { + /* + ** Get Next LM Structure from inferior image and build + ** an local abbreviated load_map structure + */ + new = (struct so_list *) xmalloc(sizeof(struct so_list)); + new->inferior_lm_add = inferior_lm; + read_memory((CORE_ADDR)inferior_lm, + &new->inferior_lm, + sizeof(struct link_map)); + + read_memory((CORE_ADDR)new->inferior_lm.lm_name, + new->inferior_so_name, + MAX_PATH_SIZE - 1); + new->inferior_so_name[MAX_PATH_SIZE - 1] = 0; + /* Zero everything after the first terminating null */ + strncpy(new->inferior_so_name, new->inferior_so_name, MAX_PATH_SIZE); + + read_memory((CORE_ADDR)new->inferior_lm.lm_ld, + &inferior_dynamic_cpy, + sizeof(struct link_dynamic)); + read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2, + &inferior_ld_2_cpy, + sizeof(struct link_dynamic_2)); + new->ld_text = inferior_ld_2_cpy.ld_text; + + new->next = 0; + new->symbols_loaded = 0; + if (so_list_ptr) + so_list_ptr->next = new; + else + so_list_head = new; + so_list_next = new; + } + return(so_list_next); +} +/*=======================================================================*/ + +static void solib_add(arg_string, from_tty) +char *arg_string; +int from_tty; +{ + register struct so_list *so = 0; /* link map state variable */ + char *val; + int sz; + + if (arg_string == 0) + re_comp ("."); + else if (val = (char *) re_comp (arg_string)) { + error ("Invalid regexp: %s", val); + } + + printf_filtered ("All shared libraries"); + if (arg_string) + printf_filtered (" matching regular expresion \"%s\"", arg_string); + printf_filtered (":\n"); + + dont_repeat(); + + while (so = find_solib(so)) { + if (re_exec(so->inferior_so_name)) { + if (so->symbols_loaded) { + printf("Symbols already loaded for %s\n", so->inferior_so_name); + } else { + /* File Name String Freed by processing */ + sz = strlen(so->inferior_so_name) + 1; + val = (char *) xmalloc(sz); + bcopy(so->inferior_so_name, val, sz); + symbol_file_add (val, from_tty, + (unsigned int)so->inferior_lm.lm_addr, 0); + so->symbols_loaded = 1; + } + } + } +} +/*=======================================================================*/ + +static void solib_info() +{ +register struct so_list *so = 0; /* link map state variable */ + + while (so = find_solib(so)) { + if (so == so_list_head) { + printf(" Address Range Symbols Shared Object Library\n"); + } + printf(" 0x%08x - 0x%08x %s %s\n", + so->inferior_lm.lm_addr, + so->inferior_lm.lm_addr + so->ld_text - 1, + (so->symbols_loaded ? "Yes" : "No "), + so->inferior_so_name); + } + if (!so_list_head) { + printf("No shared libraries loaded at this time.\n"); + } +} + +/* +** Called by Insert Breakpoint to see if Address is Shared Library Address +*/ +int +solib_address(address) + CORE_ADDR address; +{ +register struct so_list *so = 0; /* link map state variable */ + + while (so = find_solib(so)) { + if ((address >= (CORE_ADDR) so->inferior_lm.lm_addr) && + (address < (CORE_ADDR) so->inferior_lm.lm_addr + so->ld_text)) + return 1; + } + return 0; +} + +/* +** Called by free_all_symtabs +*/ +void +clear_solib() +{ +struct so_list *next; + + while (so_list_head) { + next = so_list_head->next; + free(so_list_head); + so_list_head = next; + } + +} + +void +_initialize_solib() +{ + + add_com("sharedlibrary", class_files, solib_add, + "Load shared object library symbols for files matching REGEXP."); + add_info("sharedlibrary", solib_info, + "Status of loaded shared object libraries"); + +} |