1 /* Copyright (C) 1990 Free Software Foundation, Inc.
3 This file is part of GDB.
5 GDB is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
10 GDB is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GDB; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include <sys/types.h>
32 ** local data declarations
34 #define MAX_PATH_SIZE 256
36 struct link_map inferior_lm
; /* inferior link map */
37 struct link_map
*inferior_lm_add
;
39 char inferior_so_name
[MAX_PATH_SIZE
]; /* Shared Object Library Name */
40 struct so_list
*next
; /* Next Structure */
44 static struct so_list
*so_list_head
= 0;
46 /*=======================================================================*/
52 ** This module contains the routine which finds the names of any loaded
53 ** "images" in the current process. The argument in must be NULL on the
54 ** first call, and then the returned value must be passed in on
55 ** subsequent calls. This provides the capability to "step" down the
56 ** list of loaded objects. On the last object, a NULL value is returned.
57 ** The arg and return value are "struct link_map" pointers, as defined
60 ** NOTE: This only works under SunOS4.0.
63 struct so_list
*find_solib(so_list_ptr
)
64 struct so_list
*so_list_ptr
; /* so_list_head position ptr */
66 struct so_list
*so_list_next
= 0;
67 CORE_ADDR inferior_dynamic_ptr
= 0;
68 struct link_map
*inferior_lm
= 0;
69 struct link_dynamic inferior_dynamic_cpy
;
70 struct link_dynamic_2 inferior_ld_2_cpy
;
75 if (!(so_list_next
= so_list_head
)) {
76 for (i
= 0; i
< misc_function_count
; i
++) {
77 if (!strcmp (misc_function_vector
[i
].name
, "_DYNAMIC")) {
78 inferior_dynamic_ptr
= misc_function_vector
[i
].address
;
82 if (inferior_dynamic_ptr
) {
83 read_memory(inferior_dynamic_ptr
, &inferior_dynamic_cpy
, sizeof(struct link_dynamic
));
84 if (inferior_dynamic_cpy
.ld_version
== 3) {
85 read_memory((CORE_ADDR
)inferior_dynamic_cpy
.ld_un
.ld_2
,
87 sizeof(struct link_dynamic_2
));
88 inferior_lm
= inferior_ld_2_cpy
.ld_loaded
;
94 ** Advance to next local abbreviated load_map structure
96 if (!(inferior_lm
= so_list_ptr
->inferior_lm
.lm_next
)) {
98 ** See if any were added
100 read_memory((CORE_ADDR
)so_list_ptr
->inferior_lm_add
,
101 &so_list_ptr
->inferior_lm
,
102 sizeof(struct link_map
));
103 inferior_lm
= so_list_ptr
->inferior_lm
.lm_next
;
105 so_list_next
= so_list_ptr
->next
;
107 if ((!so_list_next
) && inferior_lm
) {
109 ** Get Next LM Structure from inferior image and build
110 ** an local abbreviated load_map structure
112 new = (struct so_list
*) xmalloc(sizeof(struct so_list
));
113 new->inferior_lm_add
= inferior_lm
;
114 read_memory((CORE_ADDR
)inferior_lm
,
116 sizeof(struct link_map
));
118 read_memory((CORE_ADDR
)new->inferior_lm
.lm_name
,
119 new->inferior_so_name
,
121 new->inferior_so_name
[MAX_PATH_SIZE
- 1] = 0;
122 /* Zero everything after the first terminating null */
123 strncpy(new->inferior_so_name
, new->inferior_so_name
, MAX_PATH_SIZE
);
125 read_memory((CORE_ADDR
)new->inferior_lm
.lm_ld
,
126 &inferior_dynamic_cpy
,
127 sizeof(struct link_dynamic
));
128 read_memory((CORE_ADDR
)inferior_dynamic_cpy
.ld_un
.ld_2
,
130 sizeof(struct link_dynamic_2
));
131 new->ld_text
= inferior_ld_2_cpy
.ld_text
;
134 new->symbols_loaded
= 0;
136 so_list_ptr
->next
= new;
141 return(so_list_next
);
143 /*=======================================================================*/
145 static void solib_add(arg_string
, from_tty
)
149 register struct so_list
*so
= 0; /* link map state variable */
155 else if (val
= (char *) re_comp (arg_string
)) {
156 error ("Invalid regexp: %s", val
);
159 printf_filtered ("All shared libraries");
161 printf_filtered (" matching regular expresion \"%s\"", arg_string
);
162 printf_filtered (":\n");
166 while (so
= find_solib(so
)) {
167 if (re_exec(so
->inferior_so_name
)) {
168 if (so
->symbols_loaded
) {
169 printf("Symbols already loaded for %s\n", so
->inferior_so_name
);
171 /* File Name String Freed by processing */
172 sz
= strlen(so
->inferior_so_name
) + 1;
173 val
= (char *) xmalloc(sz
);
174 bcopy(so
->inferior_so_name
, val
, sz
);
175 symbol_file_add (val
, from_tty
,
176 (unsigned int)so
->inferior_lm
.lm_addr
, 0);
177 so
->symbols_loaded
= 1;
182 /*=======================================================================*/
184 static void solib_info()
186 register struct so_list
*so
= 0; /* link map state variable */
188 while (so
= find_solib(so
)) {
189 if (so
== so_list_head
) {
190 printf(" Address Range Symbols Shared Object Library\n");
192 printf(" 0x%08x - 0x%08x %s %s\n",
193 so
->inferior_lm
.lm_addr
,
194 so
->inferior_lm
.lm_addr
+ so
->ld_text
- 1,
195 (so
->symbols_loaded
? "Yes" : "No "),
196 so
->inferior_so_name
);
199 printf("No shared libraries loaded at this time.\n");
204 ** Called by Insert Breakpoint to see if Address is Shared Library Address
207 solib_address(address
)
210 register struct so_list
*so
= 0; /* link map state variable */
212 while (so
= find_solib(so
)) {
213 if ((address
>= (CORE_ADDR
) so
->inferior_lm
.lm_addr
) &&
214 (address
< (CORE_ADDR
) so
->inferior_lm
.lm_addr
+ so
->ld_text
))
221 ** Called by free_all_symtabs
226 struct so_list
*next
;
228 while (so_list_head
) {
229 next
= so_list_head
->next
;
240 add_com("sharedlibrary", class_files
, solib_add
,
241 "Load shared object library symbols for files matching REGEXP.");
242 add_info("sharedlibrary", solib_info
,
243 "Status of loaded shared object libraries");