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