* makefile.dos, configdj.bat: New files from DJ
[platform/upstream/binutils.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