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