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>
25 #include <sys/param.h>
37 ** local data declarations
39 #define MAX_PATH_SIZE 256
41 struct link_map inferior_lm
; /* inferior link map */
42 struct link_map
*inferior_lm_add
;
44 char inferior_so_name
[MAX_PATH_SIZE
]; /* Shared Object Library Name */
45 struct so_list
*next
; /* Next Structure */
48 struct section_table
*so_sections
;
49 struct section_table
*so_sections_end
;
52 static struct so_list
*so_list_head
= 0;
55 ** Build a section map for a shared library, record its text size in
56 ** the so_list structure and set up the text section of the shared lib.
59 solib_map_sections(so
)
63 char *scratch_pathname
;
65 struct section_table
*p
;
67 filename
= tilde_expand (so
->inferior_so_name
);
68 make_cleanup (free
, filename
);
70 scratch_chan
= openp (getenv ("PATH"), 1, filename
, O_RDONLY
, 0,
73 scratch_chan
= openp (getenv ("LD_LIBRARY_PATH"), 1, filename
, O_RDONLY
, 0,
76 perror_with_name (filename
);
78 so
->so_bfd
= bfd_fdopenr (scratch_pathname
, NULL
, scratch_chan
);
80 error ("Could not open `%s' as an executable file: %s",
81 scratch_pathname
, bfd_errmsg (bfd_error
));
82 if (!bfd_check_format (so
->so_bfd
, bfd_object
))
83 error ("\"%s\": not in executable format: %s.",
84 scratch_pathname
, bfd_errmsg (bfd_error
));
85 if (build_section_table (so
->so_bfd
, &so
->so_sections
, &so
->so_sections_end
))
86 error ("Can't find the file sections in `%s': %s",
87 exec_bfd
->filename
, bfd_errmsg (bfd_error
));
89 for (p
= so
->so_sections
; p
< so
->so_sections_end
; p
++)
91 if (strcmp (bfd_section_name (so
->so_bfd
, p
->sec_ptr
), ".text") == 0)
93 /* Determine length of text section and relocate it. */
94 so
->ld_text
= p
->endaddr
- p
->addr
;
95 p
->addr
+= (CORE_ADDR
)so
->inferior_lm
.lm_addr
;
96 p
->endaddr
+= (CORE_ADDR
)so
->inferior_lm
.lm_addr
;
99 /* All other sections are ignored for now. */
100 p
->addr
= p
->endaddr
= 0;
104 /*=======================================================================*/
110 ** This module contains the routine which finds the names of any loaded
111 ** "images" in the current process. The argument in must be NULL on the
112 ** first call, and then the returned value must be passed in on
113 ** subsequent calls. This provides the capability to "step" down the
114 ** list of loaded objects. On the last object, a NULL value is returned.
115 ** The arg and return value are "struct link_map" pointers, as defined
118 ** NOTE: This only works under SunOS4.0.
121 struct so_list
*find_solib(so_list_ptr
)
122 struct so_list
*so_list_ptr
; /* so_list_head position ptr */
124 struct so_list
*so_list_next
= 0;
125 CORE_ADDR inferior_dynamic_ptr
= 0;
126 struct link_map
*inferior_lm
= 0;
127 struct link_dynamic inferior_dynamic_cpy
;
128 struct link_dynamic_2 inferior_ld_2_cpy
;
133 if (!(so_list_next
= so_list_head
)) {
134 for (i
= 0; i
< misc_function_count
; i
++) {
135 if (!strcmp (misc_function_vector
[i
].name
, "_DYNAMIC")) {
136 inferior_dynamic_ptr
= misc_function_vector
[i
].address
;
140 if (inferior_dynamic_ptr
) {
141 read_memory(inferior_dynamic_ptr
, &inferior_dynamic_cpy
, sizeof(struct link_dynamic
));
142 if (inferior_dynamic_cpy
.ld_version
== 3) {
143 read_memory((CORE_ADDR
)inferior_dynamic_cpy
.ld_un
.ld_2
,
145 sizeof(struct link_dynamic_2
));
146 inferior_lm
= inferior_ld_2_cpy
.ld_loaded
;
152 ** Advance to next local abbreviated load_map structure
154 if (!(inferior_lm
= so_list_ptr
->inferior_lm
.lm_next
)) {
155 /* See if any were added, but be quiet if we can't read
156 from the target any more. */
159 status
= target_read_memory (
160 (CORE_ADDR
)so_list_ptr
->inferior_lm_add
,
161 &so_list_ptr
->inferior_lm
,
162 sizeof(struct link_map
));
164 inferior_lm
= so_list_ptr
->inferior_lm
.lm_next
;
168 so_list_next
= so_list_ptr
->next
;
170 if ((!so_list_next
) && inferior_lm
) {
172 ** Get Next LM Structure from inferior image and build
173 ** an local abbreviated load_map structure
175 new = (struct so_list
*) xmalloc(sizeof(struct so_list
));
176 new->inferior_lm_add
= inferior_lm
;
177 read_memory((CORE_ADDR
)inferior_lm
,
179 sizeof(struct link_map
));
181 read_memory((CORE_ADDR
)new->inferior_lm
.lm_name
,
182 new->inferior_so_name
,
184 new->inferior_so_name
[MAX_PATH_SIZE
- 1] = 0;
185 /* Zero everything after the first terminating null */
186 strncpy(new->inferior_so_name
, new->inferior_so_name
, MAX_PATH_SIZE
);
189 /* This doesn't work for core files, so instead get ld_text
190 using solib_map_sections (below). */
191 read_memory((CORE_ADDR
)new->inferior_lm
.lm_ld
,
192 &inferior_dynamic_cpy
,
193 sizeof(struct link_dynamic
));
194 read_memory((CORE_ADDR
)inferior_dynamic_cpy
.ld_un
.ld_2
,
196 sizeof(struct link_dynamic_2
));
197 new->ld_text
= inferior_ld_2_cpy
.ld_text
;
201 new->symbols_loaded
= 0;
203 new->so_sections
= NULL
;
205 so_list_ptr
->next
= new;
209 solib_map_sections (new);
213 return(so_list_next
);
217 ** Called by core_xfer_memory if the transfer form the core file failed.
218 ** We try to satisfy the request from the text sections of the shared libs.
221 solib_xfer_memory (memaddr
, myaddr
, len
, write
)
228 register struct so_list
*so
= 0;
230 while (so
= find_solib(so
))
232 res
= xfer_memory (memaddr
, myaddr
, len
, write
,
233 so
->so_bfd
, so
->so_sections
, so
->so_sections_end
);
239 /*=======================================================================*/
241 void solib_add(arg_string
, from_tty
)
245 register struct so_list
*so
= 0; /* link map state variable */
250 else if (val
= (char *) re_comp (arg_string
)) {
251 error ("Invalid regexp: %s", val
);
254 /* Getting new symbols may change our opinion about what is
256 reinit_frame_cache ();
258 printf_filtered ("All shared libraries");
260 printf_filtered (" matching regular expresion \"%s\"", arg_string
);
261 printf_filtered (":\n");
265 while (so
= find_solib(so
)) {
266 if (re_exec(so
->inferior_so_name
)) {
267 if (so
->symbols_loaded
) {
268 printf("Symbols already loaded for %s\n", so
->inferior_so_name
);
270 symbol_file_add (so
->inferior_so_name
, from_tty
,
271 (unsigned int)so
->inferior_lm
.lm_addr
, 0);
272 so
->symbols_loaded
= 1;
277 /*=======================================================================*/
279 static void solib_info()
281 register struct so_list
*so
= 0; /* link map state variable */
283 while (so
= find_solib(so
)) {
284 if (so
== so_list_head
) {
285 printf(" Address Range Symbols Shared Object Library\n");
287 printf(" 0x%08x - 0x%08x %s %s\n",
288 so
->inferior_lm
.lm_addr
,
289 so
->inferior_lm
.lm_addr
+ so
->ld_text
- 1,
290 (so
->symbols_loaded
? "Yes" : "No "),
291 so
->inferior_so_name
);
294 printf("No shared libraries loaded at this time.\n");
299 ** Called by Insert Breakpoint to see if Address is Shared Library Address
302 solib_address(address
)
305 register struct so_list
*so
= 0; /* link map state variable */
307 while (so
= find_solib(so
)) {
308 if ((address
>= (CORE_ADDR
) so
->inferior_lm
.lm_addr
) &&
309 (address
< (CORE_ADDR
) so
->inferior_lm
.lm_addr
+ so
->ld_text
))
316 ** Called by free_all_symtabs
321 struct so_list
*next
;
323 while (so_list_head
) {
324 if (so_list_head
->so_sections
)
325 free (so_list_head
->so_sections
);
326 if (so_list_head
->so_bfd
)
327 bfd_close (so_list_head
->so_bfd
);
328 next
= so_list_head
->next
;
339 add_com("sharedlibrary", class_files
, solib_add
,
340 "Load shared object library symbols for files matching REGEXP.");
341 add_info("sharedlibrary", solib_info
,
342 "Status of loaded shared object libraries");