OSDN Git Service

Update copyright notices
[pf3gnuchains/pf3gnuchains3x.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
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 /* 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.  */
43 long _bfd_chunksize = -1;
44
45 /* Return a new BFD.  All BFD's are allocated through this routine.  */
46
47 bfd *
48 _bfd_new_bfd ()
49 {
50   bfd *nbfd;
51
52   nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
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;
71   nbfd->origin = 0;                             
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
85 bfd *
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 /*
100 SECTION
101         Opening and closing BFDs
102
103 */
104
105 /*
106 FUNCTION
107         bfd_openr
108
109 SYNOPSIS
110         bfd *bfd_openr(CONST char *filename, CONST char *target);
111
112 DESCRIPTION
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
123 bfd *
124 bfd_openr (filename, target)
125      CONST char *filename;
126      CONST char *target;
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 /*
168 FUNCTION
169          bfd_fdopenr
170
171 SYNOPSIS
172          bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
173
174 DESCRIPTION
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
193 bfd *
194 bfd_fdopenr (filename, target, fd)
195      CONST char *filename;
196      CONST char *target;
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 */
252   switch (fdflags & (O_ACCMODE))
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 /*
272 FUNCTION
273         bfd_openstreamr
274
275 SYNOPSIS
276         bfd *bfd_openstreamr(const char *, const char *, PTR);
277
278 DESCRIPTION
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
284 bfd *
285 bfd_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;
310                                 
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 /*
327 FUNCTION
328         bfd_openw
329
330 SYNOPSIS
331         bfd *bfd_openw(CONST char *filename, CONST char *target);
332
333 DESCRIPTION
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
341 bfd *
342 bfd_openw (filename, target)
343      CONST char *filename;
344      CONST char *target;
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
382 FUNCTION
383         bfd_close
384
385 SYNOPSIS
386         boolean bfd_close(bfd *abfd);
387
388 DESCRIPTION
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
400 RETURNS
401         <<true>> is returned if all is ok, otherwise <<false>>.
402 */
403
404
405 boolean
406 bfd_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         {
432           int mask = umask (0);
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 /*
447 FUNCTION
448         bfd_close_all_done
449
450 SYNOPSIS
451         boolean bfd_close_all_done(bfd *);
452
453 DESCRIPTION
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
464 RETURNS
465         <<true>> is returned if all is ok, otherwise <<false>>.
466
467 */
468
469 boolean
470 bfd_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         {
487           int mask = umask (0);
488           umask (mask);
489           chmod (abfd->filename,
490                  (0777
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 /*
502 FUNCTION
503         bfd_create
504
505 SYNOPSIS
506         bfd *bfd_create(CONST char *filename, bfd *templ);
507
508 DESCRIPTION
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
516 bfd *
517 bfd_create (filename, templ)
518      CONST char *filename;
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 /*
535 FUNCTION
536         bfd_make_writable
537
538 SYNOPSIS
539         boolean bfd_make_writable(bfd *abfd);
540
541 DESCRIPTION
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
547 RETURNS
548         <<true>> is returned if all is ok, otherwise <<false>>.
549 */
550
551 boolean
552 bfd_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
563   bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory));
564   abfd->iostream = (PTR) bim;
565   /* bfd_write will grow these as needed */
566   bim->size = 0;
567   bim->buffer = 0;
568
569   abfd->flags |= BFD_IN_MEMORY;
570   abfd->direction = write_direction;
571   abfd->where = 0;
572
573   return true;
574 }
575
576 /*
577 FUNCTION
578         bfd_make_readable
579
580 SYNOPSIS
581         boolean bfd_make_readable(bfd *abfd);
582
583 DESCRIPTION
584         Takes a BFD as created by <<bfd_create>> and
585         <<bfd_make_writable>> and converts it into one like as
586         returned by <<bfd_openr>>.  It does this by writing the
587         contents out to the memory buffer, then reversing the
588         direction.
589
590 RETURNS
591         <<true>> is returned if all is ok, otherwise <<false>>.  */
592
593 boolean
594 bfd_make_readable(abfd)
595      bfd *abfd;
596 {
597   if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
598     {
599       bfd_set_error (bfd_error_invalid_operation);
600       return false;
601     }
602
603   if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
604     return false;
605
606   if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
607     return false;
608
609
610   abfd->arch_info = &bfd_default_arch_struct;
611
612   abfd->where = 0;
613   abfd->sections = (asection *) NULL;
614   abfd->format = bfd_unknown;
615   abfd->my_archive = (bfd *) NULL;
616   abfd->origin = 0;                             
617   abfd->opened_once = false;
618   abfd->output_has_begun = false;
619   abfd->section_count = 0;
620   abfd->usrdata = (PTR) NULL;
621   abfd->cacheable = false;
622   abfd->flags = BFD_IN_MEMORY;
623   abfd->mtime_set = false;
624
625   abfd->target_defaulted = true;
626   abfd->direction = read_direction;
627   abfd->sections = 0;
628   abfd->symcount = 0;
629   abfd->outsymbols = 0;
630   abfd->tdata.any = 0;
631
632   bfd_check_format(abfd, bfd_object);
633
634   return true;
635 }
636
637 /*
638 INTERNAL_FUNCTION
639         bfd_alloc
640
641 SYNOPSIS
642         PTR bfd_alloc (bfd *abfd, size_t wanted);
643
644 DESCRIPTION
645         Allocate a block of @var{wanted} bytes of memory attached to
646         <<abfd>> and return a pointer to it.
647 */
648
649
650 PTR
651 bfd_alloc (abfd, size)
652      bfd *abfd;
653      size_t size;
654 {
655   PTR ret;
656
657   ret = objalloc_alloc (abfd->memory, (unsigned long) size);
658   if (ret == NULL)
659     bfd_set_error (bfd_error_no_memory);
660   return ret;
661 }
662
663 PTR
664 bfd_zalloc (abfd, size)
665      bfd *abfd;
666      size_t size;
667 {
668   PTR res;
669
670   res = bfd_alloc (abfd, size);
671   if (res)
672     memset (res, 0, size);
673   return res;
674 }
675
676 /* Free a block allocated for a BFD.  */
677
678 void
679 bfd_release (abfd, block)
680      bfd *abfd;
681      PTR block;
682 {
683   objalloc_free_block ((struct objalloc *) abfd->memory, block);
684 }