* coff-h8300.c (reloc_howto_type): Add howto entry for
[deliverable/binutils-gdb.git] / bfd / opncls.c
CommitLineData
6724ff46 1/* opncls.c -- open and close a BFD.
b7577823 2 Copyright (C) 1990 91, 92, 93, 94, 1995 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
DHW
90 nbfd->cacheable = false;
91 nbfd->flags = 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;
4a81b561
DHW
262
263 return nbfd;
264}
123bfaa5
ILT
265
266/*
267FUNCTION
268 bfd_openstreamr
269
270SYNOPSIS
271 bfd *bfd_openstreamr();
272
273DESCRIPTION
274
275 Open a BFD for read access on an existing stdio stream. When
276 the BFD is passed to <<bfd_close>>, the stream will be closed.
277*/
278
279bfd *
280bfd_openstreamr (filename, target, stream)
281 const char *filename;
282 const char *target;
283 FILE *stream;
284{
285 bfd *nbfd;
286 const bfd_target *target_vec;
287
288 nbfd = _bfd_new_bfd ();
289 if (nbfd == NULL)
64d5f5d0 290 return NULL;
123bfaa5
ILT
291
292 target_vec = bfd_find_target (target, nbfd);
293 if (target_vec == NULL)
294 {
295 bfd_set_error (bfd_error_invalid_target);
296 return NULL;
297 }
298
64d5f5d0 299 nbfd->iostream = (PTR) stream;
123bfaa5
ILT
300 nbfd->filename = filename;
301 nbfd->direction = read_direction;
302
303 if (! bfd_cache_init (nbfd))
304 return NULL;
305
306 return nbfd;
307}
4a81b561
DHW
308\f
309/** bfd_openw -- open for writing.
6724ff46 310 Returns a pointer to a freshly-allocated BFD on success, or NULL.
4a81b561
DHW
311
312 See comment by bfd_fdopenr before you try to modify this function. */
313
b645b632
SC
314/*
315FUNCTION
316 bfd_openw
317
318SYNOPSIS
319 bfd *bfd_openw(CONST char *filename, CONST char *target);
6f715d66 320
b645b632 321DESCRIPTION
c188b0be
DM
322 Create a BFD, associated with file @var{filename}, using the
323 file format @var{target}, and return a pointer to it.
b645b632 324
9560e662
SC
325 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
326 <<bfd_error_invalid_target>>.
6f715d66
SC
327*/
328
4a81b561 329bfd *
f4bd7a8f
DM
330bfd_openw (filename, target)
331 CONST char *filename;
332 CONST char *target;
4a81b561
DHW
333{
334 bfd *nbfd;
9560e662 335 const bfd_target *target_vec;
70e00914 336
9560e662 337 bfd_set_error (bfd_error_system_call);
4a81b561
DHW
338
339 /* nbfd has to point to head of malloc'ed block so that bfd_close may
340 reclaim it correctly. */
341
f4bd7a8f 342 nbfd = _bfd_new_bfd();
64d5f5d0 343 if (nbfd == NULL)
4a81b561 344 return NULL;
4a81b561 345
c0e5039e
JG
346 target_vec = bfd_find_target (target, nbfd);
347 if (target_vec == NULL) return NULL;
348
4a81b561 349 nbfd->filename = filename;
4a81b561
DHW
350 nbfd->direction = write_direction;
351
352 if (bfd_open_file (nbfd) == NULL) {
9560e662 353 bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
fc723380 354 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
355 return NULL;
356 }
357 return nbfd;
358}
6f715d66 359
b645b632
SC
360/*
361
362FUNCTION
363 bfd_close
364
365SYNOPSIS
c188b0be 366 boolean bfd_close(bfd *abfd);
b645b632
SC
367
368DESCRIPTION
6f715d66 369
c188b0be 370 Close a BFD. If the BFD was open for writing,
b645b632
SC
371 then pending operations are completed and the file written out
372 and closed. If the created file is executable, then
373 <<chmod>> is called to mark it as such.
6f715d66 374
70e00914
KR
375 All memory attached to the BFD's obstacks is released.
376
377 The file descriptor associated with the BFD is closed (even
c188b0be 378 if it was passed in to BFD by <<bfd_fdopenr>>).
b645b632
SC
379
380RETURNS
381 <<true>> is returned if all is ok, otherwise <<false>>.
6f715d66
SC
382*/
383
b645b632 384
4a81b561 385boolean
f4bd7a8f
DM
386bfd_close (abfd)
387 bfd *abfd;
4a81b561 388{
70e00914
KR
389 boolean ret;
390
9560e662
SC
391 if (!bfd_read_p (abfd))
392 {
393 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
394 return false;
395 }
2b1d8a50 396
9560e662
SC
397 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
398 return false;
4a81b561 399
9560e662 400 ret = bfd_cache_close (abfd);
2b1d8a50
JG
401
402 /* If the file was open for writing and is now executable,
403 make it so */
9560e662 404 if (ret
70e00914 405 && abfd->direction == write_direction
9560e662
SC
406 && abfd->flags & EXEC_P)
407 {
408 struct stat buf;
409
410 if (stat (abfd->filename, &buf) == 0)
411 {
412 int mask = umask (0);
413 umask (mask);
414 chmod (abfd->filename,
415 (0777
416 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
417 }
418 }
7ed4093a 419
fc723380 420 (void) obstack_free (&abfd->memory, (PTR)0);
9560e662
SC
421 (void) free (abfd);
422
70e00914 423 return ret;
ff7ce170
PB
424}
425
b645b632
SC
426/*
427FUNCTION
428 bfd_close_all_done
429
430SYNOPSIS
431 boolean bfd_close_all_done(bfd *);
432
433DESCRIPTION
c188b0be 434 Close a BFD. Differs from <<bfd_close>>
b645b632
SC
435 since it does not complete any pending operations. This
436 routine would be used if the application had just used BFD for
437 swapping and didn't want to use any of the writing code.
ff7ce170 438
b645b632
SC
439 If the created file is executable, then <<chmod>> is called
440 to mark it as such.
ff7ce170 441
70e00914 442 All memory attached to the BFD's obstacks is released.
b645b632
SC
443
444RETURNS
445 <<true>> is returned if all is ok, otherwise <<false>>.
ff7ce170 446
ff7ce170
PB
447*/
448
449boolean
f4bd7a8f
DM
450bfd_close_all_done (abfd)
451 bfd *abfd;
ff7ce170 452{
70e00914
KR
453 boolean ret;
454
9560e662 455 ret = bfd_cache_close (abfd);
ff7ce170
PB
456
457 /* If the file was open for writing and is now executable,
458 make it so */
9560e662 459 if (ret
70e00914 460 && abfd->direction == write_direction
9560e662
SC
461 && abfd->flags & EXEC_P)
462 {
463 struct stat buf;
464
465 if (stat (abfd->filename, &buf) == 0)
466 {
467 int mask = umask (0);
468 umask (mask);
469 chmod (abfd->filename,
470 (0x777
471 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
472 }
473 }
ff7ce170
PB
474 (void) obstack_free (&abfd->memory, (PTR)0);
475 (void) free(abfd);
70e00914 476 return ret;
4a81b561 477}
fc723380 478
6f715d66 479
b645b632
SC
480/*
481FUNCTION
482 bfd_alloc_size
483
484SYNOPSIS
485 bfd_size_type bfd_alloc_size(bfd *abfd);
486
487DESCRIPTION
c188b0be 488 Return the number of bytes in the obstacks connected to @var{abfd}.
b645b632
SC
489
490*/
491
492bfd_size_type
f4bd7a8f
DM
493bfd_alloc_size (abfd)
494 bfd *abfd;
b645b632
SC
495{
496 struct _obstack_chunk *chunk = abfd->memory.chunk;
497 size_t size = 0;
498 while (chunk) {
499 size += chunk->limit - &(chunk->contents[0]);
500 chunk = chunk->prev;
501 }
502 return size;
503}
504
505
506
507/*
508FUNCTION
509 bfd_create
510
511SYNOPSIS
baf205c4 512 bfd *bfd_create(CONST char *filename, bfd *templ);
b645b632
SC
513
514DESCRIPTION
c188b0be 515 Create a new BFD in the manner of
b645b632
SC
516 <<bfd_openw>>, but without opening a file. The new BFD
517 takes the target from the target used by @var{template}. The
70e00914 518 format is always set to <<bfd_object>>.
b645b632 519
6f715d66 520*/
fc723380 521
4a81b561 522bfd *
f4bd7a8f
DM
523bfd_create (filename, templ)
524 CONST char *filename;
525 bfd *templ;
4a81b561 526{
f4bd7a8f 527 bfd *nbfd = _bfd_new_bfd();
64d5f5d0 528 if (nbfd == (bfd *)NULL)
4a81b561 529 return (bfd *)NULL;
4a81b561 530 nbfd->filename = filename;
baf205c4
JG
531 if(templ) {
532 nbfd->xvec = templ->xvec;
9872a49c 533 }
4a81b561 534 nbfd->direction = no_direction;
9872a49c 535 bfd_set_format(nbfd, bfd_object);
4a81b561 536 return nbfd;
4a81b561 537}
9872a49c 538
70e00914 539/*
b645b632
SC
540INTERNAL_FUNCTION
541 bfd_alloc_by_size_t
542
543SYNOPSIS
544 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
fc723380 545
b645b632 546DESCRIPTION
c188b0be
DM
547 Allocate a block of @var{wanted} bytes of memory in the obstack
548 attatched to <<abfd>> and return a pointer to it.
b645b632
SC
549*/
550
551
70e00914 552PTR
f4bd7a8f
DM
553bfd_alloc_by_size_t (abfd, size)
554 bfd *abfd;
555 size_t size;
7ed4093a 556{
64d5f5d0
ILT
557 PTR ret;
558
559 ret = obstack_alloc (&(abfd->memory), size);
560 if (ret == NULL)
561 bfd_set_error (bfd_error_no_memory);
562 return ret;
7ed4093a 563}
6f715d66 564
f4bd7a8f
DM
565void
566bfd_alloc_grow (abfd, ptr, size)
567 bfd *abfd;
568 PTR ptr;
569 size_t size;
6f715d66 570{
70e00914 571 (void) obstack_grow(&(abfd->memory), ptr, size);
6f715d66 572}
f4bd7a8f
DM
573
574PTR
575bfd_alloc_finish (abfd)
576 bfd *abfd;
6f715d66 577{
64d5f5d0
ILT
578 PTR ret;
579
580 ret = obstack_finish (&(abfd->memory));
581 if (ret == NULL)
582 bfd_set_error (bfd_error_no_memory);
583 return ret;
6f715d66
SC
584}
585
f4bd7a8f
DM
586PTR
587bfd_alloc (abfd, size)
588 bfd *abfd;
589 size_t size;
9872a49c 590{
7ed4093a 591 return bfd_alloc_by_size_t(abfd, (size_t)size);
9872a49c
SC
592}
593
f4bd7a8f
DM
594PTR
595bfd_zalloc (abfd, size)
596 bfd *abfd;
597 size_t size;
9872a49c 598{
70e00914
KR
599 PTR res;
600 res = bfd_alloc(abfd, size);
9783e04a
DM
601 if (res)
602 memset(res, 0, (size_t)size);
9872a49c
SC
603 return res;
604}
This page took 0.198108 seconds and 4 git commands to generate.