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