1 /* opncls.c -- open and close a BFD.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 extern void bfd_cache_init PARAMS ((bfd *));
26 FILE *bfd_open_file PARAMS ((bfd *));
28 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
29 if we do that we can't use fcntl. */
32 #define obstack_chunk_alloc bfd_xmalloc_by_size_t
33 #define obstack_chunk_free free
35 /* Return a new BFD. All BFD's are allocated through this routine. */
38 new_bfd PARAMS ((void))
42 nbfd = (bfd *)zalloc (sizeof (bfd));
47 obstack_begin((PTR)&nbfd->memory, 128);
49 nbfd->arch_info = &bfd_default_arch_struct;
51 nbfd->direction = no_direction;
52 nbfd->iostream = NULL;
54 nbfd->sections = (asection *)NULL;
55 nbfd->format = bfd_unknown;
56 nbfd->my_archive = (bfd *)NULL;
58 nbfd->opened_once = false;
59 nbfd->output_has_begun = false;
60 nbfd->section_count = 0;
61 nbfd->usrdata = (PTR)NULL;
62 nbfd->cacheable = false;
63 nbfd->flags = NO_FLAGS;
64 nbfd->mtime_set = false;
69 /* Allocate a new BFD as a member of archive OBFD. */
72 new_bfd_contained_in (obfd)
78 nbfd->xvec = obfd->xvec;
79 nbfd->my_archive = obfd;
80 nbfd->direction = read_direction;
81 nbfd->target_defaulted = obfd->target_defaulted;
87 Opening and Closing BFDs
96 bfd *bfd_openr(CONST char *filename, CONST char *target);
99 Open the file @var{filename} (using <<fopen>>) with the target
100 @var{target}. Return a pointer to the created BFD.
102 If NULL is returned then an error has occured. Possible errors
103 are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
105 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
110 DEFUN(bfd_openr, (filename, target),
111 CONST char *filename AND
115 bfd_target *target_vec;
119 bfd_error = no_memory;
123 target_vec = bfd_find_target (target, nbfd);
124 if (target_vec == NULL) {
125 bfd_error = invalid_target;
129 nbfd->filename = filename;
130 nbfd->direction = read_direction;
132 if (bfd_open_file (nbfd) == NULL) {
133 bfd_error = system_call_error; /* File didn't exist, or some such */
141 /* Don't try to `optimize' this function:
143 o - We lock using stack space so that interrupting the locking
144 won't cause a storage leak.
145 o - We open the file stream last, since we don't want to have to
146 close it if anything goes wrong. Closing the stream means closing
147 the file descriptor too, even though we didn't open it.
154 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
157 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
158 It opens a BFD on a file already described by the @var{fd}
161 When the file is later <<bfd_close>>d, the file descriptor will be closed.
163 If the caller desires that this file descriptor be cached by BFD
164 (opened as needed, closed as needed to free descriptors for
165 other opens), with the supplied @var{fd} used as an initial
166 file descriptor (but subject to closure at any time), call
167 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
168 assume no cacheing; the file descriptor will remain open until
169 <<bfd_close>>, and will not be affected by BFD operations on other
172 Possible errors are <<no_memory>>, <<invalid_target>> and <<system_call_error>>.
176 DEFUN(bfd_fdopenr,(filename, target, fd),
177 CONST char *filename AND
178 CONST char *target AND
182 bfd_target *target_vec;
185 bfd_error = system_call_error;
188 fdflags = O_RDWR; /* Assume full access */
190 fdflags = fcntl (fd, F_GETFL, NULL);
192 if (fdflags == -1) return NULL;
197 bfd_error = no_memory;
201 target_vec = bfd_find_target (target, nbfd);
202 if (target_vec == NULL) {
203 bfd_error = invalid_target;
206 #if defined(VMS) || defined(__GO32__)
207 nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
209 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
210 switch (fdflags & (O_ACCMODE)) {
211 case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
212 case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
213 case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
217 if (nbfd->iostream == NULL) {
218 (void) obstack_free (&nbfd->memory, (PTR)0);
222 /* OK, put everything where it belongs */
224 nbfd->filename = filename;
226 /* As a special case we allow a FD open for read/write to
227 be written through, although doing so requires that we end
228 the previous clause with a preposition. */
229 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
230 switch (fdflags & (O_ACCMODE)) {
231 case O_RDONLY: nbfd->direction = read_direction; break;
232 case O_WRONLY: nbfd->direction = write_direction; break;
233 case O_RDWR: nbfd->direction = both_direction; break;
237 bfd_cache_init (nbfd);
242 /** bfd_openw -- open for writing.
243 Returns a pointer to a freshly-allocated BFD on success, or NULL.
245 See comment by bfd_fdopenr before you try to modify this function. */
252 bfd *bfd_openw(CONST char *filename, CONST char *target);
255 Create a BFD, associated with file @var{filename}, using the
256 file format @var{target}, and return a pointer to it.
258 Possible errors are <<system_call_error>>, <<no_memory>>,
263 DEFUN(bfd_openw,(filename, target),
264 CONST char *filename AND
268 bfd_target *target_vec;
270 bfd_error = system_call_error;
272 /* nbfd has to point to head of malloc'ed block so that bfd_close may
273 reclaim it correctly. */
277 bfd_error = no_memory;
281 target_vec = bfd_find_target (target, nbfd);
282 if (target_vec == NULL) return NULL;
284 nbfd->filename = filename;
285 nbfd->direction = write_direction;
287 if (bfd_open_file (nbfd) == NULL) {
288 bfd_error = system_call_error; /* File not writeable, etc */
289 (void) obstack_free (&nbfd->memory, (PTR)0);
301 boolean bfd_close(bfd *abfd);
305 Close a BFD. If the BFD was open for writing,
306 then pending operations are completed and the file written out
307 and closed. If the created file is executable, then
308 <<chmod>> is called to mark it as such.
310 All memory attached to the BFD's obstacks is released.
312 The file descriptor associated with the BFD is closed (even
313 if it was passed in to BFD by <<bfd_fdopenr>>).
316 <<true>> is returned if all is ok, otherwise <<false>>.
321 DEFUN(bfd_close,(abfd),
326 if (!bfd_read_p(abfd))
327 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
330 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
332 ret = bfd_cache_close(abfd);
334 /* If the file was open for writing and is now executable,
337 && abfd->direction == write_direction
338 && abfd->flags & EXEC_P) {
340 stat(abfd->filename, &buf);
342 #define S_IXUSR 0100 /* Execute by owner. */
345 #define S_IXGRP 0010 /* Execute by group. */
348 #define S_IXOTH 0001 /* Execute by others. */
351 chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
353 (void) obstack_free (&abfd->memory, (PTR)0);
363 boolean bfd_close_all_done(bfd *);
366 Close a BFD. Differs from <<bfd_close>>
367 since it does not complete any pending operations. This
368 routine would be used if the application had just used BFD for
369 swapping and didn't want to use any of the writing code.
371 If the created file is executable, then <<chmod>> is called
374 All memory attached to the BFD's obstacks is released.
377 <<true>> is returned if all is ok, otherwise <<false>>.
382 DEFUN(bfd_close_all_done,(abfd),
387 ret = bfd_cache_close(abfd);
389 /* If the file was open for writing and is now executable,
392 && abfd->direction == write_direction
393 && abfd->flags & EXEC_P) {
395 stat(abfd->filename, &buf);
397 #define S_IXUSR 0100 /* Execute by owner. */
400 #define S_IXGRP 0010 /* Execute by group. */
403 #define S_IXOTH 0001 /* Execute by others. */
406 chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
408 (void) obstack_free (&abfd->memory, (PTR)0);
419 bfd_size_type bfd_alloc_size(bfd *abfd);
422 Return the number of bytes in the obstacks connected to @var{abfd}.
427 DEFUN(bfd_alloc_size,(abfd),
430 struct _obstack_chunk *chunk = abfd->memory.chunk;
433 size += chunk->limit - &(chunk->contents[0]);
446 bfd *bfd_create(CONST char *filename, bfd *templ);
449 Create a new BFD in the manner of
450 <<bfd_openw>>, but without opening a file. The new BFD
451 takes the target from the target used by @var{template}. The
452 format is always set to <<bfd_object>>.
457 DEFUN(bfd_create,(filename, templ),
458 CONST char *filename AND
461 bfd *nbfd = new_bfd();
462 if (nbfd == (bfd *)NULL) {
463 bfd_error = no_memory;
466 nbfd->filename = filename;
468 nbfd->xvec = templ->xvec;
470 nbfd->direction = no_direction;
471 bfd_set_format(nbfd, bfd_object);
480 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
483 Allocate a block of @var{wanted} bytes of memory in the obstack
484 attatched to <<abfd>> and return a pointer to it.
489 DEFUN(bfd_alloc_by_size_t,(abfd, size),
493 PTR res = obstack_alloc(&(abfd->memory), size);
497 DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
502 (void) obstack_grow(&(abfd->memory), ptr, size);
504 DEFUN(PTR bfd_alloc_finish,(abfd),
507 return obstack_finish(&(abfd->memory));
510 DEFUN(PTR bfd_alloc, (abfd, size),
514 return bfd_alloc_by_size_t(abfd, (size_t)size);
517 DEFUN(PTR bfd_zalloc,(abfd, size),
522 res = bfd_alloc(abfd, size);
523 memset(res, 0, (size_t)size);
527 DEFUN(PTR bfd_realloc,(abfd, old, size),
532 PTR res = bfd_alloc(abfd, size);
533 memcpy(res, old, (size_t)size);