* aoutx.h (NAME(aout,print_symbol)): Don't print
[deliverable/binutils-gdb.git] / gdb / xcoffexec.c
CommitLineData
41abdfbd 1/* Execute AIXcoff files, for GDB.
e17960fb 2 Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
41abdfbd
JG
3 Derived from exec.c. Modified by IBM Corporation.
4 Donated by IBM Corporation and Cygnus Support.
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22/* xcoff-exec - deal with executing XCOFF files. */
23
24#include <stdio.h>
25#include <sys/types.h>
26#include <sys/param.h>
27#include <fcntl.h>
28#include <string.h>
29#include <ctype.h>
30#include <sys/stat.h>
31#include <sys/ldr.h>
32
33#include "defs.h"
41abdfbd
JG
34#include "frame.h"
35#include "inferior.h"
36#include "target.h"
37#include "gdbcmd.h"
38#include "gdbcore.h"
39#include "symfile.h"
40
41#include "libbfd.h" /* BFD internals (sigh!) FIXME */
42
1ab3bf1b
JG
43/* Prototypes for local functions */
44
45static void
46add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
47
48static void
49file_command PARAMS ((char *, int));
50
51static void
52exec_close PARAMS ((int));
53
41abdfbd
JG
54struct section_table *exec_sections, *exec_sections_end;
55
56#define eq(s0, s1) !strcmp(s0, s1)
57
58/* Whether to open exec and core files read-only or read-write. */
59
60int write_files = 0;
61
62bfd *exec_bfd; /* needed by core.c */
63
64extern char *getenv();
65extern void child_create_inferior (), child_attach ();
66extern void add_syms_addr_command ();
67extern void symbol_file_command ();
68static void exec_files_info();
69
70/*
71 * the vmap struct is used to describe the virtual address space of
72 * the target we are manipulating. The first entry is always the "exec"
73 * file. Subsequent entries correspond to other objects that are
74 * mapped into the address space of a process created from the "exec" file.
75 * These are either in response to exec()ing the file, in which case all
76 * shared libraries are loaded, or a "load" system call, followed by the
77 * user's issuance of a "load" command.
78 */
79struct vmap {
80 struct vmap *nxt; /* ^ to next in chain */
81 bfd *bfd; /* BFD for mappable object library */
82 char *name; /* ^ to object file name */
83 char *member; /* ^ to member name */
84 CORE_ADDR tstart; /* virtual addr where member is mapped */
85 CORE_ADDR tend; /* virtual upper bound of member */
86 CORE_ADDR tadj; /* heuristically derived adjustment */
87 CORE_ADDR dstart; /* virtual address of data start */
88 CORE_ADDR dend; /* vitrual address of data end */
89};
90
91
92struct vmap_and_bfd {
93 bfd *pbfd;
94 struct vmap *pvmap;
95};
96
97static struct vmap *vmap; /* current vmap */
98
99extern struct target_ops exec_ops;
100
101
102/* exec_close - done with exec file, clean up all resources. */
103
1ab3bf1b 104static void
41abdfbd
JG
105exec_close(quitting) {
106 register struct vmap *vp, *nxt;
107
108 for (nxt = vmap; vp = nxt; ) {
109 nxt = vp->nxt;
110 bfd_close(vp->bfd);
111 free_named_symtabs(vp->name, vp->member); /* XXX */
112 free(vp);
113 }
114
115 vmap = 0;
116 exec_bfd = 0;
117}
118
119/*
120 * exec_file_command - handle the "exec" command, &c.
121 */
122void
123exec_file_command(filename, from_tty)
124char *filename;
125{
126 bfd *bfd;
127
128 target_preopen(from_tty);
129 unpush_target(&exec_ops);
130
131 /* Now open and digest the file the user requested, if any. */
132
133 if (filename) {
134 char *scratch_pathname;
135 int scratch_chan;
136
137 filename = tilde_expand(filename);
1ab3bf1b 138 make_cleanup (free, filename);
41abdfbd
JG
139
140 scratch_chan = openp(getenv("PATH"), 1, filename, O_RDONLY, 0
141 , &scratch_pathname);
142 if (scratch_chan < 0)
143 perror_with_name(filename);
144
145 bfd = bfd_fdopenr(scratch_pathname, NULL, scratch_chan);
146 if (!bfd)
147 error("Could not open `%s' as an executable file: %s"
148 , scratch_pathname, bfd_errmsg(bfd_error));
149
150 /* make sure we have an object file */
151
152 if (!bfd_check_format(bfd, bfd_object))
153 error("\"%s\": not in executable format: %s."
154 , scratch_pathname, bfd_errmsg(bfd_error));
155
156
157 /* setup initial vmap */
158
159 map_vmap (bfd, 0);
160 if (!vmap)
161 error("Can't find the file sections in `%s': %s"
162 , bfd->filename, bfd_errmsg(bfd_error));
163
164 exec_bfd = bfd;
165
166 if (build_section_table (exec_bfd, &exec_sections, &exec_sections_end))
167 error ("Can't find the file sections in `%s': %s",
168 exec_bfd->filename, bfd_errmsg (bfd_error));
169
170 /* make sure core, if present, matches */
171 validate_files();
172
173 push_target(&exec_ops);
174
175 /* Tell display code(if any) about the changed file name. */
176
177 if (exec_file_display_hook)
178 (*exec_file_display_hook)(filename);
179 }
180 else {
181 exec_close(0); /* just in case */
182 if (from_tty)
183 printf("No exec file now.\n");
184 }
185}
186
187/* Set both the exec file and the symbol file, in one command. What a
188 * novelty. Why did GDB go through four major releases before this
189 * command was added?
190 */
1ab3bf1b 191static void
41abdfbd
JG
192file_command(arg, from_tty)
193char *arg; {
194
195 exec_file_command(arg, from_tty);
196 symbol_file_command(arg, from_tty);
197}
198
199/* Locate all mappable sections of a BFD file.
200 table_pp_char is a char * to get it through bfd_map_over_sections;
201 we cast it back to its proper type. */
202
1ab3bf1b 203static void
41abdfbd
JG
204add_to_section_table (abfd, asect, table_pp_char)
205 bfd *abfd;
206 sec_ptr asect;
207 char *table_pp_char;
208{
209 struct section_table **table_pp = (struct section_table **)table_pp_char;
210 flagword aflag;
211
212 aflag = bfd_get_section_flags (abfd, asect);
213 /* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */
214 if (!(aflag & SEC_LOAD))
215 return;
216 (*table_pp)->sec_ptr = asect;
217 (*table_pp)->addr = bfd_section_vma (abfd, asect);
218 (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
219 (*table_pp)++;
220}
221
222int
223build_section_table (some_bfd, start, end)
224 bfd *some_bfd;
225 struct section_table **start, **end;
226{
227 unsigned count;
228
229 count = bfd_count_sections (some_bfd);
230 if (count == 0)
231 abort(); /* return 1? */
232 if (*start)
233 free (*start);
234 *start = (struct section_table *) xmalloc (count * sizeof (**start));
235 *end = *start;
236 bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end);
237 if (*end > *start + count)
238 abort();
239 /* We could realloc the table, but it probably loses for most files. */
240 return 0;
241}
242
243/*
244 * lookup_symtab_bfd - find if we currently have any symbol tables from bfd
245 */
246struct objfile *
247lookup_objfile_bfd(bfd *bfd) {
248 register struct objfile *s;
249
250 for (s = object_files; s; s = s->next)
251 if (s->obfd == bfd)
252 return s;
253 return 0;
254}
255
256
257void
258sex_to_vmap(bfd *bf, sec_ptr sex, struct vmap_and_bfd *vmap_bfd)
259{
260 register struct vmap *vp, **vpp;
261 register struct symtab *syms;
262 bfd *arch = vmap_bfd->pbfd;
263 vp = vmap_bfd->pvmap;
264
265 if ((bfd_get_section_flags(bf, sex) & SEC_LOAD) == 0)
266 return;
267
268 if (!strcmp(bfd_section_name(bf, sex), ".text")) {
269 vp->tstart = 0;
270 vp->tend = vp->tstart + bfd_section_size(bf, sex);
271
272 /* This is quite a tacky way to recognize the `exec' load segment (rather
273 than shared libraries. You should use `arch' instead. FIXMEmgo */
274 if (!vmap)
275 vp->tadj = sex->filepos - bfd_section_vma(bf, sex);
276 else
277 vp->tadj = 0;
278 }
279
280 else if (!strcmp(bfd_section_name(bf, sex), ".data")) {
281 vp->dstart = 0;
282 vp->dend = vp->dstart + bfd_section_size(bf, sex);
283 }
284
285 else if (!strcmp(bfd_section_name(bf, sex), ".bss")) /* FIXMEmgo */
286 printf ("bss section in exec! Don't know what the heck to do!\n");
287}
288
289/* Make a vmap for the BFD "bf", which might be a member of the archive
290 BFD "arch". If we have not yet read in symbols for this file, do so. */
291
292map_vmap (bfd *bf, bfd *arch)
293{
294 struct vmap_and_bfd vmap_bfd;
295 struct vmap *vp, **vpp;
296 struct objfile *obj;
41abdfbd
JG
297
298 vp = (void*) xmalloc (sizeof (*vp));
299 vp->nxt = 0;
300 vp->bfd = bf;
301 vp->name = bfd_get_filename(arch ? arch : bf);
302 vp->member = arch ? bfd_get_filename(bf) : "";
303
304 vmap_bfd.pbfd = arch;
305 vmap_bfd.pvmap = vp;
306 bfd_map_over_sections (bf, sex_to_vmap, &vmap_bfd);
307
308 obj = lookup_objfile_bfd (bf);
309 if (exec_bfd && !obj) {
1ab3bf1b 310 obj = allocate_objfile (bf, bfd_get_filename (bf), 0);
4369a140 311 syms_from_objfile (obj, 0, 0, 0);
41abdfbd
JG
312 }
313
314 /* find the end of the list, and append. */
315 for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
316 ;
317 *vpp = vp;
318}
319
1ab3bf1b 320/* Called via iterate_over_msymbols to relocate minimal symbols */
41abdfbd 321
1ab3bf1b
JG
322static void
323relocate_minimal_symbol (objfile, msymbol, arg1, arg2, arg3)
324 struct objfile *objfile;
325 struct minimal_symbol *msymbol;
326 PTR arg1;
327 PTR arg2;
328 PTR arg3;
329{
330 msymbol -> address += (int) arg1;
331}
332
333/* true, if symbol table and minimal symbol table are relocated. */
41abdfbd
JG
334
335int symtab_relocated = 0;
336
337
338/* vmap_symtab - handle symbol translation on vmapping */
339
340vmap_symtab(vp, old_start, vip)
341register struct vmap *vp;
342CORE_ADDR old_start;
343struct stat *vip;
344{
1ab3bf1b
JG
345 register struct symtab *s;
346 register struct objfile *objfile;
347
348 /*
349 * for each symbol table generated from the vp->bfd
350 */
351 for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
352 {
353 for (s = objfile -> symtabs; s != NULL; s = s -> next) {
354
355 /* skip over if this is not relocatable and doesn't have a line table */
356 if (s->nonreloc && !LINETABLE (s))
357 continue;
358
359 /* matching the symbol table's BFD and the *vp's BFD is hairy.
360 exec_file creates a seperate BFD for possibly the
361 same file as symbol_file.FIXME ALL THIS MUST BE RECTIFIED. */
362
363 if (objfile->obfd == vp->bfd) {
364 /* if they match, we luck out. */
365 ;
366 } else if (vp->member[0]) {
367 /* no match, and member present, not this one. */
368 continue;
369 } else {
370 struct stat si;
371 FILE *io;
372
373 /*
374 * no match, and no member. need to be sure.
375 */
376 io = bfd_cache_lookup(objfile->obfd);
377 if (!io)
378 fatal("cannot find BFD's iostream for sym");
379 /*
380 * see if we are referring to the same file
381 */
382 if (fstat(fileno(io), &si) < 0)
383 fatal("cannot fstat BFD for sym");
384
385 if (si.st_dev != vip->st_dev
386 || si.st_ino != vip->st_ino)
41abdfbd 387 continue;
41abdfbd 388 }
1ab3bf1b 389
41abdfbd 390 if (vp->tstart != old_start)
1ab3bf1b
JG
391 vmap_symtab_1(s, vp, old_start);
392 }
393 }
394 if (vp->tstart != old_start)
395 iterate_over_msymbols (relocate_minimal_symbol,
396 (PTR) (vp->tstart - old_start),
397 (PTR) NULL, (PTR) NULL);
398
399 symtab_relocated = 1;
41abdfbd
JG
400}
401
402
403fixup_misc_vector (int disp)
404{
405 int ii;
406 for (ii=0; ii < misc_function_count; ++ii)
407 if (misc_function_vector[ii].address < 0x10000000)
408 misc_function_vector[ii].address += disp;
409}
410
411
412vmap_symtab_1(s, vp, old_start)
413register struct symtab *s;
414register struct vmap *vp;
415CORE_ADDR old_start;
416{
417 register int i, j;
418 int len, blen;
419 register struct linetable *l;
420 struct blockvector *bv;
421 register struct block *b;
422 int depth;
423 register ulong reloc, dreloc;
424
425 if ((reloc = vp->tstart - old_start) == 0)
426 return;
427
428 dreloc = vp->dstart; /* data relocation */
429
430 /*
431 * The line table must be relocated. This is only present for
432 * b.text sections, so only vp->text type maps need be considered.
433 */
434 l = LINETABLE (s);
435 len = l->nitems;
436 for (i = 0; i < len; i++)
437 l->item[i].pc += reloc;
438
439 /* if this symbol table is not relocatable, only line table should
440 be relocated and the rest ignored. */
441 if (s->nonreloc)
442 return;
443
444 bv = BLOCKVECTOR(s);
445 len = BLOCKVECTOR_NBLOCKS(bv);
446
447 for (i = 0; i < len; i++) {
448 b = BLOCKVECTOR_BLOCK(bv, i);
449
450 BLOCK_START(b) += reloc;
451 BLOCK_END(b) += reloc;
452
453 blen = BLOCK_NSYMS(b);
454 for (j = 0; j < blen; j++) {
455 register struct symbol *sym;
456
457 sym = BLOCK_SYM(b, j);
458 switch (SYMBOL_NAMESPACE(sym)) {
459 case STRUCT_NAMESPACE:
460 case UNDEF_NAMESPACE:
461 continue;
462
463 case LABEL_NAMESPACE:
464 case VAR_NAMESPACE:
465 break;
466 }
467
468 switch (SYMBOL_CLASS(sym)) {
469 case LOC_CONST:
470 case LOC_CONST_BYTES:
471 case LOC_LOCAL:
472 case LOC_REGISTER:
473 case LOC_ARG:
474 case LOC_LOCAL_ARG:
475 case LOC_REF_ARG:
476 case LOC_REGPARM:
477 case LOC_TYPEDEF:
478 continue;
479
480#ifdef FIXME
481 case LOC_EXTERNAL:
482#endif
483 case LOC_LABEL:
484 SYMBOL_VALUE_ADDRESS(sym) += reloc;
485 break;
486
487 case LOC_STATIC:
488 SYMBOL_VALUE_ADDRESS(sym) += dreloc;
489 break;
490
491 case LOC_BLOCK:
492 break;
493
494 default:
495 fatal("botched symbol class %x"
496 , SYMBOL_CLASS(sym));
497 break;
498 }
499 }
500 }
501}
502
503/*
504 * add_vmap - add a new vmap entry based on ldinfo() information
505 */
506add_vmap(ldi)
507register struct ld_info *ldi; {
508 bfd *bfd, *last;
509 register char *mem;
510
511 mem = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1;
512 bfd = bfd_fdopenr(ldi->ldinfo_filename, NULL, ldi->ldinfo_fd);
513 if (!bfd)
514 error("Could not open `%s' as an executable file: %s"
515 , ldi->ldinfo_filename, bfd_errmsg(bfd_error));
516
517
518 /* make sure we have an object file */
519
520 if (bfd_check_format(bfd, bfd_object))
521 map_vmap (bfd, 0);
522
523 else if (bfd_check_format(bfd, bfd_archive)) {
524 last = 0;
525 /*
526 * FIXME??? am I tossing BFDs? bfd?
527 */
528 while (last = bfd_openr_next_archived_file(bfd, last))
529 if (eq(mem, last->filename))
530 break;
531
532 if (!last) {
533 bfd_close(bfd);
534/* FIXME -- should be error */
535 warning("\"%s\": member \"%s\" missing.",
536 bfd->filename, mem);
537 return;
538 }
539
540 if (!bfd_check_format(last, bfd_object)) {
541 bfd_close(last); /* XXX??? */
542 goto obj_err;
543 }
544
545 map_vmap (last, bfd);
546 }
547 else {
548 obj_err:
549 bfd_close(bfd);
550/* FIXME -- should be error */
551 warning("\"%s\": not in executable format: %s."
552 , ldi->ldinfo_filename, bfd_errmsg(bfd_error));
553 return;
554 }
555}
556
557
558/* As well as symbol tables, exec_sections need relocation. Otherwise after
559 the inferior process terminates, symbol table is relocated but there is
560 no inferior process. Thus, we have to use `exec' bfd, rather than the inferior
561 process's memory space, when lookipng at symbols.
562 `exec_sections' need to be relocated only once though, as long as the exec
563 file was not changed.
564*/
565vmap_exec ()
566{
567 static bfd *execbfd;
568 if (execbfd == exec_bfd)
569 return;
570
571 execbfd = exec_bfd;
572
573 if (!vmap || !exec_sections) {
574 printf ("WARNING: vmap not found in vmap_exec()!\n");
575 return;
576 }
577 /* First exec section is `.text', second is `.data'. If this is changed,
578 then this routine will choke. Better you should check section names,
579 FIXMEmgo. */
580 exec_sections [0].addr += vmap->tstart;
581 exec_sections [0].endaddr += vmap->tstart;
582 exec_sections [1].addr += vmap->dstart;
583 exec_sections [1].endaddr += vmap->dstart;
584}
585
586
587int
588text_adjustment (abfd)
589bfd *abfd;
590{
591 static bfd *execbfd;
592 static int adjustment;
593 sec_ptr sect;
594
595 if (exec_bfd == execbfd)
596 return adjustment;
597
598 sect = bfd_get_section_by_name (abfd, ".text");
599 if (sect)
600 adjustment = sect->filepos - sect->vma;
601 else
602 adjustment = 0x200; /* just a wild assumption */
603
604 return adjustment;
605}
606
607
608/*
609 * vmap_ldinfo - update VMAP info with ldinfo() information
610 *
611 * Input:
612 * ldi - ^ to ldinfo() results.
613 */
614vmap_ldinfo(ldi)
615register struct ld_info *ldi;
616{
617 struct stat ii, vi;
618 register struct vmap *vp;
619 register got_one, retried;
620 CORE_ADDR ostart;
621
622 /*
623 * for each *ldi, see if we have a corresponding *vp
624 * if so, update the mapping, and symbol table.
625 * if not, add an entry and symbol table.
626 */
627 do {
628 char *name = ldi->ldinfo_filename;
629 char *memb = name + strlen(name) + 1;
630
631 retried = 0;
632
633 if (fstat(ldi->ldinfo_fd, &ii) < 0)
634 fatal("cannot fstat(%d) on %s"
635 , ldi->ldinfo_fd
636 , name);
637retry:
638 for (got_one = 0, vp = vmap; vp; vp = vp->nxt) {
639 FILE *io;
640
641 /* The filenames are not always sufficient to match on. */
642 if ((name[0] == "/"
643 && !eq(name, vp->name))
644 || (memb[0] && !eq(memb, vp->member)))
645 continue;
646
647 /* totally opaque! */
648 io = bfd_cache_lookup(vp->bfd);
649 if (!io)
650 fatal("cannot find BFD's iostream for %s"
651 , vp->name);
652
653 /* see if we are referring to the same file */
654 if (fstat(fileno(io), &vi) < 0)
655 fatal("cannot fstat BFD for %s", vp->name);
656
657 if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino)
658 continue;
659
660 if (!retried)
661 close(ldi->ldinfo_fd);
662
663 ++got_one;
664
665 /* found a corresponding VMAP. remap! */
666 ostart = vp->tstart;
667
668 vp->tstart = ldi->ldinfo_textorg;
669 vp->tend = vp->tstart + ldi->ldinfo_textsize;
670 vp->dstart = ldi->ldinfo_dataorg;
671 vp->dend = vp->dstart + ldi->ldinfo_datasize;
672
673 if (vp->tadj) {
674 vp->tstart += vp->tadj;
675 vp->tend += vp->tadj;
676 }
677
678 /* relocate symbol table(s). */
679 vmap_symtab(vp, ostart, &vi);
680
681 /* there may be more, so we don't break out of the loop. */
682 }
683
684 /*
685 * if there was no matching *vp, we must perforce create
686 * the sucker(s)
687 */
688 if (!got_one && !retried) {
689 add_vmap(ldi);
690 ++retried;
691 goto retry;
692 }
693 } while (ldi->ldinfo_next
694 && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));
695
696 breakpoint_re_set();
697}
698
699/*
700 * vmap_inferior - print VMAP info for inferior
701 */
702vmap_inferior() {
703
704 if (inferior_pid == 0)
705 return 0; /* normal processing */
706
707 exec_files_info();
708
709 return 1;
710}
711
712/* Read or write the exec file.
713
714 Args are address within exec file, address within gdb address-space,
715 length, and a flag indicating whether to read or write.
716
717 Result is a length:
718
719 0: We cannot handle this address and length.
720 > 0: We have handled N bytes starting at this address.
721 (If N == length, we did it all.) We might be able
722 to handle more bytes beyond this length, but no
723 promises.
724 < 0: We cannot handle this address, but if somebody
725 else handles (-N) bytes, we can start from there.
726
727 The same routine is used to handle both core and exec files;
728 we just tail-call it with more arguments to select between them. */
729
730int
731xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
732 CORE_ADDR memaddr;
733 char *myaddr;
734 int len;
735 int write;
736 bfd *abfd;
737 struct section_table *sections, *sections_end;
738{
739 boolean res;
740 struct section_table *p;
741 CORE_ADDR nextsectaddr, memend;
742 boolean (*xfer_fn) ();
743
744 if (len <= 0)
745 abort();
746
747 memend = memaddr + len;
748 xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
749 nextsectaddr = memend;
750
751 for (p = sections; p < sections_end; p++)
752 {
753 if (p->addr <= memaddr)
754 if (p->endaddr >= memend)
755 {
756 /* Entire transfer is within this section. */
757 res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
758 return (res != false)? len: 0;
759 }
760 else if (p->endaddr <= memaddr)
761 {
762 /* This section ends before the transfer starts. */
763 continue;
764 }
765 else
766 {
767 /* This section overlaps the transfer. Just do half. */
768 len = p->endaddr - memaddr;
769 res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
770 return (res != false)? len: 0;
771 }
772 else if (p->addr < nextsectaddr)
773 nextsectaddr = p->addr;
774 }
775
776 if (nextsectaddr >= memend)
777 return 0; /* We can't help */
778 else
779 return - (nextsectaddr - memaddr); /* Next boundary where we can help */
780}
781
782/* The function called by target_xfer_memory via our target_ops */
783
784int
785exec_xfer_memory (memaddr, myaddr, len, write)
786 CORE_ADDR memaddr;
787 char *myaddr;
788 int len;
789 int write;
790{
791 return xfer_memory (memaddr, myaddr, len, write,
792 exec_bfd, exec_sections, exec_sections_end);
793}
794
795/*
796 * exec_files_info - "info files" command processor
797 */
798static void
799exec_files_info() {
800 register struct vmap *vp = vmap;
801
802 if (!vp)
803 return;
804
805 printf("\tMapping info for file `%s'.\n", vp->name);
806 printf("\t %8.8s %8.8s %8.8s %s\n"
807 , "start", "end", "section", "file(member)");
808
809 for (; vp; vp = vp->nxt)
810 printf("\t0x%8.8x 0x%8.8x %s%s%s%s\n"
811 , vp->tstart
812 , vp->tend
813 , vp->name
814 , *vp->member ? "(" : ""
815 , vp->member
816 , *vp->member ? ")" : "");
817}
818
819#ifdef DAMON
76b28d05 820/* Damon's implementation of set_section_command! It is based on the sex member
41abdfbd
JG
821 (which is a section pointer from vmap) of vmap.
822 We will not have multiple vmap entries (one for each section), rather transmit
823 text and data base offsets and fix them at the same time. Elimination of sex
824 entry in vmap make this function obsolute, use the one from exec.c.
76b28d05 825 Need further testing!! FIXMEmgo. */
41abdfbd
JG
826
827static void
828set_section_command(args, from_tty)
829char *args;
830{
831 register struct vmap *vp = vmap;
832 char *secname;
833 unsigned seclen;
834 unsigned long secaddr;
835 char secprint[100];
836 long offset;
837
838 if (args == 0)
839 error("Must specify section name and its virtual address");
840
841 /* Parse out section name */
842 for (secname = args; !isspace(*args); args++)
843 ;
844 seclen = args - secname;
845
846 /* Parse out new virtual address */
847 secaddr = parse_and_eval_address(args);
848
849 for (vp = vmap; vp; vp = vp->nxt) {
850 if (!strncmp(secname
851 , bfd_section_name(vp->bfd, vp->sex), seclen)
852 && bfd_section_name(vp->bfd, vp->sex)[seclen] == '\0') {
853 offset = secaddr - vp->tstart;
854 vp->tstart += offset;
855 vp->tend += offset;
856 exec_files_info();
857 return;
858 }
859 }
860
861 if (seclen >= sizeof(secprint))
862 seclen = sizeof(secprint) - 1;
863 strncpy(secprint, secname, seclen);
864 secprint[seclen] = '\0';
865 error("Section %s not found", secprint);
866}
867#else
868static void
869set_section_command (args, from_tty)
870 char *args;
871 int from_tty;
872{
873 struct section_table *p;
874 char *secname;
875 unsigned seclen;
876 unsigned long secaddr;
877 char secprint[100];
878 long offset;
879
880 if (args == 0)
881 error ("Must specify section name and its virtual address");
882
883 /* Parse out section name */
884 for (secname = args; !isspace(*args); args++) ;
885 seclen = args - secname;
886
887 /* Parse out new virtual address */
888 secaddr = parse_and_eval_address (args);
889
890 for (p = exec_sections; p < exec_sections_end; p++) {
891 if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
892 && bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
893 offset = secaddr - p->addr;
894 p->addr += offset;
895 p->endaddr += offset;
896 exec_files_info();
897 return;
898 }
899 }
900 if (seclen >= sizeof (secprint))
901 seclen = sizeof (secprint) - 1;
902 strncpy (secprint, secname, seclen);
903 secprint[seclen] = '\0';
904 error ("Section %s not found", secprint);
905}
906
907#endif /* !DAMON */
908
909struct target_ops exec_ops = {
910 "exec", "Local exec file",
911 "Use an executable file as a target.\n\
912Specify the filename of the executable file.",
913 exec_file_command, exec_close, /* open, close */
914 child_attach, 0, 0, 0, /* attach, detach, resume, wait, */
915 0, 0, /* fetch_registers, store_registers, */
916 0, 0, 0, /* prepare_to_store, conv_to, conv_from, */
917 exec_xfer_memory, exec_files_info,
918 0, 0, /* insert_breakpoint, remove_breakpoint, */
919 0, 0, 0, 0, 0, /* terminal stuff */
920 0, 0, /* kill, load */
e17960fb 921 0, /* lookup sym */
41abdfbd
JG
922 child_create_inferior,
923 0, /* mourn_inferior */
924 file_stratum, 0, /* next */
925 0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */
926 0, 0, /* section pointers */
927 OPS_MAGIC, /* Always the last thing */
928};
929
930
931void
932_initialize_exec()
933{
934
935 add_com("file", class_files, file_command,
936 "Use FILE as program to be debugged.\n\
937It is read for its symbols, for getting the contents of pure memory,\n\
938and it is the program executed when you use the `run' command.\n\
939If FILE cannot be found as specified, your execution directory path\n\
940($PATH) is searched for a command of that name.\n\
941No arg means to have no executable file and no symbols.");
942
943 add_com("exec-file", class_files, exec_file_command,
944 "Use FILE as program for getting contents of pure memory.\n\
945If FILE cannot be found as specified, your execution directory path\n\
946is searched for a command of that name.\n\
947No arg means have no executable file.");
948
949 add_com("section", class_files, set_section_command,
950 "Change the base address of section SECTION of the exec file to ADDR.\n\
951This can be used if the exec file does not contain section addresses,\n\
952(such as in the a.out format), or when the addresses specified in the\n\
953file itself are wrong. Each section must be changed separately. The\n\
954``info files'' command lists all the sections and their addresses.");
955
956 add_target(&exec_ops);
957}
This page took 0.089696 seconds and 4 git commands to generate.