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