/* 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 #include #include #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 . ** ** 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"); }