* stabs.texinfo (String Field): Discuss continuing stabs with ?.
[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 37bfd *
f4bd7a8f 38_bfd_new_bfd (void)
4a81b561 39{
9872a49c 40 bfd *nbfd;
fc723380 41
f4bd7a8f 42 nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
b1847ba9
JG
43 if (!nbfd)
44 return 0;
4a81b561 45
ff7ce170 46 bfd_check_init();
f4bd7a8f 47 obstack_begin(&nbfd->memory, 128);
ff7ce170
PB
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 71bfd *
f4bd7a8f 72_bfd_new_bfd_contained_in (obfd)
baf205c4 73 bfd *obfd;
4a81b561 74{
baf205c4
JG
75 bfd *nbfd;
76
f4bd7a8f 77 nbfd = _bfd_new_bfd();
baf205c4
JG
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
f4bd7a8f 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 101
c188b0be
DM
102 Calls <<bfd_find_target>>, so @var{target} is interpreted as by
103 that function.
f4bd7a8f
DM
104
105 If <<NULL>> is returned then an error has occured. Possible errors
106 are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
b645b632 107*/
4a81b561
DHW
108
109bfd *
f4bd7a8f
DM
110bfd_openr (filename, target)
111 CONST char *filename;
112 CONST char *target;
4a81b561
DHW
113{
114 bfd *nbfd;
115 bfd_target *target_vec;
116
f4bd7a8f 117 nbfd = _bfd_new_bfd();
4a81b561
DHW
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 *
f4bd7a8f
DM
176bfd_fdopenr (filename, target, fd)
177 CONST char *filename;
178 CONST char *target;
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 193
f4bd7a8f 194 nbfd = _bfd_new_bfd();
4a81b561
DHW
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 *
f4bd7a8f
DM
263bfd_openw (filename, target)
264 CONST char *filename;
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
f4bd7a8f 275 nbfd = _bfd_new_bfd();
4a81b561
DHW
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
f4bd7a8f
DM
321bfd_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
f4bd7a8f
DM
382bfd_close_all_done (abfd)
383 bfd *abfd;
ff7ce170 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
f4bd7a8f
DM
427bfd_alloc_size (abfd)
428 bfd *abfd;
b645b632
SC
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 *
f4bd7a8f
DM
457bfd_create (filename, templ)
458 CONST char *filename;
459 bfd *templ;
4a81b561 460{
f4bd7a8f 461 bfd *nbfd = _bfd_new_bfd();
4a81b561
DHW
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
f4bd7a8f
DM
489bfd_alloc_by_size_t (abfd, size)
490 bfd *abfd;
491 size_t size;
7ed4093a
SC
492{
493 PTR res = obstack_alloc(&(abfd->memory), size);
494 return res;
495}
6f715d66 496
f4bd7a8f
DM
497void
498bfd_alloc_grow (abfd, ptr, size)
499 bfd *abfd;
500 PTR ptr;
501 size_t size;
6f715d66 502{
70e00914 503 (void) obstack_grow(&(abfd->memory), ptr, size);
6f715d66 504}
f4bd7a8f
DM
505
506PTR
507bfd_alloc_finish (abfd)
508 bfd *abfd;
6f715d66
SC
509{
510 return obstack_finish(&(abfd->memory));
511}
512
f4bd7a8f
DM
513PTR
514bfd_alloc (abfd, size)
515 bfd *abfd;
516 size_t size;
9872a49c 517{
7ed4093a 518 return bfd_alloc_by_size_t(abfd, (size_t)size);
9872a49c
SC
519}
520
f4bd7a8f
DM
521PTR
522bfd_zalloc (abfd, size)
523 bfd *abfd;
524 size_t size;
9872a49c 525{
70e00914
KR
526 PTR res;
527 res = bfd_alloc(abfd, size);
fc723380 528 memset(res, 0, (size_t)size);
9872a49c
SC
529 return res;
530}
531
f4bd7a8f
DM
532PTR
533bfd_realloc (abfd, old, size)
534 bfd *abfd;
535 PTR old;
536 size_t size;
9872a49c
SC
537{
538 PTR res = bfd_alloc(abfd, size);
fc723380 539 memcpy(res, old, (size_t)size);
9872a49c
SC
540 return res;
541}
This page took 0.133017 seconds and 4 git commands to generate.