OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [opncls.c] - Blame information for rev 818

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.