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