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