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