⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xcoffexec.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Execute AIXcoff files, for GDB.   Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.   Derived from exec.c.  Modified by IBM Corporation.   Donated by IBM Corporation and Cygnus Support.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* xcoff-exec -	deal with executing XCOFF files.  */  #include "defs.h"#include <sys/types.h>#include <sys/param.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include <sys/stat.h>#include <sys/ldr.h>#include "frame.h"#include "inferior.h"#include "target.h"#include "gdbcmd.h"#include "gdbcore.h"#include "symfile.h"#include "objfiles.h"#include "libbfd.h"		/* BFD internals (sigh!)  FIXME */#include "xcoffsolib.h"/* Prototypes for local functions */static voidfile_command PARAMS ((char *, int));static voidexec_close PARAMS ((int));struct section_table *exec_sections, *exec_sections_end;#define eq(s0, s1)	!strcmp(s0, s1)/* Whether to open exec and core files read-only or read-write.  */int write_files = 0;extern int info_verbose;bfd *exec_bfd;			/* needed by core.c	*/extern char *getenv();extern void add_syms_addr_command ();extern void symbol_file_command ();static void exec_files_info();extern struct objfile *lookup_objfile_bfd ();#if 0/* * the vmap struct is used to describe the virtual address space of * the target we are manipulating.  The first entry is always the "exec" * file.  Subsequent entries correspond to other objects that are * mapped into the address space of a process created from the "exec" file. * These are either in response to exec()ing the file, in which case all * shared libraries are loaded, or a "load" system call, followed by the * user's issuance of a "load" command. */struct vmap {	struct vmap *nxt;	/* ^ to next in chain			*/	bfd *bfd;		/* BFD for mappable object library	*/	char *name;		/* ^ to object file name		*/	char *member;		/* ^ to member name			*/	CORE_ADDR tstart;	/* virtual addr where member is mapped	*/	CORE_ADDR tend;		/* virtual upper bound of member	*/	CORE_ADDR tadj;		/* heuristically derived adjustment	*/	CORE_ADDR dstart;	/* virtual address of data start	*/	CORE_ADDR dend;		/* vitrual address of data end		*/};struct vmap_and_bfd {  bfd *pbfd;  struct vmap *pvmap;};static struct vmap *vmap;	/* current vmap				*/#endif /* 0 */struct vmap *vmap;		/* current vmap */extern struct target_ops exec_ops;/* exec_close -	done with exec file, clean up all resources. */static voidexec_close(quitting){  register struct vmap *vp, *nxt;  struct objfile *obj;    for (nxt = vmap; vp = nxt; )    {      nxt = vp->nxt;      /* if there is an objfile associated with this bfd,	 free_objfile() will do proper cleanup of objfile *and* bfd. */		         if (obj = lookup_objfile_bfd (vp->bfd))	free_objfile (obj);      else	bfd_close(vp->bfd);            free_named_symtabs(vp->name);      free(vp);    }    vmap = 0;  if (exec_bfd) {    bfd_close (exec_bfd);    exec_bfd = NULL;  }  if (exec_ops.to_sections) {    free (exec_ops.to_sections);    exec_ops.to_sections = NULL;    exec_ops.to_sections_end = NULL;  }}/* * exec_file_command -	handle the "exec" command, &c. */voidexec_file_command(filename, from_tty)char *filename;{  target_preopen(from_tty);  /* Remove any previous exec file.  */  unpush_target(&exec_ops);  /* Now open and digest the file the user requested, if any. */  if (filename) {  	char *scratch_pathname;  	int scratch_chan;        	filename = tilde_expand(filename);  	make_cleanup (free, filename);        	scratch_chan = openp(getenv("PATH"), 1, filename,			     write_files? O_RDWR: O_RDONLY, 0,  			     &scratch_pathname);  	if (scratch_chan < 0)	  perror_with_name(filename);  	exec_bfd = bfd_fdopenr(scratch_pathname, NULL, scratch_chan);  	if (!exec_bfd)	  error("Could not open `%s' as an executable file: %s"  		      , scratch_pathname, bfd_errmsg(bfd_error));  	/* make sure we have an object file */  	if (!bfd_check_format(exec_bfd, bfd_object))  		error("\"%s\": not in executable format: %s.",  		      scratch_pathname, bfd_errmsg(bfd_error));  	/* setup initial vmap */  	map_vmap (exec_bfd, 0);  	if (!vmap)  		error("Can't find the file sections in `%s': %s",  		      exec_bfd->filename, bfd_errmsg(bfd_error));	if (build_section_table (exec_bfd, &exec_ops.to_sections,				&exec_ops.to_sections_end))	  error ("Can't find the file sections in `%s': %s",   		exec_bfd->filename, bfd_errmsg (bfd_error));  	/* make sure core, if present, matches */  	validate_files();  	push_target(&exec_ops);  	/* Tell display code(if any) about the changed file name. */  	if (exec_file_display_hook)  		(*exec_file_display_hook)(filename);  }   else {  	exec_close(0);	/* just in case	*/  	if (from_tty)	  printf("No exec file now.\n");  }}/* Set both the exec file and the symbol file, in one command.  What a * novelty.  Why did GDB go through four major releases before this * command was added? */static voidfile_command(arg, from_tty)char *arg; {	exec_file_command(arg, from_tty);	symbol_file_command(arg, from_tty);}/* Locate all mappable sections of a BFD file.    table_pp_char is a char * to get it through bfd_map_over_sections;   we cast it back to its proper type.  */static voidadd_to_section_table (abfd, asect, table_pp_char)     bfd *abfd;     sec_ptr asect;     char *table_pp_char;{  struct section_table **table_pp = (struct section_table **)table_pp_char;  flagword aflag;  aflag = bfd_get_section_flags (abfd, asect);  /* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */  if (!(aflag & SEC_LOAD))    return;  if (0 == bfd_section_size (abfd, asect))    return;  (*table_pp)->bfd = abfd;  (*table_pp)->sec_ptr = asect;  (*table_pp)->addr = bfd_section_vma (abfd, asect);  (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);  (*table_pp)++;}intbuild_section_table (some_bfd, start, end)     bfd *some_bfd;     struct section_table **start, **end;{  unsigned count;  count = bfd_count_sections (some_bfd);  if (count == 0)    abort();	/* return 1? */  if (*start)    free (*start);  *start = (struct section_table *) xmalloc (count * sizeof (**start));  *end = *start;  bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end);  if (*end > *start + count)    abort();  /* We could realloc the table, but it probably loses for most files.  */  return 0;}/* * lookup_symtab_bfd -	find if we currently have any symbol tables from bfd */struct objfile *lookup_objfile_bfd(bfd *bfd) {	register struct objfile *s;	for (s = object_files; s; s = s->next)		if (s->obfd == bfd)			return s;	return 0;}voidsex_to_vmap(bfd *bf, sec_ptr sex, struct vmap_and_bfd *vmap_bfd) {  register struct vmap *vp, **vpp;  register struct symtab *syms;  bfd *arch = vmap_bfd->pbfd;  vp = vmap_bfd->pvmap;  if ((bfd_get_section_flags(bf, sex) & SEC_LOAD) == 0)    return;  if (!strcmp(bfd_section_name(bf, sex), ".text")) {    vp->tstart = 0;    vp->tend   = vp->tstart + bfd_section_size(bf, sex);    /* When it comes to this adjustment value, in contrast to our previous       belief shared objects should behave the same as the main load segment.       This is the offset from the beginning of text section to the first       real instruction. */    vp->tadj = sex->filepos - bfd_section_vma(bf, sex);  }  else if (!strcmp(bfd_section_name(bf, sex), ".data")) {    vp->dstart = 0;    vp->dend   = vp->dstart + bfd_section_size(bf, sex);  }  else if (!strcmp(bfd_section_name(bf, sex), ".bss"))	/* FIXMEmgo */    printf ("bss section in exec! Don't know what the heck to do!\n");}/* Make a vmap for the BFD "bf", which might be a member of the archive   BFD "arch".  If we have not yet read in symbols for this file, do so.  */map_vmap (bfd *bf, bfd *arch){  struct vmap_and_bfd vmap_bfd;  struct vmap *vp, **vpp;  struct objfile *obj;  vp = (void*) xmalloc (sizeof (*vp));  bzero (vp, sizeof (*vp));  vp->nxt = 0;  vp->bfd = bf;  vp->name = bfd_get_filename(arch ? arch : bf);  vp->member = arch ? bfd_get_filename(bf) : "";    vmap_bfd.pbfd = arch;  vmap_bfd.pvmap = vp;  bfd_map_over_sections (bf, sex_to_vmap, &vmap_bfd);  obj = lookup_objfile_bfd (bf);  if (exec_bfd && !obj) {    obj = allocate_objfile (bf, 0);#if 0    /* This is only needed if we want to load shared libraries no matter what.       Since we provide the choice of incremental loading of shared objects       now, we do not have to load them as default anymore. */        syms_from_objfile (obj, 0, 0, 0);    new_symfile_objfile (obj, 0, 0);#endif  }  /* find the end of the list, and append. */  for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)  ;  *vpp = vp;}/* true, if symbol table and minimal symbol table are relocated. */int symtab_relocated = 0;/*  vmap_symtab -	handle symbol translation on vmapping */vmap_symtab(vp, old_start, vip)register struct vmap *vp;CORE_ADDR old_start;struct stat *vip; {  register struct symtab *s;  register struct objfile *objfile;  register struct minimal_symbol *msymbol;    /*   * for each symbol table generated from the vp->bfd   */  ALL_OBJFILES (objfile)    {      for (s = objfile -> symtabs; s != NULL; s = s -> next) {		/* skip over if this is not relocatable and doesn't have a line table */	if (s->nonreloc && !LINETABLE (s))	  continue;		/* matching the symbol table's BFD and the *vp's BFD is hairy.	   exec_file creates a seperate BFD for possibly the	   same file as symbol_file.FIXME ALL THIS MUST BE RECTIFIED. */		if (objfile->obfd == vp->bfd) {	  /* if they match, we luck out. */	  ;	} else if (vp->member[0]) {	  /* no match, and member present, not this one. */	  continue;	} else {	  struct stat si;	  FILE *io;	  	  /*	   * no match, and no member. need to be sure.	   */	  io = bfd_cache_lookup(objfile->obfd);	  if (!io)	    fatal("cannot find BFD's iostream for sym");	  /*	   * see if we are referring to the same file	   */	  if (fstat(fileno(io), &si) < 0)	    fatal("cannot fstat BFD for sym");	  	  if (vip && (si.st_dev != vip->st_dev	      || si.st_ino != vip->st_ino))	    continue;	}		if (vp->tstart != old_start) {	  /* Once we find a relocation base address for one of the symtabs	     in this objfile, it will be the same for all symtabs in this	     objfile. Clean this algorithm. FIXME. */	  for (; s; s = s->next)	    if (!s->nonreloc || LINETABLE(s))		vmap_symtab_1(s, vp, old_start);#if 0 	  Himm.., recently we nullified trampoline entry names in order not	  to confuse them with real symbols.  Appearently this turned into a	  problem, and msymbol vector did not get relocated properly.  If	  msymbols have to have non-null names, then we should name	  trampoline entries with empty strings. 	  ALL_MSYMBOLS (objfile, msymbol)#else	  for (msymbol = objfile->msymbols;		msymbol->name || msymbol->address; (msymbol)++)#endif	      if (msymbol->address < TEXT_SEGMENT_BASE)		msymbol -> address += vp->tstart - old_start;	   break;	}      }    }  if (vp->tstart != old_start) {    /* breakpoints need to be relocated as well. */    fixup_breakpoints (0, TEXT_SEGMENT_BASE, vp->tstart - old_start);  }    symtab_relocated = 1;}vmap_symtab_1(s, vp, old_start)register struct symtab *s;register struct vmap *vp;CORE_ADDR old_start; {    register int i, j;    int len, blen;    register struct linetable *l;    struct blockvector *bv;    register struct block *b;    int depth;    register ulong reloc, dreloc;        if ((reloc = vp->tstart - old_start) == 0)	return;    dreloc = vp->dstart;			/* data relocation */    /*     * The line table must be relocated.  This is only present for     * .text sections, so only vp->text type maps need be considered.     */    l = LINETABLE (s);    if (l) {      len = l->nitems;      for (i = 0; i < len; i++)	l->item[i].pc += reloc;    }    /* if this symbol table is not relocatable, only line table should       be relocated and the rest ignored. */    if (s->nonreloc)      return;        bv  = BLOCKVECTOR(s);    len = BLOCKVECTOR_NBLOCKS(bv);        for (i = 0; i < len; i++) {	b = BLOCKVECTOR_BLOCK(bv, i);		BLOCK_START(b) += reloc;	BLOCK_END(b)   += reloc;		blen = BLOCK_NSYMS(b);	for (j = 0; j < blen; j++) {	    register struct symbol *sym;	    	    sym = BLOCK_SYM(b, j);	    switch (SYMBOL_NAMESPACE(sym)) {	      case STRUCT_NAMESPACE:	      case UNDEF_NAMESPACE:		continue;			      case LABEL_NAMESPACE:	      case VAR_NAMESPACE:		break;	    }	    	    switch (SYMBOL_CLASS(sym)) {	      case LOC_CONST:	      case LOC_CONST_BYTES:	      case LOC_LOCAL:	      case LOC_REGISTER:	      case LOC_ARG:	      case LOC_LOCAL_ARG:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -