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