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