* configure: Ignore new autoconf configure options.
[binutils-gdb.git] / bfd / opncls.c
1 /* opncls.c -- open and close a BFD.
2 Copyright (C) 1990 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "obstack.h"
25
26 #ifndef S_IXUSR
27 #define S_IXUSR 0100 /* Execute by owner. */
28 #endif
29 #ifndef S_IXGRP
30 #define S_IXGRP 0010 /* Execute by group. */
31 #endif
32 #ifndef S_IXOTH
33 #define S_IXOTH 0001 /* Execute by others. */
34 #endif
35
36 /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
37 if we do that we can't use fcntl. */
38
39
40 #define obstack_chunk_alloc malloc
41 #define obstack_chunk_free free
42
43 /* Return a new BFD. All BFD's are allocated through this routine. */
44
45 bfd *
46 _bfd_new_bfd ()
47 {
48 bfd *nbfd;
49
50 nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
51 if (!nbfd)
52 {
53 bfd_set_error (bfd_error_no_memory);
54 return 0;
55 }
56
57 if (!obstack_begin(&nbfd->memory, 128))
58 {
59 bfd_set_error (bfd_error_no_memory);
60 return 0;
61 }
62
63 nbfd->arch_info = &bfd_default_arch_struct;
64
65 nbfd->direction = no_direction;
66 nbfd->iostream = NULL;
67 nbfd->where = 0;
68 nbfd->sections = (asection *)NULL;
69 nbfd->format = bfd_unknown;
70 nbfd->my_archive = (bfd *)NULL;
71 nbfd->origin = 0;
72 nbfd->opened_once = false;
73 nbfd->output_has_begun = false;
74 nbfd->section_count = 0;
75 nbfd->usrdata = (PTR)NULL;
76 nbfd->cacheable = false;
77 nbfd->flags = NO_FLAGS;
78 nbfd->mtime_set = false;
79
80 return nbfd;
81 }
82
83 /* Allocate a new BFD as a member of archive OBFD. */
84
85 bfd *
86 _bfd_new_bfd_contained_in (obfd)
87 bfd *obfd;
88 {
89 bfd *nbfd;
90
91 nbfd = _bfd_new_bfd();
92 nbfd->xvec = obfd->xvec;
93 nbfd->my_archive = obfd;
94 nbfd->direction = read_direction;
95 nbfd->target_defaulted = obfd->target_defaulted;
96 return nbfd;
97 }
98
99 /*
100 SECTION
101 Opening and closing BFDs
102
103 */
104
105 /*
106 FUNCTION
107 bfd_openr
108
109 SYNOPSIS
110 bfd *bfd_openr(CONST char *filename, CONST char *target);
111
112 DESCRIPTION
113 Open the file @var{filename} (using <<fopen>>) with the target
114 @var{target}. Return a pointer to the created BFD.
115
116 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
117 that function.
118
119 If <<NULL>> is returned then an error has occured. Possible errors
120 are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
121 */
122
123 bfd *
124 bfd_openr (filename, target)
125 CONST char *filename;
126 CONST char *target;
127 {
128 bfd *nbfd;
129 const bfd_target *target_vec;
130
131 nbfd = _bfd_new_bfd();
132 if (nbfd == NULL) {
133 bfd_set_error (bfd_error_no_memory);
134 return NULL;
135 }
136
137 target_vec = bfd_find_target (target, nbfd);
138 if (target_vec == NULL) {
139 bfd_set_error (bfd_error_invalid_target);
140 return NULL;
141 }
142
143 nbfd->filename = filename;
144 nbfd->direction = read_direction;
145
146 if (bfd_open_file (nbfd) == NULL) {
147 bfd_set_error (bfd_error_system_call); /* File didn't exist, or some such */
148 bfd_release(nbfd,0);
149 return NULL;
150 }
151 return nbfd;
152 }
153
154
155 /* Don't try to `optimize' this function:
156
157 o - We lock using stack space so that interrupting the locking
158 won't cause a storage leak.
159 o - We open the file stream last, since we don't want to have to
160 close it if anything goes wrong. Closing the stream means closing
161 the file descriptor too, even though we didn't open it.
162 */
163 /*
164 FUNCTION
165 bfd_fdopenr
166
167 SYNOPSIS
168 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
169
170 DESCRIPTION
171 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
172 It opens a BFD on a file already described by the @var{fd}
173 supplied.
174
175 When the file is later <<bfd_close>>d, the file descriptor will be closed.
176
177 If the caller desires that this file descriptor be cached by BFD
178 (opened as needed, closed as needed to free descriptors for
179 other opens), with the supplied @var{fd} used as an initial
180 file descriptor (but subject to closure at any time), call
181 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
182 assume no cacheing; the file descriptor will remain open until
183 <<bfd_close>>, and will not be affected by BFD operations on other
184 files.
185
186 Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
187 */
188
189 bfd *
190 bfd_fdopenr (filename, target, fd)
191 CONST char *filename;
192 CONST char *target;
193 int fd;
194 {
195 bfd *nbfd;
196 const bfd_target *target_vec;
197 int fdflags;
198
199 bfd_set_error (bfd_error_system_call);
200
201 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
202 fdflags = O_RDWR; /* Assume full access */
203 #else
204 fdflags = fcntl (fd, F_GETFL, NULL);
205 #endif
206 if (fdflags == -1) return NULL;
207
208 nbfd = _bfd_new_bfd();
209
210 if (nbfd == NULL) {
211 bfd_set_error (bfd_error_no_memory);
212 return NULL;
213 }
214
215 target_vec = bfd_find_target (target, nbfd);
216 if (target_vec == NULL) {
217 bfd_set_error (bfd_error_invalid_target);
218 return NULL;
219 }
220 #if defined(VMS) || defined(__GO32__) || defined (WIN32)
221 nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
222 #else
223 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
224 switch (fdflags & (O_ACCMODE)) {
225 case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
226 case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
227 case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
228 default: abort ();
229 }
230 #endif
231 if (nbfd->iostream == NULL) {
232 (void) obstack_free (&nbfd->memory, (PTR)0);
233 return NULL;
234 }
235
236 /* OK, put everything where it belongs */
237
238 nbfd->filename = filename;
239
240 /* As a special case we allow a FD open for read/write to
241 be written through, although doing so requires that we end
242 the previous clause with a preposition. */
243 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
244 switch (fdflags & (O_ACCMODE)) {
245 case O_RDONLY: nbfd->direction = read_direction; break;
246 case O_WRONLY: nbfd->direction = write_direction; break;
247 case O_RDWR: nbfd->direction = both_direction; break;
248 default: abort ();
249 }
250
251 if (! bfd_cache_init (nbfd))
252 return NULL;
253
254 return nbfd;
255 }
256
257 /*
258 FUNCTION
259 bfd_openstreamr
260
261 SYNOPSIS
262 bfd *bfd_openstreamr();
263
264 DESCRIPTION
265
266 Open a BFD for read access on an existing stdio stream. When
267 the BFD is passed to <<bfd_close>>, the stream will be closed.
268 */
269
270 bfd *
271 bfd_openstreamr (filename, target, stream)
272 const char *filename;
273 const char *target;
274 FILE *stream;
275 {
276 bfd *nbfd;
277 const bfd_target *target_vec;
278
279 nbfd = _bfd_new_bfd ();
280 if (nbfd == NULL)
281 {
282 bfd_set_error (bfd_error_no_memory);
283 return NULL;
284 }
285
286 target_vec = bfd_find_target (target, nbfd);
287 if (target_vec == NULL)
288 {
289 bfd_set_error (bfd_error_invalid_target);
290 return NULL;
291 }
292
293 nbfd->iostream = (char *) stream;
294 nbfd->filename = filename;
295 nbfd->direction = read_direction;
296
297 if (! bfd_cache_init (nbfd))
298 return NULL;
299
300 return nbfd;
301 }
302 \f
303 /** bfd_openw -- open for writing.
304 Returns a pointer to a freshly-allocated BFD on success, or NULL.
305
306 See comment by bfd_fdopenr before you try to modify this function. */
307
308 /*
309 FUNCTION
310 bfd_openw
311
312 SYNOPSIS
313 bfd *bfd_openw(CONST char *filename, CONST char *target);
314
315 DESCRIPTION
316 Create a BFD, associated with file @var{filename}, using the
317 file format @var{target}, and return a pointer to it.
318
319 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
320 <<bfd_error_invalid_target>>.
321 */
322
323 bfd *
324 bfd_openw (filename, target)
325 CONST char *filename;
326 CONST char *target;
327 {
328 bfd *nbfd;
329 const bfd_target *target_vec;
330
331 bfd_set_error (bfd_error_system_call);
332
333 /* nbfd has to point to head of malloc'ed block so that bfd_close may
334 reclaim it correctly. */
335
336 nbfd = _bfd_new_bfd();
337 if (nbfd == NULL) {
338 bfd_set_error (bfd_error_no_memory);
339 return NULL;
340 }
341
342 target_vec = bfd_find_target (target, nbfd);
343 if (target_vec == NULL) return NULL;
344
345 nbfd->filename = filename;
346 nbfd->direction = write_direction;
347
348 if (bfd_open_file (nbfd) == NULL) {
349 bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
350 (void) obstack_free (&nbfd->memory, (PTR)0);
351 return NULL;
352 }
353 return nbfd;
354 }
355
356 /*
357
358 FUNCTION
359 bfd_close
360
361 SYNOPSIS
362 boolean bfd_close(bfd *abfd);
363
364 DESCRIPTION
365
366 Close a BFD. If the BFD was open for writing,
367 then pending operations are completed and the file written out
368 and closed. If the created file is executable, then
369 <<chmod>> is called to mark it as such.
370
371 All memory attached to the BFD's obstacks is released.
372
373 The file descriptor associated with the BFD is closed (even
374 if it was passed in to BFD by <<bfd_fdopenr>>).
375
376 RETURNS
377 <<true>> is returned if all is ok, otherwise <<false>>.
378 */
379
380
381 boolean
382 bfd_close (abfd)
383 bfd *abfd;
384 {
385 boolean ret;
386
387 if (!bfd_read_p (abfd))
388 {
389 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
390 return false;
391 }
392
393 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
394 return false;
395
396 ret = bfd_cache_close (abfd);
397
398 /* If the file was open for writing and is now executable,
399 make it so */
400 if (ret
401 && abfd->direction == write_direction
402 && abfd->flags & EXEC_P)
403 {
404 struct stat buf;
405
406 if (stat (abfd->filename, &buf) == 0)
407 {
408 int mask = umask (0);
409 umask (mask);
410 chmod (abfd->filename,
411 (0777
412 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
413 }
414 }
415
416 (void) obstack_free (&abfd->memory, (PTR)0);
417 (void) free (abfd);
418
419 return ret;
420 }
421
422 /*
423 FUNCTION
424 bfd_close_all_done
425
426 SYNOPSIS
427 boolean bfd_close_all_done(bfd *);
428
429 DESCRIPTION
430 Close a BFD. Differs from <<bfd_close>>
431 since it does not complete any pending operations. This
432 routine would be used if the application had just used BFD for
433 swapping and didn't want to use any of the writing code.
434
435 If the created file is executable, then <<chmod>> is called
436 to mark it as such.
437
438 All memory attached to the BFD's obstacks is released.
439
440 RETURNS
441 <<true>> is returned if all is ok, otherwise <<false>>.
442
443 */
444
445 boolean
446 bfd_close_all_done (abfd)
447 bfd *abfd;
448 {
449 boolean ret;
450
451 ret = bfd_cache_close (abfd);
452
453 /* If the file was open for writing and is now executable,
454 make it so */
455 if (ret
456 && abfd->direction == write_direction
457 && abfd->flags & EXEC_P)
458 {
459 struct stat buf;
460
461 if (stat (abfd->filename, &buf) == 0)
462 {
463 int mask = umask (0);
464 umask (mask);
465 chmod (abfd->filename,
466 (0x777
467 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
468 }
469 }
470 (void) obstack_free (&abfd->memory, (PTR)0);
471 (void) free(abfd);
472 return ret;
473 }
474
475
476 /*
477 FUNCTION
478 bfd_alloc_size
479
480 SYNOPSIS
481 bfd_size_type bfd_alloc_size(bfd *abfd);
482
483 DESCRIPTION
484 Return the number of bytes in the obstacks connected to @var{abfd}.
485
486 */
487
488 bfd_size_type
489 bfd_alloc_size (abfd)
490 bfd *abfd;
491 {
492 struct _obstack_chunk *chunk = abfd->memory.chunk;
493 size_t size = 0;
494 while (chunk) {
495 size += chunk->limit - &(chunk->contents[0]);
496 chunk = chunk->prev;
497 }
498 return size;
499 }
500
501
502
503 /*
504 FUNCTION
505 bfd_create
506
507 SYNOPSIS
508 bfd *bfd_create(CONST char *filename, bfd *templ);
509
510 DESCRIPTION
511 Create a new BFD in the manner of
512 <<bfd_openw>>, but without opening a file. The new BFD
513 takes the target from the target used by @var{template}. The
514 format is always set to <<bfd_object>>.
515
516 */
517
518 bfd *
519 bfd_create (filename, templ)
520 CONST char *filename;
521 bfd *templ;
522 {
523 bfd *nbfd = _bfd_new_bfd();
524 if (nbfd == (bfd *)NULL) {
525 bfd_set_error (bfd_error_no_memory);
526 return (bfd *)NULL;
527 }
528 nbfd->filename = filename;
529 if(templ) {
530 nbfd->xvec = templ->xvec;
531 }
532 nbfd->direction = no_direction;
533 bfd_set_format(nbfd, bfd_object);
534 return nbfd;
535 }
536
537 /*
538 INTERNAL_FUNCTION
539 bfd_alloc_by_size_t
540
541 SYNOPSIS
542 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
543
544 DESCRIPTION
545 Allocate a block of @var{wanted} bytes of memory in the obstack
546 attatched to <<abfd>> and return a pointer to it.
547 */
548
549
550 PTR
551 bfd_alloc_by_size_t (abfd, size)
552 bfd *abfd;
553 size_t size;
554 {
555 return obstack_alloc(&(abfd->memory), size);
556 }
557
558 void
559 bfd_alloc_grow (abfd, ptr, size)
560 bfd *abfd;
561 PTR ptr;
562 size_t size;
563 {
564 (void) obstack_grow(&(abfd->memory), ptr, size);
565 }
566
567 PTR
568 bfd_alloc_finish (abfd)
569 bfd *abfd;
570 {
571 return obstack_finish(&(abfd->memory));
572 }
573
574 PTR
575 bfd_alloc (abfd, size)
576 bfd *abfd;
577 size_t size;
578 {
579 return bfd_alloc_by_size_t(abfd, (size_t)size);
580 }
581
582 PTR
583 bfd_zalloc (abfd, size)
584 bfd *abfd;
585 size_t size;
586 {
587 PTR res;
588 res = bfd_alloc(abfd, size);
589 if (res)
590 memset(res, 0, (size_t)size);
591 return res;
592 }