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