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