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