/[gcl]/gcl/binutils/bfd/opncls.c
ViewVC logotype

Diff of /gcl/binutils/bfd/opncls.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:35:39 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:14 2005 UTC
# Line 1  Line 1 
1  /* opncls.c -- open and close a BFD.  /* opncls.c -- open and close a BFD.
2     Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,     Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3     2001, 2002     2001, 2002, 2003, 2004, 2005
4     Free Software Foundation, Inc.     Free Software Foundation, Inc.
5    
6     Written by Cygnus Support.     Written by Cygnus Support.
# Line 25  Line 25 
25  #include "sysdep.h"  #include "sysdep.h"
26  #include "objalloc.h"  #include "objalloc.h"
27  #include "libbfd.h"  #include "libbfd.h"
28    #include "libiberty.h"
29    
30  #ifndef S_IXUSR  #ifndef S_IXUSR
31  #define S_IXUSR 0100    /* Execute by owner.  */  #define S_IXUSR 0100    /* Execute by owner.  */
# Line 36  Line 37 
37  #define S_IXOTH 0001    /* Execute by others.  */  #define S_IXOTH 0001    /* Execute by others.  */
38  #endif  #endif
39    
40    /* Counter used to initialize the bfd identifier.  */
41    
42    static unsigned int _bfd_id_counter = 0;
43    
44  /* fdopen is a loser -- we should use stdio exclusively.  Unfortunately  /* fdopen is a loser -- we should use stdio exclusively.  Unfortunately
45     if we do that we can't use fcntl.  */     if we do that we can't use fcntl.  */
46    
47  /* Return a new BFD.  All BFD's are allocated through this routine.  */  /* Return a new BFD.  All BFD's are allocated through this routine.  */
48    
49  bfd *  bfd *
50  _bfd_new_bfd ()  _bfd_new_bfd (void)
51  {  {
52    bfd *nbfd;    bfd *nbfd;
53    
54    nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));    nbfd = bfd_zmalloc (sizeof (bfd));
55    if (nbfd == NULL)    if (nbfd == NULL)
56      return NULL;      return NULL;
57    
58    nbfd->memory = (PTR) objalloc_create ();    nbfd->id = _bfd_id_counter++;
59    
60      nbfd->memory = objalloc_create ();
61    if (nbfd->memory == NULL)    if (nbfd->memory == NULL)
62      {      {
63        bfd_set_error (bfd_error_no_memory);        bfd_set_error (bfd_error_no_memory);
# Line 63  _bfd_new_bfd () Line 70  _bfd_new_bfd ()
70    nbfd->direction = no_direction;    nbfd->direction = no_direction;
71    nbfd->iostream = NULL;    nbfd->iostream = NULL;
72    nbfd->where = 0;    nbfd->where = 0;
73    if (!bfd_hash_table_init (&nbfd->section_htab, bfd_section_hash_newfunc))    if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
74                                  251))
75      {      {
76        free (nbfd);        free (nbfd);
77        return NULL;        return NULL;
78      }      }
79    nbfd->sections = (asection *) NULL;    nbfd->sections = NULL;
80    nbfd->section_tail = &nbfd->sections;    nbfd->section_tail = &nbfd->sections;
81    nbfd->format = bfd_unknown;    nbfd->format = bfd_unknown;
82    nbfd->my_archive = (bfd *) NULL;    nbfd->my_archive = NULL;
83    nbfd->origin = 0;    nbfd->origin = 0;
84    nbfd->opened_once = false;    nbfd->opened_once = FALSE;
85    nbfd->output_has_begun = false;    nbfd->output_has_begun = FALSE;
86    nbfd->section_count = 0;    nbfd->section_count = 0;
87    nbfd->usrdata = (PTR) NULL;    nbfd->usrdata = NULL;
88    nbfd->cacheable = false;    nbfd->cacheable = FALSE;
89    nbfd->flags = BFD_NO_FLAGS;    nbfd->flags = BFD_NO_FLAGS;
90    nbfd->mtime_set = false;    nbfd->mtime_set = FALSE;
91    
92    return nbfd;    return nbfd;
93  }  }
# Line 87  _bfd_new_bfd () Line 95  _bfd_new_bfd ()
95  /* Allocate a new BFD as a member of archive OBFD.  */  /* Allocate a new BFD as a member of archive OBFD.  */
96    
97  bfd *  bfd *
98  _bfd_new_bfd_contained_in (obfd)  _bfd_new_bfd_contained_in (bfd *obfd)
      bfd *obfd;  
