* init.c (initialized): Remove static variable.
[platform/upstream/binutils.git] / bfd / opncls.c
1 /* opncls.c -- open and close a BFD.
2    Copyright (C) 1990 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "obstack.h"
25
26 #ifndef S_IXUSR
27 #define S_IXUSR 0100    /* Execute by owner.  */
28 #endif
29 #ifndef S_IXGRP
30 #define S_IXGRP 0010    /* Execute by group.  */
31 #endif
32 #ifndef S_IXOTH
33 #define S_IXOTH 0001    /* Execute by others.  */
34 #endif
35
36 /* fdopen is a loser -- we should use stdio exclusively.  Unfortunately
37    if we do that we can't use fcntl.  */
38
39
40 #define obstack_chunk_alloc malloc
41 #define obstack_chunk_free free
42
43 /* Return a new BFD.  All BFD's are allocated through this routine.  */
44
45 bfd *
46 _bfd_new_bfd ()
47 {
48   bfd *nbfd;
49
50   nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
51   if (!nbfd)
52     {
53       bfd_set_error (bfd_error_no_memory);
54       return 0;
55     }
56
57   if (!obstack_begin(&nbfd->memory, 128))
58     {
59       bfd_set_error (bfd_error_no_memory);
60       return 0;
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 = 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     bfd_set_error (bfd_error_no_memory);
134     return NULL;
135   }
136
137   target_vec = bfd_find_target (target, nbfd);
138   if (target_vec == NULL) {
139     bfd_set_error (bfd_error_invalid_target);
140     return NULL;
141   }
142
143   nbfd->filename = filename;
144   nbfd->direction = read_direction;
145
146   if (bfd_open_file (nbfd) == NULL) {
147     bfd_set_error (bfd_error_system_call);      /* File didn't exist, or some such */
148     bfd_release(nbfd,0);
149     return NULL;
150   }
151   return nbfd;
152 }
153
154
155 /* Don't try to `optimize' this function:
156
157    o - We lock using stack space so that interrupting the locking
158        won't cause a storage leak.
159    o - We open the file stream last, since we don't want to have to
160        close it if anything goes wrong.  Closing the stream means closing
161        the file descriptor too, even though we didn't open it.
162  */
163 /*
164 FUNCTION
165          bfd_fdopenr
166
167 SYNOPSIS
168          bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
169
170 DESCRIPTION
171          <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
172          It opens a BFD on a file already described by the @var{fd}
173          supplied.
174
175          When the file is later <<bfd_close>>d, the file descriptor will be closed.
176
177          If the caller desires that this file descriptor be cached by BFD
178          (opened as needed, closed as needed to free descriptors for
179          other opens), with the supplied @var{fd} used as an initial
180          file descriptor (but subject to closure at any time), call
181          bfd_set_cacheable(bfd, 1) on the returned BFD.  The default is to
182          assume no cacheing; the file descriptor will remain open until
183          <<bfd_close>>, and will not be affected by BFD operations on other
184          files.
185
186          Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
187 */
188
189 bfd *
190 bfd_fdopenr (filename, target, fd)
191      CONST char *filename;
192      CONST char *target;
193      int fd;
194 {
195   bfd *nbfd;
196   const bfd_target *target_vec;
197   int fdflags;
198
199   bfd_set_error (bfd_error_system_call);
200
201 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
202   fdflags = O_RDWR;                     /* Assume full access */
203 #else
204   fdflags = fcntl (fd, F_GETFL, NULL);
205 #endif
206   if (fdflags == -1) return NULL;
207
208   nbfd = _bfd_new_bfd();
209
210   if (nbfd == NULL) {
211     bfd_set_error (bfd_error_no_memory);
212     return NULL;
213   }
214
215   target_vec = bfd_find_target (target, nbfd);
216   if (target_vec == NULL) {
217     bfd_set_error (bfd_error_invalid_target);
218     return NULL;
219   }
220 #if defined(VMS) || defined(__GO32__) || defined (WIN32)
221   nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
222 #else
223   /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
224   switch (fdflags & (O_ACCMODE)) {
225   case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB);   break;
226   case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB);  break;
227   case O_RDWR:   nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB);  break;
228   default: abort ();
229   }
230 #endif
231   if (nbfd->iostream == NULL) {
232     (void) obstack_free (&nbfd->memory, (PTR)0);
233     return NULL;
234   }
235
236   /* OK, put everything where it belongs */
237
238   nbfd->filename = filename;
239
240   /* As a special case we allow a FD open for read/write to
241      be written through, although doing so requires that we end
242      the previous clause with a preposition.  */
243   /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
244   switch (fdflags & (O_ACCMODE)) {
245   case O_RDONLY: nbfd->direction = read_direction; break;
246   case O_WRONLY: nbfd->direction = write_direction; break;
247   case O_RDWR: nbfd->direction = both_direction; break;
248   default: abort ();
249   }
250                                 
251   if (! bfd_cache_init (nbfd))
252     return NULL;
253
254   return nbfd;
255 }
256
257 /*
258 FUNCTION
259         bfd_openstreamr
260
261 SYNOPSIS
262         bfd *bfd_openstreamr();
263
264 DESCRIPTION
265
266         Open a BFD for read access on an existing stdio stream.  When
267         the BFD is passed to <<bfd_close>>, the stream will be closed.
268 */
269
270 bfd *
271 bfd_openstreamr (filename, target, stream)
272      const char *filename;
273      const char *target;
274      FILE *stream;
275 {
276   bfd *nbfd;
277   const bfd_target *target_vec;
278
279   nbfd = _bfd_new_bfd ();
280   if (nbfd == NULL)
281     {
282       bfd_set_error (bfd_error_no_memory);
283       return NULL;
284     }
285
286   target_vec = bfd_find_target (target, nbfd);
287   if (target_vec == NULL)
288     {
289       bfd_set_error (bfd_error_invalid_target);
290       return NULL;
291     }
292
293   nbfd->iostream = (char *) stream;
294   nbfd->filename = filename;
295   nbfd->direction = read_direction;
296                                 
297   if (! bfd_cache_init (nbfd))
298     return NULL;
299
300   return nbfd;
301 }
302 \f
303 /** bfd_openw -- open for writing.
304   Returns a pointer to a freshly-allocated BFD on success, or NULL.
305
306   See comment by bfd_fdopenr before you try to modify this function. */
307
308 /*
309 FUNCTION
310         bfd_openw
311
312 SYNOPSIS
313         bfd *bfd_openw(CONST char *filename, CONST char *target);
314
315 DESCRIPTION
316         Create a BFD, associated with file @var{filename}, using the
317         file format @var{target}, and return a pointer to it.
318
319         Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
320         <<bfd_error_invalid_target>>.
321 */
322
323 bfd *
324 bfd_openw (filename, target)
325      CONST char *filename;
326      CONST char *target;
327 {
328   bfd *nbfd;
329   const bfd_target *target_vec;
330
331   bfd_set_error (bfd_error_system_call);
332
333   /* nbfd has to point to head of malloc'ed block so that bfd_close may
334      reclaim it correctly. */
335
336   nbfd = _bfd_new_bfd();
337   if (nbfd == NULL) {
338     bfd_set_error (bfd_error_no_memory);
339     return NULL;
340   }
341
342   target_vec = bfd_find_target (target, nbfd);
343   if (target_vec == NULL) return NULL;
344
345   nbfd->filename = filename;
346   nbfd->direction = write_direction;
347
348   if (bfd_open_file (nbfd) == NULL) {
349     bfd_set_error (bfd_error_system_call);      /* File not writeable, etc */
350     (void) obstack_free (&nbfd->memory, (PTR)0);
351     return NULL;
352   }
353   return nbfd;
354 }
355
356 /*
357
358 FUNCTION
359         bfd_close
360
361 SYNOPSIS
362         boolean bfd_close(bfd *abfd);
363
364 DESCRIPTION
365
366         Close a BFD. If the BFD was open for writing,
367         then pending operations are completed and the file written out
368         and closed. If the created file is executable, then
369         <<chmod>> is called to mark it as such.
370
371         All memory attached to the BFD's obstacks is released.
372
373         The file descriptor associated with the BFD is closed (even
374         if it was passed in to BFD by <<bfd_fdopenr>>).
375
376 RETURNS
377         <<true>> is returned if all is ok, otherwise <<false>>.
378 */
379
380
381 boolean
382 bfd_close (abfd)
383      bfd *abfd;
384 {
385   boolean ret;
386
387   if (!bfd_read_p (abfd))
388     {
389       if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
390         return false;
391     }
392
393   if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
394     return false;
395
396   ret = bfd_cache_close (abfd);
397
398   /* If the file was open for writing and is now executable,
399      make it so */
400   if (ret
401       && abfd->direction == write_direction
402       && abfd->flags & EXEC_P)
403     {
404       struct stat buf;
405
406       if (stat (abfd->filename, &buf) == 0)
407         {
408           int mask = umask (0);
409           umask (mask);
410           chmod (abfd->filename,
411                  (0777
412                   & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
413         }
414     }
415
416   (void) obstack_free (&abfd->memory, (PTR)0);
417   (void) free (abfd);
418
419   return ret;
420 }
421
422 /*
423 FUNCTION
424         bfd_close_all_done
425
426 SYNOPSIS
427         boolean bfd_close_all_done(bfd *);
428
429 DESCRIPTION
430         Close a BFD.  Differs from <<bfd_close>>
431         since it does not complete any pending operations.  This
432         routine would be used if the application had just used BFD for
433         swapping and didn't want to use any of the writing code.
434
435         If the created file is executable, then <<chmod>> is called
436         to mark it as such.
437
438         All memory attached to the BFD's obstacks is released.
439
440 RETURNS
441         <<true>> is returned if all is ok, otherwise <<false>>.
442
443 */
444
445 boolean
446 bfd_close_all_done (abfd)
447      bfd *abfd;
448 {
449   boolean ret;
450
451   ret = bfd_cache_close (abfd);
452
453   /* If the file was open for writing and is now executable,
454      make it so */
455   if (ret
456       && abfd->direction == write_direction
457       && abfd->flags & EXEC_P)
458     {
459       struct stat buf;
460
461       if (stat (abfd->filename, &buf) == 0)
462         {
463           int mask = umask (0);
464           umask (mask);
465           chmod (abfd->filename,
466                  (0x777
467                   & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
468         }
469     }
470   (void) obstack_free (&abfd->memory, (PTR)0);
471   (void) free(abfd);
472   return ret;
473 }
474
475
476 /*
477 FUNCTION        
478         bfd_alloc_size
479
480 SYNOPSIS
481         bfd_size_type bfd_alloc_size(bfd *abfd);
482
483 DESCRIPTION
484         Return the number of bytes in the obstacks connected to @var{abfd}.
485
486 */
487
488 bfd_size_type
489 bfd_alloc_size (abfd)
490      bfd *abfd;
491 {
492   struct _obstack_chunk *chunk = abfd->memory.chunk;
493   size_t size = 0;
494   while (chunk) {
495     size += chunk->limit - &(chunk->contents[0]);
496     chunk = chunk->prev;
497   }
498   return size;
499 }
500
501
502
503 /*
504 FUNCTION
505         bfd_create
506
507 SYNOPSIS
508         bfd *bfd_create(CONST char *filename, bfd *templ);
509
510 DESCRIPTION
511         Create a new BFD in the manner of
512         <<bfd_openw>>, but without opening a file. The new BFD
513         takes the target from the target used by @var{template}. The
514         format is always set to <<bfd_object>>.
515
516 */
517
518 bfd *
519 bfd_create (filename, templ)
520      CONST char *filename;
521      bfd *templ;
522 {
523   bfd *nbfd = _bfd_new_bfd();
524   if (nbfd == (bfd *)NULL) {
525     bfd_set_error (bfd_error_no_memory);
526     return (bfd *)NULL;
527   }
528   nbfd->filename = filename;
529   if(templ) {
530     nbfd->xvec = templ->xvec;
531   }
532   nbfd->direction = no_direction;
533   bfd_set_format(nbfd, bfd_object);
534   return nbfd;
535 }
536
537 /*
538 INTERNAL_FUNCTION
539         bfd_alloc_by_size_t
540
541 SYNOPSIS
542         PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
543
544 DESCRIPTION
545         Allocate a block of @var{wanted} bytes of memory in the obstack
546         attatched to <<abfd>> and return a pointer to it.
547 */
548
549
550 PTR
551 bfd_alloc_by_size_t (abfd, size)
552      bfd *abfd;
553      size_t size;
554 {
555   return obstack_alloc(&(abfd->memory), size);
556 }
557
558 void
559 bfd_alloc_grow (abfd, ptr, size)
560      bfd *abfd;
561      PTR ptr;
562      size_t size;
563 {
564   (void) obstack_grow(&(abfd->memory), ptr, size);
565 }
566
567 PTR
568 bfd_alloc_finish (abfd)
569      bfd *abfd;
570 {
571   return obstack_finish(&(abfd->memory));
572 }
573
574 PTR
575 bfd_alloc (abfd, size)
576      bfd *abfd;
577      size_t size;
578 {
579   return bfd_alloc_by_size_t(abfd, (size_t)size);
580 }
581
582 PTR
583 bfd_zalloc (abfd, size)
584      bfd *abfd;
585      size_t size;
586 {
587   PTR res;
588   res = bfd_alloc(abfd, size);
589   if (res)
590     memset(res, 0, (size_t)size);
591   return res;
592 }