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