Fix some gcc -Wall warnings:
[deliverable/binutils-gdb.git] / bfd / opncls.c
CommitLineData
6724ff46 1/* opncls.c -- open and close a BFD.
50ede03d
ILT
2 Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
3 Free Software Foundation, Inc.
4
6724ff46 5 Written by Cygnus Support.
fc723380 6
6724ff46 7This file is part of BFD, the Binary File Descriptor library.
4a81b561 8
6724ff46 9This program is free software; you can redistribute it and/or modify
4a81b561 10it under the terms of the GNU General Public License as published by
6724ff46
RP
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
4a81b561 13
6724ff46 14This program is distributed in the hope that it will be useful,
4a81b561
DHW
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
6724ff46 20along with this program; if not, write to the Free Software
b7577823 21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
4a81b561 22
4a81b561 23#include "bfd.h"
ff7ce170 24#include "sysdep.h"
508539ab 25#include "objalloc.h"
4a81b561 26#include "libbfd.h"
9560e662
SC
27
28#ifndef S_IXUSR
29#define S_IXUSR 0100 /* Execute by owner. */
30#endif
31#ifndef S_IXGRP
32#define S_IXGRP 0010 /* Execute by group. */
33#endif
34#ifndef S_IXOTH
35#define S_IXOTH 0001 /* Execute by others. */
36#endif
4a81b561
DHW
37
38/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
39 if we do that we can't use fcntl. */
6724ff46 40
508539ab 41/* FIXME: This is no longer used. */
64d5f5d0
ILT
42long _bfd_chunksize = -1;
43
fc723380
JG
44/* Return a new BFD. All BFD's are allocated through this routine. */
45
baf205c4 46bfd *
751446f6 47_bfd_new_bfd ()
4a81b561 48{
9872a49c 49 bfd *nbfd;
fc723380 50
508539ab
ILT
51 nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
52 if (nbfd == NULL)
53 return NULL;
4a81b561 54
508539ab
ILT
55 nbfd->memory = (PTR) objalloc_create ();
56 if (nbfd->memory == NULL)
9783e04a 57 {
9560e662 58 bfd_set_error (bfd_error_no_memory);
508539ab 59 return NULL;
9783e04a 60 }
ff7ce170
PB
61
62 nbfd->arch_info = &bfd_default_arch_struct;
63
4a81b561
DHW
64 nbfd->direction = no_direction;
65 nbfd->iostream = NULL;
66 nbfd->where = 0;
508539ab 67 nbfd->sections = (asection *) NULL;
4a81b561 68 nbfd->format = bfd_unknown;
508539ab 69 nbfd->my_archive = (bfd *) NULL;
70e00914 70 nbfd->origin = 0;
4a81b561
DHW
71 nbfd->opened_once = false;
72 nbfd->output_has_begun = false;
73 nbfd->section_count = 0;
508539ab 74 nbfd->usrdata = (PTR) NULL;
4a81b561 75 nbfd->cacheable = false;
2055bf85 76 nbfd->flags = BFD_NO_FLAGS;
9068cbe7
SC
77 nbfd->mtime_set = false;
78
4a81b561
DHW
79 return nbfd;
80}
fc723380
JG
81
82/* Allocate a new BFD as a member of archive OBFD. */
83
baf205c4 84bfd *
f4bd7a8f 85_bfd_new_bfd_contained_in (obfd)
baf205c4 86 bfd *obfd;
4a81b561 87{
baf205c4
JG
88 bfd *nbfd;
89
508539ab 90 nbfd = _bfd_new_bfd ();
baf205c4
JG
91 nbfd->xvec = obfd->xvec;
92 nbfd->my_archive = obfd;
93 nbfd->direction = read_direction;
94 nbfd->target_defaulted = obfd->target_defaulted;
95 return nbfd;
4a81b561
DHW
96}
97
b645b632
SC
98/*
99SECTION
f4bd7a8f 100 Opening and closing BFDs
6f715d66
SC
101
102*/
6f715d66 103
b645b632
SC
104/*
105FUNCTION
106 bfd_openr
107
108SYNOPSIS
c188b0be 109 bfd *bfd_openr(CONST char *filename, CONST char *target);
b645b632
SC
110
111DESCRIPTION
c188b0be
DM
112 Open the file @var{filename} (using <<fopen>>) with the target
113 @var{target}. Return a pointer to the created BFD.
b645b632 114
c188b0be
DM
115 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
116 that function.
f4bd7a8f
DM
117
118 If <<NULL>> is returned then an error has occured. Possible errors
9560e662 119 are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
b645b632 120*/
4a81b561
DHW
121
122bfd *
f4bd7a8f
DM
123bfd_openr (filename, target)
124 CONST char *filename;
125 CONST char *target;
4a81b561
DHW
126{
127 bfd *nbfd;
9560e662 128 const bfd_target *target_vec;
4a81b561 129
508539ab 130 nbfd = _bfd_new_bfd ();
64d5f5d0 131 if (nbfd == NULL)
4a81b561 132 return NULL;
4a81b561 133
c0e5039e 134 target_vec = bfd_find_target (target, nbfd);
508539ab
ILT
135 if (target_vec == NULL)
136 {
137 objalloc_free ((struct objalloc *) nbfd->memory);
138 free (nbfd);
139 bfd_set_error (bfd_error_invalid_target);
140 return NULL;
141 }
c0e5039e 142
4a81b561 143 nbfd->filename = filename;
70e00914 144 nbfd->direction = read_direction;
4a81b561 145
508539ab
ILT
146 if (bfd_open_file (nbfd) == NULL)
147 {
148 /* File didn't exist, or some such */
149 bfd_set_error (bfd_error_system_call);
150 objalloc_free ((struct objalloc *) nbfd->memory);
151 free (nbfd);
152 return NULL;
153 }
154
4a81b561
DHW
155 return nbfd;
156}
157
4a81b561
DHW
158/* Don't try to `optimize' this function:
159
160 o - We lock using stack space so that interrupting the locking
161 won't cause a storage leak.
162 o - We open the file stream last, since we don't want to have to
163 close it if anything goes wrong. Closing the stream means closing
164 the file descriptor too, even though we didn't open it.
165 */
b645b632
SC
166/*
167FUNCTION
168 bfd_fdopenr
6f715d66 169
b645b632
SC
170SYNOPSIS
171 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
172
173DESCRIPTION
c188b0be 174 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
b645b632 175 It opens a BFD on a file already described by the @var{fd}
70e00914
KR
176 supplied.
177
c188b0be 178 When the file is later <<bfd_close>>d, the file descriptor will be closed.
70e00914
KR
179
180 If the caller desires that this file descriptor be cached by BFD
181 (opened as needed, closed as needed to free descriptors for
182 other opens), with the supplied @var{fd} used as an initial
baf205c4
JG
183 file descriptor (but subject to closure at any time), call
184 bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
70e00914 185 assume no cacheing; the file descriptor will remain open until
c188b0be 186 <<bfd_close>>, and will not be affected by BFD operations on other
70e00914 187 files.
b645b632 188
9560e662 189 Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
b645b632 190*/
4a81b561
DHW
191
192bfd *
f4bd7a8f
DM
193bfd_fdopenr (filename, target, fd)
194 CONST char *filename;
195 CONST char *target;
196 int fd;
4a81b561
DHW
197{
198 bfd *nbfd;
9560e662 199 const bfd_target *target_vec;
4a81b561 200 int fdflags;
4a81b561 201
9560e662 202 bfd_set_error (bfd_error_system_call);
b7577823 203#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
fb3be09b
JG
204 fdflags = O_RDWR; /* Assume full access */
205#else
6f715d66 206 fdflags = fcntl (fd, F_GETFL, NULL);
4a81b561 207#endif
fb3be09b 208 if (fdflags == -1) return NULL;
4a81b561 209
508539ab 210 nbfd = _bfd_new_bfd ();
64d5f5d0 211 if (nbfd == NULL)
4a81b561 212 return NULL;
c0e5039e
JG
213
214 target_vec = bfd_find_target (target, nbfd);
508539ab
ILT
215 if (target_vec == NULL)
216 {
217 bfd_set_error (bfd_error_invalid_target);
218 objalloc_free ((struct objalloc *) nbfd->memory);
219 free (nbfd);
220 return NULL;
221 }
222
50ede03d 223#if defined(VMS) || defined(__GO32__)
64d5f5d0 224 nbfd->iostream = (PTR)fopen(filename, FOPEN_RB);
ff7ce170 225#else
70e00914
KR
226 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
227 switch (fdflags & (O_ACCMODE)) {
64d5f5d0
ILT
228 case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
229 case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
230 case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
70e00914
KR
231 default: abort ();
232 }
ff7ce170 233#endif
508539ab
ILT
234
235 if (nbfd->iostream == NULL)
236 {
237 objalloc_free ((struct objalloc *) nbfd->memory);
238 free (nbfd);
239 return NULL;
240 }
70e00914 241
4a81b561
DHW
242 /* OK, put everything where it belongs */
243
244 nbfd->filename = filename;
4a81b561
DHW
245
246 /* As a special case we allow a FD open for read/write to
247 be written through, although doing so requires that we end
248 the previous clause with a preposition. */
ff7ce170 249 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
508539ab
ILT
250 switch (fdflags & O_ACCMODE)
251 {
252 case O_RDONLY: nbfd->direction = read_direction; break;
253 case O_WRONLY: nbfd->direction = write_direction; break;
254 case O_RDWR: nbfd->direction = both_direction; break;
255 default: abort ();
256 }
257
9560e662 258 if (! bfd_cache_init (nbfd))
508539ab
ILT
259 {
260 objalloc_free ((struct objalloc *) nbfd->memory);
261 free (nbfd);
262 return NULL;
263 }
2055bf85 264 nbfd->opened_once = true;
4a81b561
DHW
265
266 return nbfd;
267}
123bfaa5
ILT
268
269/*
270FUNCTION
271 bfd_openstreamr
272
273SYNOPSIS
274 bfd *bfd_openstreamr();
275
276DESCRIPTION
277
278 Open a BFD for read access on an existing stdio stream. When
279 the BFD is passed to <<bfd_close>>, the stream will be closed.
280*/
281
282bfd *
283bfd_openstreamr (filename, target, stream)
284 const char *filename;
285 const char *target;
286 FILE *stream;
287{
288 bfd *nbfd;
289 const bfd_target *target_vec;
290
291 nbfd = _bfd_new_bfd ();
292 if (nbfd == NULL)
64d5f5d0 293 return NULL;
123bfaa5
ILT
294
295 target_vec = bfd_find_target (target, nbfd);
296 if (target_vec == NULL)
297 {
298 bfd_set_error (bfd_error_invalid_target);
508539ab
ILT
299 objalloc_free ((struct objalloc *) nbfd->memory);
300 free (nbfd);
123bfaa5
ILT
301 return NULL;
302 }
303
64d5f5d0 304 nbfd->iostream = (PTR) stream;
123bfaa5
ILT
305 nbfd->filename = filename;
306 nbfd->direction = read_direction;
307
308 if (! bfd_cache_init (nbfd))
508539ab
ILT
309 {
310 objalloc_free ((struct objalloc *) nbfd->memory);
311 free (nbfd);
312 return NULL;
313 }
123bfaa5
ILT
314
315 return nbfd;
316}
4a81b561
DHW
317\f
318/** bfd_openw -- open for writing.
6724ff46 319 Returns a pointer to a freshly-allocated BFD on success, or NULL.
4a81b561
DHW
320
321 See comment by bfd_fdopenr before you try to modify this function. */
322
b645b632
SC
323/*
324FUNCTION
325 bfd_openw
326
327SYNOPSIS
328 bfd *bfd_openw(CONST char *filename, CONST char *target);
6f715d66 329
b645b632 330DESCRIPTION
c188b0be
DM
331 Create a BFD, associated with file @var{filename}, using the
332 file format @var{target}, and return a pointer to it.
b645b632 333
9560e662
SC
334 Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
335 <<bfd_error_invalid_target>>.
6f715d66
SC
336*/
337
4a81b561 338bfd *
f4bd7a8f
DM
339bfd_openw (filename, target)
340 CONST char *filename;
341 CONST char *target;
4a81b561
DHW
342{
343 bfd *nbfd;
9560e662 344 const bfd_target *target_vec;
70e00914 345
9560e662 346 bfd_set_error (bfd_error_system_call);
4a81b561
DHW
347
348 /* nbfd has to point to head of malloc'ed block so that bfd_close may
349 reclaim it correctly. */
350
508539ab 351 nbfd = _bfd_new_bfd ();
64d5f5d0 352 if (nbfd == NULL)
4a81b561 353 return NULL;
4a81b561 354
c0e5039e 355 target_vec = bfd_find_target (target, nbfd);
508539ab
ILT
356 if (target_vec == NULL)
357 {
358 objalloc_free ((struct objalloc *) nbfd->memory);
359 free (nbfd);
360 return NULL;
361 }
c0e5039e 362
4a81b561 363 nbfd->filename = filename;
4a81b561
DHW
364 nbfd->direction = write_direction;
365
508539ab
ILT
366 if (bfd_open_file (nbfd) == NULL)
367 {
368 bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
369 objalloc_free ((struct objalloc *) nbfd->memory);
370 free (nbfd);
371 return NULL;
4a81b561 372 }
508539ab 373
4a81b561
DHW
374 return nbfd;
375}
6f715d66 376
b645b632
SC
377/*
378
379FUNCTION
380 bfd_close
381
382SYNOPSIS
c188b0be 383 boolean bfd_close(bfd *abfd);
b645b632
SC
384
385DESCRIPTION
6f715d66 386
c188b0be 387 Close a BFD. If the BFD was open for writing,
b645b632
SC
388 then pending operations are completed and the file written out
389 and closed. If the created file is executable, then
390 <<chmod>> is called to mark it as such.
6f715d66 391
508539ab 392 All memory attached to the BFD is released.
70e00914
KR
393
394 The file descriptor associated with the BFD is closed (even
c188b0be 395 if it was passed in to BFD by <<bfd_fdopenr>>).
b645b632
SC
396
397RETURNS
398 <<true>> is returned if all is ok, otherwise <<false>>.
6f715d66
SC
399*/
400
b645b632 401
4a81b561 402boolean
f4bd7a8f
DM
403bfd_close (abfd)
404 bfd *abfd;
4a81b561 405{
70e00914
KR
406 boolean ret;
407
9560e662
SC
408 if (!bfd_read_p (abfd))
409 {
410 if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
411 return false;
412 }
2b1d8a50 413
9560e662
SC
414 if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
415 return false;
4a81b561 416
9560e662 417 ret = bfd_cache_close (abfd);
2b1d8a50
JG
418
419 /* If the file was open for writing and is now executable,
420 make it so */
9560e662 421 if (ret
70e00914 422 && abfd->direction == write_direction
9560e662
SC
423 && abfd->flags & EXEC_P)
424 {
425 struct stat buf;
426
427 if (stat (abfd->filename, &buf) == 0)
428 {
429 int mask = umask (0);
430 umask (mask);
431 chmod (abfd->filename,
432 (0777
433 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
434 }
435 }
7ed4093a 436
508539ab
ILT
437 objalloc_free ((struct objalloc *) abfd->memory);
438 free (abfd);
9560e662 439
70e00914 440 return ret;
ff7ce170
PB
441}
442
b645b632
SC
443/*
444FUNCTION
445 bfd_close_all_done
446
447SYNOPSIS
448 boolean bfd_close_all_done(bfd *);
449
450DESCRIPTION
c188b0be 451 Close a BFD. Differs from <<bfd_close>>
b645b632
SC
452 since it does not complete any pending operations. This
453 routine would be used if the application had just used BFD for
454 swapping and didn't want to use any of the writing code.
ff7ce170 455
b645b632
SC
456 If the created file is executable, then <<chmod>> is called
457 to mark it as such.
ff7ce170 458
508539ab 459 All memory attached to the BFD is released.
b645b632
SC
460
461RETURNS
462 <<true>> is returned if all is ok, otherwise <<false>>.
ff7ce170 463
ff7ce170
PB
464*/
465
466boolean
f4bd7a8f
DM
467bfd_close_all_done (abfd)
468 bfd *abfd;
ff7ce170 469{
70e00914
KR
470 boolean ret;
471
9560e662 472 ret = bfd_cache_close (abfd);
ff7ce170
PB
473
474 /* If the file was open for writing and is now executable,
475 make it so */
9560e662 476 if (ret
70e00914 477 && abfd->direction == write_direction
9560e662
SC
478 && abfd->flags & EXEC_P)
479 {
480 struct stat buf;
481
482 if (stat (abfd->filename, &buf) == 0)
483 {
484 int mask = umask (0);
485 umask (mask);
486 chmod (abfd->filename,
487 (0x777
488 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
489 }
490 }
fc723380 491
508539ab
ILT
492 objalloc_free ((struct objalloc *) abfd->memory);
493 free (abfd);
6f715d66 494
508539ab 495 return ret;
b645b632
SC
496}
497
b645b632
SC
498/*
499FUNCTION
500 bfd_create
501
502SYNOPSIS
baf205c4 503 bfd *bfd_create(CONST char *filename, bfd *templ);
b645b632
SC
504
505DESCRIPTION
c188b0be 506 Create a new BFD in the manner of
b645b632
SC
507 <<bfd_openw>>, but without opening a file. The new BFD
508 takes the target from the target used by @var{template}. The
70e00914 509 format is always set to <<bfd_object>>.
b645b632 510
6f715d66 511*/
fc723380 512
4a81b561 513bfd *
f4bd7a8f
DM
514bfd_create (filename, templ)
515 CONST char *filename;
516 bfd *templ;
4a81b561 517{
508539ab
ILT
518 bfd *nbfd;
519
520 nbfd = _bfd_new_bfd ();
521 if (nbfd == NULL)
522 return NULL;
4a81b561 523 nbfd->filename = filename;
508539ab 524 if (templ)
baf205c4 525 nbfd->xvec = templ->xvec;
4a81b561 526 nbfd->direction = no_direction;
508539ab 527 bfd_set_format (nbfd, bfd_object);
4a81b561 528 return nbfd;
4a81b561 529}
9872a49c 530
70e00914 531/*
b645b632 532INTERNAL_FUNCTION
50ede03d 533 bfd_alloc
b645b632
SC
534
535SYNOPSIS
50ede03d 536 PTR bfd_alloc (bfd *abfd, size_t wanted);
fc723380 537
b645b632 538DESCRIPTION
508539ab
ILT
539 Allocate a block of @var{wanted} bytes of memory attached to
540 <<abfd>> and return a pointer to it.
b645b632
SC
541*/
542
543
70e00914 544PTR
50ede03d 545bfd_alloc (abfd, size)
f4bd7a8f
DM
546 bfd *abfd;
547 size_t size;
7ed4093a 548{
64d5f5d0
ILT
549 PTR ret;
550
508539ab 551 ret = objalloc_alloc (abfd->memory, (unsigned long) size);
64d5f5d0
ILT
552 if (ret == NULL)
553 bfd_set_error (bfd_error_no_memory);
554 return ret;
7ed4093a 555}
6f715d66 556
f4bd7a8f
DM
557PTR
558bfd_zalloc (abfd, size)
559 bfd *abfd;
560 size_t size;
9872a49c 561{
70e00914 562 PTR res;
508539ab
ILT
563
564 res = bfd_alloc (abfd, size);
9783e04a 565 if (res)
508539ab 566 memset (res, 0, size);
9872a49c
SC
567 return res;
568}
508539ab
ILT
569
570/* Free a block allocated for a BFD. */
571
572void
573bfd_release (abfd, block)
574 bfd *abfd;
575 PTR block;
576{
577 objalloc_free_block ((struct objalloc *) abfd->memory, block);
578}
This page took 0.270321 seconds and 4 git commands to generate.