99  {  {
100    bfd *nbfd;    bfd *nbfd;
101    
# Line 96  _bfd_new_bfd_contained_in (obfd) Line 103  _bfd_new_bfd_contained_in (obfd)
103    if (nbfd == NULL)    if (nbfd == NULL)
104      return NULL;      return NULL;
105    nbfd->xvec = obfd->xvec;    nbfd->xvec = obfd->xvec;
106      nbfd->iovec = obfd->iovec;
107    nbfd->my_archive = obfd;    nbfd->my_archive = obfd;
108    nbfd->direction = read_direction;    nbfd->direction = read_direction;
109    nbfd->target_defaulted = obfd->target_defaulted;    nbfd->target_defaulted = obfd->target_defaulted;
# Line 105  _bfd_new_bfd_contained_in (obfd) Line 113  _bfd_new_bfd_contained_in (obfd)
113  /* Delete a BFD.  */  /* Delete a BFD.  */
114    
115  void  void
116  _bfd_delete_bfd (abfd)  _bfd_delete_bfd (bfd *abfd)
      bfd *abfd;  
117  {  {
118    bfd_hash_table_free (&abfd->section_htab);    bfd_hash_table_free (&abfd->section_htab);
119    objalloc_free ((struct objalloc *) abfd->memory);    objalloc_free ((struct objalloc *) abfd->memory);
# Line 124  FUNCTION Line 131  FUNCTION
131          bfd_openr          bfd_openr
132    
133  SYNOPSIS  SYNOPSIS
134          bfd *bfd_openr(const char *filename, const char *target);          bfd *bfd_openr (const char *filename, const char *target);
135    
136  DESCRIPTION  DESCRIPTION
137          Open the file @var{filename} (using <<fopen>>) with the target          Open the file @var{filename} (using <<fopen>>) with the target
# Line 134  DESCRIPTION Line 141  DESCRIPTION
141          that function.          that function.
142    
143          If <<NULL>> is returned then an error has occured.   Possible errors          If <<NULL>> is returned then an error has occured.   Possible errors
144          are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.          are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
145            <<system_call>> error.
146  */  */
147    
148  bfd *  bfd *
149  bfd_openr (filename, target)  bfd_openr (const char *filename, const char *target)
      const char *filename;  
      const char *target;  
150  {  {
151    bfd *nbfd;    bfd *nbfd;
152    const bfd_target *target_vec;    const bfd_target *target_vec;
# Line 179  bfd_openr (filename, target) Line 185  bfd_openr (filename, target)
185         the file descriptor too, even though we didn't open it.  */         the file descriptor too, even though we didn't open it.  */
186  /*  /*
187  FUNCTION  FUNCTION
188           bfd_fdopenr          bfd_fdopenr
189    
190  SYNOPSIS  SYNOPSIS
191           bfd *bfd_fdopenr(const char *filename, const char *target, int fd);          bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
192    
193  DESCRIPTION  DESCRIPTION
194           <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.          <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
195           It opens a BFD on a file already described by the @var{fd}          <<fopen>>.  It opens a BFD on a file already described by the
196           supplied.          @var{fd} supplied.
197    
198           When the file is later <<bfd_close>>d, the file descriptor will be closed.          When the file is later <<bfd_close>>d, the file descriptor will
199            be closed.  If the caller desires that this file descriptor be
200           If the caller desires that this file descriptor be cached by BFD          cached by BFD (opened as needed, closed as needed to free
201           (opened as needed, closed as needed to free descriptors for          descriptors for other opens), with the supplied @var{fd} used as
202           other opens), with the supplied @var{fd} used as an initial          an initial file descriptor (but subject to closure at any time),
203           file descriptor (but subject to closure at any time), call          call bfd_set_cacheable(bfd, 1) on the returned BFD.  The default
204           bfd_set_cacheable(bfd, 1) on the returned BFD.  The default is to          is to assume no caching; the file descriptor will remain open
205           assume no cacheing; the file descriptor will remain open until          until <<bfd_close>>, and will not be affected by BFD operations
206           <<bfd_close>>, and will not be affected by BFD operations on other          on other files.
          files.  
207    
208           Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.          Possible errors are <<bfd_error_no_memory>>,
209            <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
210  */  */
211    
212  bfd *  bfd *
213  bfd_fdopenr (filename, target, fd)  bfd_fdopenr (const char *filename, const char *target, int fd)
      const char *filename;  
      const char *target;  
      int fd;  
214  {  {
215    bfd *nbfd;    bfd *nbfd;
216    const bfd_target *target_vec;    const bfd_target *target_vec;
# Line 234  bfd_fdopenr (filename, target, fd) Line 237  bfd_fdopenr (filename, target, fd)
237      }      }
238    
239  #ifndef HAVE_FDOPEN  #ifndef HAVE_FDOPEN
240    nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);    nbfd->iostream = fopen (filename, FOPEN_RB);
241  #else  #else
242    /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */    /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */
243    switch (fdflags & (O_ACCMODE))    switch (fdflags & (O_ACCMODE))
244      {      {
245      case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB);   break;      case O_RDONLY: nbfd->iostream = fdopen (fd, FOPEN_RB);   break;
246      case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB);  break;      case O_WRONLY: nbfd->iostream = fdopen (fd, FOPEN_RUB);  break;
247      case O_RDWR:   nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB);  break;      case O_RDWR:   nbfd->iostream = fdopen (fd, FOPEN_RUB);  break;
248      default: abort ();      default: abort ();
249      }      }
250  #endif  #endif
# Line 272  bfd_fdopenr (filename, target, fd) Line 275  bfd_fdopenr (filename, target, fd)
275        _bfd_delete_bfd (nbfd);        _bfd_delete_bfd (nbfd);
276        return NULL;        return NULL;
277      }      }
278    nbfd->opened_once = true;    nbfd->opened_once = TRUE;
279    
280    return nbfd;    return nbfd;
281  }  }
# Line 282  FUNCTION Line 285  FUNCTION
285          bfd_openstreamr          bfd_openstreamr
286    
287  SYNOPSIS  SYNOPSIS
288          bfd *bfd_openstreamr(const char *, const char *, PTR);          bfd *bfd_openstreamr (const char *, const char *, void *);
289    
290  DESCRIPTION  DESCRIPTION
291    
# Line 291  DESCRIPTION Line 294  DESCRIPTION
294  */  */
295    
296  bfd *  bfd *
297  bfd_openstreamr (filename, target, streamarg)  bfd_openstreamr (const char *filename, const char *target, void *streamarg)
      const char *filename;  
      const char *target;  
      PTR streamarg;  
