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