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