/* opncls.c -- open and close a BFD.
- Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Copyright (C) 1990 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
-extern void bfd_cache_init PARAMS ((bfd *));
-FILE *bfd_open_file PARAMS ((bfd *));
+
+#ifndef S_IXUSR
+#define S_IXUSR 0100 /* Execute by owner. */
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010 /* Execute by group. */
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001 /* Execute by others. */
+#endif
/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
if we do that we can't use fcntl. */
-#define obstack_chunk_alloc bfd_xmalloc_by_size_t
+#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
+#ifndef HAVE_GETPAGESIZE
+#define getpagesize() 2048
+#endif
+
+long _bfd_chunksize = -1;
+
/* Return a new BFD. All BFD's are allocated through this routine. */
bfd *
-new_bfd PARAMS ((void))
+_bfd_new_bfd ()
{
bfd *nbfd;
- nbfd = (bfd *)zalloc (sizeof (bfd));
+ nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
if (!nbfd)
return 0;
- bfd_check_init();
- obstack_begin((PTR)&nbfd->memory, 128);
+ if (_bfd_chunksize <= 0)
+ {
+ _bfd_chunksize = getpagesize ();
+ if (_bfd_chunksize <= 0)
+ _bfd_chunksize = 2048;
+ /* Leave some slush space, since many malloc implementations
+ prepend a header, and may wind up wasting another page
+ because of it. */
+ _bfd_chunksize -= 32;
+ }
+
+ if (!obstack_begin(&nbfd->memory, _bfd_chunksize))
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return 0;
+ }
nbfd->arch_info = &bfd_default_arch_struct;
/* Allocate a new BFD as a member of archive OBFD. */
bfd *
-new_bfd_contained_in (obfd)
+_bfd_new_bfd_contained_in (obfd)
bfd *obfd;
{
bfd *nbfd;
- nbfd = new_bfd();
+ nbfd = _bfd_new_bfd();
nbfd->xvec = obfd->xvec;
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
/*
SECTION
- Opening and Closing BFDs
+ Opening and closing BFDs
*/
Open the file @var{filename} (using <<fopen>>) with the target
@var{target}. Return a pointer to the created BFD.
- If NULL is returned then an error has occured. Possible errors
- are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
-
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
+
+ If <<NULL>> is returned then an error has occured. Possible errors
+ are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
*/
bfd *
-DEFUN(bfd_openr, (filename, target),
- CONST char *filename AND
- CONST char *target)
+bfd_openr (filename, target)
+ CONST char *filename;
+ CONST char *target;
{
bfd *nbfd;
- bfd_target *target_vec;
+ const bfd_target *target_vec;
- nbfd = new_bfd();
- if (nbfd == NULL) {
- bfd_error = no_memory;
+ nbfd = _bfd_new_bfd();
+ if (nbfd == NULL)
return NULL;
- }
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
- bfd_error = invalid_target;
+ bfd_set_error (bfd_error_invalid_target);
return NULL;
}
nbfd->direction = read_direction;
if (bfd_open_file (nbfd) == NULL) {
- bfd_error = system_call_error; /* File didn't exist, or some such */
+ bfd_set_error (bfd_error_system_call); /* File didn't exist, or some such */
bfd_release(nbfd,0);
return NULL;
}
<<bfd_close>>, and will not be affected by BFD operations on other
files.
- Possible errors are <<no_memory>>, <<invalid_target>> and <<system_call_error>>.
+ Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
*/
bfd *
-DEFUN(bfd_fdopenr,(filename, target, fd),
- CONST char *filename AND
- CONST char *target AND
- int fd)
+bfd_fdopenr (filename, target, fd)
+ CONST char *filename;
+ CONST char *target;
+ int fd;
{
bfd *nbfd;
- bfd_target *target_vec;
+ const bfd_target *target_vec;
int fdflags;
- bfd_error = system_call_error;
-
-#ifdef NO_FCNTL
+ bfd_set_error (bfd_error_system_call);
+#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
fdflags = O_RDWR; /* Assume full access */
#else
fdflags = fcntl (fd, F_GETFL, NULL);
#endif
if (fdflags == -1) return NULL;
- nbfd = new_bfd();
+ nbfd = _bfd_new_bfd();
- if (nbfd == NULL) {
- bfd_error = no_memory;
+ if (nbfd == NULL)
return NULL;
- }
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
- bfd_error = invalid_target;
+ bfd_set_error (bfd_error_invalid_target);
return NULL;
}
-#if defined(VMS) || defined(__GO32__)
- nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
+#if defined(VMS) || defined(__GO32__) || defined (WINGDB)
+ nbfd->iostream = (PTR)fopen(filename, FOPEN_RB);
#else
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
switch (fdflags & (O_ACCMODE)) {
- case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
- case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
- case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
+ case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
+ case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
+ case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
default: abort ();
}
#endif
default: abort ();
}
- bfd_cache_init (nbfd);
+ if (! bfd_cache_init (nbfd))
+ return NULL;
+
+ return nbfd;
+}
+
+/*
+FUNCTION
+ bfd_openstreamr
+
+SYNOPSIS
+ bfd *bfd_openstreamr();
+
+DESCRIPTION
+
+ Open a BFD for read access on an existing stdio stream. When
+ the BFD is passed to <<bfd_close>>, the stream will be closed.
+*/
+
+bfd *
+bfd_openstreamr (filename, target, stream)
+ const char *filename;
+ const char *target;
+ FILE *stream;
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_target);
+ return NULL;
+ }
+
+ nbfd->iostream = (PTR) stream;
+ nbfd->filename = filename;
+ nbfd->direction = read_direction;
+
+ if (! bfd_cache_init (nbfd))
+ return NULL;
return nbfd;
}
Create a BFD, associated with file @var{filename}, using the
file format @var{target}, and return a pointer to it.
- Possible errors are <<system_call_error>>, <<no_memory>>,
- <<invalid_target>>.
+ Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
+ <<bfd_error_invalid_target>>.
*/
bfd *
-DEFUN(bfd_openw,(filename, target),
- CONST char *filename AND
- CONST char *target)
+bfd_openw (filename, target)
+ CONST char *filename;
+ CONST char *target;
{
bfd *nbfd;
- bfd_target *target_vec;
+ const bfd_target *target_vec;
- bfd_error = system_call_error;
+ 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. */
- nbfd = new_bfd();
- if (nbfd == NULL) {
- bfd_error = no_memory;
+ nbfd = _bfd_new_bfd();
+ if (nbfd == NULL)
return NULL;
- }
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) return NULL;
nbfd->direction = write_direction;
if (bfd_open_file (nbfd) == NULL) {
- bfd_error = system_call_error; /* File not writeable, etc */
+ bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
(void) obstack_free (&nbfd->memory, (PTR)0);
return NULL;
}
boolean
-DEFUN(bfd_close,(abfd),
- bfd *abfd)
+bfd_close (abfd)
+ bfd *abfd;
{
boolean ret;
- if (!bfd_read_p(abfd))
- if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
- return false;
+ if (!bfd_read_p (abfd))
+ {
+ if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
+ return false;
+ }
- if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
+ if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
+ return false;
- ret = bfd_cache_close(abfd);
+ ret = bfd_cache_close (abfd);
/* If the file was open for writing and is now executable,
make it so */
- if (ret == true
+ if (ret
&& abfd->direction == write_direction
- && abfd->flags & EXEC_P) {
- struct stat buf;
- stat(abfd->filename, &buf);
-#ifndef S_IXUSR
-#define S_IXUSR 0100 /* Execute by owner. */
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 0010 /* Execute by group. */
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 0001 /* Execute by others. */
-#endif
+ && abfd->flags & EXEC_P)
+ {
+ struct stat buf;
+
+ if (stat (abfd->filename, &buf) == 0)
+ {
+ int mask = umask (0);
+ umask (mask);
+ chmod (abfd->filename,
+ (0777
+ & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ }
+ }
- chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
- }
(void) obstack_free (&abfd->memory, (PTR)0);
- (void) free(abfd);
+ (void) free (abfd);
+
return ret;
}
*/
boolean
-DEFUN(bfd_close_all_done,(abfd),
- bfd *abfd)
+bfd_close_all_done (abfd)
+ bfd *abfd;
{
boolean ret;
- ret = bfd_cache_close(abfd);
+ ret = bfd_cache_close (abfd);
/* If the file was open for writing and is now executable,
make it so */
- if (ret == true
+ if (ret
&& abfd->direction == write_direction
- && abfd->flags & EXEC_P) {
- struct stat buf;
- stat(abfd->filename, &buf);
-#ifndef S_IXUSR
-#define S_IXUSR 0100 /* Execute by owner. */
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 0010 /* Execute by group. */
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 0001 /* Execute by others. */
-#endif
-
- chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
- }
+ && abfd->flags & EXEC_P)
+ {
+ struct stat buf;
+
+ if (stat (abfd->filename, &buf) == 0)
+ {
+ int mask = umask (0);
+ umask (mask);
+ chmod (abfd->filename,
+ (0x777
+ & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ }
+ }
(void) obstack_free (&abfd->memory, (PTR)0);
(void) free(abfd);
return ret;
*/
bfd_size_type
-DEFUN(bfd_alloc_size,(abfd),
- bfd *abfd)
+bfd_alloc_size (abfd)
+ bfd *abfd;
{
struct _obstack_chunk *chunk = abfd->memory.chunk;
size_t size = 0;
*/
bfd *
-DEFUN(bfd_create,(filename, templ),
- CONST char *filename AND
- bfd *templ)
+bfd_create (filename, templ)
+ CONST char *filename;
+ bfd *templ;
{
- bfd *nbfd = new_bfd();
- if (nbfd == (bfd *)NULL) {
- bfd_error = no_memory;
+ bfd *nbfd = _bfd_new_bfd();
+ if (nbfd == (bfd *)NULL)
return (bfd *)NULL;
- }
nbfd->filename = filename;
if(templ) {
nbfd->xvec = templ->xvec;
PTR
-DEFUN(bfd_alloc_by_size_t,(abfd, size),
- bfd *abfd AND
- size_t size)
+bfd_alloc_by_size_t (abfd, size)
+ bfd *abfd;
+ size_t size;
{
- PTR res = obstack_alloc(&(abfd->memory), size);
- return res;
+ PTR ret;
+
+ ret = obstack_alloc (&(abfd->memory), size);
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
}
-DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
- bfd *abfd AND
- PTR ptr AND
- size_t size)
+void
+bfd_alloc_grow (abfd, ptr, size)
+ bfd *abfd;
+ PTR ptr;
+ size_t size;
{
(void) obstack_grow(&(abfd->memory), ptr, size);
}
-DEFUN(PTR bfd_alloc_finish,(abfd),
- bfd *abfd)
+
+PTR
+bfd_alloc_finish (abfd)
+ bfd *abfd;
{
- return obstack_finish(&(abfd->memory));
+ PTR ret;
+
+ ret = obstack_finish (&(abfd->memory));
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
}
-DEFUN(PTR bfd_alloc, (abfd, size),
- bfd *abfd AND
- size_t size)
+PTR
+bfd_alloc (abfd, size)
+ bfd *abfd;
+ size_t size;
{
return bfd_alloc_by_size_t(abfd, (size_t)size);
}
-DEFUN(PTR bfd_zalloc,(abfd, size),
- bfd *abfd AND
- size_t size)
+PTR
+bfd_zalloc (abfd, size)
+ bfd *abfd;
+ size_t size;
{
PTR res;
res = bfd_alloc(abfd, size);
- memset(res, 0, (size_t)size);
- return res;
-}
-
-DEFUN(PTR bfd_realloc,(abfd, old, size),
- bfd *abfd AND
- PTR old AND
- size_t size)
-{
- PTR res = bfd_alloc(abfd, size);
- memcpy(res, old, (size_t)size);
+ if (res)
+ memset(res, 0, (size_t)size);
return res;
}