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