1 /* opncls.c -- open and close a BFD.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
4 Free Software Foundation, Inc.
6 Written by Cygnus Support.
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 #define S_IXUSR 0100 /* Execute by owner. */
33 #define S_IXGRP 0010 /* Execute by group. */
36 #define S_IXOTH 0001 /* Execute by others. */
39 /* Counter used to initialize the bfd identifier. */
41 static unsigned int _bfd_id_counter = 0;
43 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
44 if we do that we can't use fcntl. */
46 /* Return a new BFD. All BFD's are allocated through this routine. */
53 nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));
57 nbfd->id = _bfd_id_counter++;
59 nbfd->memory = (PTR) objalloc_create ();
60 if (nbfd->memory == NULL)
62 bfd_set_error (bfd_error_no_memory);
67 nbfd->arch_info = &bfd_default_arch_struct;
69 nbfd->direction = no_direction;
70 nbfd->iostream = NULL;
72 if (!bfd_hash_table_init_n (&nbfd->section_htab,
73 bfd_section_hash_newfunc,
79 nbfd->sections = (asection *) NULL;
80 nbfd->section_tail = &nbfd->sections;
81 nbfd->format = bfd_unknown;
82 nbfd->my_archive = (bfd *) NULL;
84 nbfd->opened_once = FALSE;
85 nbfd->output_has_begun = FALSE;
86 nbfd->section_count = 0;
87 nbfd->usrdata = (PTR) NULL;
88 nbfd->cacheable = FALSE;
89 nbfd->flags = BFD_NO_FLAGS;
90 nbfd->mtime_set = FALSE;
95 /* Allocate a new BFD as a member of archive OBFD. */
98 _bfd_new_bfd_contained_in (obfd)
103 nbfd = _bfd_new_bfd ();
106 nbfd->xvec = obfd->xvec;
107 nbfd->my_archive = obfd;
108 nbfd->direction = read_direction;
109 nbfd->target_defaulted = obfd->target_defaulted;
116 _bfd_delete_bfd (abfd)
119 bfd_hash_table_free (&abfd->section_htab);
120 objalloc_free ((struct objalloc *) abfd->memory);
126 Opening and closing BFDs
135 bfd *bfd_openr(const char *filename, const char *target);
138 Open the file @var{filename} (using <<fopen>>) with the target
139 @var{target}. Return a pointer to the created BFD.
141 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
144 If <<NULL>> is returned then an error has occured. Possible errors
145 are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
146 <<system_call>> error.
150 bfd_openr (filename, target)
151 const char *filename;
155 const bfd_target *target_vec;
157 nbfd = _bfd_new_bfd ();
161 target_vec = bfd_find_target (target, nbfd);
162 if (target_vec == NULL)
164 _bfd_delete_bfd (nbfd);
168 nbfd->filename = filename;
169 nbfd->direction = read_direction;
171 if (bfd_open_file (nbfd) == NULL)
173 /* File didn't exist, or some such. */
174 bfd_set_error (bfd_error_system_call);
175 _bfd_delete_bfd (nbfd);
182 /* Don't try to `optimize' this function:
184 o - We lock using stack space so that interrupting the locking
185 won't cause a storage leak.
186 o - We open the file stream last, since we don't want to have to
187 close it if anything goes wrong. Closing the stream means closing
188 the file descriptor too, even though we didn't open it. */
194 bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
197 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
198 <<fopen>>. It opens a BFD on a file already described by the
201 When the file is later <<bfd_close>>d, the file descriptor will
202 be closed. If the caller desires that this file descriptor be
203 cached by BFD (opened as needed, closed as needed to free
204 descriptors for other opens), with the supplied @var{fd} used as
205 an initial file descriptor (but subject to closure at any time),
206 call bfd_set_cacheable(bfd, 1) on the returned BFD. The default
207 is to assume no cacheing; the file descriptor will remain open
208 until <<bfd_close>>, and will not be affected by BFD operations
211 Possible errors are <<bfd_error_no_memory>>,
212 <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
216 bfd_fdopenr (filename, target, fd)
217 const char *filename;
222 const bfd_target *target_vec;
225 bfd_set_error (bfd_error_system_call);
226 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
227 fdflags = O_RDWR; /* Assume full access. */
229 fdflags = fcntl (fd, F_GETFL, NULL);
234 nbfd = _bfd_new_bfd ();
238 target_vec = bfd_find_target (target, nbfd);
239 if (target_vec == NULL)
241 _bfd_delete_bfd (nbfd);
246 nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);
248 /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */
249 switch (fdflags & (O_ACCMODE))
251 case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
252 case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
253 case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
258 if (nbfd->iostream == NULL)
260 _bfd_delete_bfd (nbfd);
264 /* OK, put everything where it belongs. */
265 nbfd->filename = filename;
267 /* As a special case we allow a FD open for read/write to
268 be written through, although doing so requires that we end
269 the previous clause with a preposition. */
270 /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */
271 switch (fdflags & (O_ACCMODE))
273 case O_RDONLY: nbfd->direction = read_direction; break;
274 case O_WRONLY: nbfd->direction = write_direction; break;
275 case O_RDWR: nbfd->direction = both_direction; break;
279 if (! bfd_cache_init (nbfd))
281 _bfd_delete_bfd (nbfd);
284 nbfd->opened_once = TRUE;
294 bfd *bfd_openstreamr(const char *, const char *, PTR);
298 Open a BFD for read access on an existing stdio stream. When
299 the BFD is passed to <<bfd_close>>, the stream will be closed.
303 bfd_openstreamr (filename, target, streamarg)
304 const char *filename;
308 FILE *stream = (FILE *) streamarg;
310 const bfd_target *target_vec;
312 nbfd = _bfd_new_bfd ();
316 target_vec = bfd_find_target (target, nbfd);
317 if (target_vec == NULL)
319 _bfd_delete_bfd (nbfd);
323 nbfd->iostream = (PTR) stream;
324 nbfd->filename = filename;
325 nbfd->direction = read_direction;
327 if (! bfd_cache_init (nbfd))
329 _bfd_delete_bfd (nbfd);
336 /* bfd_openw -- open for writing.
337 Returns a pointer to a freshly-allocated BFD on success, or NULL.
339 See comment by bfd_fdopenr before you try to modify this function. */
346 bfd *bfd_openw(const char *filename, const char *target);
349 Create a BFD, associated with file @var{filename}, using the
350 file format @var{target}, and return a pointer to it.
352 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
353 <<bfd_error_invalid_target>>.
357 bfd_openw (filename, target)
358 const char *filename;
362 const bfd_target *target_vec;
364 /* nbfd has to point to head of malloc'ed block so that bfd_close may
365 reclaim it correctly. */
366 nbfd = _bfd_new_bfd ();
370 target_vec = bfd_find_target (target, nbfd);
371 if (target_vec == NULL)
373 _bfd_delete_bfd (nbfd);
377 nbfd->filename = filename;
378 nbfd->direction = write_direction;
380 if (bfd_open_file (nbfd) == NULL)
382 /* File not writeable, etc. */
383 bfd_set_error (bfd_error_system_call);
384 _bfd_delete_bfd (nbfd);
397 bfd_boolean bfd_close (bfd *abfd);
401 Close a BFD. If the BFD was open for writing, then pending
402 operations are completed and the file written out and closed.
403 If the created file is executable, then <<chmod>> is called
406 All memory attached to the BFD is released.
408 The file descriptor associated with the BFD is closed (even
409 if it was passed in to BFD by <<bfd_fdopenr>>).
412 <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
422 if (bfd_write_p (abfd))
424 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
428 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
431 ret = bfd_cache_close (abfd);
433 /* If the file was open for writing and is now executable,
436 && abfd->direction == write_direction
437 && abfd->flags & EXEC_P)
441 if (stat (abfd->filename, &buf) == 0)
443 unsigned int mask = umask (0);
446 chmod (abfd->filename,
448 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
452 _bfd_delete_bfd (abfd);
462 bfd_boolean bfd_close_all_done (bfd *);
465 Close a BFD. Differs from <<bfd_close>> since it does not
466 complete any pending operations. This routine would be used
467 if the application had just used BFD for swapping and didn't
468 want to use any of the writing code.
470 If the created file is executable, then <<chmod>> is called
473 All memory attached to the BFD is released.
476 <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
480 bfd_close_all_done (abfd)
485 ret = bfd_cache_close (abfd);
487 /* If the file was open for writing and is now executable,
490 && abfd->direction == write_direction
491 && abfd->flags & EXEC_P)
495 if (stat (abfd->filename, &buf) == 0)
497 unsigned int mask = umask (0);
500 chmod (abfd->filename,
502 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
506 _bfd_delete_bfd (abfd);
516 bfd *bfd_create(const char *filename, bfd *templ);
519 Create a new BFD in the manner of <<bfd_openw>>, but without
520 opening a file. The new BFD takes the target from the target
521 used by @var{template}. The format is always set to <<bfd_object>>.
525 bfd_create (filename, templ)
526 const char *filename;
531 nbfd = _bfd_new_bfd ();
534 nbfd->filename = filename;
536 nbfd->xvec = templ->xvec;
537 nbfd->direction = no_direction;
538 bfd_set_format (nbfd, bfd_object);
548 bfd_boolean bfd_make_writable (bfd *abfd);
551 Takes a BFD as created by <<bfd_create>> and converts it
552 into one like as returned by <<bfd_openw>>. It does this
553 by converting the BFD to BFD_IN_MEMORY. It's assumed that
554 you will call <<bfd_make_readable>> on this bfd later.
557 <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
561 bfd_make_writable(abfd)
564 struct bfd_in_memory *bim;
566 if (abfd->direction != no_direction)
568 bfd_set_error (bfd_error_invalid_operation);
572 bim = ((struct bfd_in_memory *)
573 bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
574 abfd->iostream = (PTR) bim;
575 /* bfd_bwrite will grow these as needed. */
579 abfd->flags |= BFD_IN_MEMORY;
580 abfd->direction = write_direction;
591 bfd_boolean bfd_make_readable (bfd *abfd);
594 Takes a BFD as created by <<bfd_create>> and
595 <<bfd_make_writable>> and converts it into one like as
596 returned by <<bfd_openr>>. It does this by writing the
597 contents out to the memory buffer, then reversing the
601 <<TRUE>> is returned if all is ok, otherwise <<FALSE>>. */
604 bfd_make_readable(abfd)
607 if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
609 bfd_set_error (bfd_error_invalid_operation);
613 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
616 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
620 abfd->arch_info = &bfd_default_arch_struct;
623 abfd->format = bfd_unknown;
624 abfd->my_archive = (bfd *) NULL;
626 abfd->opened_once = FALSE;
627 abfd->output_has_begun = FALSE;
628 abfd->section_count = 0;
629 abfd->usrdata = (PTR) NULL;
630 abfd->cacheable = FALSE;
631 abfd->flags = BFD_IN_MEMORY;
632 abfd->mtime_set = FALSE;
634 abfd->target_defaulted = TRUE;
635 abfd->direction = read_direction;
638 abfd->outsymbols = 0;
641 bfd_section_list_clear (abfd);
642 bfd_check_format (abfd, bfd_object);
652 PTR bfd_alloc (bfd *abfd, size_t wanted);
655 Allocate a block of @var{wanted} bytes of memory attached to
656 <<abfd>> and return a pointer to it.
661 bfd_alloc (abfd, size)
667 if (size != (unsigned long) size)
669 bfd_set_error (bfd_error_no_memory);
673 ret = objalloc_alloc (abfd->memory, (unsigned long) size);
675 bfd_set_error (bfd_error_no_memory);
680 bfd_zalloc (abfd, size)
686 res = bfd_alloc (abfd, size);
688 memset (res, 0, (size_t) size);
692 /* Free a block allocated for a BFD.
693 Note: Also frees all more recently allocated blocks! */
696 bfd_release (abfd, block)
700 objalloc_free_block ((struct objalloc *) abfd->memory, block);