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