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