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