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