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