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. */
27 extern void bfd_cache_init();
28 FILE *bfd_open_file();
30 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
31 if we do that we can't use fcntl. */
34 #define obstack_chunk_alloc bfd_xmalloc
35 #define obstack_chunk_free free
37 /* Return a new BFD. All BFD's are allocated through this routine. */
43 nbfd = (bfd *)zalloc (sizeof (bfd));
48 obstack_begin((PTR)&nbfd->memory, 128);
50 nbfd->arch_info = &bfd_default_arch_struct;
52 nbfd->direction = no_direction;
53 nbfd->iostream = NULL;
55 nbfd->sections = (asection *)NULL;
56 nbfd->format = bfd_unknown;
57 nbfd->my_archive = (bfd *)NULL;
59 nbfd->opened_once = false;
60 nbfd->output_has_begun = false;
61 nbfd->section_count = 0;
62 nbfd->usrdata = (PTR)NULL;
63 nbfd->sections = (asection *)NULL;
64 nbfd->cacheable = false;
65 nbfd->flags = NO_FLAGS;
66 nbfd->mtime_set = false;
72 /* Allocate a new BFD as a member of archive OBFD. */
74 bfd *new_bfd_contained_in(obfd)
77 bfd *nbfd = new_bfd();
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 This function opens the file supplied (using <<fopen>>) with the target
100 supplied, it returns 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.
107 DEFUN(bfd_openr, (filename, target),
108 CONST char *filename AND
112 bfd_target *target_vec;
116 bfd_error = no_memory;
120 target_vec = bfd_find_target (target, nbfd);
121 if (target_vec == NULL) {
122 bfd_error = invalid_target;
126 nbfd->filename = filename;
127 nbfd->direction = read_direction;
129 if (bfd_open_file (nbfd) == NULL) {
130 bfd_error = system_call_error; /* File didn't exist, or some such */
138 /* Don't try to `optimize' this function:
140 o - We lock using stack space so that interrupting the locking
141 won't cause a storage leak.
142 o - We open the file stream last, since we don't want to have to
143 close it if anything goes wrong. Closing the stream means closing
144 the file descriptor too, even though we didn't open it.
151 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
154 bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen.
155 It opens a BFD on a file already described by the @var{fd}
158 Possible errors are no_memory, invalid_target and system_call
163 DEFUN(bfd_fdopenr,(filename, target, fd),
164 CONST char *filename AND
165 CONST char *target AND
169 bfd_target *target_vec;
172 bfd_error = system_call_error;
175 fdflags = O_RDWR; /* Assume full access */
177 fdflags = fcntl (fd, F_GETFL, NULL);
179 if (fdflags == -1) return NULL;
184 bfd_error = no_memory;
188 target_vec = bfd_find_target (target, nbfd);
189 if (target_vec == NULL) {
190 bfd_error = invalid_target;
194 #ifdef FASCIST_FDOPEN
195 nbfd->iostream = (char *) fdopen (fd, FOPEN_RB);
197 /* if the fd were open for read only, this still would not hurt: */
198 nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB);
200 if (nbfd->iostream == NULL) {
201 (void) obstack_free (&nbfd->memory, (PTR)0);
205 /* OK, put everything where it belongs */
207 nbfd->filename = filename;
209 /* As a special case we allow a FD open for read/write to
210 be written through, although doing so requires that we end
211 the previous clause with a preposition. */
212 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
213 switch (fdflags & (O_ACCMODE)) {
214 case O_RDONLY: nbfd->direction = read_direction; break;
215 case O_WRONLY: nbfd->direction = write_direction; break;
216 case O_RDWR: nbfd->direction = both_direction; break;
220 bfd_cache_init (nbfd);
225 /** bfd_openw -- open for writing.
226 Returns a pointer to a freshly-allocated BFD on success, or NULL.
228 See comment by bfd_fdopenr before you try to modify this function. */
235 bfd *bfd_openw(CONST char *filename, CONST char *target);
238 Creates a BFD, associated with file @var{filename}, using the
239 file format @var{target}, and returns a pointer to it.
241 Possible errors are system_call_error, no_memory,
246 DEFUN(bfd_openw,(filename, target),
247 CONST char *filename AND
251 bfd_target *target_vec;
253 bfd_error = system_call_error;
255 /* nbfd has to point to head of malloc'ed block so that bfd_close may
256 reclaim it correctly. */
260 bfd_error = no_memory;
264 target_vec = bfd_find_target (target, nbfd);
265 if (target_vec == NULL) return NULL;
267 nbfd->filename = filename;
268 nbfd->direction = write_direction;
270 if (bfd_open_file (nbfd) == NULL) {
271 bfd_error = system_call_error; /* File not writeable, etc */
272 (void) obstack_free (&nbfd->memory, (PTR)0);
284 boolean bfd_close(bfd *);
288 This function closes a BFD. If the BFD was open for writing,
289 then pending operations are completed and the file written out
290 and closed. If the created file is executable, then
291 <<chmod>> is called to mark it as such.
293 All memory attached to the BFD's obstacks is released.
296 <<true>> is returned if all is ok, otherwise <<false>>.
301 DEFUN(bfd_close,(abfd),
304 if (!bfd_read_p(abfd))
305 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
308 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
310 bfd_cache_close(abfd);
312 /* If the file was open for writing and is now executable,
314 if (abfd->direction == write_direction
315 && abfd->flags & EXEC_P) {
317 stat(abfd->filename, &buf);
319 #define S_IXUSR 0100 /* Execute by owner. */
322 #define S_IXGRP 0010 /* Execute by group. */
325 #define S_IXOTH 0001 /* Execute by others. */
328 chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
330 (void) obstack_free (&abfd->memory, (PTR)0);
340 boolean bfd_close_all_done(bfd *);
343 This function closes a BFD. It differs from <<bfd_close>>
344 since it does not complete any pending operations. This
345 routine would be used if the application had just used BFD for
346 swapping and didn't want to use any of the writing code.
348 If the created file is executable, then <<chmod>> is called
351 All memory attached to the BFD's obstacks is released.
354 <<true>> is returned if all is ok, otherwise <<false>>.
359 DEFUN(bfd_close_all_done,(abfd),
362 bfd_cache_close(abfd);
364 /* If the file was open for writing and is now executable,
366 if (abfd->direction == write_direction
367 && abfd->flags & EXEC_P) {
369 stat(abfd->filename, &buf);
371 #define S_IXUSR 0100 /* Execute by owner. */
374 #define S_IXGRP 0010 /* Execute by group. */
377 #define S_IXOTH 0001 /* Execute by others. */
380 chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
382 (void) obstack_free (&abfd->memory, (PTR)0);
393 bfd_size_type bfd_alloc_size(bfd *abfd);
396 Return the number of bytes in the obstacks connected to the
402 DEFUN(bfd_alloc_size,(abfd),
405 struct _obstack_chunk *chunk = abfd->memory.chunk;
408 size += chunk->limit - &(chunk->contents[0]);
421 bfd *bfd_create(CONST char *filename, bfd *template);
424 This routine creates a new BFD in the manner of
425 <<bfd_openw>>, but without opening a file. The new BFD
426 takes the target from the target used by @var{template}. The
427 format is always set to <<bfd_object>>.
432 DEFUN(bfd_create,(filename, template),
433 CONST char *filename AND
436 bfd *nbfd = new_bfd();
437 if (nbfd == (bfd *)NULL) {
438 bfd_error = no_memory;
441 nbfd->filename = filename;
443 nbfd->xvec = template->xvec;
445 nbfd->direction = no_direction;
446 bfd_set_format(nbfd, bfd_object);
455 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
458 This function allocates a block of memory in the obstack
459 attatched to <<abfd>> and returns a pointer to it.
464 DEFUN(bfd_alloc_by_size_t,(abfd, size),
468 PTR res = obstack_alloc(&(abfd->memory), size);
472 DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
477 (void) obstack_grow(&(abfd->memory), ptr, size);
479 DEFUN(PTR bfd_alloc_finish,(abfd),
482 return obstack_finish(&(abfd->memory));
485 DEFUN(PTR bfd_alloc, (abfd, size),
489 return bfd_alloc_by_size_t(abfd, (size_t)size);
492 DEFUN(PTR bfd_zalloc,(abfd, size),
496 PTR res = bfd_alloc(abfd, size);
497 memset(res, 0, (size_t)size);
501 DEFUN(PTR bfd_realloc,(abfd, old, size),
506 PTR res = bfd_alloc(abfd, size);
507 memcpy(res, old, (size_t)size);