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