2002-02-18 David O'Brien <obrien@FreeBSD.org>
[binutils.git] / bfd / opncls.c
blob0b285d4b8ceda14e65696582d122e4971c36b4cf
1 /* opncls.c -- open and close a BFD.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3 2001
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. */
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "objalloc.h"
27 #include "libbfd.h"
29 #ifndef S_IXUSR
30 #define S_IXUSR 0100 /* Execute by owner. */
31 #endif
32 #ifndef S_IXGRP
33 #define S_IXGRP 0010 /* Execute by group. */
34 #endif
35 #ifndef S_IXOTH
36 #define S_IXOTH 0001 /* Execute by others. */
37 #endif
39 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
40 if we do that we can't use fcntl. */
42 /* FIXME: This is no longer used. */
43 long _bfd_chunksize = -1;
45 /* Return a new BFD. All BFD's are allocated through this routine. */
47 bfd *
48 _bfd_new_bfd ()
50 bfd *nbfd;
52 nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));
53 if (nbfd == NULL)
54 return NULL;
56 nbfd->memory = (PTR) objalloc_create ();
57 if (nbfd->memory == NULL)
59 bfd_set_error (bfd_error_no_memory);
60 free (nbfd);
61 return NULL;
64 nbfd->arch_info = &bfd_default_arch_struct;
66 nbfd->direction = no_direction;
67 nbfd->iostream = NULL;
68 nbfd->where = 0;
69 if (!bfd_hash_table_init (&nbfd->section_htab, bfd_section_hash_newfunc))
71 free (nbfd);
72 return NULL;
74 nbfd->sections = (asection *) NULL;
75 nbfd->section_tail = &nbfd->sections;
76 nbfd->format = bfd_unknown;
77 nbfd->my_archive = (bfd *) NULL;
78 nbfd->origin = 0;
79 nbfd->opened_once = false;
80 nbfd->output_has_begun = false;
81 nbfd->section_count = 0;
82 nbfd->usrdata = (PTR) NULL;
83 nbfd->cacheable = false;
84 nbfd->flags = BFD_NO_FLAGS;
85 nbfd->mtime_set = false;
87 return nbfd;
90 /* Allocate a new BFD as a member of archive OBFD. */
92 bfd *
93 _bfd_new_bfd_contained_in (obfd)
94 bfd *obfd;
96 bfd *nbfd;
98 nbfd = _bfd_new_bfd ();
99 nbfd->xvec = obfd->xvec;
100 nbfd->my_archive = obfd;
101 nbfd->direction = read_direction;
102 nbfd->target_defaulted = obfd->target_defaulted;
103 return nbfd;
106 /* Delete a BFD. */
108 void
109 _bfd_delete_bfd (abfd)
110 bfd *abfd;
112 bfd_hash_table_free (&abfd->section_htab);
113 objalloc_free ((struct objalloc *) abfd->memory);
114 free (abfd);
118 SECTION
119 Opening and closing BFDs
124 FUNCTION
125 bfd_openr
127 SYNOPSIS
128 bfd *bfd_openr(const char *filename, const char *target);
130 DESCRIPTION
131 Open the file @var{filename} (using <<fopen>>) with the target
132 @var{target}. Return a pointer to the created BFD.
134 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
135 that function.
137 If <<NULL>> is returned then an error has occured. Possible errors
138 are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
141 bfd *
142 bfd_openr (filename, target)
143 const char *filename;
144 const char *target;
146 bfd *nbfd;
147 const bfd_target *target_vec;
149 nbfd = _bfd_new_bfd ();
150 if (nbfd == NULL)
151 return NULL;
153 target_vec = bfd_find_target (target, nbfd);
154 if (target_vec == NULL)
156 bfd_set_error (bfd_error_invalid_target);
157 _bfd_delete_bfd (nbfd);
158 return NULL;
161 nbfd->filename = filename;
162 nbfd->direction = read_direction;
164 if (bfd_open_file (nbfd) == NULL)
166 /* File didn't exist, or some such */
167 bfd_set_error (bfd_error_system_call);
168 _bfd_delete_bfd (nbfd);
169 return NULL;
172 return nbfd;
175 /* Don't try to `optimize' this function:
177 o - We lock using stack space so that interrupting the locking
178 won't cause a storage leak.
179 o - We open the file stream last, since we don't want to have to
180 close it if anything goes wrong. Closing the stream means closing
181 the file descriptor too, even though we didn't open it.
184 FUNCTION
185 bfd_fdopenr
187 SYNOPSIS
188 bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
190 DESCRIPTION
191 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
192 It opens a BFD on a file already described by the @var{fd}
193 supplied.
195 When the file is later <<bfd_close>>d, the file descriptor will be closed.
197 If the caller desires that this file descriptor be cached by BFD
198 (opened as needed, closed as needed to free descriptors for
199 other opens), with the supplied @var{fd} used as an initial
200 file descriptor (but subject to closure at any time), call
201 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
202 assume no cacheing; the file descriptor will remain open until
203 <<bfd_close>>, and will not be affected by BFD operations on other
204 files.
206 Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
209 bfd *
210 bfd_fdopenr (filename, target, fd)
211 const char *filename;
212 const char *target;
213 int fd;
215 bfd *nbfd;
216 const bfd_target *target_vec;
217 int fdflags;
219 bfd_set_error (bfd_error_system_call);
220 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
221 fdflags = O_RDWR; /* Assume full access */
222 #else
223 fdflags = fcntl (fd, F_GETFL, NULL);
224 #endif
225 if (fdflags == -1) return NULL;
227 nbfd = _bfd_new_bfd ();
228 if (nbfd == NULL)
229 return NULL;
231 target_vec = bfd_find_target (target, nbfd);
232 if (target_vec == NULL)
234 bfd_set_error (bfd_error_invalid_target);
235 _bfd_delete_bfd (nbfd);
236 return NULL;
239 #ifndef HAVE_FDOPEN
240 nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);
241 #else
242 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
243 switch (fdflags & (O_ACCMODE))
245 case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
246 case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
247 case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
248 default: abort ();
250 #endif
252 if (nbfd->iostream == NULL)
254 _bfd_delete_bfd (nbfd);
255 return NULL;
258 /* OK, put everything where it belongs */
260 nbfd->filename = filename;
262 /* As a special case we allow a FD open for read/write to
263 be written through, although doing so requires that we end
264 the previous clause with a preposition. */
265 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
266 switch (fdflags & (O_ACCMODE))
268 case O_RDONLY: nbfd->direction = read_direction; break;
269 case O_WRONLY: nbfd->direction = write_direction; break;
270 case O_RDWR: nbfd->direction = both_direction; break;
271 default: abort ();
274 if (! bfd_cache_init (nbfd))
276 _bfd_delete_bfd (nbfd);
277 return NULL;
279 nbfd->opened_once = true;
281 return nbfd;
285 FUNCTION
286 bfd_openstreamr
288 SYNOPSIS
289 bfd *bfd_openstreamr(const char *, const char *, PTR);
291 DESCRIPTION
293 Open a BFD for read access on an existing stdio stream. When
294 the BFD is passed to <<bfd_close>>, the stream will be closed.
297 bfd *
298 bfd_openstreamr (filename, target, streamarg)
299 const char *filename;
300 const char *target;
301 PTR streamarg;
303 FILE *stream = (FILE *) streamarg;
304 bfd *nbfd;
305 const bfd_target *target_vec;
307 nbfd = _bfd_new_bfd ();
308 if (nbfd == NULL)
309 return NULL;
311 target_vec = bfd_find_target (target, nbfd);
312 if (target_vec == NULL)
314 bfd_set_error (bfd_error_invalid_target);
315 _bfd_delete_bfd (nbfd);
316 return NULL;
319 nbfd->iostream = (PTR) stream;
320 nbfd->filename = filename;
321 nbfd->direction = read_direction;
323 if (! bfd_cache_init (nbfd))
325 _bfd_delete_bfd (nbfd);
326 return NULL;
329 return nbfd;
332 /** bfd_openw -- open for writing.
333 Returns a pointer to a freshly-allocated BFD on success, or NULL.
335 See comment by bfd_fdopenr before you try to modify this function. */
338 FUNCTION
339 bfd_openw
341 SYNOPSIS
342 bfd *bfd_openw(const char *filename, const char *target);
344 DESCRIPTION
345 Create a BFD, associated with file @var{filename}, using the
346 file format @var{target}, and return a pointer to it.
348 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
349 <<bfd_error_invalid_target>>.
352 bfd *
353 bfd_openw (filename, target)
354 const char *filename;
355 const char *target;
357 bfd *nbfd;
358 const bfd_target *target_vec;
360 bfd_set_error (bfd_error_system_call);
362 /* nbfd has to point to head of malloc'ed block so that bfd_close may
363 reclaim it correctly. */
365 nbfd = _bfd_new_bfd ();
366 if (nbfd == NULL)
367 return NULL;
369 target_vec = bfd_find_target (target, nbfd);
370 if (target_vec == NULL)
372 _bfd_delete_bfd (nbfd);
373 return NULL;
376 nbfd->filename = filename;
377 nbfd->direction = write_direction;
379 if (bfd_open_file (nbfd) == NULL)
381 bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
382 _bfd_delete_bfd (nbfd);
383 return NULL;
386 return nbfd;
391 FUNCTION
392 bfd_close
394 SYNOPSIS
395 boolean bfd_close(bfd *abfd);
397 DESCRIPTION
399 Close a BFD. If the BFD was open for writing,
400 then pending operations are completed and the file written out
401 and closed. If the created file is executable, then
402 <<chmod>> is called to mark it as such.
404 All memory attached to the BFD is released.
406 The file descriptor associated with the BFD is closed (even
407 if it was passed in to BFD by <<bfd_fdopenr>>).
409 RETURNS
410 <<true>> is returned if all is ok, otherwise <<false>>.
414 boolean
415 bfd_close (abfd)
416 bfd *abfd;
418 boolean ret;
420 if (!bfd_read_p (abfd))
422 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
423 return false;
426 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
427 return false;
429 ret = bfd_cache_close (abfd);
431 /* If the file was open for writing and is now executable,
432 make it so */
433 if (ret
434 && abfd->direction == write_direction
435 && abfd->flags & EXEC_P)
437 struct stat buf;
439 if (stat (abfd->filename, &buf) == 0)
441 unsigned int mask = umask (0);
442 umask (mask);
443 chmod (abfd->filename,
444 (0777
445 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
449 _bfd_delete_bfd (abfd);
451 return ret;
455 FUNCTION
456 bfd_close_all_done
458 SYNOPSIS
459 boolean bfd_close_all_done(bfd *);
461 DESCRIPTION
462 Close a BFD. Differs from <<bfd_close>>
463 since it does not complete any pending operations. This
464 routine would be used if the application had just used BFD for
465 swapping and didn't want to use any of the writing code.
467 If the created file is executable, then <<chmod>> is called
468 to mark it as such.
470 All memory attached to the BFD is released.
472 RETURNS
473 <<true>> is returned if all is ok, otherwise <<false>>.
477 boolean
478 bfd_close_all_done (abfd)
479 bfd *abfd;
481 boolean ret;
483 ret = bfd_cache_close (abfd);
485 /* If the file was open for writing and is now executable,
486 make it so */
487 if (ret
488 && abfd->direction == write_direction
489 && abfd->flags & EXEC_P)
491 struct stat buf;
493 if (stat (abfd->filename, &buf) == 0)
495 unsigned int mask = umask (0);
496 umask (mask);
497 chmod (abfd->filename,
498 (0777
499 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
503 _bfd_delete_bfd (abfd);
505 return ret;
509 FUNCTION
510 bfd_create
512 SYNOPSIS
513 bfd *bfd_create(const char *filename, bfd *templ);
515 DESCRIPTION
516 Create a new BFD in the manner of
517 <<bfd_openw>>, but without opening a file. The new BFD
518 takes the target from the target used by @var{template}. The
519 format is always set to <<bfd_object>>.
523 bfd *
524 bfd_create (filename, templ)
525 const char *filename;
526 bfd *templ;
528 bfd *nbfd;
530 nbfd = _bfd_new_bfd ();
531 if (nbfd == NULL)
532 return NULL;
533 nbfd->filename = filename;
534 if (templ)
535 nbfd->xvec = templ->xvec;
536 nbfd->direction = no_direction;
537 bfd_set_format (nbfd, bfd_object);
538 return nbfd;
542 FUNCTION
543 bfd_make_writable
545 SYNOPSIS
546 boolean bfd_make_writable(bfd *abfd);
548 DESCRIPTION
549 Takes a BFD as created by <<bfd_create>> and converts it
550 into one like as returned by <<bfd_openw>>. It does this
551 by converting the BFD to BFD_IN_MEMORY. It's assumed that
552 you will call <<bfd_make_readable>> on this bfd later.
554 RETURNS
555 <<true>> is returned if all is ok, otherwise <<false>>.
558 boolean
559 bfd_make_writable(abfd)
560 bfd *abfd;
562 struct bfd_in_memory *bim;
564 if (abfd->direction != no_direction)
566 bfd_set_error (bfd_error_invalid_operation);
567 return false;
570 bim = ((struct bfd_in_memory *)
571 bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
572 abfd->iostream = (PTR) bim;
573 /* bfd_bwrite will grow these as needed */
574 bim->size = 0;
575 bim->buffer = 0;
577 abfd->flags |= BFD_IN_MEMORY;
578 abfd->direction = write_direction;
579 abfd->where = 0;
581 return true;
585 FUNCTION
586 bfd_make_readable
588 SYNOPSIS
589 boolean bfd_make_readable(bfd *abfd);
591 DESCRIPTION
592 Takes a BFD as created by <<bfd_create>> and
593 <<bfd_make_writable>> and converts it into one like as
594 returned by <<bfd_openr>>. It does this by writing the
595 contents out to the memory buffer, then reversing the
596 direction.
598 RETURNS
599 <<true>> is returned if all is ok, otherwise <<false>>. */
601 boolean
602 bfd_make_readable(abfd)
603 bfd *abfd;
605 if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
607 bfd_set_error (bfd_error_invalid_operation);
608 return false;
611 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
612 return false;
614 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
615 return false;
618 abfd->arch_info = &bfd_default_arch_struct;
620 abfd->where = 0;
621 abfd->sections = (asection *) NULL;
622 abfd->format = bfd_unknown;
623 abfd->my_archive = (bfd *) NULL;
624 abfd->origin = 0;
625 abfd->opened_once = false;
626 abfd->output_has_begun = false;
627 abfd->section_count = 0;
628 abfd->usrdata = (PTR) NULL;
629 abfd->cacheable = false;
630 abfd->flags = BFD_IN_MEMORY;
631 abfd->mtime_set = false;
633 abfd->target_defaulted = true;
634 abfd->direction = read_direction;
635 abfd->sections = 0;
636 abfd->symcount = 0;
637 abfd->outsymbols = 0;
638 abfd->tdata.any = 0;
640 bfd_check_format(abfd, bfd_object);
642 return true;
646 INTERNAL_FUNCTION
647 bfd_alloc
649 SYNOPSIS
650 PTR bfd_alloc (bfd *abfd, size_t wanted);
652 DESCRIPTION
653 Allocate a block of @var{wanted} bytes of memory attached to
654 <<abfd>> and return a pointer to it.
659 bfd_alloc (abfd, size)
660 bfd *abfd;
661 bfd_size_type size;
663 PTR ret;
665 if (size != (unsigned long) size)
667 bfd_set_error (bfd_error_no_memory);
668 return NULL;
671 ret = objalloc_alloc (abfd->memory, (unsigned long) size);
672 if (ret == NULL)
673 bfd_set_error (bfd_error_no_memory);
674 return ret;
678 bfd_zalloc (abfd, size)
679 bfd *abfd;
680 bfd_size_type size;
682 PTR res;
684 res = bfd_alloc (abfd, size);
685 if (res)
686 memset (res, 0, (size_t) size);
687 return res;
690 /* Free a block allocated for a BFD.
691 Note: Also frees all more recently allocated blocks! */
693 void
694 bfd_release (abfd, block)
695 bfd *abfd;
696 PTR block;
698 objalloc_free_block ((struct objalloc *) abfd->memory, block);