298  {  {
299    FILE *stream = (FILE *) streamarg;    FILE *stream = streamarg;
300    bfd *nbfd;    bfd *nbfd;
301    const bfd_target *target_vec;    const bfd_target *target_vec;
302    
# Line 311  bfd_openstreamr (filename, target, strea Line 311  bfd_openstreamr (filename, target, strea
311        return NULL;        return NULL;
312      }      }
313    
314    nbfd->iostream = (PTR) stream;    nbfd->iostream = stream;
315    nbfd->filename = filename;    nbfd->filename = filename;
316    nbfd->direction = read_direction;    nbfd->direction = read_direction;
317    
# Line 323  bfd_openstreamr (filename, target, strea Line 323  bfd_openstreamr (filename, target, strea
323    
324    return nbfd;    return nbfd;
325  }  }
326    
327    /*
328    FUNCTION
329            bfd_openr_iovec
330    
331    SYNOPSIS
332            bfd *bfd_openr_iovec (const char *filename, const char *target,
333                                  void *(*open) (struct bfd *nbfd,
334                                                 void *open_closure),
335                                  void *open_closure,
336                                  file_ptr (*pread) (struct bfd *nbfd,
337                                                     void *stream,
338                                                     void *buf,
339                                                     file_ptr nbytes,
340                                                     file_ptr offset),
341                                  int (*close) (struct bfd *nbfd,
342                                                void *stream));
343    
344    DESCRIPTION
345    
346            Create and return a BFD backed by a read-only @var{stream}.
347            The @var{stream} is created using @var{open}, accessed using
348            @var{pread} and destroyed using @var{close}.
349    
350            Calls <<bfd_find_target>>, so @var{target} is interpreted as by
351            that function.
352    
353            Calls @var{open} (which can call <<bfd_zalloc>> and
354            <<bfd_get_filename>>) to obtain the read-only stream backing
355            the BFD.  @var{open} either succeeds returning the
356            non-<<NULL>> @var{stream}, or fails returning <<NULL>>
357            (setting <<bfd_error>>).
358    
359            Calls @var{pread} to request @var{nbytes} of data from
360            @var{stream} starting at @var{offset} (e.g., via a call to
361            <<bfd_read>>).  @var{pread} either succeeds returning the
362            number of bytes read (which can be less than @var{nbytes} when
363            end-of-file), or fails returning -1 (setting <<bfd_error>>).
364    
365            Calls @var{close} when the BFD is later closed using
366            <<bfd_close>>.  @var{close} either succeeds returning 0, or
367            fails returning -1 (setting <<bfd_error>>).
368    
369            If <<bfd_openr_iovec>> returns <<NULL>> then an error has
370            occurred.  Possible errors are <<bfd_error_no_memory>>,
371            <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
372    
373    */
374    
375    struct opncls
376    {
377      void *stream;
378      file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf,
379                         file_ptr nbytes, file_ptr offset);
380      int (*close) (struct bfd *abfd, void *stream);
381      file_ptr where;
382    };
383    
384    static file_ptr
385    opncls_btell (struct bfd *abfd)
386    {
387      struct opncls *vec = abfd->iostream;
388      return vec->where;
389    }
390    
391    static int
392    opncls_bseek (struct bfd *abfd, file_ptr offset, int whence)
393    {
394      struct opncls *vec = abfd->iostream;
395      switch (whence)
396        {
397        case SEEK_SET: vec->where = offset; break;
398        case SEEK_CUR: vec->where += offset; break;
399        case SEEK_END: return -1;
400        }
401      return 0;
402    }
403    
404    static file_ptr
405    opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
406    {
407      struct opncls *vec = abfd->iostream;
408      file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where);
409      if (nread < 0)
410        return nread;
411      vec->where += nread;
412      return nread;
413    }
414    
415    static file_ptr
416    opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
417                  const void *where ATTRIBUTE_UNUSED,
418                  file_ptr nbytes ATTRIBUTE_UNUSED)
419    {
420      return -1;
421    }
422    
423    static int
424    opncls_bclose (struct bfd *abfd)
425    {
426      struct opncls *vec = abfd->iostream;
427      /* Since the VEC's memory is bound to the bfd deleting the bfd will
428         free it.  */
429      int status = 0;
430      if (vec->close != NULL)
431        status = (vec->close) (abfd, vec->stream);
432      abfd->iostream = NULL;
433      return status;
434    }
435    
436    static int
437    opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
438    {
439      return 0;
440    }
441    
442    static int
443    opncls_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, struct stat *sb)
444    {
445      memset (sb, 0, sizeof (*sb));
446      return 0;
447    }
448    
449    static const struct bfd_iovec opncls_iovec = {
450      &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
451      &opncls_bclose, &opncls_bflush, &opncls_bstat
452    };
453    
454    bfd *
455    bfd_openr_iovec (const char *filename, const char *target,
456                     void *(*open) (struct bfd *nbfd,
457                                    void *open_closure),
458                     void *open_closure,
459                     file_ptr (*pread) (struct bfd *abfd,
460                                        void *stream,
461                                        void *buf,
462                                        file_ptr nbytes,
463                                        file_ptr offset),
464                     int (*close) (struct bfd *nbfd,
465                                   void *stream))
466    {
467      bfd *nbfd;
468      const bfd_target *target_vec;
469      struct opncls *vec;
470      void *stream;
471    
472      nbfd = _bfd_new_bfd ();
473      if (nbfd == NULL)
474        return NULL;
475    
476      target_vec = bfd_find_target (target, nbfd);
477      if (target_vec == NULL)
478        {
479          _bfd_delete_bfd (nbfd);
480          return NULL;
481        }
482    
483      nbfd->filename = filename;
484      nbfd->direction = read_direction;
485    
486      stream = open (nbfd, open_closure);
487      if (stream == NULL)
488        {
489          _bfd_delete_bfd (nbfd);
490          return NULL;
491        }
492    
493      vec = bfd_zalloc (nbfd, sizeof (struct opncls));
494      vec->stream = stream;
495      vec->pread = pread;
496      vec->close = close;
497    
498      nbfd->iovec = &opncls_iovec;
499      nbfd->iostream = vec;
500    
501      return nbfd;
502    }
503    
504  /* bfd_openw -- open for writing.  /* bfd_openw -- open for writing.
505     Returns a pointer to a freshly-allocated BFD on success, or NULL.     Returns a pointer to a freshly-allocated BFD on success, or NULL.
# Line 334  FUNCTION Line 511  FUNCTION
511          bfd_openw          bfd_openw
512    
513  SYNOPSIS  SYNOPSIS
514          bfd *bfd_openw(const char *filename, const char *target);          bfd *bfd_openw (const char *filename, const char *target);
515    
516  DESCRIPTION  DESCRIPTION
517          Create a BFD, associated with file @var{filename}, using the          Create a BFD, associated with file @var{filename}, using the
# Line 345  DESCRIPTION Line 522  DESCRIPTION
522  */  */
523    
524  bfd *  bfd *
525  bfd_openw (filename, target)  bfd_openw (const char *filename, const char *target)
      const char *filename;  
      const char *target;  
