libbfd.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,383 行 · 第 1/3 页

C
1,383
字号
	fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",		 (long) real_size, i->data, (long) offset2);      i->size = real_size;      windowp->data = (PTR) ((bfd_byte *) i->data + offset2);      windowp->size = size;      i->mapped = 1;      return true;    }  else if (debug_windows)    {      if (ok_to_map)	fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"),		 (unsigned long) i->data, (int) i->mapped);      else	fprintf (stderr, _("not mapping: env var not set\n"));    }#else  ok_to_map = 0;#endif#ifdef HAVE_MPROTECT  if (!writable)    {      size_to_alloc += pagesize - 1;      size_to_alloc -= size_to_alloc % pagesize;    }#endif  if (debug_windows)    fprintf (stderr, "\n\t%s(%6ld)",	     i->data ? "realloc" : " malloc", (long) size_to_alloc);  i->data = (PTR) bfd_realloc (i->data, size_to_alloc);  if (debug_windows)    fprintf (stderr, "\t-> %p\n", i->data);  i->refcount = 1;  if (i->data == NULL)    {      if (size_to_alloc == 0)	return true;      bfd_set_error (bfd_error_no_memory);      return false;    }  if (bfd_seek (abfd, offset, SEEK_SET) != 0)    return false;  i->size = bfd_read (i->data, size, 1, abfd);  if (i->size != size)    return false;  i->mapped = 0;#ifdef HAVE_MPROTECT  if (!writable)    {      if (debug_windows)	fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,		 (long) i->size);      mprotect (i->data, i->size, PROT_READ);    }#endif  windowp->data = i->data;  windowp->size = i->size;  return true;}#endif /* USE_MMAP */bfd_size_typebfd_write (ptr, size, nitems, abfd)     CONST PTR ptr;     bfd_size_type size;     bfd_size_type nitems;     bfd *abfd;{  long nwrote;  if ((abfd->flags & BFD_IN_MEMORY) != 0)    {      struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream);      size *= nitems;      if (abfd->where + size > bim->size)	{	  long newsize, oldsize = (bim->size + 127) & ~127;	  bim->size = abfd->where + size;	  /* Round up to cut down on memory fragmentation */	  newsize = (bim->size + 127) & ~127;	  if (newsize > oldsize)	    {	      bim->buffer = bfd_realloc (bim->buffer, newsize);	      if (bim->buffer == 0)		{		  bim->size = 0;		  return 0;		}	    }	}      memcpy (bim->buffer + abfd->where, ptr, size);      abfd->where += size;      return size;    }  nwrote = fwrite (ptr, 1, (size_t) (size * nitems),		   bfd_cache_lookup (abfd));  if (nwrote > 0)    abfd->where += nwrote;  if ((bfd_size_type) nwrote != size * nitems)    {#ifdef ENOSPC      if (nwrote >= 0)	errno = ENOSPC;#endif      bfd_set_error (bfd_error_system_call);    }  return nwrote;}/*INTERNAL_FUNCTION	bfd_write_bigendian_4byte_intSYNOPSIS	void bfd_write_bigendian_4byte_int(bfd *abfd,  int i);DESCRIPTION	Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big	endian order regardless of what else is going on.  This is useful in	archives.*/voidbfd_write_bigendian_4byte_int (abfd, i)     bfd *abfd;     int i;{  bfd_byte buffer[4];  bfd_putb32(i, buffer);  if (bfd_write((PTR)buffer, 4, 1, abfd) != 4)    abort ();}longbfd_tell (abfd)     bfd *abfd;{  file_ptr ptr;  if ((abfd->flags & BFD_IN_MEMORY) != 0)    return abfd->where;  ptr = ftell (bfd_cache_lookup(abfd));  if (abfd->my_archive)    ptr -= abfd->origin;  abfd->where = ptr;  return ptr;}intbfd_flush (abfd)     bfd *abfd;{  if ((abfd->flags & BFD_IN_MEMORY) != 0)    return 0;  return fflush (bfd_cache_lookup(abfd));}/* Returns 0 for success, negative value for failure (in which case   bfd_get_error can retrieve the error code).  */intbfd_stat (abfd, statbuf)     bfd *abfd;     struct stat *statbuf;{  FILE *f;  int result;  if ((abfd->flags & BFD_IN_MEMORY) != 0)    abort ();  f = bfd_cache_lookup (abfd);  if (f == NULL)    {      bfd_set_error (bfd_error_system_call);      return -1;    }  result = fstat (fileno (f), statbuf);  if (result < 0)    bfd_set_error (bfd_error_system_call);  return result;}/* Returns 0 for success, nonzero for failure (in which case bfd_get_error   can retrieve the error code).  */intbfd_seek (abfd, position, direction)     bfd *abfd;     file_ptr position;     int direction;{  int result;  FILE *f;  file_ptr file_position;  /* For the time being, a BFD may not seek to it's end.  The problem     is that we don't easily have a way to recognize the end of an     element in an archive.  */  BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);  if (direction == SEEK_CUR && position == 0)    return 0;  if ((abfd->flags & BFD_IN_MEMORY) != 0)    {      struct bfd_in_memory *bim;      bim = (struct bfd_in_memory *) abfd->iostream;      if (direction == SEEK_SET)	abfd->where = position;      else	abfd->where += position;      if ((bfd_size_type) abfd->where > bim->size)	{	  if ((abfd->direction == write_direction) ||	      (abfd->direction == both_direction))	    {	      long newsize, oldsize = (bim->size + 127) & ~127;	      bim->size = abfd->where;	      /* Round up to cut down on memory fragmentation */	      newsize = (bim->size + 127) & ~127;	      if (newsize > oldsize)	        {		  bim->buffer = bfd_realloc (bim->buffer, newsize);		  if (bim->buffer == 0)		    {		      bim->size = 0;		      bfd_set_error (bfd_error_no_memory);		      return -1;		    }	        }	    }	  else	    {	      abfd->where = bim->size;	      bfd_set_error (bfd_error_file_truncated);	      return -1;	    }	}      return 0;    }  if (abfd->format != bfd_archive && abfd->my_archive == 0)    {#if 0      /* Explanation for this code: I'm only about 95+% sure that the above	 conditions are sufficient and that all i/o calls are properly	 adjusting the `where' field.  So this is sort of an `assert'	 that the `where' field is correct.  If we can go a while without	 tripping the abort, we can probably safely disable this code,	 so that the real optimizations happen.  */      file_ptr where_am_i_now;      where_am_i_now = ftell (bfd_cache_lookup (abfd));      if (abfd->my_archive)	where_am_i_now -= abfd->origin;      if (where_am_i_now != abfd->where)	abort ();#endif      if (direction == SEEK_SET && position == abfd->where)	return 0;    }  else    {      /* We need something smarter to optimize access to archives.	 Currently, anything inside an archive is read via the file	 handle for the archive.  Which means that a bfd_seek on one	 component affects the `current position' in the archive, as	 well as in any other component.	 It might be sufficient to put a spike through the cache	 abstraction, and look to the archive for the file position,	 but I think we should try for something cleaner.	 In the meantime, no optimization for archives.  */    }  f = bfd_cache_lookup (abfd);  file_position = position;  if (direction == SEEK_SET && abfd->my_archive != NULL)    file_position += abfd->origin;  result = fseek (f, file_position, direction);  if (result != 0)    {      int hold_errno = errno;      /* Force redetermination of `where' field.  */      bfd_tell (abfd);      /* An EINVAL error probably means that the file offset was         absurd.  */      if (hold_errno == EINVAL)	bfd_set_error (bfd_error_file_truncated);      else	{	  bfd_set_error (bfd_error_system_call);	  errno = hold_errno;	}    }  else    {      /* Adjust `where' field.  */      if (direction == SEEK_SET)	abfd->where = position;      else	abfd->where += position;    }  return result;}/** The do-it-yourself (byte) sex-change kit *//* The middle letter e.g. get<b>short indicates Big or Little endian   target machine.  It doesn't matter what the byte order of the host   machine is; these routines work for either.  *//* FIXME: Should these take a count argument?   Answer (gnu@cygnus.com):  No, but perhaps they should be inline                             functions in swap.h #ifdef __GNUC__.                             Gprof them later and find out.  *//*FUNCTION	bfd_put_sizeFUNCTION	bfd_get_sizeDESCRIPTION	These macros as used for reading and writing raw data in	sections; each access (except for bytes) is vectored through	the target format of the BFD and mangled accordingly. The	mangling performs any necessary endian translations and	removes alignment restrictions.  Note that types accepted and	returned by these macros are identical so they can be swapped	around in macros---for example, @file{libaout.h} defines <<GET_WORD>>	to either <<bfd_get_32>> or <<bfd_get_64>>.	In the put routines, @var{val} must be a <<bfd_vma>>.  If we are on a	system without prototypes, the caller is responsible for making	sure that is true, with a cast if necessary.  We don't cast	them in the macro definitions because that would prevent <<lint>>	or <<gcc -Wall>> from detecting sins such as passing a pointer.	To detect calling these with less than a <<bfd_vma>>, use	<<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s...{* Byte swapping macros for user section data.  *}..#define bfd_put_8(abfd, val, ptr) \.                ((void) (*((unsigned char *) (ptr)) = (unsigned char) (val))).#define bfd_put_signed_8 \.		bfd_put_8.#define bfd_get_8(abfd, ptr) \.                (*(unsigned char *) (ptr)).#define bfd_get_signed_8(abfd, ptr) \.		((*(unsigned char *) (ptr) ^ 0x80) - 0x80)..#define bfd_put_16(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_putx16, ((val),(ptr))).#define bfd_put_signed_16 \.		 bfd_put_16.#define bfd_get_16(abfd, ptr) \.                BFD_SEND(abfd, bfd_getx16, (ptr)).#define bfd_get_signed_16(abfd, ptr) \.         	 BFD_SEND (abfd, bfd_getx_signed_16, (ptr))..#define bfd_put_32(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_putx32, ((val),(ptr))).#define bfd_put_signed_32 \.		 bfd_put_32.#define bfd_get_32(abfd, ptr) \.                BFD_SEND(abfd, bfd_getx32, (ptr)).#define bfd_get_signed_32(abfd, ptr) \.		 BFD_SEND(abfd, bfd_getx_signed_32, (ptr))..#define bfd_put_64(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_putx64, ((val), (ptr))).#define bfd_put_signed_64 \.		 bfd_put_64.#define bfd_get_64(abfd, ptr) \.                BFD_SEND(abfd, bfd_getx64, (ptr)).#define bfd_get_signed_64(abfd, ptr) \.		 BFD_SEND(abfd, bfd_getx_signed_64, (ptr))..#define bfd_get(bits, abfd, ptr)				\.                ((bits) == 8 ? bfd_get_8 (abfd, ptr)		\.		 : (bits) == 16 ? bfd_get_16 (abfd, ptr)	\.		 : (bits) == 32 ? bfd_get_32 (abfd, ptr)	\.		 : (bits) == 64 ? bfd_get_64 (abfd, ptr)	\.		 : (abort (), (bfd_vma) - 1))..#define bfd_put(bits, abfd, val, ptr)				\.                ((bits) == 8 ? bfd_put_8 (abfd, val, ptr)	\.		 : (bits) == 16 ? bfd_put_16 (abfd, val, ptr)	\.		 : (bits) == 32 ? bfd_put_32 (abfd, val, ptr)	\.		 : (bits) == 64 ? bfd_put_64 (abfd, val, ptr)	\.		 : (abort (), (void) 0)).*//*FUNCTION	bfd_h_put_size	bfd_h_get_sizeDESCRIPTION	These macros have the same function as their <<bfd_get_x>>	bretheren, except that they are used for removing information	for the header records of object files. Believe it or not,	some object files keep their header records in big endian	order and their data in little endian order...{* Byte swapping macros for file header data.  *}..#define bfd_h_put_8(abfd, val, ptr) \.		bfd_put_8 (abfd, val, ptr).#define bfd_h_put_signed_8(abfd, val, ptr) \.		bfd_put_8 (abfd, val, ptr).#define bfd_h_get_8(abfd, ptr) \.		bfd_get_8 (abfd, ptr).#define bfd_h_get_signed_8(abfd, ptr) \.		bfd_get_signed_8 (abfd, ptr)..#define bfd_h_put_16(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_h_putx16,(val,ptr)).#define bfd_h_put_signed_16 \.		 bfd_h_put_16.#define bfd_h_get_16(abfd, ptr) \.                BFD_SEND(abfd, bfd_h_getx16,(ptr)).#define bfd_h_get_signed_16(abfd, ptr) \.		 BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))..#define bfd_h_put_32(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_h_putx32,(val,ptr)).#define bfd_h_put_signed_32 \.		 bfd_h_put_32.#define bfd_h_get_32(abfd, ptr) \.                BFD_SEND(abfd, bfd_h_getx32,(ptr)).#define bfd_h_get_signed_32(abfd, ptr) \.		 BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))..#define bfd_h_put_64(abfd, val, ptr) \.                BFD_SEND(abfd, bfd_h_putx64,(val, ptr)).#define bfd_h_put_signed_64 \.		 bfd_h_put_64.#define bfd_h_get_64(abfd, ptr) \.                BFD_SEND(abfd, bfd_h_getx64,(ptr)).#define bfd_h_get_signed_64(abfd, ptr) \.		 BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)).*//* Sign extension to bfd_signed_vma.  */#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)

⌨️ 快捷键说明

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