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