* elfcode.h (map_program_segments): Restore check of file_size !=
[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
baf205c4
JG
37bfd *
38new_bfd PARAMS ((void))
4a81b561 39{
9872a49c 40 bfd *nbfd;
fc723380 41
b1847ba9
JG
42 nbfd = (bfd *)zalloc (sizeof (bfd));
43 if (!nbfd)
44 return 0;
4a81b561 45
ff7ce170
PB
46 bfd_check_init();
47 obstack_begin((PTR)&nbfd->memory, 128);
48
49 nbfd->arch_info = &bfd_default_arch_struct;
50
4a81b561
DHW
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;
70e00914 57 nbfd->origin = 0;
4a81b561
DHW
58 nbfd->opened_once = false;
59 nbfd->output_has_begun = false;
60 nbfd->section_count = 0;
9846338e 61 nbfd->usrdata = (PTR)NULL;
4a81b561
DHW
62 nbfd->cacheable = false;
63 nbfd->flags = NO_FLAGS;
9068cbe7
SC
64 nbfd->mtime_set = false;
65
4a81b561
DHW
66 return nbfd;
67}
fc723380
JG
68
69/* Allocate a new BFD as a member of archive OBFD. */
70
baf205c4
JG
71bfd *
72new_bfd_contained_in (obfd)
73 bfd *obfd;
4a81b561 74{
baf205c4
JG
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;
4a81b561
DHW
83}
84
b645b632
SC
85/*
86SECTION
87 Opening and Closing BFDs
6f715d66
SC
88
89*/
6f715d66 90
b645b632
SC
91/*
92FUNCTION
93 bfd_openr
94
95SYNOPSIS
c188b0be 96 bfd *bfd_openr(CONST char *filename, CONST char *target);
b645b632
SC
97
98DESCRIPTION
c188b0be
DM
99 Open the file @var{filename} (using <<fopen>>) with the target
100 @var{target}. Return a pointer to the created BFD.
b645b632
SC
101
102 If NULL is returned then an error has occured. Possible errors
103 are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
c188b0be
DM
104
105 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
106 that function.
b645b632 107*/
4a81b561
DHW
108
109bfd *
9846338e
SC
110DEFUN(bfd_openr, (filename, target),
111 CONST char *filename AND
112 CONST char *target)
4a81b561
DHW
113{
114 bfd *nbfd;
115 bfd_target *target_vec;
116
4a81b561
DHW
117 nbfd = new_bfd();
118 if (nbfd == NULL) {
119 bfd_error = no_memory;
120 return NULL;
121 }
122
c0e5039e
JG
123 target_vec = bfd_find_target (target, nbfd);
124 if (target_vec == NULL) {
125 bfd_error = invalid_target;
126 return NULL;
127 }
128
4a81b561 129 nbfd->filename = filename;
70e00914 130 nbfd->direction = read_direction;
4a81b561
DHW
131
132 if (bfd_open_file (nbfd) == NULL) {
133 bfd_error = system_call_error; /* File didn't exist, or some such */
9872a49c 134 bfd_release(nbfd,0);
4a81b561
DHW
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 */
b645b632
SC
149/*
150FUNCTION
151 bfd_fdopenr
6f715d66 152
b645b632
SC
153SYNOPSIS
154 bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
155
156DESCRIPTION
c188b0be 157 <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
b645b632 158 It opens a BFD on a file already described by the @var{fd}
70e00914
KR
159 supplied.
160
c188b0be 161 When the file is later <<bfd_close>>d, the file descriptor will be closed.
70e00914
KR
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
baf205c4
JG
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
70e00914 168 assume no cacheing; the file descriptor will remain open until
c188b0be 169 <<bfd_close>>, and will not be affected by BFD operations on other
70e00914 170 files.
b645b632 171
c188b0be 172 Possible errors are <<no_memory>>, <<invalid_target>> and <<system_call_error>>.
b645b632 173*/
4a81b561
DHW
174
175bfd *
9846338e
SC
176DEFUN(bfd_fdopenr,(filename, target, fd),
177 CONST char *filename AND
178 CONST char *target AND
179 int fd)
4a81b561
DHW
180{
181 bfd *nbfd;
182 bfd_target *target_vec;
183 int fdflags;
4a81b561 184
4a81b561 185 bfd_error = system_call_error;
70e00914 186
fb3be09b
JG
187#ifdef NO_FCNTL
188 fdflags = O_RDWR; /* Assume full access */
189#else
6f715d66 190 fdflags = fcntl (fd, F_GETFL, NULL);
4a81b561 191#endif
fb3be09b 192 if (fdflags == -1) return NULL;
4a81b561
DHW
193
194 nbfd = new_bfd();
195
196 if (nbfd == NULL) {
197 bfd_error = no_memory;
198 return NULL;
199 }
c0e5039e
JG
200
201 target_vec = bfd_find_target (target, nbfd);
202 if (target_vec == NULL) {
203 bfd_error = invalid_target;
204 return NULL;
205 }
70e00914
KR
206#if defined(VMS) || defined(__GO32__)
207 nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
ff7ce170 208#else
70e00914
KR
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 }
ff7ce170 216#endif
4a81b561 217 if (nbfd->iostream == NULL) {
fc723380 218 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
219 return NULL;
220 }
70e00914 221
4a81b561
DHW
222 /* OK, put everything where it belongs */
223
224 nbfd->filename = filename;
4a81b561
DHW
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. */
ff7ce170
PB
229 /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
230 switch (fdflags & (O_ACCMODE)) {
4a81b561 231 case O_RDONLY: nbfd->direction = read_direction; break;
70e00914 232 case O_WRONLY: nbfd->direction = write_direction; break;
4a81b561
DHW
233 case O_RDWR: nbfd->direction = both_direction; break;
234 default: abort ();
235 }
70e00914 236
c0e5039e 237 bfd_cache_init (nbfd);
4a81b561
DHW
238
239 return nbfd;
240}
241\f
242/** bfd_openw -- open for writing.
6724ff46 243 Returns a pointer to a freshly-allocated BFD on success, or NULL.
4a81b561
DHW
244
245 See comment by bfd_fdopenr before you try to modify this function. */
246
b645b632
SC
247/*
248FUNCTION
249 bfd_openw
250
251SYNOPSIS
252 bfd *bfd_openw(CONST char *filename, CONST char *target);
6f715d66 253
b645b632 254DESCRIPTION
c188b0be
DM
255 Create a BFD, associated with file @var{filename}, using the
256 file format @var{target}, and return a pointer to it.
b645b632 257
c188b0be
DM
258 Possible errors are <<system_call_error>>, <<no_memory>>,
259 <<invalid_target>>.
6f715d66
SC
260*/
261
4a81b561 262bfd *
9846338e
SC
263DEFUN(bfd_openw,(filename, target),
264 CONST char *filename AND
265 CONST char *target)
4a81b561
DHW
266{
267 bfd *nbfd;
268 bfd_target *target_vec;
70e00914 269
4a81b561
DHW
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
c0e5039e
JG
281 target_vec = bfd_find_target (target, nbfd);
282 if (target_vec == NULL) return NULL;
283
4a81b561 284 nbfd->filename = filename;
4a81b561
DHW
285 nbfd->direction = write_direction;
286
287 if (bfd_open_file (nbfd) == NULL) {
288 bfd_error = system_call_error; /* File not writeable, etc */
fc723380 289 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
290 return NULL;
291 }
292 return nbfd;
293}
6f715d66 294
b645b632
SC
295/*
296
297FUNCTION
298 bfd_close
299
300SYNOPSIS
c188b0be 301 boolean bfd_close(bfd *abfd);
b645b632
SC
302
303DESCRIPTION
6f715d66 304
c188b0be 305 Close a BFD. If the BFD was open for writing,
b645b632
SC
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.
6f715d66 309
70e00914
KR
310 All memory attached to the BFD's obstacks is released.
311
312 The file descriptor associated with the BFD is closed (even
c188b0be 313 if it was passed in to BFD by <<bfd_fdopenr>>).
b645b632
SC
314
315RETURNS
316 <<true>> is returned if all is ok, otherwise <<false>>.
6f715d66
SC
317*/
318
b645b632 319
4a81b561 320boolean
6f715d66
SC
321DEFUN(bfd_close,(abfd),
322 bfd *abfd)
4a81b561 323{
70e00914
KR
324 boolean ret;
325
2b1d8a50
JG
326 if (!bfd_read_p(abfd))
327 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
328 return false;
329
4a81b561
DHW
330 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
331
70e00914 332 ret = bfd_cache_close(abfd);
2b1d8a50
JG
333
334 /* If the file was open for writing and is now executable,
335 make it so */
70e00914
KR
336 if (ret == true
337 && abfd->direction == write_direction
4a81b561
DHW
338 && abfd->flags & EXEC_P) {
339 struct stat buf;
340 stat(abfd->filename, &buf);
7ed4093a
SC
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
b645b632 351 chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
4a81b561 352 }
fc723380 353 (void) obstack_free (&abfd->memory, (PTR)0);
ff7ce170 354 (void) free(abfd);
70e00914 355 return ret;
ff7ce170
PB
356}
357
b645b632
SC
358/*
359FUNCTION
360 bfd_close_all_done
361
362SYNOPSIS
363 boolean bfd_close_all_done(bfd *);
364
365DESCRIPTION
c188b0be 366 Close a BFD. Differs from <<bfd_close>>
b645b632
SC
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.
ff7ce170 370
b645b632
SC
371 If the created file is executable, then <<chmod>> is called
372 to mark it as such.
ff7ce170 373
70e00914 374 All memory attached to the BFD's obstacks is released.
b645b632
SC
375
376RETURNS
377 <<true>> is returned if all is ok, otherwise <<false>>.
ff7ce170 378
ff7ce170
PB
379*/
380
381boolean
382DEFUN(bfd_close_all_done,(abfd),
383 bfd *abfd)
384{
70e00914
KR
385 boolean ret;
386
387 ret = bfd_cache_close(abfd);
ff7ce170
PB
388
389 /* If the file was open for writing and is now executable,
390 make it so */
70e00914
KR
391 if (ret == true
392 && abfd->direction == write_direction
ff7ce170
PB
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
b645b632 406 chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
ff7ce170
PB
407 }
408 (void) obstack_free (&abfd->memory, (PTR)0);
409 (void) free(abfd);
70e00914 410 return ret;
4a81b561 411}
fc723380 412
6f715d66 413
b645b632
SC
414/*
415FUNCTION
416 bfd_alloc_size
417
418SYNOPSIS
419 bfd_size_type bfd_alloc_size(bfd *abfd);
420
421DESCRIPTION
c188b0be 422 Return the number of bytes in the obstacks connected to @var{abfd}.
b645b632
SC
423
424*/
425
426bfd_size_type
427DEFUN(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/*
442FUNCTION
443 bfd_create
444
445SYNOPSIS
baf205c4 446 bfd *bfd_create(CONST char *filename, bfd *templ);
b645b632
SC
447
448DESCRIPTION
c188b0be 449 Create a new BFD in the manner of
b645b632
SC
450 <<bfd_openw>>, but without opening a file. The new BFD
451 takes the target from the target used by @var{template}. The
70e00914 452 format is always set to <<bfd_object>>.
b645b632 453
6f715d66 454*/
fc723380 455
4a81b561 456bfd *
baf205c4 457DEFUN(bfd_create,(filename, templ),
9846338e 458 CONST char *filename AND
baf205c4 459 bfd *templ)
4a81b561
DHW
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;
baf205c4
JG
467 if(templ) {
468 nbfd->xvec = templ->xvec;
9872a49c 469 }
4a81b561 470 nbfd->direction = no_direction;
9872a49c 471 bfd_set_format(nbfd, bfd_object);
4a81b561 472 return nbfd;
4a81b561 473}
9872a49c 474
70e00914 475/*
b645b632
SC
476INTERNAL_FUNCTION
477 bfd_alloc_by_size_t
478
479SYNOPSIS
480 PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
fc723380 481
b645b632 482DESCRIPTION
c188b0be
DM
483 Allocate a block of @var{wanted} bytes of memory in the obstack
484 attatched to <<abfd>> and return a pointer to it.
b645b632
SC
485*/
486
487
70e00914 488PTR
b645b632 489DEFUN(bfd_alloc_by_size_t,(abfd, size),
7ed4093a
SC
490 bfd *abfd AND
491 size_t size)
492{
493 PTR res = obstack_alloc(&(abfd->memory), size);
494 return res;
495}
6f715d66
SC
496
497DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
498 bfd *abfd AND
499 PTR ptr AND
70e00914 500 size_t size)
6f715d66 501{
70e00914 502 (void) obstack_grow(&(abfd->memory), ptr, size);
6f715d66
SC
503}
504DEFUN(PTR bfd_alloc_finish,(abfd),
505 bfd *abfd)
506{
507 return obstack_finish(&(abfd->memory));
508}
509
9872a49c
SC
510DEFUN(PTR bfd_alloc, (abfd, size),
511 bfd *abfd AND
70e00914 512 size_t size)
9872a49c 513{
7ed4093a 514 return bfd_alloc_by_size_t(abfd, (size_t)size);
9872a49c
SC
515}
516
517DEFUN(PTR bfd_zalloc,(abfd, size),
518 bfd *abfd AND
70e00914 519 size_t size)
9872a49c 520{
70e00914
KR
521 PTR res;
522 res = bfd_alloc(abfd, size);
fc723380 523 memset(res, 0, (size_t)size);
9872a49c
SC
524 return res;
525}
526
527DEFUN(PTR bfd_realloc,(abfd, old, size),
528 bfd *abfd AND
529 PTR old AND
70e00914 530 size_t size)
9872a49c
SC
531{
532 PTR res = bfd_alloc(abfd, size);
fc723380 533 memcpy(res, old, (size_t)size);
9872a49c
SC
534 return res;
535}
This page took 0.124412 seconds and 4 git commands to generate.