* libaout.h (WRITE_HEADERS): Set header's a_text field always.
[deliverable/binutils-gdb.git] / bfd / opncls.c
CommitLineData
6724ff46
RP
1/* opncls.c -- open and close a BFD.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
fc723380 4
6724ff46 5This file is part of BFD, the Binary File Descriptor library.
4a81b561 6
6724ff46 7This program is free software; you can redistribute it and/or modify
4a81b561 8it under the terms of the GNU General Public License as published by
6724ff46
RP
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
4a81b561 11
6724ff46 12This program is distributed in the hope that it will be useful,
4a81b561
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
6724ff46
RP
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
4a81b561
DHW
20
21/* $Id$ */
22
7ed4093a 23#include <sysdep.h>
4a81b561
DHW
24#include "bfd.h"
25#include "libbfd.h"
6724ff46 26#include "obstack.h"
4a81b561
DHW
27extern void bfd_cache_init();
28FILE *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. */
6724ff46 32
4a81b561
DHW
33/** Locking
34
35 Locking is loosely controlled by the preprocessor variable
36 BFD_LOCKS. I say loosely because Unix barely understands locking
37 -- at least in BSD it doesn't affect programs which don't
38 explicitly use it! That is to say it's practically useless, though
39 if everyone uses this library you'll be OK.
40
41 From among the many and varied lock facilities available, (none of
42 which, of course, knows about any other) we use the fcntl locks,
43 because they're Posix.
44
6724ff46
RP
45 The reason that @code{bfd_openr} and @code{bfd_fdopenr} exist, yet
46 only @code{bfd_openw} exists is because of locking. When we do
47 output, we lock the filename file for output, then open a temporary
48 file which does not actually get its correct filename until closing
49 time. This is safest, but requires the asymmetry in read and write
50 entry points.
4a81b561
DHW
51
52 Perhaps, since unix has so many different kinds of locking anyway,
53 we should use the emacs lock scheme?... */
4a81b561 54
55a97094 55#define obstack_chunk_alloc malloc
9872a49c
SC
56#define obstack_chunk_free free
57
fc723380
JG
58/* Return a new BFD. All BFD's are allocated through this routine. */
59
4a81b561
DHW
60bfd *new_bfd()
61{
9872a49c 62 bfd *nbfd;
fc723380 63
b1847ba9
JG
64 nbfd = (bfd *)zalloc (sizeof (bfd));
65 if (!nbfd)
66 return 0;
4a81b561 67
7ed4093a 68 obstack_begin((PTR)&nbfd->memory, 128);
b1847ba9 69
4a81b561
DHW
70 nbfd->direction = no_direction;
71 nbfd->iostream = NULL;
72 nbfd->where = 0;
73 nbfd->sections = (asection *)NULL;
74 nbfd->format = bfd_unknown;
75 nbfd->my_archive = (bfd *)NULL;
76 nbfd->origin = 0;
77 nbfd->opened_once = false;
78 nbfd->output_has_begun = false;
79 nbfd->section_count = 0;
9846338e 80 nbfd->usrdata = (PTR)NULL;
4a81b561
DHW
81 nbfd->sections = (asection *)NULL;
82 nbfd->cacheable = false;
83 nbfd->flags = NO_FLAGS;
fc723380 84 nbfd->mtime_set = 0;
4a81b561
DHW
85 return nbfd;
86}
fc723380
JG
87
88/* Allocate a new BFD as a member of archive OBFD. */
89
4a81b561
DHW
90bfd *new_bfd_contained_in(obfd)
91bfd *obfd;
92{
9846338e 93 bfd *nbfd = new_bfd();
4a81b561
DHW
94 nbfd->xvec = obfd->xvec;
95 nbfd->my_archive = obfd;
96 nbfd->direction = read_direction;
97 return nbfd;
98}
99
6f715d66
SC
100/*doc*
101@section Opening and Closing BFDs
102
103*/
104/*proto*
105*i bfd_openr
6724ff46
RP
106Opens the file supplied (using @code{fopen}) with the target supplied, it
107returns a pointer to the created BFD.
6f715d66
SC
108
109If NULL is returned then an error has occured.
110Possible errors are no_memory, invalid_target or system_call error.
111*; PROTO(bfd*, bfd_openr, (CONST char *filename,CONST char*target));
112*-*/
4a81b561
DHW
113
114bfd *
9846338e
SC
115DEFUN(bfd_openr, (filename, target),
116 CONST char *filename AND
117 CONST char *target)
4a81b561
DHW
118{
119 bfd *nbfd;
120 bfd_target *target_vec;
121
4a81b561
DHW
122 nbfd = new_bfd();
123 if (nbfd == NULL) {
124 bfd_error = no_memory;
125 return NULL;
126 }
127
c0e5039e
JG
128 target_vec = bfd_find_target (target, nbfd);
129 if (target_vec == NULL) {
130 bfd_error = invalid_target;
131 return NULL;
132 }
133
4a81b561 134 nbfd->filename = filename;
4a81b561
DHW
135 nbfd->direction = read_direction;
136
137 if (bfd_open_file (nbfd) == NULL) {
138 bfd_error = system_call_error; /* File didn't exist, or some such */
9872a49c 139 bfd_release(nbfd,0);
4a81b561
DHW
140 return NULL;
141 }
142 return nbfd;
143}
144
145
146/* Don't try to `optimize' this function:
147
148 o - We lock using stack space so that interrupting the locking
149 won't cause a storage leak.
150 o - We open the file stream last, since we don't want to have to
151 close it if anything goes wrong. Closing the stream means closing
152 the file descriptor too, even though we didn't open it.
153 */
6f715d66
SC
154/*proto*
155*i bfd_fdopenr
6724ff46 156bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen. It opens a BFD on
6f715d66
SC
157a file already described by the @var{fd} supplied.
158
159Possible errors are no_memory, invalid_target and system_call error.
160*; PROTO(bfd *, bfd_fdopenr,
161 (CONST char *filename, CONST char *target, int fd));
162*-*/
4a81b561
DHW
163
164bfd *
9846338e
SC
165DEFUN(bfd_fdopenr,(filename, target, fd),
166 CONST char *filename AND
167 CONST char *target AND
168 int fd)
4a81b561
DHW
169{
170 bfd *nbfd;
171 bfd_target *target_vec;
172 int fdflags;
173#ifdef BFD_LOCKS
174 struct flock lock, *lockp = &lock;
175#endif
176
4a81b561
DHW
177 bfd_error = system_call_error;
178
6f715d66 179 fdflags = fcntl (fd, F_GETFL, NULL);
4a81b561
DHW
180 if (fdflags == -1) return NULL;
181
182#ifdef BFD_LOCKS
183 lockp->l_type = F_RDLCK;
184 if (fcntl (fd, F_SETLKW, lockp) == -1) return NULL;
185#endif
186
187 nbfd = new_bfd();
188
189 if (nbfd == NULL) {
190 bfd_error = no_memory;
191 return NULL;
192 }
c0e5039e
JG
193
194 target_vec = bfd_find_target (target, nbfd);
195 if (target_vec == NULL) {
196 bfd_error = invalid_target;
197 return NULL;
198 }
199
4a81b561
DHW
200#ifdef BFD_LOCKS
201 nbfd->lock = (struct flock *) (nbfd + 1);
202#endif
203 /* if the fd were open for read only, this still would not hurt: */
204 nbfd->iostream = (char *) fdopen (fd, "r+");
205 if (nbfd->iostream == NULL) {
fc723380 206 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
207 return NULL;
208 }
209
210 /* OK, put everything where it belongs */
211
212 nbfd->filename = filename;
4a81b561
DHW
213
214 /* As a special case we allow a FD open for read/write to
215 be written through, although doing so requires that we end
216 the previous clause with a preposition. */
217 switch (fdflags & O_ACCMODE) {
218 case O_RDONLY: nbfd->direction = read_direction; break;
219 case O_WRONLY: nbfd->direction = write_direction; break;
220 case O_RDWR: nbfd->direction = both_direction; break;
221 default: abort ();
222 }
223
224#ifdef BFD_LOCKS
225 memcpy (nbfd->lock, lockp, sizeof (struct flock))
226#endif
227
c0e5039e 228 bfd_cache_init (nbfd);
4a81b561
DHW
229
230 return nbfd;
231}
232\f
233/** bfd_openw -- open for writing.
6724ff46 234 Returns a pointer to a freshly-allocated BFD on success, or NULL.
4a81b561
DHW
235
236 See comment by bfd_fdopenr before you try to modify this function. */
237
6f715d66 238/*proto* bfd_openw
6724ff46 239Creates a BFD, associated with file @var{filename}, using the file
6f715d66
SC
240format @var{target}, and returns a pointer to it.
241
242Possible errors are system_call_error, no_memory, invalid_target.
243*; PROTO(bfd *, bfd_openw, (CONST char *filename, CONST char *target));
244*/
245
4a81b561 246bfd *
9846338e
SC
247DEFUN(bfd_openw,(filename, target),
248 CONST char *filename AND
249 CONST char *target)
4a81b561
DHW
250{
251 bfd *nbfd;
252 bfd_target *target_vec;
253
4a81b561
DHW
254 bfd_error = system_call_error;
255
256 /* nbfd has to point to head of malloc'ed block so that bfd_close may
257 reclaim it correctly. */
258
259 nbfd = new_bfd();
260 if (nbfd == NULL) {
261 bfd_error = no_memory;
262 return NULL;
263 }
264
c0e5039e
JG
265 target_vec = bfd_find_target (target, nbfd);
266 if (target_vec == NULL) return NULL;
267
4a81b561 268 nbfd->filename = filename;
4a81b561
DHW
269 nbfd->direction = write_direction;
270
271 if (bfd_open_file (nbfd) == NULL) {
272 bfd_error = system_call_error; /* File not writeable, etc */
fc723380 273 (void) obstack_free (&nbfd->memory, (PTR)0);
4a81b561
DHW
274 return NULL;
275 }
276 return nbfd;
277}
6f715d66
SC
278
279/*proto* bfd_close
6724ff46 280This function closes a BFD. If the BFD was open for writing, then
6f715d66
SC
281pending operations are completed and the file written out and closed.
282If the created file is executable, then @code{chmod} is called to mark
283it as such.
284
188d6d22 285All memory attached to the BFD's obstacks is released.
6f715d66
SC
286
287@code{true} is returned if all is ok, otherwise @code{false}.
288*; PROTO(boolean, bfd_close,(bfd *));
289*/
290
4a81b561 291boolean
6f715d66
SC
292DEFUN(bfd_close,(abfd),
293 bfd *abfd)
4a81b561 294{
2b1d8a50
JG
295 if (!bfd_read_p(abfd))
296 if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
297 return false;
298
4a81b561
DHW
299 if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
300
301 bfd_cache_close(abfd);
2b1d8a50
JG
302
303 /* If the file was open for writing and is now executable,
304 make it so */
4a81b561
DHW
305 if (abfd->direction == write_direction
306 && abfd->flags & EXEC_P) {
307 struct stat buf;
308 stat(abfd->filename, &buf);
7ed4093a
SC
309#ifndef S_IXUSR
310#define S_IXUSR 0100 /* Execute by owner. */
311#endif
312#ifndef S_IXGRP
313#define S_IXGRP 0010 /* Execute by group. */
314#endif
315#ifndef S_IXOTH
316#define S_IXOTH 0001 /* Execute by others. */
317#endif
318
4a81b561
DHW
319 chmod(abfd->filename,buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH);
320 }
fc723380 321 (void) obstack_free (&abfd->memory, (PTR)0);
2b1d8a50 322 /* FIXME, shouldn't we de-allocate the bfd as well? */
4a81b561
DHW
323 return true;
324}
fc723380 325
6f715d66 326/*proto* bfd_create
6724ff46
RP
327This routine creates a new BFD in the manner of @code{bfd_openw}, but without
328opening a file. The new BFD takes the target from the target used by
6f715d66
SC
329@var{template}. The format is always set to @code{bfd_object}.
330
331*; PROTO(bfd *, bfd_create, (CONST char *filename, bfd *template));
332*/
fc723380 333
4a81b561 334bfd *
9846338e
SC
335DEFUN(bfd_create,(filename, template),
336 CONST char *filename AND
6f715d66 337 bfd *template)
4a81b561
DHW
338{
339 bfd *nbfd = new_bfd();
340 if (nbfd == (bfd *)NULL) {
341 bfd_error = no_memory;
342 return (bfd *)NULL;
343 }
344 nbfd->filename = filename;
9872a49c
SC
345 if(template) {
346 nbfd->xvec = template->xvec;
347 }
4a81b561 348 nbfd->direction = no_direction;
9872a49c 349 bfd_set_format(nbfd, bfd_object);
4a81b561 350 return nbfd;
4a81b561 351}
9872a49c 352
fc723380
JG
353/* Memory allocation */
354
7ed4093a
SC
355DEFUN(PTR bfd_alloc_by_size_t,(abfd, size),
356 bfd *abfd AND
357 size_t size)
358{
359 PTR res = obstack_alloc(&(abfd->memory), size);
360 return res;
361}
6f715d66
SC
362
363DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
364 bfd *abfd AND
365 PTR ptr AND
366 bfd_size_type size)
367{
6724ff46 368 (void) obstack_grow(&(abfd->memory), ptr, size);
6f715d66
SC
369}
370DEFUN(PTR bfd_alloc_finish,(abfd),
371 bfd *abfd)
372{
373 return obstack_finish(&(abfd->memory));
374}
375
9872a49c
SC
376DEFUN(PTR bfd_alloc, (abfd, size),
377 bfd *abfd AND
fc723380 378 bfd_size_type size)
9872a49c 379{
7ed4093a 380 return bfd_alloc_by_size_t(abfd, (size_t)size);
9872a49c
SC
381}
382
383DEFUN(PTR bfd_zalloc,(abfd, size),
384 bfd *abfd AND
fc723380 385 bfd_size_type size)
9872a49c
SC
386{
387 PTR res = bfd_alloc(abfd, size);
fc723380 388 memset(res, 0, (size_t)size);
9872a49c
SC
389 return res;
390}
391
392DEFUN(PTR bfd_realloc,(abfd, old, size),
393 bfd *abfd AND
394 PTR old AND
fc723380 395 bfd_size_type size)
9872a49c
SC
396{
397 PTR res = bfd_alloc(abfd, size);
fc723380 398 memcpy(res, old, (size_t)size);
9872a49c
SC
399 return res;
400}
401
6f715d66
SC
402/*proto* bfd_alloc_size
403Return the number of bytes in the obstacks connected to the supplied
6724ff46 404BFD.
6f715d66
SC
405*; PROTO(bfd_size_type,bfd_alloc_size,(bfd *abfd));
406*/
9872a49c 407
6f715d66
SC
408bfd_size_type
409DEFUN( bfd_alloc_size,(abfd),
9872a49c
SC
410 bfd *abfd)
411{
412 struct _obstack_chunk *chunk = abfd->memory.chunk;
413 size_t size = 0;
414 while (chunk) {
415 size += chunk->limit - &(chunk->contents[0]);
416 chunk = chunk->prev;
417 }
418 return size;
419}
This page took 0.050186 seconds and 4 git commands to generate.