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