Stricter prototyping, to force type conversions between 64-bit target and
[deliverable/binutils-gdb.git] / bfd / opncls.c
CommitLineData
6724ff46
RP
1/* opncls.c -- open and close a BFD.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
fc723380 4
6724ff46 5This file is part of BFD, the Binary File Descriptor library.
4a81b561 6
6724ff46 7This program is free software; you can redistribute it and/or modify
4a81b561 8it under the terms of the GNU General Public License as published by
6724ff46
RP
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
4a81b561 11
6724ff46 12This program is distributed in the hope that it will be useful,
4a81b561
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
6724ff46
RP
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
4a81b561 20
4a81b561 21#include "bfd.h"
ff7ce170 22#include "sysdep.h"
4a81b561 23#include "libbfd.h"
6724ff46 24#include "obstack.h"
70e00914
KR
25extern void bfd_cache_init PARAMS ((bfd *));
26FILE *bfd_open_file PARAMS ((bfd *));
4a81b561
DHW
27
28/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
29 if we do that we can't use fcntl. */
6724ff46 30
4a81b561 31
70e00914 32#define obstack_chunk_alloc bfd_xmalloc_by_size_t
9872a49c
SC
33#define obstack_chunk_free free
34
fc723380
JG
35/* Return a new BFD. All BFD's are allocated through this routine. */
36
70e00914 37bfd *new_bfd PARAMS ((void))
4a81b561 38{
9872a49c 39 bfd *nbfd;
fc723380 40
b1847ba9
JG
41 nbfd = (bfd *)zalloc (sizeof (bfd));
42 if (!nbfd)
43 return 0;
4a81b561 44
ff7ce170
PB
45 bfd_check_init();
46 obstack_begin((PTR)&nbfd->memory, 128);
47
48 nbfd->arch_info = &bfd_default_arch_struct;
49
4a81b561
DHW
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;
70e00914 56 nbfd->origin = 0;
4a81b561
DHW
57 nbfd->opened_once = false;
58 nbfd->output_has_begun = false;
59 nbfd->section_count = 0;
9846338e 60 nbfd->usrdata = (PTR)NULL;
4a81b561
DHW
61 nbfd->sections = (asection *)NULL;
62 nbfd->cacheable = false;
63 nbfd->flags = NO_FLAGS;
9068cbe7
SC
64 nbfd->mtime_set = false;
65
70e00914 66
4a81b561
DHW
67 return nbfd;
68}
fc723380
JG
69
70/* Allocate a new BFD as a member of archive OBFD. */
71
4a81b561
DHW
72bfd *new_bfd_contained_in(obfd)
73bfd *obfd;
74{
9846338e 75 bfd *nbfd = new_bfd();
4a81b561
DHW
76 nbfd->xvec = obfd->xvec;
77 nbfd->my_archive = obfd;
78 nbfd->direction = read_direction;
9068cbe7 79 nbfd->target_defaulted = obfd->target_defaulted;
4a81b561
DHW
80 return nbfd;
81}
82
b645b632
SC
83/*
84SECTION
85 Opening and Closing BFDs
6f715d66
SC
86
87*/
6f715d66 88
b645b632
SC
89/*
90FUNCTION
91 bfd_openr
92
93SYNOPSIS
94 bfd *bfd_openr(CONST char *filename, CONST char*target);
95
96DESCRIPTION
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*/
4a81b561
DHW
103
104bfd *
9846338e
SC
105DEFUN(bfd_openr, (filename, target),
106 CONST char *filename AND
107 CONST char *target)
4a81b561
DHW
108{
109 bfd *nbfd;
110 bfd_target *target_vec;
111
4a81b561
DHW
112 nbfd = new_bfd();
113 if (nbfd == NULL) {
114 bfd_error = no_memory;
115 return NULL;
116 }
117
c0e5039e
JG
118 target_vec = bfd_find_target (target, nbfd);
119 if (target_vec == NULL) {
120 bfd_error = invalid_target;
121 return NULL;
122 }
123
4a81b561 124 nbfd->filename = filename;
70e00914 125 nbfd->direction = read_direction;
4a81b561
DHW
126
127 if (bfd_open_file (nbfd) == NULL) {
128 bfd_error = system_call_error; /* File didn't exist, or some such */
9872a49c 129 bfd_release(nbfd,0);
4a81b561
DHW
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 */
b645b632
SC
144/*
145FUNCTION
146 bfd_fdopenr
6f715d66 147
b645b632
SC
148SYNOPSIS
149 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
150
151DESCRIPTION
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}
70e00914
KR
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.
b645b632
SC
166
167 Possible errors are no_memory, invalid_target and system_call
168 error.
169*/
4a81b561
DHW
170
171bfd *
9846338e
SC
172DEFUN(bfd_fdopenr,(filename, target, fd),
173 CONST char *filename AND
174 CONST char *target AND
175 int fd)
4a81b561
DHW
176{
177 bfd *nbfd;
178 bfd_target *target_vec;
179 int fdflags;
4a81b561 180
4a81b561 181 bfd_error = system_call_error;
70e00914 182
fb3be09b
JG
183#ifdef NO_FCNTL
184 fdflags = O_RDWR; /* Assume full access */
185#else
6f715d66 186 fdflags = fcntl (fd, F_GETFL, NULL);
4a81b561 187#endif
fb3be09b 188 if (fdflags == -1) return NULL;
4a81b561
DHW
189
190 nbfd = new_bfd();
191
192 if (nbfd == NULL) {
193 bfd_error = no_memory;
194 return NULL;
195 }
c0e5039e
JG
196
197 target_vec = bfd_find_target (target, nbfd);
198 if (target_vec == NULL) {
199 bfd_error = invalid_target;
200 return NULL;
201 }
70e00914
KR
202#if defined(VMS) || defined(__GO32__)
203 nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
ff7ce170 204#else
70e00914
KR
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 }
ff7ce170 212#endif
4a81b561 213 if (nbfd->iostream == NULL) {
fc723380 214 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
215 return NULL;
216 }
70e00914 217
4a81b561
DHW
218 /* OK, put everything where it belongs */
219
220 nbfd->filename = filename;
4a81b561
DHW
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. */
ff7ce170
PB
225 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
226 switch (fdflags & (O_ACCMODE)) {
4a81b561 227 case O_RDONLY: nbfd->direction = read_direction; break;
70e00914 228 case O_WRONLY: nbfd->direction = write_direction; break;
4a81b561
DHW
229 case O_RDWR: nbfd->direction = both_direction; break;
230 default: abort ();
231 }
70e00914 232
c0e5039e 233 bfd_cache_init (nbfd);
4a81b561
DHW
234
235 return nbfd;
236}
237\f
238/** bfd_openw -- open for writing.
6724ff46 239 Returns a pointer to a freshly-allocated BFD on success, or NULL.
4a81b561
DHW
240
241 See comment by bfd_fdopenr before you try to modify this function. */
242
b645b632
SC
243/*
244FUNCTION
245 bfd_openw
246
247SYNOPSIS
248 bfd *bfd_openw(CONST char *filename, CONST char *target);
6f715d66 249
b645b632
SC
250DESCRIPTION
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,
70e00914 255 invalid_target.
6f715d66
SC
256*/
257
4a81b561 258bfd *
9846338e
SC
259DEFUN(bfd_openw,(filename, target),
260 CONST char *filename AND
261 CONST char *target)
4a81b561
DHW
262{
263 bfd *nbfd;
264 bfd_target *target_vec;
70e00914 265
4a81b561
DHW
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
c0e5039e
JG
277 target_vec = bfd_find_target (target, nbfd);
278 if (target_vec == NULL) return NULL;
279
4a81b561 280 nbfd->filename = filename;
4a81b561
DHW
281 nbfd->direction = write_direction;
282
283 if (bfd_open_file (nbfd) == NULL) {
284 bfd_error = system_call_error; /* File not writeable, etc */
fc723380 285 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
286 return NULL;
287 }
288 return nbfd;
289}
6f715d66 290
b645b632
SC
291/*
292
293FUNCTION
294 bfd_close
295
296SYNOPSIS
297 boolean bfd_close(bfd *);
298
299DESCRIPTION
6f715d66 300
b645b632
SC
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.
6f715d66 305
70e00914
KR
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).
b645b632
SC
310
311RETURNS
312 <<true>> is returned if all is ok, otherwise <<false>>.
6f715d66
SC
313*/
314
b645b632 315
4a81b561 316boolean
6f715d66
SC
317DEFUN(bfd_close,(abfd),
318 bfd *abfd)
4a81b561 319{
70e00914
KR
320 boolean ret;
321
2b1d8a50
JG
322 if (!bfd_read_p(abfd))
323 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
324 return false;
325
4a81b561
DHW
326 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
327
70e00914 328 ret = bfd_cache_close(abfd);
2b1d8a50
JG
329
330 /* If the file was open for writing and is now executable,
331 make it so */
70e00914
KR
332 if (ret == true
333 && abfd->direction == write_direction
4a81b561
DHW
334 && abfd->flags & EXEC_P) {
335 struct stat buf;
336 stat(abfd->filename, &buf);
7ed4093a
SC
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
b645b632 347 chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
4a81b561 348 }
fc723380 349 (void) obstack_free (&abfd->memory, (PTR)0);
ff7ce170 350 (void) free(abfd);
70e00914 351 return ret;
ff7ce170
PB
352}
353
b645b632
SC
354/*
355FUNCTION
356 bfd_close_all_done
357
358SYNOPSIS
359 boolean bfd_close_all_done(bfd *);
360
361DESCRIPTION
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.
ff7ce170 366
b645b632
SC
367 If the created file is executable, then <<chmod>> is called
368 to mark it as such.
ff7ce170 369
70e00914 370 All memory attached to the BFD's obstacks is released.
b645b632
SC
371
372RETURNS
373 <<true>> is returned if all is ok, otherwise <<false>>.
ff7ce170 374
ff7ce170
PB
375*/
376
377boolean
378DEFUN(bfd_close_all_done,(abfd),
379 bfd *abfd)
380{
70e00914
KR
381 boolean ret;
382
383 ret = bfd_cache_close(abfd);
ff7ce170
PB
384
385 /* If the file was open for writing and is now executable,
386 make it so */
70e00914
KR
387 if (ret == true
388 && abfd->direction == write_direction
ff7ce170
PB
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
b645b632 402 chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
ff7ce170
PB
403 }
404 (void) obstack_free (&abfd->memory, (PTR)0);
405 (void) free(abfd);
70e00914 406 return ret;
4a81b561 407}
fc723380 408
6f715d66 409
b645b632
SC
410/*
411FUNCTION
412 bfd_alloc_size
413
414SYNOPSIS
415 bfd_size_type bfd_alloc_size(bfd *abfd);
416
417DESCRIPTION
418 Return the number of bytes in the obstacks connected to the
419 supplied BFD.
420
421*/
422
423bfd_size_type
424DEFUN(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/*
439FUNCTION
440 bfd_create
441
442SYNOPSIS
443 bfd *bfd_create(CONST char *filename, bfd *template);
444
445DESCRIPTION
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
70e00914 449 format is always set to <<bfd_object>>.
b645b632 450
6f715d66 451*/
fc723380 452
4a81b561 453bfd *
9846338e
SC
454DEFUN(bfd_create,(filename, template),
455 CONST char *filename AND
6f715d66 456 bfd *template)
4a81b561
DHW
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;
9872a49c
SC
464 if(template) {
465 nbfd->xvec = template->xvec;
466 }
4a81b561 467 nbfd->direction = no_direction;
9872a49c 468 bfd_set_format(nbfd, bfd_object);
4a81b561 469 return nbfd;
4a81b561 470}
9872a49c 471
70e00914 472/*
b645b632
SC
473INTERNAL_FUNCTION
474 bfd_alloc_by_size_t
475
476SYNOPSIS
477 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
fc723380 478
b645b632
SC
479DESCRIPTION
480 This function allocates a block of memory in the obstack
481 attatched to <<abfd>> and returns a pointer to it.
482*/
483
484
70e00914 485PTR
b645b632 486DEFUN(bfd_alloc_by_size_t,(abfd, size),
7ed4093a
SC
487 bfd *abfd AND
488 size_t size)
489{
490 PTR res = obstack_alloc(&(abfd->memory), size);
491 return res;
492}
6f715d66
SC
493
494DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
495 bfd *abfd AND
496 PTR ptr AND
70e00914 497 size_t size)
6f715d66 498{
70e00914 499 (void) obstack_grow(&(abfd->memory), ptr, size);
6f715d66
SC
500}
501DEFUN(PTR bfd_alloc_finish,(abfd),
502 bfd *abfd)
503{
504 return obstack_finish(&(abfd->memory));
505}
506
9872a49c
SC
507DEFUN(PTR bfd_alloc, (abfd, size),
508 bfd *abfd AND
70e00914 509 size_t size)
9872a49c 510{
7ed4093a 511 return bfd_alloc_by_size_t(abfd, (size_t)size);
9872a49c
SC
512}
513
514DEFUN(PTR bfd_zalloc,(abfd, size),
515 bfd *abfd AND
70e00914 516 size_t size)
9872a49c 517{
70e00914
KR
518 PTR res;
519 res = bfd_alloc(abfd, size);
fc723380 520 memset(res, 0, (size_t)size);
9872a49c
SC
521 return res;
522}
523
524DEFUN(PTR bfd_realloc,(abfd, old, size),
525 bfd *abfd AND
526 PTR old AND
70e00914 527 size_t size)
9872a49c
SC
528{
529 PTR res = bfd_alloc(abfd, size);
fc723380 530 memcpy(res, old, (size_t)size);
9872a49c
SC
531 return res;
532}
This page took 0.116012 seconds and 4 git commands to generate.