X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fopncls.c;h=c24438820bd4f537bd2f7389e7fc4c60eed7ac21;hb=52b69c9e01afa3fffa5f9e83d7e560f47610d651;hp=57ca0d0a25948b5180397c65ff1311e290057222;hpb=27e232885db363fb545fd2f450e72d929e59b8f6;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/opncls.c b/bfd/opncls.c index 57ca0d0a25..c24438820b 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -1,24 +1,25 @@ /* opncls.c -- open and close a BFD. - Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997 + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, + 2001, 2002 Free Software Foundation, Inc. Written by Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the 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 of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -35,12 +36,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define S_IXOTH 0001 /* Execute by others. */ #endif +/* Counter used to initialize the bfd identifier. */ + +static unsigned int _bfd_id_counter = 0; + /* fdopen is a loser -- we should use stdio exclusively. Unfortunately if we do that we can't use fcntl. */ -/* FIXME: This is no longer used. */ -long _bfd_chunksize = -1; - /* Return a new BFD. All BFD's are allocated through this routine. */ bfd * @@ -48,14 +50,17 @@ _bfd_new_bfd () { bfd *nbfd; - nbfd = (bfd *) bfd_zmalloc (sizeof (bfd)); + nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd)); if (nbfd == NULL) return NULL; + nbfd->id = _bfd_id_counter++; + nbfd->memory = (PTR) objalloc_create (); if (nbfd->memory == NULL) { bfd_set_error (bfd_error_no_memory); + free (nbfd); return NULL; } @@ -64,17 +69,25 @@ _bfd_new_bfd () nbfd->direction = no_direction; nbfd->iostream = NULL; nbfd->where = 0; + if (!bfd_hash_table_init_n (&nbfd->section_htab, + bfd_section_hash_newfunc, + 251)) + { + free (nbfd); + return NULL; + } nbfd->sections = (asection *) NULL; + nbfd->section_tail = &nbfd->sections; nbfd->format = bfd_unknown; nbfd->my_archive = (bfd *) NULL; - nbfd->origin = 0; - nbfd->opened_once = false; - nbfd->output_has_begun = false; + nbfd->origin = 0; + nbfd->opened_once = FALSE; + nbfd->output_has_begun = FALSE; nbfd->section_count = 0; nbfd->usrdata = (PTR) NULL; - nbfd->cacheable = false; + nbfd->cacheable = FALSE; nbfd->flags = BFD_NO_FLAGS; - nbfd->mtime_set = false; + nbfd->mtime_set = FALSE; return nbfd; } @@ -88,6 +101,8 @@ _bfd_new_bfd_contained_in (obfd) bfd *nbfd; nbfd = _bfd_new_bfd (); + if (nbfd == NULL) + return NULL; nbfd->xvec = obfd->xvec; nbfd->my_archive = obfd; nbfd->direction = read_direction; @@ -95,6 +110,17 @@ _bfd_new_bfd_contained_in (obfd) return nbfd; } +/* Delete a BFD. */ + +void +_bfd_delete_bfd (abfd) + bfd *abfd; +{ + bfd_hash_table_free (&abfd->section_htab); + objalloc_free ((struct objalloc *) abfd->memory); + free (abfd); +} + /* SECTION Opening and closing BFDs @@ -106,7 +132,7 @@ FUNCTION bfd_openr SYNOPSIS - bfd *bfd_openr(CONST char *filename, CONST char *target); + bfd *bfd_openr(const char *filename, const char *target); DESCRIPTION Open the file @var{filename} (using <>) with the target @@ -116,13 +142,14 @@ DESCRIPTION that function. If <> is returned then an error has occured. Possible errors - are <>, <> or <> error. + are <>, <> or + <> error. */ bfd * bfd_openr (filename, target) - CONST char *filename; - CONST char *target; + const char *filename; + const char *target; { bfd *nbfd; const bfd_target *target_vec; @@ -134,9 +161,7 @@ bfd_openr (filename, target) target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); - bfd_set_error (bfd_error_invalid_target); + _bfd_delete_bfd (nbfd); return NULL; } @@ -145,10 +170,9 @@ bfd_openr (filename, target) if (bfd_open_file (nbfd) == NULL) { - /* File didn't exist, or some such */ + /* File didn't exist, or some such. */ bfd_set_error (bfd_error_system_call); - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } @@ -161,38 +185,37 @@ bfd_openr (filename, target) won't cause a storage leak. o - We open the file stream last, since we don't want to have to close it if anything goes wrong. Closing the stream means closing - the file descriptor too, even though we didn't open it. - */ + the file descriptor too, even though we didn't open it. */ /* FUNCTION - bfd_fdopenr + bfd_fdopenr SYNOPSIS - bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd); + bfd *bfd_fdopenr(const char *filename, const char *target, int fd); DESCRIPTION - <> is to <> much like <> is to <>. - It opens a BFD on a file already described by the @var{fd} - supplied. - - When the file is later <>d, the file descriptor will be closed. - - If the caller desires that this file descriptor be cached by BFD - (opened as needed, closed as needed to free descriptors for - other opens), with the supplied @var{fd} used as an initial - file descriptor (but subject to closure at any time), call - bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to - assume no cacheing; the file descriptor will remain open until - <>, and will not be affected by BFD operations on other - files. - - Possible errors are <>, <> and <>. + <> is to <> much like <> is to + <>. It opens a BFD on a file already described by the + @var{fd} supplied. + + When the file is later <>d, the file descriptor will + be closed. If the caller desires that this file descriptor be + cached by BFD (opened as needed, closed as needed to free + descriptors for other opens), with the supplied @var{fd} used as + an initial file descriptor (but subject to closure at any time), + call bfd_set_cacheable(bfd, 1) on the returned BFD. The default + is to assume no cacheing; the file descriptor will remain open + until <>, and will not be affected by BFD operations + on other files. + + Possible errors are <>, + <> and <>. */ bfd * bfd_fdopenr (filename, target, fd) - CONST char *filename; - CONST char *target; + const char *filename; + const char *target; int fd; { bfd *nbfd; @@ -201,11 +224,12 @@ bfd_fdopenr (filename, target, fd) bfd_set_error (bfd_error_system_call); #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL) - fdflags = O_RDWR; /* Assume full access */ + fdflags = O_RDWR; /* Assume full access. */ #else fdflags = fcntl (fd, F_GETFL, NULL); #endif - if (fdflags == -1) return NULL; + if (fdflags == -1) + return NULL; nbfd = _bfd_new_bfd (); if (nbfd == NULL) @@ -214,16 +238,14 @@ bfd_fdopenr (filename, target, fd) target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } #ifndef HAVE_FDOPEN nbfd->iostream = (PTR) fopen (filename, FOPEN_RB); #else - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ + /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */ switch (fdflags & (O_ACCMODE)) { case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break; @@ -235,20 +257,18 @@ bfd_fdopenr (filename, target, fd) if (nbfd->iostream == NULL) { - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } - /* OK, put everything where it belongs */ - + /* OK, put everything where it belongs. */ nbfd->filename = filename; /* As a special case we allow a FD open for read/write to be written through, although doing so requires that we end the previous clause with a preposition. */ - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (fdflags & O_ACCMODE) + /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */ + switch (fdflags & (O_ACCMODE)) { case O_RDONLY: nbfd->direction = read_direction; break; case O_WRONLY: nbfd->direction = write_direction; break; @@ -258,11 +278,10 @@ bfd_fdopenr (filename, target, fd) if (! bfd_cache_init (nbfd)) { - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } - nbfd->opened_once = true; + nbfd->opened_once = TRUE; return nbfd; } @@ -297,37 +316,34 @@ bfd_openstreamr (filename, target, streamarg) target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } nbfd->iostream = (PTR) stream; nbfd->filename = filename; nbfd->direction = read_direction; - + if (! bfd_cache_init (nbfd)) { - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } return nbfd; } -/** bfd_openw -- open for writing. - Returns a pointer to a freshly-allocated BFD on success, or NULL. +/* bfd_openw -- open for writing. + Returns a pointer to a freshly-allocated BFD on success, or NULL. - See comment by bfd_fdopenr before you try to modify this function. */ + See comment by bfd_fdopenr before you try to modify this function. */ /* FUNCTION bfd_openw SYNOPSIS - bfd *bfd_openw(CONST char *filename, CONST char *target); + bfd *bfd_openw(const char *filename, const char *target); DESCRIPTION Create a BFD, associated with file @var{filename}, using the @@ -339,17 +355,14 @@ DESCRIPTION bfd * bfd_openw (filename, target) - CONST char *filename; - CONST char *target; + const char *filename; + const char *target; { bfd *nbfd; const bfd_target *target_vec; - bfd_set_error (bfd_error_system_call); - /* nbfd has to point to head of malloc'ed block so that bfd_close may - reclaim it correctly. */ - + reclaim it correctly. */ nbfd = _bfd_new_bfd (); if (nbfd == NULL) return NULL; @@ -357,8 +370,7 @@ bfd_openw (filename, target) target_vec = bfd_find_target (target, nbfd); if (target_vec == NULL) { - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + _bfd_delete_bfd (nbfd); return NULL; } @@ -367,9 +379,9 @@ bfd_openw (filename, target) if (bfd_open_file (nbfd) == NULL) { - bfd_set_error (bfd_error_system_call); /* File not writeable, etc */ - objalloc_free ((struct objalloc *) nbfd->memory); - free (nbfd); + /* File not writeable, etc. */ + bfd_set_error (bfd_error_system_call); + _bfd_delete_bfd (nbfd); return NULL; } @@ -382,14 +394,14 @@ FUNCTION bfd_close SYNOPSIS - boolean bfd_close(bfd *abfd); + bfd_boolean bfd_close (bfd *abfd); DESCRIPTION - Close a BFD. If the BFD was open for writing, - then pending operations are completed and the file written out - and closed. If the created file is executable, then - <> is called to mark it as such. + Close a BFD. If the BFD was open for writing, then pending + operations are completed and the file written out and closed. + If the created file is executable, then <> is called + to mark it as such. All memory attached to the BFD is released. @@ -397,29 +409,29 @@ DESCRIPTION if it was passed in to BFD by <>). RETURNS - <> is returned if all is ok, otherwise <>. + <> is returned if all is ok, otherwise <>. */ -boolean +bfd_boolean bfd_close (abfd) bfd *abfd; { - boolean ret; + bfd_boolean ret; - if (!bfd_read_p (abfd)) + if (bfd_write_p (abfd)) { if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) - return false; + return FALSE; } if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return false; + return FALSE; ret = bfd_cache_close (abfd); /* If the file was open for writing and is now executable, - make it so */ + make it so. */ if (ret && abfd->direction == write_direction && abfd->flags & EXEC_P) @@ -428,7 +440,8 @@ bfd_close (abfd) if (stat (abfd->filename, &buf) == 0) { - int mask = umask (0); + unsigned int mask = umask (0); + umask (mask); chmod (abfd->filename, (0777 @@ -436,8 +449,7 @@ bfd_close (abfd) } } - objalloc_free ((struct objalloc *) abfd->memory); - free (abfd); + _bfd_delete_bfd (abfd); return ret; } @@ -447,13 +459,13 @@ FUNCTION bfd_close_all_done SYNOPSIS - boolean bfd_close_all_done(bfd *); + bfd_boolean bfd_close_all_done (bfd *); DESCRIPTION - Close a BFD. Differs from <> - since it does not complete any pending operations. This - routine would be used if the application had just used BFD for - swapping and didn't want to use any of the writing code. + Close a BFD. Differs from <> since it does not + complete any pending operations. This routine would be used + if the application had just used BFD for swapping and didn't + want to use any of the writing code. If the created file is executable, then <> is called to mark it as such. @@ -461,20 +473,19 @@ DESCRIPTION All memory attached to the BFD is released. RETURNS - <> is returned if all is ok, otherwise <>. - + <> is returned if all is ok, otherwise <>. */ -boolean +bfd_boolean bfd_close_all_done (abfd) bfd *abfd; { - boolean ret; + bfd_boolean ret; ret = bfd_cache_close (abfd); /* If the file was open for writing and is now executable, - make it so */ + make it so. */ if (ret && abfd->direction == write_direction && abfd->flags & EXEC_P) @@ -483,7 +494,8 @@ bfd_close_all_done (abfd) if (stat (abfd->filename, &buf) == 0) { - int mask = umask (0); + unsigned int mask = umask (0); + umask (mask); chmod (abfd->filename, (0777 @@ -491,8 +503,7 @@ bfd_close_all_done (abfd) } } - objalloc_free ((struct objalloc *) abfd->memory); - free (abfd); + _bfd_delete_bfd (abfd); return ret; } @@ -502,19 +513,17 @@ FUNCTION bfd_create SYNOPSIS - bfd *bfd_create(CONST char *filename, bfd *templ); + bfd *bfd_create(const char *filename, bfd *templ); DESCRIPTION - Create a new BFD in the manner of - <>, but without opening a file. The new BFD - takes the target from the target used by @var{template}. The - format is always set to <>. - + Create a new BFD in the manner of <>, but without + opening a file. The new BFD takes the target from the target + used by @var{template}. The format is always set to <>. */ bfd * bfd_create (filename, templ) - CONST char *filename; + const char *filename; bfd *templ; { bfd *nbfd; @@ -527,6 +536,7 @@ bfd_create (filename, templ) nbfd->xvec = templ->xvec; nbfd->direction = no_direction; bfd_set_format (nbfd, bfd_object); + return nbfd; } @@ -535,7 +545,7 @@ FUNCTION bfd_make_writable SYNOPSIS - boolean bfd_make_writable(bfd *abfd); + bfd_boolean bfd_make_writable (bfd *abfd); DESCRIPTION Takes a BFD as created by <> and converts it @@ -544,10 +554,10 @@ DESCRIPTION you will call <> on this bfd later. RETURNS - <> is returned if all is ok, otherwise <>. + <> is returned if all is ok, otherwise <>. */ -boolean +bfd_boolean bfd_make_writable(abfd) bfd *abfd; { @@ -556,12 +566,13 @@ bfd_make_writable(abfd) if (abfd->direction != no_direction) { bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } - bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); + bim = ((struct bfd_in_memory *) + bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory))); abfd->iostream = (PTR) bim; - /* bfd_write will grow these as needed */ + /* bfd_bwrite will grow these as needed. */ bim->size = 0; bim->buffer = 0; @@ -569,7 +580,7 @@ bfd_make_writable(abfd) abfd->direction = write_direction; abfd->where = 0; - return true; + return TRUE; } /* @@ -577,7 +588,7 @@ FUNCTION bfd_make_readable SYNOPSIS - boolean bfd_make_readable(bfd *abfd); + bfd_boolean bfd_make_readable (bfd *abfd); DESCRIPTION Takes a BFD as created by <> and @@ -587,50 +598,50 @@ DESCRIPTION direction. RETURNS - <> is returned if all is ok, otherwise <>. */ + <> is returned if all is ok, otherwise <>. */ -boolean +bfd_boolean bfd_make_readable(abfd) bfd *abfd; { if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY)) { bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) - return false; + return FALSE; if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return false; + return FALSE; abfd->arch_info = &bfd_default_arch_struct; abfd->where = 0; - abfd->sections = (asection *) NULL; abfd->format = bfd_unknown; abfd->my_archive = (bfd *) NULL; - abfd->origin = 0; - abfd->opened_once = false; - abfd->output_has_begun = false; + abfd->origin = 0; + abfd->opened_once = FALSE; + abfd->output_has_begun = FALSE; abfd->section_count = 0; abfd->usrdata = (PTR) NULL; - abfd->cacheable = false; + abfd->cacheable = FALSE; abfd->flags = BFD_IN_MEMORY; - abfd->mtime_set = false; + abfd->mtime_set = FALSE; - abfd->target_defaulted = true; + abfd->target_defaulted = TRUE; abfd->direction = read_direction; abfd->sections = 0; abfd->symcount = 0; abfd->outsymbols = 0; abfd->tdata.any = 0; - bfd_check_format(abfd, bfd_object); + bfd_section_list_clear (abfd); + bfd_check_format (abfd, bfd_object); - return true; + return TRUE; } /* @@ -649,10 +660,16 @@ DESCRIPTION PTR bfd_alloc (abfd, size) bfd *abfd; - size_t size; + bfd_size_type size; { PTR ret; + if (size != (unsigned long) size) + { + bfd_set_error (bfd_error_no_memory); + return NULL; + } + ret = objalloc_alloc (abfd->memory, (unsigned long) size); if (ret == NULL) bfd_set_error (bfd_error_no_memory); @@ -662,17 +679,18 @@ bfd_alloc (abfd, size) PTR bfd_zalloc (abfd, size) bfd *abfd; - size_t size; + bfd_size_type size; { PTR res; res = bfd_alloc (abfd, size); if (res) - memset (res, 0, size); + memset (res, 0, (size_t) size); return res; } -/* Free a block allocated for a BFD. */ +/* Free a block allocated for a BFD. + Note: Also frees all more recently allocated blocks! */ void bfd_release (abfd, block)