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