526  {  {
527    bfd *nbfd;    bfd *nbfd;
528    const bfd_target *target_vec;    const bfd_target *target_vec;
# Line 385  FUNCTION Line 560  FUNCTION
560          bfd_close          bfd_close
561    
562  SYNOPSIS  SYNOPSIS
563          boolean bfd_close(bfd *abfd);          bfd_boolean bfd_close (bfd *abfd);
564    
565  DESCRIPTION  DESCRIPTION
566    
567          Close a BFD. If the BFD was open for writing,          Close a BFD. If the BFD was open for writing, then pending
568          then pending operations are completed and the file written out          operations are completed and the file written out and closed.
569          and closed. If the created file is executable, then          If the created file is executable, then <<chmod>> is called
570          <<chmod>> is called to mark it as such.          to mark it as such.
571    
572          All memory attached to the BFD is released.          All memory attached to the BFD is released.
573    
# Line 400  DESCRIPTION Line 575  DESCRIPTION
575          if it was passed in to BFD by <<bfd_fdopenr>>).          if it was passed in to BFD by <<bfd_fdopenr>>).
576    
577  RETURNS  RETURNS
578          <<true>> is returned if all is ok, otherwise <<false>>.          <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
579  */  */
580    
581    
582  boolean  bfd_boolean
583  bfd_close (abfd)  bfd_close (bfd *abfd)
      bfd *abfd;  
