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