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