The list of changes is too long to fit in the cvs log (since it truncates!).
[deliverable/binutils-gdb.git] / gdb / solib.c
CommitLineData
bd5635a1
RP
1/* Copyright (C) 1990 Free Software Foundation, Inc.
2
3This file is part of GDB.
4
5GDB is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 1, or (at your option)
8any later version.
9
10GDB is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GDB; see the file COPYING. If not, write to
17the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19/*
20** symbol definitions
21*/
22#include <sys/types.h>
23#include <string.h>
24#include <link.h>
d0237a54
JK
25#include <sys/param.h>
26#include <fcntl.h>
27#include <stdio.h>
bd5635a1
RP
28#include "defs.h"
29#include "param.h"
30#include "symtab.h"
31#include "gdbcore.h"
32#include "command.h"
b3fdaf3d 33#include "target.h"
2403f49b 34#include "frame.h"
bd5635a1
RP
35
36/*
37** local data declarations
38*/
39#define MAX_PATH_SIZE 256
40struct so_list {
41 struct link_map inferior_lm; /* inferior link map */
42 struct link_map *inferior_lm_add;
43 long ld_text;
44 char inferior_so_name[MAX_PATH_SIZE]; /* Shared Object Library Name */
45 struct so_list *next; /* Next Structure */
46 int symbols_loaded;
d0237a54
JK
47 bfd *so_bfd;
48 struct section_table *so_sections;
49 struct section_table *so_sections_end;
bd5635a1
RP
50};
51
52static struct so_list *so_list_head = 0;
53
d0237a54
JK
54/*
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.
57*/
58static void
59solib_map_sections(so)
60struct so_list *so;
61{
62 char *filename;
63 char *scratch_pathname;
64 int scratch_chan;
65 struct section_table *p;
66
67 filename = tilde_expand (so->inferior_so_name);
68 make_cleanup (free, filename);
69
70 scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
71 &scratch_pathname);
72 if (scratch_chan < 0)
73 scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, O_RDONLY, 0,
74 &scratch_pathname);
75 if (scratch_chan < 0)
76 perror_with_name (filename);
77
78 so->so_bfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
79 if (!so->so_bfd)
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));
88
89 for (p = so->so_sections; p < so->so_sections_end; p++)
90 {
91 if (strcmp (bfd_section_name (so->so_bfd, p->sec_ptr), ".text") == 0)
92 {
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;
97 }
98 else
99 /* All other sections are ignored for now. */
100 p->addr = p->endaddr = 0;
101 }
102}
103
bd5635a1
RP
104/*=======================================================================*/
105
106/* find_solib
107**
108**Description:
109**
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
116** in <link.h>.
117**
118** NOTE: This only works under SunOS4.0.
119*/
120
121struct so_list *find_solib(so_list_ptr)
122struct so_list *so_list_ptr; /* so_list_head position ptr */
123{
124struct so_list *so_list_next = 0;
125CORE_ADDR inferior_dynamic_ptr = 0;
126struct link_map *inferior_lm = 0;
127struct link_dynamic inferior_dynamic_cpy;
128struct link_dynamic_2 inferior_ld_2_cpy;
129struct so_list *new;
130int i;
131
132 if (!so_list_ptr) {
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;
137 break;
138 }
139 }
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,
144 &inferior_ld_2_cpy,
145 sizeof(struct link_dynamic_2));
146 inferior_lm = inferior_ld_2_cpy.ld_loaded;
147 }
148 }
149 }
150 } else {
151 /*
152 ** Advance to next local abbreviated load_map structure
153 */
154 if (!(inferior_lm = so_list_ptr->inferior_lm.lm_next)) {
b3fdaf3d
JK
155 /* See if any were added, but be quiet if we can't read
156 from the target any more. */
157 int status;
158
159 status = target_read_memory (
160 (CORE_ADDR)so_list_ptr->inferior_lm_add,
e1ce8aa5 161 (char *)&so_list_ptr->inferior_lm,
b3fdaf3d
JK
162 sizeof(struct link_map));
163 if (status == 0)
164 inferior_lm = so_list_ptr->inferior_lm.lm_next;
165 else
166 inferior_lm = 0;
bd5635a1
RP
167 }
168 so_list_next = so_list_ptr->next;
169 }
170 if ((!so_list_next) && inferior_lm) {
171 /*
172 ** Get Next LM Structure from inferior image and build
173 ** an local abbreviated load_map structure
174 */
175 new = (struct so_list *) xmalloc(sizeof(struct so_list));
176 new->inferior_lm_add = inferior_lm;
177 read_memory((CORE_ADDR)inferior_lm,
178 &new->inferior_lm,
179 sizeof(struct link_map));
180
181 read_memory((CORE_ADDR)new->inferior_lm.lm_name,
182 new->inferior_so_name,
183 MAX_PATH_SIZE - 1);
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);
187
d0237a54
JK
188#if 0
189 /* This doesn't work for core files, so instead get ld_text
190 using solib_map_sections (below). */
bd5635a1
RP
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,
195 &inferior_ld_2_cpy,
196 sizeof(struct link_dynamic_2));
197 new->ld_text = inferior_ld_2_cpy.ld_text;
d0237a54
JK
198#endif
199
bd5635a1
RP
200 new->next = 0;
201 new->symbols_loaded = 0;
d0237a54
JK
202 new->so_bfd = NULL;
203 new->so_sections = NULL;
bd5635a1
RP
204 if (so_list_ptr)
205 so_list_ptr->next = new;
206 else
207 so_list_head = new;
d0237a54
JK
208
209 solib_map_sections (new);
210
bd5635a1
RP
211 so_list_next = new;
212 }
213 return(so_list_next);
214}
d0237a54
JK
215
216/*
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.
219*/
220int
221solib_xfer_memory (memaddr, myaddr, len, write)
222 CORE_ADDR memaddr;
223 char *myaddr;
224 int len;
225 int write;
226{
227 int res;
228 register struct so_list *so = 0;
229
230 while (so = find_solib(so))
231 {
232 res = xfer_memory (memaddr, myaddr, len, write,
233 so->so_bfd, so->so_sections, so->so_sections_end);
234 if (res)
235 return res;
236 }
237 return 0;
238}
bd5635a1
RP
239/*=======================================================================*/
240
d0237a54 241void solib_add(arg_string, from_tty)
bd5635a1
RP
242char *arg_string;
243int from_tty;
244{
245 register struct so_list *so = 0; /* link map state variable */
246 char *val;
bd5635a1
RP
247
248 if (arg_string == 0)
249 re_comp (".");
250 else if (val = (char *) re_comp (arg_string)) {
251 error ("Invalid regexp: %s", val);
252 }
2403f49b
JK
253
254 /* Getting new symbols may change our opinion about what is
255 frameless. */
256 reinit_frame_cache ();
bd5635a1
RP
257
258 printf_filtered ("All shared libraries");
259 if (arg_string)
260 printf_filtered (" matching regular expresion \"%s\"", arg_string);
261 printf_filtered (":\n");
262
263 dont_repeat();
264
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);
269 } else {
b3fdaf3d 270 symbol_file_add (so->inferior_so_name, from_tty,
bd5635a1
RP
271 (unsigned int)so->inferior_lm.lm_addr, 0);
272 so->symbols_loaded = 1;
273 }
274 }
275 }
276}
277/*=======================================================================*/
278
279static void solib_info()
280{
281register struct so_list *so = 0; /* link map state variable */
282
283 while (so = find_solib(so)) {
284 if (so == so_list_head) {
285 printf(" Address Range Symbols Shared Object Library\n");
286 }
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);
292 }
293 if (!so_list_head) {
294 printf("No shared libraries loaded at this time.\n");
295 }
296}
297
298/*
299** Called by Insert Breakpoint to see if Address is Shared Library Address
300*/
301int
302solib_address(address)
303 CORE_ADDR address;
304{
305register struct so_list *so = 0; /* link map state variable */
306
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))
310 return 1;
311 }
312 return 0;
313}
314
315/*
316** Called by free_all_symtabs
317*/
318void
319clear_solib()
320{
321struct so_list *next;
322
323 while (so_list_head) {
d0237a54
JK
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);
bd5635a1
RP
328 next = so_list_head->next;
329 free(so_list_head);
330 so_list_head = next;
331 }
332
333}
334
335void
336_initialize_solib()
337{
338
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");
343
344}
This page took 0.038184 seconds and 4 git commands to generate.