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