584  {  {
585    boolean ret;    bfd_boolean ret;
586    
587    if (bfd_write_p (abfd))    if (bfd_write_p (abfd))
588      {      {
589        if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))        if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
590          return false;          return FALSE;
591      }      }
592    
593    if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))    if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
594      return false;      return FALSE;
595    
596    ret = bfd_cache_close (abfd);    /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io
597         vector.  */
598      if (!(abfd->flags & BFD_IN_MEMORY))
599        ret = abfd->iovec->bclose (abfd);
600      else
601        ret = TRUE;
602    
603    /* If the file was open for writing and is now executable,    /* If the file was open for writing and is now executable,
604       make it so.  */       make it so.  */
# Line 431  bfd_close (abfd) Line 610  bfd_close (abfd)
610    
611        if (stat (abfd->filename, &buf) == 0)        if (stat (abfd->filename, &buf) == 0)
612          {          {
613            unsigned int mask = umask (0);            unsigned int mask = umask (0);
614    
615            umask (mask);            umask (mask);
616            chmod (abfd->filename,            chmod (abfd->filename,
# Line 450  FUNCTION Line 629  FUNCTION
629          bfd_close_all_done          bfd_close_all_done
630    
631  SYNOPSIS  SYNOPSIS
632          boolean bfd_close_all_done(bfd *);          bfd_boolean bfd_close_all_done (bfd *);
633    
634  DESCRIPTION  DESCRIPTION
635          Close a BFD.  Differs from <<bfd_close>>          Close a BFD.  Differs from <<bfd_close>> since it does not
636          since it does not complete any pending operations.  This          complete any pending operations.  This routine would be used
637          routine would be used if the application had just used BFD for          if the application had just used BFD for swapping and didn't
638          swapping and didn't want to use any of the writing code.          want to use any of the writing code.
639    
640          If the created file is executable, then <<chmod>> is called          If the created file is executable, then <<chmod>> is called
641          to mark it as such.          to mark it as such.
# Line 464  DESCRIPTION Line 643  DESCRIPTION
643          All memory attached to the BFD is released.          All memory attached to the BFD is released.
644    
645  RETURNS  RETURNS
646          <<true>> is returned if all is ok, otherwise <<false>>.          <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
647  */  */
648    
649  boolean  bfd_boolean
650  bfd_close_all_done (abfd)  bfd_close_all_done (bfd *abfd)
      bfd *abfd;  
651  {  {
652    boolean ret;    bfd_boolean ret;
653    
654    ret = bfd_cache_close (abfd);    ret = bfd_cache_close (abfd);
655    
# Line 504  FUNCTION Line 682  FUNCTION
682          bfd_create          bfd_create
683    
684  SYNOPSIS  SYNOPSIS
685          bfd *bfd_create(const char *filename, bfd *templ);          bfd *bfd_create (const char *filename, bfd *templ);
686    
687  DESCRIPTION  DESCRIPTION
688          Create a new BFD in the manner of          Create a new BFD in the manner of <<bfd_openw>>, but without
689          <<bfd_openw>>, but without opening a file. The new BFD          opening a file. The new BFD takes the target from the target
690          takes the target from the target used by @var{template}. The          used by @var{template}. The format is always set to <<bfd_object>>.
         format is always set to <<bfd_object>>.  
691  */  */
692    
693  bfd *  bfd *
694  bfd_create (filename, templ)  bfd_create (const char *filename, bfd *templ)
      const char *filename;  
      bfd *templ;  
695  {  {
696    bfd *nbfd;    bfd *nbfd;
697    
# Line 537  FUNCTION Line 712  FUNCTION
712          bfd_make_writable          bfd_make_writable
713    
714  SYNOPSIS  SYNOPSIS
715          boolean bfd_make_writable(bfd *abfd);          bfd_boolean bfd_make_writable (bfd *abfd);
716    
717  DESCRIPTION  DESCRIPTION
718          Takes a BFD as created by <<bfd_create>> and converts it          Takes a BFD as created by <<bfd_create>> and converts it
# Line 546  DESCRIPTION Line 721  DESCRIPTION
721          you will call <<bfd_make_readable>> on this bfd later.          you will call <<bfd_make_readable>> on this bfd later.
722    
723  RETURNS  RETURNS
724          <<true>> is returned if all is ok, otherwise <<false>>.          <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
725  */  */
726    
727  boolean  bfd_boolean
728  bfd_make_writable(abfd)  bfd_make_writable (bfd *abfd)
      bfd *abfd;  
729  {  {
730    struct bfd_in_memory *bim;    struct bfd_in_memory *bim;
731    
732    if (abfd->direction != no_direction)    if (abfd->direction != no_direction)
733      {      {
734        bfd_set_error (bfd_error_invalid_operation);        bfd_set_error (bfd_error_invalid_operation);
735        return false;        return FALSE;
736      }      }
737    
738    bim = ((struct bfd_in_memory *)    bim = bfd_malloc (sizeof (struct bfd_in_memory));
739           bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));    abfd->iostream = bim;
   abfd->iostream = (PTR) bim;  
740    /* bfd_bwrite will grow these as needed.  */    /* bfd_bwrite will grow these as needed.  */
741    bim->size = 0;    bim->size = 0;
742    bim->buffer = 0;    bim->buffer = 0;
# Line 572  bfd_make_writable(abfd) Line 745  bfd_make_writable(abfd)
745    abfd->direction = write_direction;    abfd->direction = write_direction;
746    abfd->where = 0;    abfd->where = 0;
747    
748    return true;    return TRUE;
749  }  }
750    
751  /*  /*
# Line 580  FUNCTION Line 753  FUNCTION
753          bfd_make_readable          bfd_make_readable
754    
755  SYNOPSIS  SYNOPSIS
756          boolean bfd_make_readable(bfd *abfd);          bfd_boolean bfd_make_readable (bfd *abfd);
757    
758  DESCRIPTION  DESCRIPTION
759          Takes a BFD as created by <<bfd_create>> and          Takes a BFD as created by <<bfd_create>> and
# Line 590  DESCRIPTION Line 763  DESCRIPTION
763          direction.          direction.
764    
765  RETURNS  RETURNS
766          <<true>> is returned if all is ok, otherwise <<false>>.  */          <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.  */
767    
768  boolean  bfd_boolean
769  bfd_make_readable(abfd)  bfd_make_readable (bfd *abfd)
      bfd *abfd;  
770  {  {
771    if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))    if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
772      {      {
773        bfd_set_error (bfd_error_invalid_operation);        bfd_set_error (bfd_error_invalid_operation);
774        return false;        return FALSE;
775      }      }
776    
777    if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))    if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
778      return false;      return FALSE;
779    
780    if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))    if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
781      return false;      return FALSE;
782    
783    
784    abfd->arch_info = &bfd_default_arch_struct;    abfd->arch_info = &bfd_default_arch_struct;
785    
786    abfd->where = 0;    abfd->where = 0;
787    abfd->format = bfd_unknown;    abfd->format = bfd_unknown;
788    abfd->my_archive = (bfd *) NULL;    abfd->my_archive = NULL;
789    abfd->origin = 0;    abfd->origin = 0;
790    abfd->opened_once = false;    abfd->opened_once = FALSE;
791    abfd->output_has_begun = false;    abfd->output_has_begun = FALSE;
792    abfd->section_count = 0;    abfd->section_count = 0;
793    abfd->usrdata = (PTR) NULL;    abfd->usrdata = NULL;
794    abfd->cacheable = false;    abfd->cacheable = FALSE;
795    abfd->flags = BFD_IN_MEMORY;    abfd->flags = BFD_IN_MEMORY;
796    abfd->mtime_set = false;    abfd->mtime_set = FALSE;
797    
798    abfd->target_defaulted = true;    abfd->target_defaulted = TRUE;
799    abfd->direction = read_direction;    abfd->direction = read_direction;
800    abfd->sections = 0;    abfd->sections = 0;
801    abfd->symcount = 0;    abfd->symcount = 0;
# Line 633  bfd_make_readable(abfd) Line 805  bfd_make_readable(abfd)
805    bfd_section_list_clear (abfd);    bfd_section_list_clear (abfd);
806    bfd_check_format (abfd, bfd_object);    bfd_check_format (abfd, bfd_object);
807    
808    return true;    return TRUE;
809  }  }
810    
811  /*  /*
# Line 641  INTERNAL_FUNCTION Line 813  INTERNAL_FUNCTION
813          bfd_alloc          bfd_alloc
814    
815  SYNOPSIS  SYNOPSIS
816          PTR bfd_alloc (bfd *abfd, size_t wanted);          void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
817    
818  DESCRIPTION  DESCRIPTION
819          Allocate a block of @var{wanted} bytes of memory attached to          Allocate a block of @var{wanted} bytes of memory attached to
820          <<abfd>> and return a pointer to it.          <<abfd>> and return a pointer to it.
821  */  */
822    
823    void *
824  PTR  bfd_alloc (bfd *abfd, bfd_size_type size)
 bfd_alloc (abfd, size)  
      bfd *abfd;  
      bfd_size_type size;  
825  {  {
826    PTR ret;    void *ret;
827    
828    if (size != (unsigned long) size)    if (size != (unsigned long) size)
829      {      {
# Line 668  bfd_alloc (abfd, size) Line 837  bfd_alloc (abfd, size)
837    return ret;    return ret;
838  }  }
839    
840  PTR  /*
841  bfd_zalloc (abfd, size)  INTERNAL_FUNCTION
842       bfd *abfd;          bfd_zalloc
843       bfd_size_type size;  
844    SYNOPSIS
845            void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
846    
847    DESCRIPTION
848            Allocate a block of @var{wanted} bytes of zeroed memory
849            attached to <<abfd>> and return a pointer to it.
850    */
851    
852    void *
853    bfd_zalloc (bfd *abfd, bfd_size_type size)
854  {  {
855    PTR res;    void *res;
856    
857    res = bfd_alloc (abfd, size);    res = bfd_alloc (abfd, size);
858    if (res)    if (res)
# Line 685  bfd_zalloc (abfd, size) Line 864  bfd_zalloc (abfd, size)
864     Note:  Also frees all more recently allocated blocks!  */     Note:  Also frees all more recently allocated blocks!  */
865    
866  void  void
867  bfd_release (abfd, block)  bfd_release (bfd *abfd, void *block)
      bfd *abfd;  
      PTR block;  
868  {  {
869    objalloc_free_block ((struct objalloc *) abfd->memory, block);    objalloc_free_block ((struct objalloc *) abfd->memory, block);
870  }  }
871    
872    
873    /*
874       GNU Extension: separate debug-info files
875    
876       The idea here is that a special section called .gnu_debuglink might be
877       embedded in a binary file, which indicates that some *other* file
878       contains the real debugging information. This special section contains a
879       filename and CRC32 checksum, which we read and resolve to another file,
880       if it exists.
881    
882       This facilitates "optional" provision of debugging information, without
883       having to provide two complete copies of every binary object (with and
884       without debug symbols).
885    */
886    
887    #define GNU_DEBUGLINK   ".gnu_debuglink"
888    /*
889    FUNCTION
890            bfd_calc_gnu_debuglink_crc32
891    
892    SYNOPSIS
893            unsigned long bfd_calc_gnu_debuglink_crc32
894              (unsigned long crc, const unsigned char *buf, bfd_size_type len);
895    
896    DESCRIPTION
897            Computes a CRC value as used in the .gnu_debuglink section.
898            Advances the previously computed @var{crc} value by computing
899            and adding in the crc32 for @var{len} bytes of @var{buf}.
900    
901    RETURNS
902            Return the updated CRC32 value.
903    */
904    
905    unsigned long
906    bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
907                                  const unsigned char *buf,
908                                  bfd_size_type len)
909    {
910      static const unsigned long crc32_table[256] =
911        {
912          0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
913          0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
914          0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
915          0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
916          0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
917          0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
918          0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
919          0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
920          0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
921          0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
922          0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
923          0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
924          0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
925          0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
926          0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
927          0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
928          0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
929          0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
930          0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
931          0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
932          0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
933          0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
934          0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
935          0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
936          0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
937          0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
938          0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
939          0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
940          0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
941          0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
942          0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
943          0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
944          0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
945          0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
946          0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
947          0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
948          0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
949          0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
950          0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
951          0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
952          0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
953          0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
954          0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
955          0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
956          0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
957          0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
958          0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
959          0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
960          0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
961          0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
962          0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
963          0x2d02ef8d
964        };
965      const unsigned char *end;
966    
967      crc = ~crc & 0xffffffff;
968      for (end = buf + len; buf < end; ++ buf)
969        crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
970      return ~crc & 0xffffffff;;
971    }
972    
973    
974    /*
975    INTERNAL_FUNCTION
976            get_debug_link_info
977    
978    SYNOPSIS
979            char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
980    
981    DESCRIPTION
982            fetch the filename and CRC32 value for any separate debuginfo
983            associated with @var{abfd}. Return NULL if no such info found,
984            otherwise return filename and update @var{crc32_out}.
985    */
986    
987    static char *
988    get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
989    {
990      asection *sect;
991      unsigned long crc32;
992      bfd_byte *contents;
993      int crc_offset;
994      char *name;
995    
996      BFD_ASSERT (abfd);
997      BFD_ASSERT (crc32_out);
998    
999      sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
1000    
1001      if (sect == NULL)
1002        return NULL;
1003    
1004      if (!bfd_malloc_and_get_section (abfd, sect, &contents))
1005        {
1006          if (contents != NULL)
1007            free (contents);
1008          return NULL;
1009        }
1010    
1011      /* Crc value is stored after the filename, aligned up to 4 bytes.  */
1012      name = (char *) contents;
1013      crc_offset = strlen (name) + 1;
1014      crc_offset = (crc_offset + 3) & ~3;
1015    
1016      crc32 = bfd_get_32 (abfd, contents + crc_offset);
1017    
1018      *crc32_out = crc32;
1019      return name;
1020    }
1021    
1022    /*
1023    INTERNAL_FUNCTION
1024            separate_debug_file_exists
1025    
1026    SYNOPSIS
1027            bfd_boolean separate_debug_file_exists
1028              (char *name, unsigned long crc32);
1029    
1030    DESCRIPTION
1031            Checks to see if @var{name} is a file and if its contents
1032            match @var{crc32}.
1033    */
1034    
1035    static bfd_boolean
1036    separate_debug_file_exists (const char *name, const unsigned long crc)
1037    {
1038      static unsigned char buffer [8 * 1024];
1039      unsigned long file_crc = 0;
1040      int fd;
1041      bfd_size_type count;
1042    
1043      BFD_ASSERT (name);
1044    
1045      fd = open (name, O_RDONLY);
1046      if (fd < 0)
1047        return FALSE;
1048    
1049      while ((count = read (fd, buffer, sizeof (buffer))) > 0)
1050        file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
1051    
1052      close (fd);
1053    
1054      return crc == file_crc;
1055    }
1056    
1057    
1058    /*
1059    INTERNAL_FUNCTION
1060            find_separate_debug_file
1061    
1062    SYNOPSIS
1063            char *find_separate_debug_file (bfd *abfd);
1064    
1065    DESCRIPTION
1066            Searches @var{abfd} for a reference to separate debugging
1067            information, scans various locations in the filesystem, including
1068            the file tree rooted at @var{debug_file_directory}, and returns a
1069            filename of such debugging information if the file is found and has
1070            matching CRC32.  Returns NULL if no reference to debugging file
1071            exists, or file cannot be found.
1072    */
1073    
1074    static char *
1075    find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
1076    {
1077      char *basename;
1078      char *dir;
1079      char *debugfile;
1080      unsigned long crc32;
1081      int i;
1082    
1083      BFD_ASSERT (abfd);
1084      if (debug_file_directory == NULL)
1085        debug_file_directory = ".";
1086    
1087      /* BFD may have been opened from a stream.  */
1088      if (! abfd->filename)
1089        return NULL;
1090    
1091      basename = get_debug_link_info (abfd, & crc32);
1092      if (basename == NULL)
1093        return NULL;
1094    
1095      if (strlen (basename) < 1)
1096        {
1097          free (basename);
1098          return NULL;
1099        }
1100    
1101      dir = strdup (abfd->filename);
1102      if (dir == NULL)
1103        {
1104          free (basename);
1105          return NULL;
1106        }
1107      BFD_ASSERT (strlen (dir) != 0);
1108    
1109      /* Strip off filename part.  */
1110      for (i = strlen (dir) - 1; i >= 0; i--)
1111        if (IS_DIR_SEPARATOR (dir[i]))
1112          break;
1113    
1114      dir[i + 1] = '\0';
1115      BFD_ASSERT (dir[i] == '/' || dir[0] == '\0');
1116    
1117      debugfile = malloc (strlen (debug_file_directory) + 1
1118                          + strlen (dir)
1119                          + strlen (".debug/")
1120                          + strlen (basename)
1121                          + 1);
1122      if (debugfile == NULL)
1123        {
1124          free (basename);
1125          free (dir);
1126          return NULL;
1127        }
1128    
1129      /* First try in the same directory as the original file:  */
1130      strcpy (debugfile, dir);
1131      strcat (debugfile, basename);
1132    
1133      if (separate_debug_file_exists (debugfile, crc32))
1134        {
1135          free (basename);
1136          free (dir);
1137          return debugfile;
1138        }
1139    
1140      /* Then try in a subdirectory called .debug.  */
1141      strcpy (debugfile, dir);
1142      strcat (debugfile, ".debug/");
1143      strcat (debugfile, basename);
1144    
1145      if (separate_debug_file_exists (debugfile, crc32))
1146        {
1147          free (basename);
1148          free (dir);
1149          return debugfile;
1150        }
1151    
1152      /* Then try in the global debugfile directory.  */
1153      strcpy (debugfile, debug_file_directory);
1154      i = strlen (debug_file_directory) - 1;
1155      if (i > 0
1156          && debug_file_directory[i] != '/'
1157          && dir[0] != '/')
1158        strcat (debugfile, "/");
1159      strcat (debugfile, dir);
1160      strcat (debugfile, basename);
1161    
1162      if (separate_debug_file_exists (debugfile, crc32))
1163        {
1164          free (basename);
1165          free (dir);
1166          return debugfile;
1167        }
1168    
1169      free (debugfile);
1170      free (basename);
1171      free (dir);
1172      return NULL;
1173    }
1174    
1175    
1176    /*
1177    FUNCTION
1178            bfd_follow_gnu_debuglink
1179    
1180    SYNOPSIS
1181            char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
1182    
1183    DESCRIPTION
1184    
1185            Takes a BFD and searches it for a .gnu_debuglink section.  If this
1186            section is found, it examines the section for the name and checksum
1187            of a '.debug' file containing auxiliary debugging information.  It
1188            then searches the filesystem for this .debug file in some standard
1189            locations, including the directory tree rooted at @var{dir}, and if
1190            found returns the full filename.
1191    
1192            If @var{dir} is NULL, it will search a default path configured into
1193            libbfd at build time.  [XXX this feature is not currently
1194            implemented].
1195    
1196    RETURNS
1197            <<NULL>> on any errors or failure to locate the .debug file,
1198            otherwise a pointer to a heap-allocated string containing the
1199            filename.  The caller is responsible for freeing this string.
1200    */
1201    
1202    char *
1203    bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
1204    {
1205      return find_separate_debug_file (abfd, dir);
1206    }
1207    
1208    /*
1209    FUNCTION
1210            bfd_create_gnu_debuglink_section
1211    
1212    SYNOPSIS
1213            struct bfd_section *bfd_create_gnu_debuglink_section
1214              (bfd *abfd, const char *filename);
1215    
1216    DESCRIPTION
1217    
1218            Takes a @var{BFD} and adds a .gnu_debuglink section to it.  The section is sized
1219            to be big enough to contain a link to the specified @var{filename}.
1220    
1221    RETURNS
1222            A pointer to the new section is returned if all is ok.  Otherwise <<NULL>> is
1223            returned and bfd_error is set.
1224    */
1225    
1226    asection *
1227    bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename)
1228    {
1229      asection *sect;
1230      bfd_size_type debuglink_size;
1231    
1232      if (abfd == NULL || filename == NULL)
1233        {
1234          bfd_set_error (bfd_error_invalid_operation);
1235          return NULL;
1236        }
1237    
1238      /* Strip off any path components in filename.  */
1239      filename = lbasename (filename);
1240    
1241      sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
1242      if (sect)
1243        {
1244          /* Section already exists.  */
1245          bfd_set_error (bfd_error_invalid_operation);
1246          return NULL;
1247        }
1248    
1249      sect = bfd_make_section (abfd, GNU_DEBUGLINK);
1250      if (sect == NULL)
1251        return NULL;
1252    
1253      if (! bfd_set_section_flags (abfd, sect,
1254                                   SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING))
1255        /* XXX Should we delete the section from the bfd ?  */
1256        return NULL;
1257    
1258    
1259      debuglink_size = strlen (filename) + 1;
1260      debuglink_size += 3;
1261      debuglink_size &= ~3;
1262      debuglink_size += 4;
1263    
1264      if (! bfd_set_section_size (abfd, sect, debuglink_size))
1265        /* XXX Should we delete the section from the bfd ?  */
1266        return NULL;
1267    
1268      return sect;
1269    }
1270    
1271    
1272    /*
1273    FUNCTION
1274            bfd_fill_in_gnu_debuglink_section
1275    
1276    SYNOPSIS
1277            bfd_boolean bfd_fill_in_gnu_debuglink_section
1278              (bfd *abfd, struct bfd_section *sect, const char *filename);
1279    
1280    DESCRIPTION
1281    
1282            Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
1283            and fills in the contents of the section to contain a link to the
1284            specified @var{filename}.  The filename should be relative to the
1285            current directory.
1286    
1287    RETURNS
1288            <<TRUE>> is returned if all is ok.  Otherwise <<FALSE>> is returned
1289            and bfd_error is set.
1290    */
1291    
1292    bfd_boolean
1293    bfd_fill_in_gnu_debuglink_section (bfd *abfd,
1294                                       struct bfd_section *sect,
1295                                       const char *filename)
1296    {
1297      bfd_size_type debuglink_size;
1298      unsigned long crc32;
1299      char * contents;
1300      bfd_size_type crc_offset;
1301      FILE * handle;
1302      static unsigned char buffer[8 * 1024];
1303      size_t count;
1304    
1305      if (abfd == NULL || sect == NULL || filename == NULL)
1306        {
1307          bfd_set_error (bfd_error_invalid_operation);
1308          return FALSE;
1309        }
1310    
1311      /* Make sure that we can read the file.
1312         XXX - Should we attempt to locate the debug info file using the same
1313         algorithm as gdb ?  At the moment, since we are creating the
1314         .gnu_debuglink section, we insist upon the user providing us with a
1315         correct-for-section-creation-time path, but this need not conform to
1316         the gdb location algorithm.  */
1317      handle = fopen (filename, FOPEN_RB);
1318      if (handle == NULL)
1319        {
1320          bfd_set_error (bfd_error_system_call);
1321          return FALSE;
1322        }
1323    
1324      crc32 = 0;
1325      while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
1326        crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
1327      fclose (handle);
1328    
1329      /* Strip off any path components in filename,
1330         now that we no longer need them.  */
1331      filename = lbasename (filename);
1332    
1333      debuglink_size = strlen (filename) + 1;
1334      debuglink_size += 3;
1335      debuglink_size &= ~3;
1336      debuglink_size += 4;
1337    
1338      contents = malloc (debuglink_size);
1339      if (contents == NULL)
1340        {
1341          /* XXX Should we delete the section from the bfd ?  */
1342          bfd_set_error (bfd_error_no_memory);
1343          return FALSE;
1344        }
1345    
1346      strcpy (contents, filename);
1347      crc_offset = debuglink_size - 4;
1348    
1349      bfd_put_32 (abfd, crc32, contents + crc_offset);
1350    
1351      if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
1352        {
1353          /* XXX Should we delete the section from the bfd ?  */
1354          free (contents);
1355          return FALSE;
1356        }
1357    
1358      return TRUE;
1359    }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26