opncls.c revision 1.1 1 1.1 christos /* opncls.c -- open and close a BFD.
2 1.1 christos Copyright 1990-2013 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos Written by Cygnus Support.
5 1.1 christos
6 1.1 christos This file is part of BFD, the Binary File Descriptor library.
7 1.1 christos
8 1.1 christos This program is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3 of the License, or
11 1.1 christos (at your option) any later version.
12 1.1 christos
13 1.1 christos This program is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program; if not, write to the Free Software
20 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 1.1 christos MA 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include "sysdep.h"
24 1.1 christos #include "bfd.h"
25 1.1 christos #include "objalloc.h"
26 1.1 christos #include "libbfd.h"
27 1.1 christos #include "libiberty.h"
28 1.1 christos
29 1.1 christos #ifndef S_IXUSR
30 1.1 christos #define S_IXUSR 0100 /* Execute by owner. */
31 1.1 christos #endif
32 1.1 christos #ifndef S_IXGRP
33 1.1 christos #define S_IXGRP 0010 /* Execute by group. */
34 1.1 christos #endif
35 1.1 christos #ifndef S_IXOTH
36 1.1 christos #define S_IXOTH 0001 /* Execute by others. */
37 1.1 christos #endif
38 1.1 christos
39 1.1 christos /* Counters used to initialize the bfd identifier. */
40 1.1 christos
41 1.1 christos static unsigned int bfd_id_counter = 0;
42 1.1 christos static unsigned int bfd_reserved_id_counter = 0;
43 1.1 christos
44 1.1 christos /*
45 1.1 christos CODE_FRAGMENT
46 1.1 christos .{* Set to N to open the next N BFDs using an alternate id space. *}
47 1.1 christos .extern unsigned int bfd_use_reserved_id;
48 1.1 christos */
49 1.1 christos unsigned int bfd_use_reserved_id = 0;
50 1.1 christos
51 1.1 christos /* fdopen is a loser -- we should use stdio exclusively. Unfortunately
52 1.1 christos if we do that we can't use fcntl. */
53 1.1 christos
54 1.1 christos /* Return a new BFD. All BFD's are allocated through this routine. */
55 1.1 christos
56 1.1 christos bfd *
57 1.1 christos _bfd_new_bfd (void)
58 1.1 christos {
59 1.1 christos bfd *nbfd;
60 1.1 christos
61 1.1 christos nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
62 1.1 christos if (nbfd == NULL)
63 1.1 christos return NULL;
64 1.1 christos
65 1.1 christos if (bfd_use_reserved_id)
66 1.1 christos {
67 1.1 christos nbfd->id = --bfd_reserved_id_counter;
68 1.1 christos --bfd_use_reserved_id;
69 1.1 christos }
70 1.1 christos else
71 1.1 christos nbfd->id = bfd_id_counter++;
72 1.1 christos
73 1.1 christos nbfd->memory = objalloc_create ();
74 1.1 christos if (nbfd->memory == NULL)
75 1.1 christos {
76 1.1 christos bfd_set_error (bfd_error_no_memory);
77 1.1 christos free (nbfd);
78 1.1 christos return NULL;
79 1.1 christos }
80 1.1 christos
81 1.1 christos nbfd->arch_info = &bfd_default_arch_struct;
82 1.1 christos
83 1.1 christos if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
84 1.1 christos sizeof (struct section_hash_entry), 13))
85 1.1 christos {
86 1.1 christos free (nbfd);
87 1.1 christos return NULL;
88 1.1 christos }
89 1.1 christos
90 1.1 christos return nbfd;
91 1.1 christos }
92 1.1 christos
93 1.1 christos static const struct bfd_iovec opncls_iovec;
94 1.1 christos
95 1.1 christos /* Allocate a new BFD as a member of archive OBFD. */
96 1.1 christos
97 1.1 christos bfd *
98 1.1 christos _bfd_new_bfd_contained_in (bfd *obfd)
99 1.1 christos {
100 1.1 christos bfd *nbfd;
101 1.1 christos
102 1.1 christos nbfd = _bfd_new_bfd ();
103 1.1 christos if (nbfd == NULL)
104 1.1 christos return NULL;
105 1.1 christos nbfd->xvec = obfd->xvec;
106 1.1 christos nbfd->iovec = obfd->iovec;
107 1.1 christos if (obfd->iovec == &opncls_iovec)
108 1.1 christos nbfd->iostream = obfd->iostream;
109 1.1 christos nbfd->my_archive = obfd;
110 1.1 christos nbfd->direction = read_direction;
111 1.1 christos nbfd->target_defaulted = obfd->target_defaulted;
112 1.1 christos return nbfd;
113 1.1 christos }
114 1.1 christos
115 1.1 christos /* Delete a BFD. */
116 1.1 christos
117 1.1 christos static void
118 1.1 christos _bfd_delete_bfd (bfd *abfd)
119 1.1 christos {
120 1.1 christos if (abfd->memory)
121 1.1 christos {
122 1.1 christos bfd_hash_table_free (&abfd->section_htab);
123 1.1 christos objalloc_free ((struct objalloc *) abfd->memory);
124 1.1 christos }
125 1.1 christos
126 1.1 christos if (abfd->filename)
127 1.1 christos free ((char *) abfd->filename);
128 1.1 christos free (abfd->arelt_data);
129 1.1 christos free (abfd);
130 1.1 christos }
131 1.1 christos
132 1.1 christos /* Free objalloc memory. */
133 1.1 christos
134 1.1 christos bfd_boolean
135 1.1 christos _bfd_free_cached_info (bfd *abfd)
136 1.1 christos {
137 1.1 christos if (abfd->memory)
138 1.1 christos {
139 1.1 christos bfd_hash_table_free (&abfd->section_htab);
140 1.1 christos objalloc_free ((struct objalloc *) abfd->memory);
141 1.1 christos
142 1.1 christos abfd->sections = NULL;
143 1.1 christos abfd->section_last = NULL;
144 1.1 christos abfd->outsymbols = NULL;
145 1.1 christos abfd->tdata.any = NULL;
146 1.1 christos abfd->usrdata = NULL;
147 1.1 christos abfd->memory = NULL;
148 1.1 christos }
149 1.1 christos
150 1.1 christos return TRUE;
151 1.1 christos }
152 1.1 christos
153 1.1 christos /*
154 1.1 christos SECTION
155 1.1 christos Opening and closing BFDs
156 1.1 christos
157 1.1 christos SUBSECTION
158 1.1 christos Functions for opening and closing
159 1.1 christos */
160 1.1 christos
161 1.1 christos /*
162 1.1 christos FUNCTION
163 1.1 christos bfd_fopen
164 1.1 christos
165 1.1 christos SYNOPSIS
166 1.1 christos bfd *bfd_fopen (const char *filename, const char *target,
167 1.1 christos const char *mode, int fd);
168 1.1 christos
169 1.1 christos DESCRIPTION
170 1.1 christos Open the file @var{filename} with the target @var{target}.
171 1.1 christos Return a pointer to the created BFD. If @var{fd} is not -1,
172 1.1 christos then <<fdopen>> is used to open the file; otherwise, <<fopen>>
173 1.1 christos is used. @var{mode} is passed directly to <<fopen>> or
174 1.1 christos <<fdopen>>.
175 1.1 christos
176 1.1 christos Calls <<bfd_find_target>>, so @var{target} is interpreted as by
177 1.1 christos that function.
178 1.1 christos
179 1.1 christos The new BFD is marked as cacheable iff @var{fd} is -1.
180 1.1 christos
181 1.1 christos If <<NULL>> is returned then an error has occured. Possible errors
182 1.1 christos are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
183 1.1 christos <<system_call>> error.
184 1.1 christos
185 1.1 christos On error, @var{fd} is always closed.
186 1.1 christos
187 1.1 christos A copy of the @var{filename} argument is stored in the newly created
188 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
189 1.1 christos */
190 1.1 christos
191 1.1 christos bfd *
192 1.1 christos bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
193 1.1 christos {
194 1.1 christos bfd *nbfd;
195 1.1 christos const bfd_target *target_vec;
196 1.1 christos
197 1.1 christos nbfd = _bfd_new_bfd ();
198 1.1 christos if (nbfd == NULL)
199 1.1 christos {
200 1.1 christos if (fd != -1)
201 1.1 christos close (fd);
202 1.1 christos return NULL;
203 1.1 christos }
204 1.1 christos
205 1.1 christos target_vec = bfd_find_target (target, nbfd);
206 1.1 christos if (target_vec == NULL)
207 1.1 christos {
208 1.1 christos if (fd != -1)
209 1.1 christos close (fd);
210 1.1 christos _bfd_delete_bfd (nbfd);
211 1.1 christos return NULL;
212 1.1 christos }
213 1.1 christos
214 1.1 christos #ifdef HAVE_FDOPEN
215 1.1 christos if (fd != -1)
216 1.1 christos nbfd->iostream = fdopen (fd, mode);
217 1.1 christos else
218 1.1 christos #endif
219 1.1 christos nbfd->iostream = real_fopen (filename, mode);
220 1.1 christos if (nbfd->iostream == NULL)
221 1.1 christos {
222 1.1 christos bfd_set_error (bfd_error_system_call);
223 1.1 christos _bfd_delete_bfd (nbfd);
224 1.1 christos return NULL;
225 1.1 christos }
226 1.1 christos
227 1.1 christos /* OK, put everything where it belongs. */
228 1.1 christos
229 1.1 christos /* PR 11983: Do not cache the original filename, but
230 1.1 christos rather make a copy - the original might go away. */
231 1.1 christos nbfd->filename = xstrdup (filename);
232 1.1 christos
233 1.1 christos /* Figure out whether the user is opening the file for reading,
234 1.1 christos writing, or both, by looking at the MODE argument. */
235 1.1 christos if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a')
236 1.1 christos && mode[1] == '+')
237 1.1 christos nbfd->direction = both_direction;
238 1.1 christos else if (mode[0] == 'r')
239 1.1 christos nbfd->direction = read_direction;
240 1.1 christos else
241 1.1 christos nbfd->direction = write_direction;
242 1.1 christos
243 1.1 christos if (! bfd_cache_init (nbfd))
244 1.1 christos {
245 1.1 christos _bfd_delete_bfd (nbfd);
246 1.1 christos return NULL;
247 1.1 christos }
248 1.1 christos nbfd->opened_once = TRUE;
249 1.1 christos
250 1.1 christos /* If we opened the file by name, mark it cacheable; we can close it
251 1.1 christos and reopen it later. However, if a file descriptor was provided,
252 1.1 christos then it may have been opened with special flags that make it
253 1.1 christos unsafe to close and reopen the file. */
254 1.1 christos if (fd == -1)
255 1.1 christos (void) bfd_set_cacheable (nbfd, TRUE);
256 1.1 christos
257 1.1 christos return nbfd;
258 1.1 christos }
259 1.1 christos
260 1.1 christos /*
261 1.1 christos FUNCTION
262 1.1 christos bfd_openr
263 1.1 christos
264 1.1 christos SYNOPSIS
265 1.1 christos bfd *bfd_openr (const char *filename, const char *target);
266 1.1 christos
267 1.1 christos DESCRIPTION
268 1.1 christos Open the file @var{filename} (using <<fopen>>) with the target
269 1.1 christos @var{target}. Return a pointer to the created BFD.
270 1.1 christos
271 1.1 christos Calls <<bfd_find_target>>, so @var{target} is interpreted as by
272 1.1 christos that function.
273 1.1 christos
274 1.1 christos If <<NULL>> is returned then an error has occured. Possible errors
275 1.1 christos are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
276 1.1 christos <<system_call>> error.
277 1.1 christos
278 1.1 christos A copy of the @var{filename} argument is stored in the newly created
279 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
280 1.1 christos */
281 1.1 christos
282 1.1 christos bfd *
283 1.1 christos bfd_openr (const char *filename, const char *target)
284 1.1 christos {
285 1.1 christos return bfd_fopen (filename, target, FOPEN_RB, -1);
286 1.1 christos }
287 1.1 christos
288 1.1 christos /* Don't try to `optimize' this function:
289 1.1 christos
290 1.1 christos o - We lock using stack space so that interrupting the locking
291 1.1 christos won't cause a storage leak.
292 1.1 christos o - We open the file stream last, since we don't want to have to
293 1.1 christos close it if anything goes wrong. Closing the stream means closing
294 1.1 christos the file descriptor too, even though we didn't open it. */
295 1.1 christos /*
296 1.1 christos FUNCTION
297 1.1 christos bfd_fdopenr
298 1.1 christos
299 1.1 christos SYNOPSIS
300 1.1 christos bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
301 1.1 christos
302 1.1 christos DESCRIPTION
303 1.1 christos <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
304 1.1 christos <<fopen>>. It opens a BFD on a file already described by the
305 1.1 christos @var{fd} supplied.
306 1.1 christos
307 1.1 christos When the file is later <<bfd_close>>d, the file descriptor will
308 1.1 christos be closed. If the caller desires that this file descriptor be
309 1.1 christos cached by BFD (opened as needed, closed as needed to free
310 1.1 christos descriptors for other opens), with the supplied @var{fd} used as
311 1.1 christos an initial file descriptor (but subject to closure at any time),
312 1.1 christos call bfd_set_cacheable(bfd, 1) on the returned BFD. The default
313 1.1 christos is to assume no caching; the file descriptor will remain open
314 1.1 christos until <<bfd_close>>, and will not be affected by BFD operations
315 1.1 christos on other files.
316 1.1 christos
317 1.1 christos Possible errors are <<bfd_error_no_memory>>,
318 1.1 christos <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
319 1.1 christos
320 1.1 christos On error, @var{fd} is closed.
321 1.1 christos
322 1.1 christos A copy of the @var{filename} argument is stored in the newly created
323 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
324 1.1 christos */
325 1.1 christos
326 1.1 christos bfd *
327 1.1 christos bfd_fdopenr (const char *filename, const char *target, int fd)
328 1.1 christos {
329 1.1 christos const char *mode;
330 1.1 christos #if defined(HAVE_FCNTL) && defined(F_GETFL)
331 1.1 christos int fdflags;
332 1.1 christos #endif
333 1.1 christos
334 1.1 christos #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
335 1.1 christos mode = FOPEN_RUB; /* Assume full access. */
336 1.1 christos #else
337 1.1 christos fdflags = fcntl (fd, F_GETFL, NULL);
338 1.1 christos if (fdflags == -1)
339 1.1 christos {
340 1.1 christos int save = errno;
341 1.1 christos
342 1.1 christos close (fd);
343 1.1 christos errno = save;
344 1.1 christos bfd_set_error (bfd_error_system_call);
345 1.1 christos return NULL;
346 1.1 christos }
347 1.1 christos
348 1.1 christos /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */
349 1.1 christos switch (fdflags & (O_ACCMODE))
350 1.1 christos {
351 1.1 christos case O_RDONLY: mode = FOPEN_RB; break;
352 1.1 christos case O_WRONLY: mode = FOPEN_RUB; break;
353 1.1 christos case O_RDWR: mode = FOPEN_RUB; break;
354 1.1 christos default: abort ();
355 1.1 christos }
356 1.1 christos #endif
357 1.1 christos
358 1.1 christos return bfd_fopen (filename, target, mode, fd);
359 1.1 christos }
360 1.1 christos
361 1.1 christos /*
362 1.1 christos FUNCTION
363 1.1 christos bfd_openstreamr
364 1.1 christos
365 1.1 christos SYNOPSIS
366 1.1 christos bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
367 1.1 christos
368 1.1 christos DESCRIPTION
369 1.1 christos
370 1.1 christos Open a BFD for read access on an existing stdio stream. When
371 1.1 christos the BFD is passed to <<bfd_close>>, the stream will be closed.
372 1.1 christos
373 1.1 christos A copy of the @var{filename} argument is stored in the newly created
374 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
375 1.1 christos */
376 1.1 christos
377 1.1 christos bfd *
378 1.1 christos bfd_openstreamr (const char *filename, const char *target, void *streamarg)
379 1.1 christos {
380 1.1 christos FILE *stream = (FILE *) streamarg;
381 1.1 christos bfd *nbfd;
382 1.1 christos const bfd_target *target_vec;
383 1.1 christos
384 1.1 christos nbfd = _bfd_new_bfd ();
385 1.1 christos if (nbfd == NULL)
386 1.1 christos return NULL;
387 1.1 christos
388 1.1 christos target_vec = bfd_find_target (target, nbfd);
389 1.1 christos if (target_vec == NULL)
390 1.1 christos {
391 1.1 christos _bfd_delete_bfd (nbfd);
392 1.1 christos return NULL;
393 1.1 christos }
394 1.1 christos
395 1.1 christos nbfd->iostream = stream;
396 1.1 christos /* PR 11983: Do not cache the original filename, but
397 1.1 christos rather make a copy - the original might go away. */
398 1.1 christos nbfd->filename = xstrdup (filename);
399 1.1 christos nbfd->direction = read_direction;
400 1.1 christos
401 1.1 christos if (! bfd_cache_init (nbfd))
402 1.1 christos {
403 1.1 christos _bfd_delete_bfd (nbfd);
404 1.1 christos return NULL;
405 1.1 christos }
406 1.1 christos
407 1.1 christos return nbfd;
408 1.1 christos }
409 1.1 christos
410 1.1 christos /*
411 1.1 christos FUNCTION
412 1.1 christos bfd_openr_iovec
413 1.1 christos
414 1.1 christos SYNOPSIS
415 1.1 christos bfd *bfd_openr_iovec (const char *filename, const char *target,
416 1.1 christos void *(*open_func) (struct bfd *nbfd,
417 1.1 christos void *open_closure),
418 1.1 christos void *open_closure,
419 1.1 christos file_ptr (*pread_func) (struct bfd *nbfd,
420 1.1 christos void *stream,
421 1.1 christos void *buf,
422 1.1 christos file_ptr nbytes,
423 1.1 christos file_ptr offset),
424 1.1 christos int (*close_func) (struct bfd *nbfd,
425 1.1 christos void *stream),
426 1.1 christos int (*stat_func) (struct bfd *abfd,
427 1.1 christos void *stream,
428 1.1 christos struct stat *sb));
429 1.1 christos
430 1.1 christos DESCRIPTION
431 1.1 christos
432 1.1 christos Create and return a BFD backed by a read-only @var{stream}.
433 1.1 christos The @var{stream} is created using @var{open_func}, accessed using
434 1.1 christos @var{pread_func} and destroyed using @var{close_func}.
435 1.1 christos
436 1.1 christos Calls <<bfd_find_target>>, so @var{target} is interpreted as by
437 1.1 christos that function.
438 1.1 christos
439 1.1 christos Calls @var{open_func} (which can call <<bfd_zalloc>> and
440 1.1 christos <<bfd_get_filename>>) to obtain the read-only stream backing
441 1.1 christos the BFD. @var{open_func} either succeeds returning the
442 1.1 christos non-<<NULL>> @var{stream}, or fails returning <<NULL>>
443 1.1 christos (setting <<bfd_error>>).
444 1.1 christos
445 1.1 christos Calls @var{pread_func} to request @var{nbytes} of data from
446 1.1 christos @var{stream} starting at @var{offset} (e.g., via a call to
447 1.1 christos <<bfd_read>>). @var{pread_func} either succeeds returning the
448 1.1 christos number of bytes read (which can be less than @var{nbytes} when
449 1.1 christos end-of-file), or fails returning -1 (setting <<bfd_error>>).
450 1.1 christos
451 1.1 christos Calls @var{close_func} when the BFD is later closed using
452 1.1 christos <<bfd_close>>. @var{close_func} either succeeds returning 0, or
453 1.1 christos fails returning -1 (setting <<bfd_error>>).
454 1.1 christos
455 1.1 christos Calls @var{stat_func} to fill in a stat structure for bfd_stat,
456 1.1 christos bfd_get_size, and bfd_get_mtime calls. @var{stat_func} returns 0
457 1.1 christos on success, or returns -1 on failure (setting <<bfd_error>>).
458 1.1 christos
459 1.1 christos If <<bfd_openr_iovec>> returns <<NULL>> then an error has
460 1.1 christos occurred. Possible errors are <<bfd_error_no_memory>>,
461 1.1 christos <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
462 1.1 christos
463 1.1 christos A copy of the @var{filename} argument is stored in the newly created
464 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
465 1.1 christos */
466 1.1 christos
467 1.1 christos struct opncls
468 1.1 christos {
469 1.1 christos void *stream;
470 1.1 christos file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf,
471 1.1 christos file_ptr nbytes, file_ptr offset);
472 1.1 christos int (*close) (struct bfd *abfd, void *stream);
473 1.1 christos int (*stat) (struct bfd *abfd, void *stream, struct stat *sb);
474 1.1 christos file_ptr where;
475 1.1 christos };
476 1.1 christos
477 1.1 christos static file_ptr
478 1.1 christos opncls_btell (struct bfd *abfd)
479 1.1 christos {
480 1.1 christos struct opncls *vec = (struct opncls *) abfd->iostream;
481 1.1 christos return vec->where;
482 1.1 christos }
483 1.1 christos
484 1.1 christos static int
485 1.1 christos opncls_bseek (struct bfd *abfd, file_ptr offset, int whence)
486 1.1 christos {
487 1.1 christos struct opncls *vec = (struct opncls *) abfd->iostream;
488 1.1 christos switch (whence)
489 1.1 christos {
490 1.1 christos case SEEK_SET: vec->where = offset; break;
491 1.1 christos case SEEK_CUR: vec->where += offset; break;
492 1.1 christos case SEEK_END: return -1;
493 1.1 christos }
494 1.1 christos return 0;
495 1.1 christos }
496 1.1 christos
497 1.1 christos static file_ptr
498 1.1 christos opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
499 1.1 christos {
500 1.1 christos struct opncls *vec = (struct opncls *) abfd->iostream;
501 1.1 christos file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where);
502 1.1 christos if (nread < 0)
503 1.1 christos return nread;
504 1.1 christos vec->where += nread;
505 1.1 christos return nread;
506 1.1 christos }
507 1.1 christos
508 1.1 christos static file_ptr
509 1.1 christos opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
510 1.1 christos const void *where ATTRIBUTE_UNUSED,
511 1.1 christos file_ptr nbytes ATTRIBUTE_UNUSED)
512 1.1 christos {
513 1.1 christos return -1;
514 1.1 christos }
515 1.1 christos
516 1.1 christos static int
517 1.1 christos opncls_bclose (struct bfd *abfd)
518 1.1 christos {
519 1.1 christos struct opncls *vec = (struct opncls *) abfd->iostream;
520 1.1 christos /* Since the VEC's memory is bound to the bfd deleting the bfd will
521 1.1 christos free it. */
522 1.1 christos int status = 0;
523 1.1 christos if (vec->close != NULL)
524 1.1 christos status = (vec->close) (abfd, vec->stream);
525 1.1 christos abfd->iostream = NULL;
526 1.1 christos return status;
527 1.1 christos }
528 1.1 christos
529 1.1 christos static int
530 1.1 christos opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
531 1.1 christos {
532 1.1 christos return 0;
533 1.1 christos }
534 1.1 christos
535 1.1 christos static int
536 1.1 christos opncls_bstat (struct bfd *abfd, struct stat *sb)
537 1.1 christos {
538 1.1 christos struct opncls *vec = (struct opncls *) abfd->iostream;
539 1.1 christos
540 1.1 christos memset (sb, 0, sizeof (*sb));
541 1.1 christos if (vec->stat == NULL)
542 1.1 christos return 0;
543 1.1 christos
544 1.1 christos return (vec->stat) (abfd, vec->stream, sb);
545 1.1 christos }
546 1.1 christos
547 1.1 christos static void *
548 1.1 christos opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
549 1.1 christos void *addr ATTRIBUTE_UNUSED,
550 1.1 christos bfd_size_type len ATTRIBUTE_UNUSED,
551 1.1 christos int prot ATTRIBUTE_UNUSED,
552 1.1 christos int flags ATTRIBUTE_UNUSED,
553 1.1 christos file_ptr offset ATTRIBUTE_UNUSED,
554 1.1 christos void **map_addr ATTRIBUTE_UNUSED,
555 1.1 christos bfd_size_type *map_len ATTRIBUTE_UNUSED)
556 1.1 christos {
557 1.1 christos return (void *) -1;
558 1.1 christos }
559 1.1 christos
560 1.1 christos static const struct bfd_iovec opncls_iovec = {
561 1.1 christos &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
562 1.1 christos &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap
563 1.1 christos };
564 1.1 christos
565 1.1 christos bfd *
566 1.1 christos bfd_openr_iovec (const char *filename, const char *target,
567 1.1 christos void *(*open_p) (struct bfd *, void *),
568 1.1 christos void *open_closure,
569 1.1 christos file_ptr (*pread_p) (struct bfd *, void *, void *,
570 1.1 christos file_ptr, file_ptr),
571 1.1 christos int (*close_p) (struct bfd *, void *),
572 1.1 christos int (*stat_p) (struct bfd *, void *, struct stat *))
573 1.1 christos {
574 1.1 christos bfd *nbfd;
575 1.1 christos const bfd_target *target_vec;
576 1.1 christos struct opncls *vec;
577 1.1 christos void *stream;
578 1.1 christos
579 1.1 christos nbfd = _bfd_new_bfd ();
580 1.1 christos if (nbfd == NULL)
581 1.1 christos return NULL;
582 1.1 christos
583 1.1 christos target_vec = bfd_find_target (target, nbfd);
584 1.1 christos if (target_vec == NULL)
585 1.1 christos {
586 1.1 christos _bfd_delete_bfd (nbfd);
587 1.1 christos return NULL;
588 1.1 christos }
589 1.1 christos
590 1.1 christos /* PR 11983: Do not cache the original filename, but
591 1.1 christos rather make a copy - the original might go away. */
592 1.1 christos nbfd->filename = xstrdup (filename);
593 1.1 christos nbfd->direction = read_direction;
594 1.1 christos
595 1.1 christos /* `open_p (...)' would get expanded by an the open(2) syscall macro. */
596 1.1 christos stream = (*open_p) (nbfd, open_closure);
597 1.1 christos if (stream == NULL)
598 1.1 christos {
599 1.1 christos _bfd_delete_bfd (nbfd);
600 1.1 christos return NULL;
601 1.1 christos }
602 1.1 christos
603 1.1 christos vec = (struct opncls *) bfd_zalloc (nbfd, sizeof (struct opncls));
604 1.1 christos vec->stream = stream;
605 1.1 christos vec->pread = pread_p;
606 1.1 christos vec->close = close_p;
607 1.1 christos vec->stat = stat_p;
608 1.1 christos
609 1.1 christos nbfd->iovec = &opncls_iovec;
610 1.1 christos nbfd->iostream = vec;
611 1.1 christos
612 1.1 christos return nbfd;
613 1.1 christos }
614 1.1 christos
615 1.1 christos /* bfd_openw -- open for writing.
617 1.1 christos Returns a pointer to a freshly-allocated BFD on success, or NULL.
618 1.1 christos
619 1.1 christos See comment by bfd_fdopenr before you try to modify this function. */
620 1.1 christos
621 1.1 christos /*
622 1.1 christos FUNCTION
623 1.1 christos bfd_openw
624 1.1 christos
625 1.1 christos SYNOPSIS
626 1.1 christos bfd *bfd_openw (const char *filename, const char *target);
627 1.1 christos
628 1.1 christos DESCRIPTION
629 1.1 christos Create a BFD, associated with file @var{filename}, using the
630 1.1 christos file format @var{target}, and return a pointer to it.
631 1.1 christos
632 1.1 christos Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
633 1.1 christos <<bfd_error_invalid_target>>.
634 1.1 christos
635 1.1 christos A copy of the @var{filename} argument is stored in the newly created
636 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
637 1.1 christos */
638 1.1 christos
639 1.1 christos bfd *
640 1.1 christos bfd_openw (const char *filename, const char *target)
641 1.1 christos {
642 1.1 christos bfd *nbfd;
643 1.1 christos const bfd_target *target_vec;
644 1.1 christos
645 1.1 christos /* nbfd has to point to head of malloc'ed block so that bfd_close may
646 1.1 christos reclaim it correctly. */
647 1.1 christos nbfd = _bfd_new_bfd ();
648 1.1 christos if (nbfd == NULL)
649 1.1 christos return NULL;
650 1.1 christos
651 1.1 christos target_vec = bfd_find_target (target, nbfd);
652 1.1 christos if (target_vec == NULL)
653 1.1 christos {
654 1.1 christos _bfd_delete_bfd (nbfd);
655 1.1 christos return NULL;
656 1.1 christos }
657 1.1 christos
658 1.1 christos /* PR 11983: Do not cache the original filename, but
659 1.1 christos rather make a copy - the original might go away. */
660 1.1 christos nbfd->filename = xstrdup (filename);
661 1.1 christos nbfd->direction = write_direction;
662 1.1 christos
663 1.1 christos if (bfd_open_file (nbfd) == NULL)
664 1.1 christos {
665 1.1 christos /* File not writeable, etc. */
666 1.1 christos bfd_set_error (bfd_error_system_call);
667 1.1 christos _bfd_delete_bfd (nbfd);
668 1.1 christos return NULL;
669 1.1 christos }
670 1.1 christos
671 1.1 christos return nbfd;
672 1.1 christos }
673 1.1 christos
674 1.1 christos static inline void
675 1.1 christos _maybe_make_executable (bfd * abfd)
676 1.1 christos {
677 1.1 christos /* If the file was open for writing and is now executable,
678 1.1 christos make it so. */
679 1.1 christos if (abfd->direction == write_direction
680 1.1 christos && (abfd->flags & (EXEC_P | DYNAMIC)) != 0)
681 1.1 christos {
682 1.1 christos struct stat buf;
683 1.1 christos
684 1.1 christos if (stat (abfd->filename, &buf) == 0
685 1.1 christos /* Do not attempt to change non-regular files. This is
686 1.1 christos here especially for configure scripts and kernel builds
687 1.1 christos which run tests with "ld [...] -o /dev/null". */
688 1.1 christos && S_ISREG(buf.st_mode))
689 1.1 christos {
690 1.1 christos unsigned int mask = umask (0);
691 1.1 christos
692 1.1 christos umask (mask);
693 1.1 christos chmod (abfd->filename,
694 1.1 christos (0777
695 1.1 christos & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
696 1.1 christos }
697 1.1 christos }
698 1.1 christos }
699 1.1 christos
700 1.1 christos /*
701 1.1 christos
702 1.1 christos FUNCTION
703 1.1 christos bfd_close
704 1.1 christos
705 1.1 christos SYNOPSIS
706 1.1 christos bfd_boolean bfd_close (bfd *abfd);
707 1.1 christos
708 1.1 christos DESCRIPTION
709 1.1 christos
710 1.1 christos Close a BFD. If the BFD was open for writing, then pending
711 1.1 christos operations are completed and the file written out and closed.
712 1.1 christos If the created file is executable, then <<chmod>> is called
713 1.1 christos to mark it as such.
714 1.1 christos
715 1.1 christos All memory attached to the BFD is released.
716 1.1 christos
717 1.1 christos The file descriptor associated with the BFD is closed (even
718 1.1 christos if it was passed in to BFD by <<bfd_fdopenr>>).
719 1.1 christos
720 1.1 christos RETURNS
721 1.1 christos <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
722 1.1 christos */
723 1.1 christos
724 1.1 christos
725 1.1 christos bfd_boolean
726 1.1 christos bfd_close (bfd *abfd)
727 1.1 christos {
728 1.1 christos bfd_boolean ret;
729 1.1 christos
730 1.1 christos if (bfd_write_p (abfd))
731 1.1 christos {
732 1.1 christos if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
733 1.1 christos return FALSE;
734 1.1 christos }
735 1.1 christos
736 1.1 christos if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
737 1.1 christos return FALSE;
738 1.1 christos
739 1.1 christos ret = abfd->iovec->bclose (abfd) == 0;
740 1.1 christos
741 1.1 christos if (ret)
742 1.1 christos _maybe_make_executable (abfd);
743 1.1 christos
744 1.1 christos _bfd_delete_bfd (abfd);
745 1.1 christos
746 1.1 christos return ret;
747 1.1 christos }
748 1.1 christos
749 1.1 christos /*
750 1.1 christos FUNCTION
751 1.1 christos bfd_close_all_done
752 1.1 christos
753 1.1 christos SYNOPSIS
754 1.1 christos bfd_boolean bfd_close_all_done (bfd *);
755 1.1 christos
756 1.1 christos DESCRIPTION
757 1.1 christos Close a BFD. Differs from <<bfd_close>> since it does not
758 1.1 christos complete any pending operations. This routine would be used
759 1.1 christos if the application had just used BFD for swapping and didn't
760 1.1 christos want to use any of the writing code.
761 1.1 christos
762 1.1 christos If the created file is executable, then <<chmod>> is called
763 1.1 christos to mark it as such.
764 1.1 christos
765 1.1 christos All memory attached to the BFD is released.
766 1.1 christos
767 1.1 christos RETURNS
768 1.1 christos <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
769 1.1 christos */
770 1.1 christos
771 1.1 christos bfd_boolean
772 1.1 christos bfd_close_all_done (bfd *abfd)
773 1.1 christos {
774 1.1 christos bfd_boolean ret;
775 1.1 christos
776 1.1 christos ret = bfd_cache_close (abfd);
777 1.1 christos
778 1.1 christos if (ret)
779 1.1 christos _maybe_make_executable (abfd);
780 1.1 christos
781 1.1 christos _bfd_delete_bfd (abfd);
782 1.1 christos
783 1.1 christos return ret;
784 1.1 christos }
785 1.1 christos
786 1.1 christos /*
787 1.1 christos FUNCTION
788 1.1 christos bfd_create
789 1.1 christos
790 1.1 christos SYNOPSIS
791 1.1 christos bfd *bfd_create (const char *filename, bfd *templ);
792 1.1 christos
793 1.1 christos DESCRIPTION
794 1.1 christos Create a new BFD in the manner of <<bfd_openw>>, but without
795 1.1 christos opening a file. The new BFD takes the target from the target
796 1.1 christos used by @var{templ}. The format is always set to <<bfd_object>>.
797 1.1 christos
798 1.1 christos A copy of the @var{filename} argument is stored in the newly created
799 1.1 christos BFD. It can be accessed via the bfd_get_filename() macro.
800 1.1 christos */
801 1.1 christos
802 1.1 christos bfd *
803 1.1 christos bfd_create (const char *filename, bfd *templ)
804 1.1 christos {
805 1.1 christos bfd *nbfd;
806 1.1 christos
807 1.1 christos nbfd = _bfd_new_bfd ();
808 1.1 christos if (nbfd == NULL)
809 1.1 christos return NULL;
810 1.1 christos /* PR 11983: Do not cache the original filename, but
811 1.1 christos rather make a copy - the original might go away. */
812 1.1 christos nbfd->filename = xstrdup (filename);
813 1.1 christos if (templ)
814 1.1 christos nbfd->xvec = templ->xvec;
815 1.1 christos nbfd->direction = no_direction;
816 1.1 christos bfd_set_format (nbfd, bfd_object);
817 1.1 christos
818 1.1 christos return nbfd;
819 1.1 christos }
820 1.1 christos
821 1.1 christos /*
822 1.1 christos FUNCTION
823 1.1 christos bfd_make_writable
824 1.1 christos
825 1.1 christos SYNOPSIS
826 1.1 christos bfd_boolean bfd_make_writable (bfd *abfd);
827 1.1 christos
828 1.1 christos DESCRIPTION
829 1.1 christos Takes a BFD as created by <<bfd_create>> and converts it
830 1.1 christos into one like as returned by <<bfd_openw>>. It does this
831 1.1 christos by converting the BFD to BFD_IN_MEMORY. It's assumed that
832 1.1 christos you will call <<bfd_make_readable>> on this bfd later.
833 1.1 christos
834 1.1 christos RETURNS
835 1.1 christos <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
836 1.1 christos */
837 1.1 christos
838 1.1 christos bfd_boolean
839 1.1 christos bfd_make_writable (bfd *abfd)
840 1.1 christos {
841 1.1 christos struct bfd_in_memory *bim;
842 1.1 christos
843 1.1 christos if (abfd->direction != no_direction)
844 1.1 christos {
845 1.1 christos bfd_set_error (bfd_error_invalid_operation);
846 1.1 christos return FALSE;
847 1.1 christos }
848 1.1 christos
849 1.1 christos bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory));
850 1.1 christos if (bim == NULL)
851 1.1 christos return FALSE; /* bfd_error already set. */
852 1.1 christos abfd->iostream = bim;
853 1.1 christos /* bfd_bwrite will grow these as needed. */
854 1.1 christos bim->size = 0;
855 1.1 christos bim->buffer = 0;
856 1.1 christos
857 1.1 christos abfd->flags |= BFD_IN_MEMORY;
858 1.1 christos abfd->iovec = &_bfd_memory_iovec;
859 1.1 christos abfd->origin = 0;
860 1.1 christos abfd->direction = write_direction;
861 1.1 christos abfd->where = 0;
862 1.1 christos
863 1.1 christos return TRUE;
864 1.1 christos }
865 1.1 christos
866 1.1 christos /*
867 1.1 christos FUNCTION
868 1.1 christos bfd_make_readable
869 1.1 christos
870 1.1 christos SYNOPSIS
871 1.1 christos bfd_boolean bfd_make_readable (bfd *abfd);
872 1.1 christos
873 1.1 christos DESCRIPTION
874 1.1 christos Takes a BFD as created by <<bfd_create>> and
875 1.1 christos <<bfd_make_writable>> and converts it into one like as
876 1.1 christos returned by <<bfd_openr>>. It does this by writing the
877 1.1 christos contents out to the memory buffer, then reversing the
878 1.1 christos direction.
879 1.1 christos
880 1.1 christos RETURNS
881 1.1 christos <<TRUE>> is returned if all is ok, otherwise <<FALSE>>. */
882 1.1 christos
883 1.1 christos bfd_boolean
884 1.1 christos bfd_make_readable (bfd *abfd)
885 1.1 christos {
886 1.1 christos if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
887 1.1 christos {
888 1.1 christos bfd_set_error (bfd_error_invalid_operation);
889 1.1 christos return FALSE;
890 1.1 christos }
891 1.1 christos
892 1.1 christos if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
893 1.1 christos return FALSE;
894 1.1 christos
895 1.1 christos if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
896 1.1 christos return FALSE;
897 1.1 christos
898 1.1 christos abfd->arch_info = &bfd_default_arch_struct;
899 1.1 christos
900 1.1 christos abfd->where = 0;
901 1.1 christos abfd->format = bfd_unknown;
902 1.1 christos abfd->my_archive = NULL;
903 1.1 christos abfd->origin = 0;
904 1.1 christos abfd->opened_once = FALSE;
905 1.1 christos abfd->output_has_begun = FALSE;
906 1.1 christos abfd->section_count = 0;
907 1.1 christos abfd->usrdata = NULL;
908 1.1 christos abfd->cacheable = FALSE;
909 1.1 christos abfd->flags |= BFD_IN_MEMORY;
910 1.1 christos abfd->mtime_set = FALSE;
911 1.1 christos
912 1.1 christos abfd->target_defaulted = TRUE;
913 1.1 christos abfd->direction = read_direction;
914 1.1 christos abfd->sections = 0;
915 1.1 christos abfd->symcount = 0;
916 1.1 christos abfd->outsymbols = 0;
917 1.1 christos abfd->tdata.any = 0;
918 1.1 christos
919 1.1 christos bfd_section_list_clear (abfd);
920 1.1 christos bfd_check_format (abfd, bfd_object);
921 1.1 christos
922 1.1 christos return TRUE;
923 1.1 christos }
924 1.1 christos
925 1.1 christos /*
926 1.1 christos FUNCTION
927 1.1 christos bfd_alloc
928 1.1 christos
929 1.1 christos SYNOPSIS
930 1.1 christos void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
931 1.1 christos
932 1.1 christos DESCRIPTION
933 1.1 christos Allocate a block of @var{wanted} bytes of memory attached to
934 1.1 christos <<abfd>> and return a pointer to it.
935 1.1 christos */
936 1.1 christos
937 1.1 christos void *
938 1.1 christos bfd_alloc (bfd *abfd, bfd_size_type size)
939 1.1 christos {
940 1.1 christos void *ret;
941 1.1 christos
942 1.1 christos if (size != (unsigned long) size)
943 1.1 christos {
944 1.1 christos bfd_set_error (bfd_error_no_memory);
945 1.1 christos return NULL;
946 1.1 christos }
947 1.1 christos
948 1.1 christos ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
949 1.1 christos if (ret == NULL)
950 1.1 christos bfd_set_error (bfd_error_no_memory);
951 1.1 christos return ret;
952 1.1 christos }
953 1.1 christos
954 1.1 christos /*
955 1.1 christos INTERNAL_FUNCTION
956 1.1 christos bfd_alloc2
957 1.1 christos
958 1.1 christos SYNOPSIS
959 1.1 christos void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
960 1.1 christos
961 1.1 christos DESCRIPTION
962 1.1 christos Allocate a block of @var{nmemb} elements of @var{size} bytes each
963 1.1 christos of memory attached to <<abfd>> and return a pointer to it.
964 1.1 christos */
965 1.1 christos
966 1.1 christos void *
967 1.1 christos bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
968 1.1 christos {
969 1.1 christos void *ret;
970 1.1 christos
971 1.1 christos if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
972 1.1 christos && size != 0
973 1.1 christos && nmemb > ~(bfd_size_type) 0 / size)
974 1.1 christos {
975 1.1 christos bfd_set_error (bfd_error_no_memory);
976 1.1 christos return NULL;
977 1.1 christos }
978 1.1 christos
979 1.1 christos size *= nmemb;
980 1.1 christos
981 1.1 christos if (size != (unsigned long) size)
982 1.1 christos {
983 1.1 christos bfd_set_error (bfd_error_no_memory);
984 1.1 christos return NULL;
985 1.1 christos }
986 1.1 christos
987 1.1 christos ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
988 1.1 christos if (ret == NULL)
989 1.1 christos bfd_set_error (bfd_error_no_memory);
990 1.1 christos return ret;
991 1.1 christos }
992 1.1 christos
993 1.1 christos /*
994 1.1 christos FUNCTION
995 1.1 christos bfd_zalloc
996 1.1 christos
997 1.1 christos SYNOPSIS
998 1.1 christos void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
999 1.1 christos
1000 1.1 christos DESCRIPTION
1001 1.1 christos Allocate a block of @var{wanted} bytes of zeroed memory
1002 1.1 christos attached to <<abfd>> and return a pointer to it.
1003 1.1 christos */
1004 1.1 christos
1005 1.1 christos void *
1006 1.1 christos bfd_zalloc (bfd *abfd, bfd_size_type size)
1007 1.1 christos {
1008 1.1 christos void *res;
1009 1.1 christos
1010 1.1 christos res = bfd_alloc (abfd, size);
1011 1.1 christos if (res)
1012 1.1 christos memset (res, 0, (size_t) size);
1013 1.1 christos return res;
1014 1.1 christos }
1015 1.1 christos
1016 1.1 christos /*
1017 1.1 christos INTERNAL_FUNCTION
1018 1.1 christos bfd_zalloc2
1019 1.1 christos
1020 1.1 christos SYNOPSIS
1021 1.1 christos void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
1022 1.1 christos
1023 1.1 christos DESCRIPTION
1024 1.1 christos Allocate a block of @var{nmemb} elements of @var{size} bytes each
1025 1.1 christos of zeroed memory attached to <<abfd>> and return a pointer to it.
1026 1.1 christos */
1027 1.1 christos
1028 1.1 christos void *
1029 1.1 christos bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
1030 1.1 christos {
1031 1.1 christos void *res;
1032 1.1 christos
1033 1.1 christos if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
1034 1.1 christos && size != 0
1035 1.1 christos && nmemb > ~(bfd_size_type) 0 / size)
1036 1.1 christos {
1037 1.1 christos bfd_set_error (bfd_error_no_memory);
1038 1.1 christos return NULL;
1039 1.1 christos }
1040 1.1 christos
1041 1.1 christos size *= nmemb;
1042 1.1 christos
1043 1.1 christos res = bfd_alloc (abfd, size);
1044 1.1 christos if (res)
1045 1.1 christos memset (res, 0, (size_t) size);
1046 1.1 christos return res;
1047 1.1 christos }
1048 1.1 christos
1049 1.1 christos /* Free a block allocated for a BFD.
1050 1.1 christos Note: Also frees all more recently allocated blocks! */
1051 1.1 christos
1052 1.1 christos void
1053 1.1 christos bfd_release (bfd *abfd, void *block)
1054 1.1 christos {
1055 1.1 christos objalloc_free_block ((struct objalloc *) abfd->memory, block);
1056 1.1 christos }
1057 1.1 christos
1058 1.1 christos
1059 1.1 christos /*
1060 1.1 christos GNU Extension: separate debug-info files
1061 1.1 christos
1062 1.1 christos The idea here is that a special section called .gnu_debuglink might be
1063 1.1 christos embedded in a binary file, which indicates that some *other* file
1064 1.1 christos contains the real debugging information. This special section contains a
1065 1.1 christos filename and CRC32 checksum, which we read and resolve to another file,
1066 1.1 christos if it exists.
1067 1.1 christos
1068 1.1 christos This facilitates "optional" provision of debugging information, without
1069 1.1 christos having to provide two complete copies of every binary object (with and
1070 1.1 christos without debug symbols). */
1071 1.1 christos
1072 1.1 christos #define GNU_DEBUGLINK ".gnu_debuglink"
1073 1.1 christos #define GNU_DEBUGALTLINK ".gnu_debugaltlink"
1074 1.1 christos
1075 1.1 christos /*
1076 1.1 christos FUNCTION
1077 1.1 christos bfd_calc_gnu_debuglink_crc32
1078 1.1 christos
1079 1.1 christos SYNOPSIS
1080 1.1 christos unsigned long bfd_calc_gnu_debuglink_crc32
1081 1.1 christos (unsigned long crc, const unsigned char *buf, bfd_size_type len);
1082 1.1 christos
1083 1.1 christos DESCRIPTION
1084 1.1 christos Computes a CRC value as used in the .gnu_debuglink section.
1085 1.1 christos Advances the previously computed @var{crc} value by computing
1086 1.1 christos and adding in the crc32 for @var{len} bytes of @var{buf}.
1087 1.1 christos
1088 1.1 christos RETURNS
1089 1.1 christos Return the updated CRC32 value.
1090 1.1 christos */
1091 1.1 christos
1092 1.1 christos unsigned long
1093 1.1 christos bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
1094 1.1 christos const unsigned char *buf,
1095 1.1 christos bfd_size_type len)
1096 1.1 christos {
1097 1.1 christos static const unsigned long crc32_table[256] =
1098 1.1 christos {
1099 1.1 christos 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
1100 1.1 christos 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
1101 1.1 christos 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
1102 1.1 christos 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1103 1.1 christos 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
1104 1.1 christos 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1105 1.1 christos 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
1106 1.1 christos 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1107 1.1 christos 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
1108 1.1 christos 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
1109 1.1 christos 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
1110 1.1 christos 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1111 1.1 christos 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
1112 1.1 christos 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
1113 1.1 christos 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
1114 1.1 christos 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1115 1.1 christos 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
1116 1.1 christos 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1117 1.1 christos 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
1118 1.1 christos 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1119 1.1 christos 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
1120 1.1 christos 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
1121 1.1 christos 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
1122 1.1 christos 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1123 1.1 christos 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
1124 1.1 christos 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
1125 1.1 christos 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
1126 1.1 christos 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1127 1.1 christos 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
1128 1.1 christos 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1129 1.1 christos 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
1130 1.1 christos 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1131 1.1 christos 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
1132 1.1 christos 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
1133 1.1 christos 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
1134 1.1 christos 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1135 1.1 christos 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
1136 1.1 christos 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
1137 1.1 christos 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
1138 1.1 christos 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1139 1.1 christos 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
1140 1.1 christos 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1141 1.1 christos 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
1142 1.1 christos 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1143 1.1 christos 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
1144 1.1 christos 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
1145 1.1 christos 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
1146 1.1 christos 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1147 1.1 christos 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
1148 1.1 christos 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
1149 1.1 christos 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
1150 1.1 christos 0x2d02ef8d
1151 1.1 christos };
1152 1.1 christos const unsigned char *end;
1153 1.1 christos
1154 1.1 christos crc = ~crc & 0xffffffff;
1155 1.1 christos for (end = buf + len; buf < end; ++ buf)
1156 1.1 christos crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
1157 1.1 christos return ~crc & 0xffffffff;
1158 1.1 christos }
1159 1.1 christos
1160 1.1 christos
1161 1.1 christos /*
1162 1.1 christos FUNCTION
1163 1.1 christos bfd_get_debug_link_info
1164 1.1 christos
1165 1.1 christos SYNOPSIS
1166 1.1 christos char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
1167 1.1 christos
1168 1.1 christos DESCRIPTION
1169 1.1 christos Fetch the filename and CRC32 value for any separate debuginfo
1170 1.1 christos associated with @var{abfd}. Return NULL if no such info found,
1171 1.1 christos otherwise return filename and update @var{crc32_out}. The
1172 1.1 christos returned filename is allocated with @code{malloc}; freeing it
1173 1.1 christos is the responsibility of the caller.
1174 1.1 christos */
1175 1.1 christos
1176 1.1 christos char *
1177 1.1 christos bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
1178 1.1 christos {
1179 1.1 christos asection *sect;
1180 1.1 christos unsigned long crc32;
1181 1.1 christos bfd_byte *contents;
1182 1.1 christos int crc_offset;
1183 1.1 christos char *name;
1184 1.1 christos
1185 1.1 christos BFD_ASSERT (abfd);
1186 1.1 christos BFD_ASSERT (crc32_out);
1187 1.1 christos
1188 1.1 christos sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
1189 1.1 christos
1190 1.1 christos if (sect == NULL)
1191 1.1 christos return NULL;
1192 1.1 christos
1193 1.1 christos if (!bfd_malloc_and_get_section (abfd, sect, &contents))
1194 1.1 christos {
1195 1.1 christos if (contents != NULL)
1196 1.1 christos free (contents);
1197 1.1 christos return NULL;
1198 1.1 christos }
1199 1.1 christos
1200 1.1 christos /* Crc value is stored after the filename, aligned up to 4 bytes. */
1201 1.1 christos name = (char *) contents;
1202 1.1 christos crc_offset = strlen (name) + 1;
1203 1.1 christos crc_offset = (crc_offset + 3) & ~3;
1204 1.1 christos
1205 1.1 christos crc32 = bfd_get_32 (abfd, contents + crc_offset);
1206 1.1 christos
1207 1.1 christos *crc32_out = crc32;
1208 1.1 christos return name;
1209 1.1 christos }
1210 1.1 christos
1211 1.1 christos /*
1212 1.1 christos FUNCTION
1213 1.1 christos bfd_get_alt_debug_link_info
1214 1.1 christos
1215 1.1 christos SYNOPSIS
1216 1.1 christos char *bfd_get_alt_debug_link_info (bfd * abfd,
1217 1.1 christos bfd_size_type *buildid_len,
1218 1.1 christos bfd_byte **buildid_out);
1219 1.1 christos
1220 1.1 christos DESCRIPTION
1221 1.1 christos Fetch the filename and BuildID value for any alternate debuginfo
1222 1.1 christos associated with @var{abfd}. Return NULL if no such info found,
1223 1.1 christos otherwise return filename and update @var{buildid_len} and
1224 1.1 christos @var{buildid_out}. The returned filename and build_id are
1225 1.1 christos allocated with @code{malloc}; freeing them is the
1226 1.1 christos responsibility of the caller.
1227 1.1 christos */
1228 1.1 christos
1229 1.1 christos char *
1230 1.1 christos bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
1231 1.1 christos bfd_byte **buildid_out)
1232 1.1 christos {
1233 1.1 christos asection *sect;
1234 1.1 christos bfd_byte *contents;
1235 1.1 christos int buildid_offset;
1236 1.1 christos char *name;
1237 1.1 christos
1238 1.1 christos BFD_ASSERT (abfd);
1239 1.1 christos BFD_ASSERT (buildid_len);
1240 1.1 christos BFD_ASSERT (buildid_out);
1241 1.1 christos
1242 1.1 christos sect = bfd_get_section_by_name (abfd, GNU_DEBUGALTLINK);
1243 1.1 christos
1244 1.1 christos if (sect == NULL)
1245 1.1 christos return NULL;
1246 1.1 christos
1247 1.1 christos if (!bfd_malloc_and_get_section (abfd, sect, & contents))
1248 1.1 christos {
1249 1.1 christos if (contents != NULL)
1250 1.1 christos free (contents);
1251 1.1 christos return NULL;
1252 1.1 christos }
1253 1.1 christos
1254 1.1 christos /* BuildID value is stored after the filename. */
1255 1.1 christos name = (char *) contents;
1256 1.1 christos buildid_offset = strlen (name) + 1;
1257 1.1 christos
1258 1.1 christos *buildid_len = bfd_get_section_size (sect) - buildid_offset;
1259 1.1 christos *buildid_out = bfd_malloc (*buildid_len);
1260 1.1 christos memcpy (*buildid_out, contents + buildid_offset, *buildid_len);
1261 1.1 christos
1262 1.1 christos return name;
1263 1.1 christos }
1264 1.1 christos
1265 1.1 christos /*
1266 1.1 christos INTERNAL_FUNCTION
1267 1.1 christos separate_debug_file_exists
1268 1.1 christos
1269 1.1 christos SYNOPSIS
1270 1.1 christos bfd_boolean separate_debug_file_exists
1271 1.1 christos (char *name, unsigned long crc32);
1272 1.1 christos
1273 1.1 christos DESCRIPTION
1274 1.1 christos Checks to see if @var{name} is a file and if its contents
1275 1.1 christos match @var{crc32}.
1276 1.1 christos */
1277 1.1 christos
1278 1.1 christos static bfd_boolean
1279 1.1 christos separate_debug_file_exists (const char *name, const unsigned long crc)
1280 1.1 christos {
1281 1.1 christos static unsigned char buffer [8 * 1024];
1282 1.1 christos unsigned long file_crc = 0;
1283 1.1 christos FILE *f;
1284 1.1 christos bfd_size_type count;
1285 1.1 christos
1286 1.1 christos BFD_ASSERT (name);
1287 1.1 christos
1288 1.1 christos f = real_fopen (name, FOPEN_RB);
1289 1.1 christos if (f == NULL)
1290 1.1 christos return FALSE;
1291 1.1 christos
1292 1.1 christos while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0)
1293 1.1 christos file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
1294 1.1 christos
1295 1.1 christos fclose (f);
1296 1.1 christos
1297 1.1 christos return crc == file_crc;
1298 1.1 christos }
1299 1.1 christos
1300 1.1 christos /*
1301 1.1 christos INTERNAL_FUNCTION
1302 1.1 christos separate_alt_debug_file_exists
1303 1.1 christos
1304 1.1 christos SYNOPSIS
1305 1.1 christos bfd_boolean separate_alt_debug_file_exists
1306 1.1 christos (char *name, unsigned long crc32);
1307 1.1 christos
1308 1.1 christos DESCRIPTION
1309 1.1 christos Checks to see if @var{name} is a file and if its BuildID
1310 1.1 christos matches @var{buildid}.
1311 1.1 christos */
1312 1.1 christos
1313 1.1 christos static bfd_boolean
1314 1.1 christos separate_alt_debug_file_exists (const char *name,
1315 1.1 christos const unsigned long buildid ATTRIBUTE_UNUSED)
1316 1.1 christos {
1317 1.1 christos FILE *f;
1318 1.1 christos
1319 1.1 christos BFD_ASSERT (name);
1320 1.1 christos
1321 1.1 christos f = real_fopen (name, FOPEN_RB);
1322 1.1 christos if (f == NULL)
1323 1.1 christos return FALSE;
1324 1.1 christos
1325 1.1 christos /* FIXME: Add code to check buildid. */
1326 1.1 christos
1327 1.1 christos fclose (f);
1328 1.1 christos
1329 1.1 christos return TRUE;
1330 1.1 christos }
1331 1.1 christos
1332 1.1 christos /*
1333 1.1 christos INTERNAL_FUNCTION
1334 1.1 christos find_separate_debug_file
1335 1.1 christos
1336 1.1 christos SYNOPSIS
1337 1.1 christos char *find_separate_debug_file (bfd *abfd);
1338 1.1 christos
1339 1.1 christos DESCRIPTION
1340 1.1 christos Searches @var{abfd} for a section called @var{section_name} which
1341 1.1 christos is expected to contain a reference to a file containing separate
1342 1.1 christos debugging information. The function scans various locations in
1343 1.1 christos the filesystem, including the file tree rooted at
1344 1.1 christos @var{debug_file_directory}, and returns the first matching
1345 1.1 christos filename that it finds. If @var{check_crc} is TRUE then the
1346 1.1 christos contents of the file must also match the CRC value contained in
1347 1.1 christos @var{section_name}. Returns NULL if no valid file could be found.
1348 1.1 christos */
1349 1.1 christos
1350 1.1 christos typedef char * (* get_func_type) (bfd *, unsigned long *);
1351 1.1 christos typedef bfd_boolean (* check_func_type) (const char *, const unsigned long);
1352 1.1 christos
1353 1.1 christos static char *
1354 1.1 christos find_separate_debug_file (bfd * abfd,
1355 1.1 christos const char * debug_file_directory,
1356 1.1 christos get_func_type get_func,
1357 1.1 christos check_func_type check_func)
1358 1.1 christos {
1359 1.1 christos char *base;
1360 1.1 christos char *dir;
1361 1.1 christos char *debugfile;
1362 1.1 christos char *canon_dir;
1363 1.1 christos unsigned long crc32;
1364 1.1 christos size_t dirlen;
1365 1.1 christos size_t canon_dirlen;
1366 1.1 christos
1367 1.1 christos BFD_ASSERT (abfd);
1368 1.1 christos if (debug_file_directory == NULL)
1369 1.1 christos debug_file_directory = ".";
1370 1.1 christos
1371 1.1 christos /* BFD may have been opened from a stream. */
1372 1.1 christos if (abfd->filename == NULL)
1373 1.1 christos {
1374 1.1 christos bfd_set_error (bfd_error_invalid_operation);
1375 1.1 christos return NULL;
1376 1.1 christos }
1377 1.1 christos
1378 1.1 christos base = get_func (abfd, & crc32);
1379 1.1 christos
1380 1.1 christos if (base == NULL)
1381 1.1 christos return NULL;
1382 1.1 christos
1383 1.1 christos if (base[0] == '\0')
1384 1.1 christos {
1385 1.1 christos free (base);
1386 1.1 christos bfd_set_error (bfd_error_no_debug_section);
1387 1.1 christos return NULL;
1388 1.1 christos }
1389 1.1 christos
1390 1.1 christos for (dirlen = strlen (abfd->filename); dirlen > 0; dirlen--)
1391 1.1 christos if (IS_DIR_SEPARATOR (abfd->filename[dirlen - 1]))
1392 1.1 christos break;
1393 1.1 christos
1394 1.1 christos dir = (char *) bfd_malloc (dirlen + 1);
1395 1.1 christos if (dir == NULL)
1396 1.1 christos {
1397 1.1 christos free (base);
1398 1.1 christos return NULL;
1399 1.1 christos }
1400 1.1 christos memcpy (dir, abfd->filename, dirlen);
1401 1.1 christos dir[dirlen] = '\0';
1402 1.1 christos
1403 1.1 christos /* Compute the canonical name of the bfd object with all symbolic links
1404 1.1 christos resolved, for use in the global debugfile directory. */
1405 1.1 christos canon_dir = lrealpath (abfd->filename);
1406 1.1 christos for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--)
1407 1.1 christos if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1]))
1408 1.1 christos break;
1409 1.1 christos canon_dir[canon_dirlen] = '\0';
1410 1.1 christos
1411 1.1 christos debugfile = (char *)
1412 1.1 christos bfd_malloc (strlen (debug_file_directory) + 1
1413 1.1 christos + (canon_dirlen > dirlen ? canon_dirlen : dirlen)
1414 1.1 christos + strlen (".debug/")
1415 1.1 christos + strlen (base)
1416 1.1 christos + 1);
1417 1.1 christos if (debugfile == NULL)
1418 1.1 christos goto found; /* Actually this returns NULL. */
1419 1.1 christos
1420 1.1 christos /* First try in the same directory as the original file: */
1421 1.1 christos strcpy (debugfile, dir);
1422 1.1 christos strcat (debugfile, base);
1423 1.1 christos
1424 1.1 christos if (check_func (debugfile, crc32))
1425 1.1 christos goto found;
1426 1.1 christos
1427 1.1 christos /* Then try in a subdirectory called .debug. */
1428 1.1 christos strcpy (debugfile, dir);
1429 1.1 christos strcat (debugfile, ".debug/");
1430 1.1 christos strcat (debugfile, base);
1431 1.1 christos
1432 1.1 christos if (check_func (debugfile, crc32))
1433 1.1 christos goto found;
1434 1.1 christos
1435 1.1 christos /* Then try in the global debugfile directory. */
1436 1.1 christos strcpy (debugfile, debug_file_directory);
1437 1.1 christos dirlen = strlen (debug_file_directory) - 1;
1438 1.1 christos if (dirlen > 0
1439 1.1 christos && debug_file_directory[dirlen] != '/'
1440 1.1 christos && canon_dir[0] != '/')
1441 1.1 christos strcat (debugfile, "/");
1442 1.1 christos strcat (debugfile, canon_dir);
1443 1.1 christos strcat (debugfile, base);
1444 1.1 christos
1445 1.1 christos if (check_func (debugfile, crc32))
1446 1.1 christos goto found;
1447 1.1 christos
1448 1.1 christos /* Failed to find the file. */
1449 1.1 christos free (debugfile);
1450 1.1 christos debugfile = NULL;
1451 1.1 christos
1452 1.1 christos found:
1453 1.1 christos free (base);
1454 1.1 christos free (dir);
1455 1.1 christos free (canon_dir);
1456 1.1 christos return debugfile;
1457 1.1 christos }
1458 1.1 christos
1459 1.1 christos
1460 1.1 christos /*
1461 1.1 christos FUNCTION
1462 1.1 christos bfd_follow_gnu_debuglink
1463 1.1 christos
1464 1.1 christos SYNOPSIS
1465 1.1 christos char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
1466 1.1 christos
1467 1.1 christos DESCRIPTION
1468 1.1 christos
1469 1.1 christos Takes a BFD and searches it for a .gnu_debuglink section. If this
1470 1.1 christos section is found, it examines the section for the name and checksum
1471 1.1 christos of a '.debug' file containing auxiliary debugging information. It
1472 1.1 christos then searches the filesystem for this .debug file in some standard
1473 1.1 christos locations, including the directory tree rooted at @var{dir}, and if
1474 1.1 christos found returns the full filename.
1475 1.1 christos
1476 1.1 christos If @var{dir} is NULL, it will search a default path configured into
1477 1.1 christos libbfd at build time. [XXX this feature is not currently
1478 1.1 christos implemented].
1479 1.1 christos
1480 1.1 christos RETURNS
1481 1.1 christos <<NULL>> on any errors or failure to locate the .debug file,
1482 1.1 christos otherwise a pointer to a heap-allocated string containing the
1483 1.1 christos filename. The caller is responsible for freeing this string.
1484 1.1 christos */
1485 1.1 christos
1486 1.1 christos char *
1487 1.1 christos bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
1488 1.1 christos {
1489 1.1 christos return find_separate_debug_file (abfd, dir,
1490 1.1 christos bfd_get_debug_link_info,
1491 1.1 christos separate_debug_file_exists);
1492 1.1 christos }
1493 1.1 christos
1494 1.1 christos /* Helper for bfd_follow_gnu_debugaltlink. It just pretends to return
1495 1.1 christos a CRC. .gnu_debugaltlink supplies a build-id, which is different,
1496 1.1 christos but this is ok because separate_alt_debug_file_exists ignores the
1497 1.1 christos CRC anyway. */
1498 1.1 christos
1499 1.1 christos static char *
1500 1.1 christos get_alt_debug_link_info_shim (bfd * abfd, unsigned long *crc32_out)
1501 1.1 christos {
1502 1.1 christos bfd_size_type len;
1503 1.1 christos bfd_byte *buildid = NULL;
1504 1.1 christos char *result = bfd_get_alt_debug_link_info (abfd, &len, &buildid);
1505 1.1 christos
1506 1.1 christos *crc32_out = 0;
1507 1.1 christos free (buildid);
1508 1.1 christos
1509 1.1 christos return result;
1510 1.1 christos }
1511 1.1 christos
1512 1.1 christos /*
1513 1.1 christos FUNCTION
1514 1.1 christos bfd_follow_gnu_debugaltlink
1515 1.1 christos
1516 1.1 christos SYNOPSIS
1517 1.1 christos char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
1518 1.1 christos
1519 1.1 christos DESCRIPTION
1520 1.1 christos
1521 1.1 christos Takes a BFD and searches it for a .gnu_debugaltlink section. If this
1522 1.1 christos section is found, it examines the section for the name of a file
1523 1.1 christos containing auxiliary debugging information. It then searches the
1524 1.1 christos filesystem for this file in a set of standard locations, including
1525 1.1 christos the directory tree rooted at @var{dir}, and if found returns the
1526 1.1 christos full filename.
1527 1.1 christos
1528 1.1 christos If @var{dir} is NULL, it will search a default path configured into
1529 1.1 christos libbfd at build time. [FIXME: This feature is not currently
1530 1.1 christos implemented].
1531 1.1 christos
1532 1.1 christos RETURNS
1533 1.1 christos <<NULL>> on any errors or failure to locate the debug file,
1534 1.1 christos otherwise a pointer to a heap-allocated string containing the
1535 1.1 christos filename. The caller is responsible for freeing this string.
1536 1.1 christos */
1537 1.1 christos
1538 1.1 christos char *
1539 1.1 christos bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir)
1540 1.1 christos {
1541 1.1 christos return find_separate_debug_file (abfd, dir,
1542 1.1 christos get_alt_debug_link_info_shim,
1543 1.1 christos separate_alt_debug_file_exists);
1544 1.1 christos }
1545 1.1 christos
1546 1.1 christos /*
1547 1.1 christos FUNCTION
1548 1.1 christos bfd_create_gnu_debuglink_section
1549 1.1 christos
1550 1.1 christos SYNOPSIS
1551 1.1 christos struct bfd_section *bfd_create_gnu_debuglink_section
1552 1.1 christos (bfd *abfd, const char *filename);
1553 1.1 christos
1554 1.1 christos DESCRIPTION
1555 1.1 christos
1556 1.1 christos Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized
1557 1.1 christos to be big enough to contain a link to the specified @var{filename}.
1558 1.1 christos
1559 1.1 christos RETURNS
1560 1.1 christos A pointer to the new section is returned if all is ok. Otherwise <<NULL>> is
1561 1.1 christos returned and bfd_error is set.
1562 1.1 christos */
1563 1.1 christos
1564 1.1 christos asection *
1565 1.1 christos bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename)
1566 1.1 christos {
1567 1.1 christos asection *sect;
1568 1.1 christos bfd_size_type debuglink_size;
1569 1.1 christos flagword flags;
1570 1.1 christos
1571 1.1 christos if (abfd == NULL || filename == NULL)
1572 1.1 christos {
1573 1.1 christos bfd_set_error (bfd_error_invalid_operation);
1574 1.1 christos return NULL;
1575 1.1 christos }
1576 1.1 christos
1577 1.1 christos /* Strip off any path components in filename. */
1578 1.1 christos filename = lbasename (filename);
1579 1.1 christos
1580 1.1 christos sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
1581 1.1 christos if (sect)
1582 1.1 christos {
1583 1.1 christos /* Section already exists. */
1584 1.1 christos bfd_set_error (bfd_error_invalid_operation);
1585 1.1 christos return NULL;
1586 1.1 christos }
1587 1.1 christos
1588 1.1 christos flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
1589 1.1 christos sect = bfd_make_section_with_flags (abfd, GNU_DEBUGLINK, flags);
1590 1.1 christos if (sect == NULL)
1591 1.1 christos return NULL;
1592 1.1 christos
1593 1.1 christos debuglink_size = strlen (filename) + 1;
1594 1.1 christos debuglink_size += 3;
1595 1.1 christos debuglink_size &= ~3;
1596 1.1 christos debuglink_size += 4;
1597 1.1 christos
1598 1.1 christos if (! bfd_set_section_size (abfd, sect, debuglink_size))
1599 1.1 christos /* XXX Should we delete the section from the bfd ? */
1600 1.1 christos return NULL;
1601 1.1 christos
1602 1.1 christos return sect;
1603 1.1 christos }
1604 1.1 christos
1605 1.1 christos
1606 1.1 christos /*
1607 1.1 christos FUNCTION
1608 1.1 christos bfd_fill_in_gnu_debuglink_section
1609 1.1 christos
1610 1.1 christos SYNOPSIS
1611 1.1 christos bfd_boolean bfd_fill_in_gnu_debuglink_section
1612 1.1 christos (bfd *abfd, struct bfd_section *sect, const char *filename);
1613 1.1 christos
1614 1.1 christos DESCRIPTION
1615 1.1 christos
1616 1.1 christos Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
1617 1.1 christos and fills in the contents of the section to contain a link to the
1618 1.1 christos specified @var{filename}. The filename should be relative to the
1619 1.1 christos current directory.
1620 1.1 christos
1621 1.1 christos RETURNS
1622 1.1 christos <<TRUE>> is returned if all is ok. Otherwise <<FALSE>> is returned
1623 1.1 christos and bfd_error is set.
1624 1.1 christos */
1625 1.1 christos
1626 1.1 christos bfd_boolean
1627 1.1 christos bfd_fill_in_gnu_debuglink_section (bfd *abfd,
1628 1.1 christos struct bfd_section *sect,
1629 1.1 christos const char *filename)
1630 1.1 christos {
1631 1.1 christos bfd_size_type debuglink_size;
1632 1.1 christos unsigned long crc32;
1633 1.1 christos char * contents;
1634 1.1 christos bfd_size_type crc_offset;
1635 1.1 christos FILE * handle;
1636 1.1 christos static unsigned char buffer[8 * 1024];
1637 1.1 christos size_t count;
1638 1.1 christos size_t filelen;
1639 1.1 christos
1640 1.1 christos if (abfd == NULL || sect == NULL || filename == NULL)
1641 1.1 christos {
1642 1.1 christos bfd_set_error (bfd_error_invalid_operation);
1643 1.1 christos return FALSE;
1644 1.1 christos }
1645 1.1 christos
1646 1.1 christos /* Make sure that we can read the file.
1647 1.1 christos XXX - Should we attempt to locate the debug info file using the same
1648 1.1 christos algorithm as gdb ? At the moment, since we are creating the
1649 1.1 christos .gnu_debuglink section, we insist upon the user providing us with a
1650 1.1 christos correct-for-section-creation-time path, but this need not conform to
1651 1.1 christos the gdb location algorithm. */
1652 1.1 christos handle = real_fopen (filename, FOPEN_RB);
1653 1.1 christos if (handle == NULL)
1654 1.1 christos {
1655 1.1 christos bfd_set_error (bfd_error_system_call);
1656 1.1 christos return FALSE;
1657 1.1 christos }
1658 1.1 christos
1659 1.1 christos crc32 = 0;
1660 1.1 christos while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
1661 1.1 christos crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
1662 1.1 christos fclose (handle);
1663 1.1 christos
1664 1.1 christos /* Strip off any path components in filename,
1665 1.1 christos now that we no longer need them. */
1666 1.1 christos filename = lbasename (filename);
1667 1.1 christos
1668 1.1 christos filelen = strlen (filename);
1669 1.1 christos debuglink_size = filelen + 1;
1670 1.1 christos debuglink_size += 3;
1671 1.1 christos debuglink_size &= ~3;
1672 1.1 christos debuglink_size += 4;
1673 1.1 christos
1674 1.1 christos contents = (char *) bfd_malloc (debuglink_size);
1675 1.1 christos if (contents == NULL)
1676 1.1 christos {
1677 1.1 christos /* XXX Should we delete the section from the bfd ? */
1678 1.1 christos return FALSE;
1679 1.1 christos }
1680 1.1 christos
1681 1.1 christos crc_offset = debuglink_size - 4;
1682 1.1 christos memcpy (contents, filename, filelen);
1683 1.1 christos memset (contents + filelen, 0, crc_offset - filelen);
1684 1.1 christos
1685 1.1 christos bfd_put_32 (abfd, crc32, contents + crc_offset);
1686 1.1 christos
1687 1.1 christos if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
1688 1.1 christos {
1689 1.1 christos /* XXX Should we delete the section from the bfd ? */
1690 1.1 christos free (contents);
1691 1.1 christos return FALSE;
1692 1.1 christos }
1693 1.1 christos
1694 1.1 christos return TRUE;
1695 }
1696