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