* target.h: Add to_doc and target_preopen.
[deliverable/binutils-gdb.git] / gdb / exec.c
CommitLineData
bd5635a1
RP
1/* Work with executable files, for GDB.
2 Copyright (C) 1988, 1989 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6GDB is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GDB is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GDB; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include <stdio.h>
21#include "defs.h"
22#include "param.h"
23#include "frame.h"
24#include "inferior.h"
25#include "target.h"
26
27#ifdef USG
28#include <sys/types.h>
29#endif
30
31#include <sys/param.h>
32#include <fcntl.h>
33
34#include "gdbcore.h"
35
36#ifdef STILL_NEEDED_FOR_DECSTATION
37#include <sys/dir.h> /* For DECstations */
38#include <sys/user.h> /* After a.out.h */
39#include <sys/file.h>
40#endif
41
42#include <sys/stat.h>
43
44extern char *getenv();
45extern void child_create_inferior (), child_attach ();
be2c3f35 46extern void add_syms_addr_command ();
bd5635a1
RP
47extern void symbol_file_command ();
48
49/* The Binary File Descriptor handle for the executable file. */
50
51bfd *exec_bfd = NULL;
52
53/* The base and bounds of the table of the exec file's sections. */
54
55struct section_table *exec_sections, *exec_sections_end;
56
57/* Forward decl */
58
59extern struct target_ops exec_ops;
60
61void
62exec_close (quitting)
63 int quitting;
64{
65 if (exec_bfd) {
66 bfd_close (exec_bfd);
67 exec_bfd = NULL;
68 }
69}
70
71void
72exec_file_command (filename, from_tty)
73 char *filename;
74 int from_tty;
75{
f2fc6e7a 76 target_preopen (from_tty);
bd5635a1
RP
77
78 /* Remove any previous exec file. */
79 unpush_target (&exec_ops);
80
81 /* Now open and digest the file the user requested, if any. */
82
83 if (filename)
84 {
85 char *scratch_pathname;
86 int scratch_chan;
87
88 filename = tilde_expand (filename);
89 make_cleanup (free, filename);
90
91/* FIXME, if writeable is set, open for read/write. */
92 scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
93 &scratch_pathname);
94 if (scratch_chan < 0)
95 perror_with_name (filename);
96
97 exec_bfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
98 if (!exec_bfd)
99 error ("Could not open `%s' as an executable file: %s",
100 scratch_pathname, bfd_errmsg (bfd_error));
101 if (!bfd_check_format (exec_bfd, bfd_object))
102 error ("\"%s\": not in executable format: %s.",
103 scratch_pathname, bfd_errmsg (bfd_error));
104
105#if FIXME
106/* This code needs to be incorporated into BFD */
107#ifdef COFF_ENCAPSULATE
108 /* If we have a coff header, it can give us better values for
109 text_start and exec_data_start. This is particularly useful
110 for remote debugging of embedded systems. */
111 if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE)
112 {
113 struct coffheader ch;
114 int val;
115 val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1);
116 if (val == -1)
117 perror_with_name (filename);
118 val = myread (execchan, &ch, sizeof (ch));
119 if (val < 0)
120 perror_with_name (filename);
121 text_start = ch.text_start;
122 exec_data_start = ch.data_start;
123 } else
124#endif
125 {
126 text_start =
127 IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr);
128 exec_data_start = IS_OBJECT_FILE (exec_aouthdr)
129 ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr);
130 }
131#endif FIXME
132
133 if (build_section_table (exec_bfd, &exec_sections, &exec_sections_end))
134 error ("Can't find the file sections in `%s': %s",
135 exec_bfd->filename, bfd_errmsg (bfd_error));
136
137 validate_files ();
138
139 push_target (&exec_ops);
140
141 /* Tell display code (if any) about the changed file name. */
142 if (exec_file_display_hook)
143 (*exec_file_display_hook) (filename);
144 }
145 else if (from_tty)
146 printf ("No exec file now.\n");
147}
148
149/* Set both the exec file and the symbol file, in one command.
150 What a novelty. Why did GDB go through four major releases before this
151 command was added? */
152
153void
154file_command (arg, from_tty)
155 char *arg;
156 int from_tty;
157{
158 /* FIXME, if we lose on reading the symbol file, we should revert
159 the exec file, but that's rough. */
160 exec_file_command (arg, from_tty);
161 symbol_file_command (arg, from_tty);
162}
163
164\f
165/* Locate all mappable sections of a BFD file. */
166
167void
168add_to_section_table (abfd, asect, table_pp)
169 bfd *abfd;
170 sec_ptr asect;
171 struct section_table **table_pp;
172{
173 flagword aflag;
174
175 aflag = bfd_get_section_flags (abfd, asect);
176 /* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */
177 if (!(aflag & SEC_LOAD))
178 return;
179 (*table_pp)->sec_ptr = asect;
180 (*table_pp)->addr = bfd_section_vma (abfd, asect);
181 (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
182 (*table_pp)++;
183}
184
185int
186build_section_table (some_bfd, start, end)
187 bfd *some_bfd;
188 struct section_table **start, **end;
189{
190 unsigned count;
191
192 count = bfd_count_sections (some_bfd);
193 if (count == 0)
194 abort(); /* return 1? */
195 *start = (struct section_table *) xmalloc (count * sizeof (**start));
196 *end = *start;
197 bfd_map_over_sections (some_bfd, add_to_section_table, end);
198 if (*end > *start + count)
199 abort();
200 /* We could realloc the table, but it probably loses for most files. */
201 return 0;
202}
203\f
204/* Read or write the exec file.
205
206 Args are address within exec file, address within gdb address-space,
207 length, and a flag indicating whether to read or write.
208
209 Result is a length:
210
211 0: We cannot handle this address and length.
212 > 0: We have handled N bytes starting at this address.
213 (If N == length, we did it all.) We might be able
214 to handle more bytes beyond this length, but no
215 promises.
216 < 0: We cannot handle this address, but if somebody
217 else handles (-N) bytes, we can start from there.
218
219 The same routine is used to handle both core and exec files;
220 we just tail-call it with more arguments to select between them. */
221
222int
223xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
224 CORE_ADDR memaddr;
225 char *myaddr;
226 int len;
227 int write;
228 bfd *abfd;
229 struct section_table *sections, *sections_end;
230{
231 boolean res;
232 struct section_table *p;
233 CORE_ADDR nextsectaddr, memend;
234 boolean (*xfer_fn) ();
235
236 if (len <= 0)
237 abort();
238
239 memend = memaddr + len;
240 xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
241 nextsectaddr = memend;
242
243 for (p = sections; p < sections_end; p++)
244 {
245 if (p->addr <= memaddr)
246 if (p->endaddr >= memend)
247 {
248 /* Entire transfer is within this section. */
249 res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
250 return (res != false)? len: 0;
251 }
252 else if (p->endaddr <= memaddr)
253 {
254 /* This section ends before the transfer starts. */
255 continue;
256 }
257 else
258 {
259 /* This section overlaps the transfer. Just do half. */
260 len = p->endaddr - memaddr;
261 res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
262 return (res != false)? len: 0;
263 }
264 else if (p->addr < nextsectaddr)
265 nextsectaddr = p->addr;
266 }
267
268 if (nextsectaddr >= memend)
269 return 0; /* We can't help */
270 else
271 return - (nextsectaddr - memaddr); /* Next boundary where we can help */
272}
273
274/* The function called by target_xfer_memory via our target_ops */
275
276int
277exec_xfer_memory (memaddr, myaddr, len, write)
278 CORE_ADDR memaddr;
279 char *myaddr;
280 int len;
281 int write;
282{
283 return xfer_memory (memaddr, myaddr, len, write,
284 exec_bfd, exec_sections, exec_sections_end);
285}
286
287
288#ifdef FIXME
289#ifdef REG_STACK_SEGMENT
290/* MOVE TO BFD... */
291 /* Pyramids and AM29000s have an extra segment in the virtual address space
292 for the (control) stack of register-window frames. The AM29000 folk
293 call it the "register stack" rather than the "memory stack". */
294 else if (memaddr >= reg_stack_start && memaddr < reg_stack_end)
295 {
296 i = min (len, reg_stack_end - memaddr);
297 fileptr = memaddr - reg_stack_start + reg_stack_offset;
298 wanna_xfer = coredata;
299 }
300#endif /* REG_STACK_SEGMENT */
301#endif FIXME
302\f
303static void
304exec_files_info ()
305{
306 struct section_table *p;
307
308 printf ("\tExecutable file `%s'.\n", bfd_get_filename(exec_bfd));
309
310 for (p = exec_sections; p < exec_sections_end; p++)
311 printf("\texecutable from 0x%08x to 0x%08x is %s\n",
312 p->addr, p->endaddr,
313 bfd_section_name (exec_bfd, p->sec_ptr));
314}
315
f2fc6e7a
JK
316static void
317set_section_command (args, from_tty)
318 char *args;
319 int from_tty;
320{
321 struct section_table *p;
322 char *secname;
323 unsigned seclen;
324 unsigned long secaddr;
325 char secprint[100];
326 long offset;
327
328 if (args == 0)
329 error ("Must specify section name and its virtual address");
330
331 /* Parse out section name */
332 for (secname = args; !isspace(*args); args++) ;
333 seclen = args - secname;
334
335 /* Parse out new virtual address */
336 secaddr = parse_and_eval_address (args);
337
338 for (p = exec_sections; p < exec_sections_end; p++) {
339 if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
340 && bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
341 offset = secaddr - p->addr;
342 p->addr += offset;
343 p->endaddr += offset;
344 exec_files_info();
345 return;
346 }
347 }
348 if (seclen >= sizeof (secprint))
349 seclen = sizeof (secprint) - 1;
350 strncpy (secprint, secname, seclen);
351 secprint[seclen] = '\0';
352 error ("Section %s not found", secprint);
353}
354
bd5635a1
RP
355struct target_ops exec_ops = {
356 "exec", "Local exec file",
f2fc6e7a
JK
357 "Use an executable file as a target.\n\
358Specify the filename of the executable file.",
bd5635a1
RP
359 exec_file_command, exec_close, /* open, close */
360 child_attach, 0, 0, 0, /* attach, detach, resume, wait, */
361 0, 0, /* fetch_registers, store_registers, */
362 0, 0, 0, /* prepare_to_store, conv_to, conv_from, */
363 exec_xfer_memory, exec_files_info,
364 0, 0, /* insert_breakpoint, remove_breakpoint, */
365 0, 0, 0, 0, 0, /* terminal stuff */
64e52224
JG
366 0, 0, /* kill, load */
367 add_syms_addr_command,
368 0, 0, /* call fn, lookup sym */
bd5635a1
RP
369 child_create_inferior,
370 0, /* mourn_inferior */
371 file_stratum, 0, /* next */
372 0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */
373 OPS_MAGIC, /* Always the last thing */
374};
375
376void
377_initialize_exec()
378{
379
380 add_com ("file", class_files, file_command,
381 "Use FILE as program to be debugged.\n\
382It is read for its symbols, for getting the contents of pure memory,\n\
383and it is the program executed when you use the `run' command.\n\
384If FILE cannot be found as specified, your execution directory path\n\
385($PATH) is searched for a command of that name.\n\
386No arg means to have no executable file and no symbols.");
387
388 add_com ("exec-file", class_files, exec_file_command,
389 "Use FILE as program for getting contents of pure memory.\n\
390If FILE cannot be found as specified, your execution directory path\n\
391is searched for a command of that name.\n\
392No arg means have no executable file.");
393
f2fc6e7a
JK
394 add_com ("section", class_files, set_section_command,
395 "Change the base address of section SECTION of the exec file to ADDR.\n\
396This can be used if the exec file does not contain section addresses,\n\
397(such as in the a.out format), or when the addresses specified in the\n\
398file itself are wrong. Each section must be changed separately. The\n\
399``info files'' command lists all the sections and their addresses.");
400
bd5635a1
RP
401 add_target (&exec_ops);
402}
This page took 0.037341 seconds and 4 git commands to generate.