Back to index

cell-binutils  2.17cvs20070401
opncls.c
Go to the documentation of this file.
00001 /* opncls.c -- open and close a BFD.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
00003    2001, 2002, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005 
00006    Written by Cygnus Support.
00007 
00008    This file is part of BFD, the Binary File Descriptor library.
00009 
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2 of the License, or
00013    (at your option) any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program; if not, write to the Free Software
00022    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00023 
00024 #include "bfd.h"
00025 #include "sysdep.h"
00026 #include "objalloc.h"
00027 #include "libbfd.h"
00028 #include "libiberty.h"
00029 
00030 #ifndef S_IXUSR
00031 #define S_IXUSR 0100 /* Execute by owner.  */
00032 #endif
00033 #ifndef S_IXGRP
00034 #define S_IXGRP 0010 /* Execute by group.  */
00035 #endif
00036 #ifndef S_IXOTH
00037 #define S_IXOTH 0001 /* Execute by others.  */
00038 #endif
00039 
00040 /* Counter used to initialize the bfd identifier.  */
00041 
00042 static unsigned int _bfd_id_counter = 0;
00043 
00044 /* fdopen is a loser -- we should use stdio exclusively.  Unfortunately
00045    if we do that we can't use fcntl.  */
00046 
00047 /* Return a new BFD.  All BFD's are allocated through this routine.  */
00048 
00049 bfd *
00050 _bfd_new_bfd (void)
00051 {
00052   bfd *nbfd;
00053 
00054   nbfd = bfd_zmalloc (sizeof (bfd));
00055   if (nbfd == NULL)
00056     return NULL;
00057 
00058   nbfd->id = _bfd_id_counter++;
00059 
00060   nbfd->memory = objalloc_create ();
00061   if (nbfd->memory == NULL)
00062     {
00063       bfd_set_error (bfd_error_no_memory);
00064       free (nbfd);
00065       return NULL;
00066     }
00067 
00068   nbfd->arch_info = &bfd_default_arch_struct;
00069 
00070   nbfd->direction = no_direction;
00071   nbfd->iostream = NULL;
00072   nbfd->where = 0;
00073   if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
00074                            sizeof (struct section_hash_entry), 251))
00075     {
00076       free (nbfd);
00077       return NULL;
00078     }
00079   nbfd->sections = NULL;
00080   nbfd->section_last = NULL;
00081   nbfd->format = bfd_unknown;
00082   nbfd->my_archive = NULL;
00083   nbfd->origin = 0;
00084   nbfd->opened_once = FALSE;
00085   nbfd->output_has_begun = FALSE;
00086   nbfd->section_count = 0;
00087   nbfd->usrdata = NULL;
00088   nbfd->cacheable = FALSE;
00089   nbfd->flags = BFD_NO_FLAGS;
00090   nbfd->mtime_set = FALSE;
00091 
00092   return nbfd;
00093 }
00094 
00095 /* Allocate a new BFD as a member of archive OBFD.  */
00096 
00097 bfd *
00098 _bfd_new_bfd_contained_in (bfd *obfd)
00099 {
00100   bfd *nbfd;
00101 
00102   nbfd = _bfd_new_bfd ();
00103   if (nbfd == NULL)
00104     return NULL;
00105   nbfd->xvec = obfd->xvec;
00106   nbfd->iovec = obfd->iovec;
00107   nbfd->my_archive = obfd;
00108   nbfd->direction = read_direction;
00109   nbfd->target_defaulted = obfd->target_defaulted;
00110   return nbfd;
00111 }
00112 
00113 /* Delete a BFD.  */
00114 
00115 void
00116 _bfd_delete_bfd (bfd *abfd)
00117 {
00118   if (abfd->memory)
00119     {
00120       bfd_hash_table_free (&abfd->section_htab);
00121       objalloc_free ((struct objalloc *) abfd->memory);
00122     }
00123   free (abfd);
00124 }
00125 
00126 /* Free objalloc memory.  */
00127 
00128 bfd_boolean
00129 _bfd_free_cached_info (bfd *abfd)
00130 {
00131   if (abfd->memory)
00132     {
00133       bfd_hash_table_free (&abfd->section_htab);
00134       objalloc_free ((struct objalloc *) abfd->memory);
00135 
00136       abfd->sections = NULL;
00137       abfd->section_last = NULL;
00138       abfd->outsymbols = NULL;
00139       abfd->tdata.any = NULL;
00140       abfd->usrdata = NULL;
00141       abfd->memory = NULL;
00142     }
00143 
00144   return TRUE;
00145 }
00146 
00147 /*
00148 SECTION
00149        Opening and closing BFDs
00150 
00151 SUBSECTION
00152        Functions for opening and closing
00153 */
00154 
00155 /*
00156 FUNCTION
00157        bfd_fopen
00158 
00159 SYNOPSIS
00160        bfd *bfd_fopen (const char *filename, const char *target,
00161                         const char *mode, int fd);
00162 
00163 DESCRIPTION
00164        Open the file @var{filename} with the target @var{target}.
00165        Return a pointer to the created BFD.  If @var{fd} is not -1,
00166        then <<fdopen>> is used to open the file; otherwise, <<fopen>>
00167        is used.  @var{mode} is passed directly to <<fopen>> or
00168        <<fdopen>>. 
00169 
00170        Calls <<bfd_find_target>>, so @var{target} is interpreted as by
00171        that function.
00172 
00173        The new BFD is marked as cacheable iff @var{fd} is -1.
00174 
00175        If <<NULL>> is returned then an error has occured.   Possible errors
00176        are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
00177        <<system_call>> error.
00178 */
00179 
00180 bfd *
00181 bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
00182 {
00183   bfd *nbfd;
00184   const bfd_target *target_vec;
00185 
00186   nbfd = _bfd_new_bfd ();
00187   if (nbfd == NULL)
00188     return NULL;
00189 
00190   target_vec = bfd_find_target (target, nbfd);
00191   if (target_vec == NULL)
00192     {
00193       _bfd_delete_bfd (nbfd);
00194       return NULL;
00195     }
00196   
00197 #ifdef HAVE_FDOPEN
00198   if (fd != -1)
00199     nbfd->iostream = fdopen (fd, mode);
00200   else
00201 #endif
00202     nbfd->iostream = real_fopen (filename, mode);
00203   if (nbfd->iostream == NULL)
00204     {
00205       bfd_set_error (bfd_error_system_call);
00206       _bfd_delete_bfd (nbfd);
00207       return NULL;
00208     }
00209 
00210   /* OK, put everything where it belongs.  */
00211   nbfd->filename = filename;
00212 
00213   /* Figure out whether the user is opening the file for reading,
00214      writing, or both, by looking at the MODE argument.  */
00215   if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a') 
00216       && mode[1] == '+')
00217     nbfd->direction = both_direction;
00218   else if (mode[0] == 'r')
00219     nbfd->direction = read_direction;
00220   else
00221     nbfd->direction = write_direction;
00222 
00223   if (! bfd_cache_init (nbfd))
00224     {
00225       _bfd_delete_bfd (nbfd);
00226       return NULL;
00227     }
00228   nbfd->opened_once = TRUE;
00229   /* If we opened the file by name, mark it cacheable; we can close it
00230      and reopen it later.  However, if a file descriptor was provided,
00231      then it may have been opened with special flags that make it
00232      unsafe to close and reopen the file.  */
00233   if (fd == -1)
00234     bfd_set_cacheable (nbfd, TRUE);
00235 
00236   return nbfd;
00237 }
00238 
00239 /*
00240 FUNCTION
00241        bfd_openr
00242 
00243 SYNOPSIS
00244        bfd *bfd_openr (const char *filename, const char *target);
00245 
00246 DESCRIPTION
00247        Open the file @var{filename} (using <<fopen>>) with the target
00248        @var{target}.  Return a pointer to the created BFD.
00249 
00250        Calls <<bfd_find_target>>, so @var{target} is interpreted as by
00251        that function.
00252 
00253        If <<NULL>> is returned then an error has occured.   Possible errors
00254        are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
00255        <<system_call>> error.
00256 */
00257 
00258 bfd *
00259 bfd_openr (const char *filename, const char *target)
00260 {
00261   return bfd_fopen (filename, target, FOPEN_RB, -1);
00262 }
00263 
00264 /* Don't try to `optimize' this function:
00265 
00266    o - We lock using stack space so that interrupting the locking
00267        won't cause a storage leak.
00268    o - We open the file stream last, since we don't want to have to
00269        close it if anything goes wrong.  Closing the stream means closing
00270        the file descriptor too, even though we didn't open it.  */
00271 /*
00272 FUNCTION
00273        bfd_fdopenr
00274 
00275 SYNOPSIS
00276        bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
00277 
00278 DESCRIPTION
00279        <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
00280        <<fopen>>.  It opens a BFD on a file already described by the
00281        @var{fd} supplied.
00282 
00283        When the file is later <<bfd_close>>d, the file descriptor will
00284        be closed.  If the caller desires that this file descriptor be
00285        cached by BFD (opened as needed, closed as needed to free
00286        descriptors for other opens), with the supplied @var{fd} used as
00287        an initial file descriptor (but subject to closure at any time),
00288        call bfd_set_cacheable(bfd, 1) on the returned BFD.  The default
00289        is to assume no caching; the file descriptor will remain open
00290        until <<bfd_close>>, and will not be affected by BFD operations
00291        on other files.
00292 
00293        Possible errors are <<bfd_error_no_memory>>,
00294        <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
00295 */
00296 
00297 bfd *
00298 bfd_fdopenr (const char *filename, const char *target, int fd)
00299 {
00300   const char *mode;
00301 #if defined(HAVE_FCNTL) && defined(F_GETFL)
00302   int fdflags;
00303 #endif
00304 
00305 #if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
00306   mode = FOPEN_RUB; /* Assume full access.  */
00307 #else
00308   fdflags = fcntl (fd, F_GETFL, NULL);
00309   if (fdflags == -1)
00310     {
00311       bfd_set_error (bfd_error_system_call);
00312       return NULL;
00313     }
00314 
00315   /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */
00316   switch (fdflags & (O_ACCMODE))
00317     {
00318     case O_RDONLY: mode = FOPEN_RB; break;
00319     case O_WRONLY: mode = FOPEN_RUB; break;
00320     case O_RDWR:   mode = FOPEN_RUB; break;
00321     default: abort ();
00322     }
00323 #endif
00324 
00325   return bfd_fopen (filename, target, mode, fd);
00326 }
00327 
00328 /*
00329 FUNCTION
00330        bfd_openstreamr
00331 
00332 SYNOPSIS
00333        bfd *bfd_openstreamr (const char *, const char *, void *);
00334 
00335 DESCRIPTION
00336 
00337        Open a BFD for read access on an existing stdio stream.  When
00338        the BFD is passed to <<bfd_close>>, the stream will be closed.
00339 */
00340 
00341 bfd *
00342 bfd_openstreamr (const char *filename, const char *target, void *streamarg)
00343 {
00344   FILE *stream = streamarg;
00345   bfd *nbfd;
00346   const bfd_target *target_vec;
00347 
00348   nbfd = _bfd_new_bfd ();
00349   if (nbfd == NULL)
00350     return NULL;
00351 
00352   target_vec = bfd_find_target (target, nbfd);
00353   if (target_vec == NULL)
00354     {
00355       _bfd_delete_bfd (nbfd);
00356       return NULL;
00357     }
00358 
00359   nbfd->iostream = stream;
00360   nbfd->filename = filename;
00361   nbfd->direction = read_direction;
00362 
00363   if (! bfd_cache_init (nbfd))
00364     {
00365       _bfd_delete_bfd (nbfd);
00366       return NULL;
00367     }
00368 
00369   return nbfd;
00370 }
00371 
00372 /*
00373 FUNCTION
00374        bfd_openr_iovec
00375 
00376 SYNOPSIS
00377         bfd *bfd_openr_iovec (const char *filename, const char *target,
00378                               void *(*open) (struct bfd *nbfd,
00379                                              void *open_closure),
00380                               void *open_closure,
00381                               file_ptr (*pread) (struct bfd *nbfd,
00382                                                  void *stream,
00383                                                  void *buf,
00384                                                  file_ptr nbytes,
00385                                                  file_ptr offset),
00386                               int (*close) (struct bfd *nbfd,
00387                                             void *stream),
00388                            int (*stat) (struct bfd *abfd,
00389                                       void *stream,
00390                                       struct stat *sb));
00391 
00392 DESCRIPTION
00393 
00394         Create and return a BFD backed by a read-only @var{stream}.
00395         The @var{stream} is created using @var{open}, accessed using
00396         @var{pread} and destroyed using @var{close}.
00397 
00398        Calls <<bfd_find_target>>, so @var{target} is interpreted as by
00399        that function.
00400 
00401        Calls @var{open} (which can call <<bfd_zalloc>> and
00402        <<bfd_get_filename>>) to obtain the read-only stream backing
00403        the BFD.  @var{open} either succeeds returning the
00404        non-<<NULL>> @var{stream}, or fails returning <<NULL>>
00405        (setting <<bfd_error>>).
00406 
00407        Calls @var{pread} to request @var{nbytes} of data from
00408        @var{stream} starting at @var{offset} (e.g., via a call to
00409        <<bfd_read>>).  @var{pread} either succeeds returning the
00410        number of bytes read (which can be less than @var{nbytes} when
00411        end-of-file), or fails returning -1 (setting <<bfd_error>>).
00412 
00413        Calls @var{close} when the BFD is later closed using
00414        <<bfd_close>>.  @var{close} either succeeds returning 0, or
00415        fails returning -1 (setting <<bfd_error>>).
00416 
00417        Calls @var{stat} to fill in a stat structure for bfd_stat,
00418        bfd_get_size, and bfd_get_mtime calls.  @var{stat} returns 0
00419        on success, or returns -1 on failure (setting <<bfd_error>>).
00420 
00421        If <<bfd_openr_iovec>> returns <<NULL>> then an error has
00422        occurred.  Possible errors are <<bfd_error_no_memory>>,
00423        <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
00424 
00425 */
00426 
00427 struct opncls
00428 {
00429   void *stream;
00430   file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf,
00431                    file_ptr nbytes, file_ptr offset);
00432   int (*close) (struct bfd *abfd, void *stream);
00433   int (*stat) (struct bfd *abfd, void *stream, struct stat *sb);
00434   file_ptr where;
00435 };
00436 
00437 static file_ptr
00438 opncls_btell (struct bfd *abfd)
00439 {
00440   struct opncls *vec = abfd->iostream;
00441   return vec->where;
00442 }
00443 
00444 static int
00445 opncls_bseek (struct bfd *abfd, file_ptr offset, int whence)
00446 {
00447   struct opncls *vec = abfd->iostream;
00448   switch (whence)
00449     {
00450     case SEEK_SET: vec->where = offset; break;
00451     case SEEK_CUR: vec->where += offset; break;
00452     case SEEK_END: return -1;
00453     }
00454   return 0;
00455 }
00456 
00457 static file_ptr
00458 opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
00459 {
00460   struct opncls *vec = abfd->iostream;
00461   file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where);
00462   if (nread < 0)
00463     return nread;
00464   vec->where += nread;
00465   return nread;
00466 }
00467 
00468 static file_ptr
00469 opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
00470              const void *where ATTRIBUTE_UNUSED,
00471              file_ptr nbytes ATTRIBUTE_UNUSED)
00472 {
00473   return -1;
00474 }
00475 
00476 static int
00477 opncls_bclose (struct bfd *abfd)
00478 {
00479   struct opncls *vec = abfd->iostream;
00480   /* Since the VEC's memory is bound to the bfd deleting the bfd will
00481      free it.  */
00482   int status = 0;
00483   if (vec->close != NULL)
00484     status = (vec->close) (abfd, vec->stream);
00485   abfd->iostream = NULL;
00486   return status;
00487 }
00488 
00489 static int
00490 opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
00491 {
00492   return 0;
00493 }
00494 
00495 static int
00496 opncls_bstat (struct bfd *abfd, struct stat *sb)
00497 {
00498   struct opncls *vec = abfd->iostream;
00499 
00500   memset (sb, 0, sizeof (*sb));
00501   if (vec->stat == NULL)
00502     return 0;
00503 
00504   return (vec->stat) (abfd, vec->stream, sb);
00505 }
00506 
00507 static const struct bfd_iovec opncls_iovec = {
00508   &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
00509   &opncls_bclose, &opncls_bflush, &opncls_bstat
00510 };
00511 
00512 bfd *
00513 bfd_openr_iovec (const char *filename, const char *target,
00514                void *(*open) (struct bfd *nbfd,
00515                             void *open_closure),
00516                void *open_closure,
00517                file_ptr (*pread) (struct bfd *abfd,
00518                                 void *stream,
00519                                 void *buf,
00520                                 file_ptr nbytes,
00521                                 file_ptr offset),
00522                int (*close) (struct bfd *nbfd,
00523                             void *stream),
00524                int (*stat) (struct bfd *abfd,
00525                            void *stream,
00526                            struct stat *sb))
00527 {
00528   bfd *nbfd;
00529   const bfd_target *target_vec;
00530   struct opncls *vec;
00531   void *stream;
00532 
00533   nbfd = _bfd_new_bfd ();
00534   if (nbfd == NULL)
00535     return NULL;
00536 
00537   target_vec = bfd_find_target (target, nbfd);
00538   if (target_vec == NULL)
00539     {
00540       _bfd_delete_bfd (nbfd);
00541       return NULL;
00542     }
00543 
00544   nbfd->filename = filename;
00545   nbfd->direction = read_direction;
00546 
00547   stream = open (nbfd, open_closure);
00548   if (stream == NULL)
00549     {
00550       _bfd_delete_bfd (nbfd);
00551       return NULL;
00552     }
00553 
00554   vec = bfd_zalloc (nbfd, sizeof (struct opncls));
00555   vec->stream = stream;
00556   vec->pread = pread;
00557   vec->close = close;
00558   vec->stat = stat;
00559 
00560   nbfd->iovec = &opncls_iovec;
00561   nbfd->iostream = vec;
00562 
00563   return nbfd;
00564 }
00565 
00566 /* bfd_openw -- open for writing.
00567    Returns a pointer to a freshly-allocated BFD on success, or NULL.
00568 
00569    See comment by bfd_fdopenr before you try to modify this function.  */
00570 
00571 /*
00572 FUNCTION
00573        bfd_openw
00574 
00575 SYNOPSIS
00576        bfd *bfd_openw (const char *filename, const char *target);
00577 
00578 DESCRIPTION
00579        Create a BFD, associated with file @var{filename}, using the
00580        file format @var{target}, and return a pointer to it.
00581 
00582        Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
00583        <<bfd_error_invalid_target>>.
00584 */
00585 
00586 bfd *
00587 bfd_openw (const char *filename, const char *target)
00588 {
00589   bfd *nbfd;
00590   const bfd_target *target_vec;
00591 
00592   /* nbfd has to point to head of malloc'ed block so that bfd_close may
00593      reclaim it correctly.  */
00594   nbfd = _bfd_new_bfd ();
00595   if (nbfd == NULL)
00596     return NULL;
00597 
00598   target_vec = bfd_find_target (target, nbfd);
00599   if (target_vec == NULL)
00600     {
00601       _bfd_delete_bfd (nbfd);
00602       return NULL;
00603     }
00604 
00605   nbfd->filename = filename;
00606   nbfd->direction = write_direction;
00607 
00608   if (bfd_open_file (nbfd) == NULL)
00609     {
00610       /* File not writeable, etc.  */
00611       bfd_set_error (bfd_error_system_call);
00612       _bfd_delete_bfd (nbfd);
00613       return NULL;
00614   }
00615 
00616   return nbfd;
00617 }
00618 
00619 /*
00620 
00621 FUNCTION
00622        bfd_close
00623 
00624 SYNOPSIS
00625        bfd_boolean bfd_close (bfd *abfd);
00626 
00627 DESCRIPTION
00628 
00629        Close a BFD. If the BFD was open for writing, then pending
00630        operations are completed and the file written out and closed.
00631        If the created file is executable, then <<chmod>> is called
00632        to mark it as such.
00633 
00634        All memory attached to the BFD is released.
00635 
00636        The file descriptor associated with the BFD is closed (even
00637        if it was passed in to BFD by <<bfd_fdopenr>>).
00638 
00639 RETURNS
00640        <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
00641 */
00642 
00643 
00644 bfd_boolean
00645 bfd_close (bfd *abfd)
00646 {
00647   bfd_boolean ret;
00648 
00649   if (bfd_write_p (abfd))
00650     {
00651       if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
00652        return FALSE;
00653     }
00654 
00655   if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
00656     return FALSE;
00657 
00658   /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io
00659      vector.  */
00660   if (!(abfd->flags & BFD_IN_MEMORY))
00661     ret = abfd->iovec->bclose (abfd);
00662   else
00663     ret = TRUE;
00664 
00665   /* If the file was open for writing and is now executable,
00666      make it so.  */
00667   if (ret
00668       && abfd->direction == write_direction
00669       && abfd->flags & EXEC_P)
00670     {
00671       struct stat buf;
00672 
00673       if (stat (abfd->filename, &buf) == 0)
00674        {
00675          unsigned int mask = umask (0);
00676 
00677          umask (mask);
00678          chmod (abfd->filename,
00679                (0777
00680                 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
00681        }
00682     }
00683 
00684   _bfd_delete_bfd (abfd);
00685 
00686   return ret;
00687 }
00688 
00689 /*
00690 FUNCTION
00691        bfd_close_all_done
00692 
00693 SYNOPSIS
00694        bfd_boolean bfd_close_all_done (bfd *);
00695 
00696 DESCRIPTION
00697        Close a BFD.  Differs from <<bfd_close>> since it does not
00698        complete any pending operations.  This routine would be used
00699        if the application had just used BFD for swapping and didn't
00700        want to use any of the writing code.
00701 
00702        If the created file is executable, then <<chmod>> is called
00703        to mark it as such.
00704 
00705        All memory attached to the BFD is released.
00706 
00707 RETURNS
00708        <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
00709 */
00710 
00711 bfd_boolean
00712 bfd_close_all_done (bfd *abfd)
00713 {
00714   bfd_boolean ret;
00715 
00716   ret = bfd_cache_close (abfd);
00717 
00718   /* If the file was open for writing and is now executable,
00719      make it so.  */
00720   if (ret
00721       && abfd->direction == write_direction
00722       && abfd->flags & EXEC_P)
00723     {
00724       struct stat buf;
00725 
00726       if (stat (abfd->filename, &buf) == 0)
00727        {
00728          unsigned int mask = umask (0);
00729 
00730          umask (mask);
00731          chmod (abfd->filename,
00732                (0777
00733                 & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
00734        }
00735     }
00736 
00737   _bfd_delete_bfd (abfd);
00738 
00739   return ret;
00740 }
00741 
00742 /*
00743 FUNCTION
00744        bfd_create
00745 
00746 SYNOPSIS
00747        bfd *bfd_create (const char *filename, bfd *templ);
00748 
00749 DESCRIPTION
00750        Create a new BFD in the manner of <<bfd_openw>>, but without
00751        opening a file. The new BFD takes the target from the target
00752        used by @var{template}. The format is always set to <<bfd_object>>.
00753 */
00754 
00755 bfd *
00756 bfd_create (const char *filename, bfd *templ)
00757 {
00758   bfd *nbfd;
00759 
00760   nbfd = _bfd_new_bfd ();
00761   if (nbfd == NULL)
00762     return NULL;
00763   nbfd->filename = filename;
00764   if (templ)
00765     nbfd->xvec = templ->xvec;
00766   nbfd->direction = no_direction;
00767   bfd_set_format (nbfd, bfd_object);
00768 
00769   return nbfd;
00770 }
00771 
00772 /*
00773 FUNCTION
00774        bfd_make_writable
00775 
00776 SYNOPSIS
00777        bfd_boolean bfd_make_writable (bfd *abfd);
00778 
00779 DESCRIPTION
00780        Takes a BFD as created by <<bfd_create>> and converts it
00781        into one like as returned by <<bfd_openw>>.  It does this
00782        by converting the BFD to BFD_IN_MEMORY.  It's assumed that
00783        you will call <<bfd_make_readable>> on this bfd later.
00784 
00785 RETURNS
00786        <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
00787 */
00788 
00789 bfd_boolean
00790 bfd_make_writable (bfd *abfd)
00791 {
00792   struct bfd_in_memory *bim;
00793 
00794   if (abfd->direction != no_direction)
00795     {
00796       bfd_set_error (bfd_error_invalid_operation);
00797       return FALSE;
00798     }
00799 
00800   bim = bfd_malloc (sizeof (struct bfd_in_memory));
00801   abfd->iostream = bim;
00802   /* bfd_bwrite will grow these as needed.  */
00803   bim->size = 0;
00804   bim->buffer = 0;
00805 
00806   abfd->flags |= BFD_IN_MEMORY;
00807   abfd->direction = write_direction;
00808   abfd->where = 0;
00809 
00810   return TRUE;
00811 }
00812 
00813 /*
00814 FUNCTION
00815        bfd_make_readable
00816 
00817 SYNOPSIS
00818        bfd_boolean bfd_make_readable (bfd *abfd);
00819 
00820 DESCRIPTION
00821        Takes a BFD as created by <<bfd_create>> and
00822        <<bfd_make_writable>> and converts it into one like as
00823        returned by <<bfd_openr>>.  It does this by writing the
00824        contents out to the memory buffer, then reversing the
00825        direction.
00826 
00827 RETURNS
00828        <<TRUE>> is returned if all is ok, otherwise <<FALSE>>.  */
00829 
00830 bfd_boolean
00831 bfd_make_readable (bfd *abfd)
00832 {
00833   if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
00834     {
00835       bfd_set_error (bfd_error_invalid_operation);
00836       return FALSE;
00837     }
00838 
00839   if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
00840     return FALSE;
00841 
00842   if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
00843     return FALSE;
00844 
00845 
00846   abfd->arch_info = &bfd_default_arch_struct;
00847 
00848   abfd->where = 0;
00849   abfd->format = bfd_unknown;
00850   abfd->my_archive = NULL;
00851   abfd->origin = 0;
00852   abfd->opened_once = FALSE;
00853   abfd->output_has_begun = FALSE;
00854   abfd->section_count = 0;
00855   abfd->usrdata = NULL;
00856   abfd->cacheable = FALSE;
00857   abfd->flags = BFD_IN_MEMORY;
00858   abfd->mtime_set = FALSE;
00859 
00860   abfd->target_defaulted = TRUE;
00861   abfd->direction = read_direction;
00862   abfd->sections = 0;
00863   abfd->symcount = 0;
00864   abfd->outsymbols = 0;
00865   abfd->tdata.any = 0;
00866 
00867   bfd_section_list_clear (abfd);
00868   bfd_check_format (abfd, bfd_object);
00869 
00870   return TRUE;
00871 }
00872 
00873 /*
00874 INTERNAL_FUNCTION
00875        bfd_alloc
00876 
00877 SYNOPSIS
00878        void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
00879 
00880 DESCRIPTION
00881        Allocate a block of @var{wanted} bytes of memory attached to
00882        <<abfd>> and return a pointer to it.
00883 */
00884 
00885 void *
00886 bfd_alloc (bfd *abfd, bfd_size_type size)
00887 {
00888   void *ret;
00889 
00890   if (size != (unsigned long) size)
00891     {
00892       bfd_set_error (bfd_error_no_memory);
00893       return NULL;
00894     }
00895 
00896   ret = objalloc_alloc (abfd->memory, (unsigned long) size);
00897   if (ret == NULL)
00898     bfd_set_error (bfd_error_no_memory);
00899   return ret;
00900 }
00901 
00902 /*
00903 INTERNAL_FUNCTION
00904        bfd_alloc2
00905 
00906 SYNOPSIS
00907        void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
00908 
00909 DESCRIPTION
00910        Allocate a block of @var{nmemb} elements of @var{size} bytes each
00911        of memory attached to <<abfd>> and return a pointer to it.
00912 */
00913 
00914 void *
00915 bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
00916 {
00917   void *ret;
00918 
00919   if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
00920       && size != 0
00921       && nmemb > ~(bfd_size_type) 0 / size)
00922     {
00923       bfd_set_error (bfd_error_no_memory);
00924       return NULL;
00925     }
00926 
00927   size *= nmemb;
00928 
00929   if (size != (unsigned long) size)
00930     {
00931       bfd_set_error (bfd_error_no_memory);
00932       return NULL;
00933     }
00934 
00935   ret = objalloc_alloc (abfd->memory, (unsigned long) size);
00936   if (ret == NULL)
00937     bfd_set_error (bfd_error_no_memory);
00938   return ret;
00939 }
00940 
00941 /*
00942 INTERNAL_FUNCTION
00943        bfd_zalloc
00944 
00945 SYNOPSIS
00946        void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
00947 
00948 DESCRIPTION
00949        Allocate a block of @var{wanted} bytes of zeroed memory
00950        attached to <<abfd>> and return a pointer to it.
00951 */
00952 
00953 void *
00954 bfd_zalloc (bfd *abfd, bfd_size_type size)
00955 {
00956   void *res;
00957 
00958   res = bfd_alloc (abfd, size);
00959   if (res)
00960     memset (res, 0, (size_t) size);
00961   return res;
00962 }
00963 
00964 /*
00965 INTERNAL_FUNCTION
00966        bfd_zalloc2
00967 
00968 SYNOPSIS
00969        void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
00970 
00971 DESCRIPTION
00972        Allocate a block of @var{nmemb} elements of @var{size} bytes each
00973        of zeroed memory attached to <<abfd>> and return a pointer to it.
00974 */
00975 
00976 void *
00977 bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
00978 {
00979   void *res;
00980 
00981   if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
00982       && size != 0
00983       && nmemb > ~(bfd_size_type) 0 / size)
00984     {
00985       bfd_set_error (bfd_error_no_memory);
00986       return NULL;
00987     }
00988 
00989   size *= nmemb;
00990 
00991   res = bfd_alloc (abfd, size);
00992   if (res)
00993     memset (res, 0, (size_t) size);
00994   return res;
00995 }
00996 
00997 /* Free a block allocated for a BFD.
00998    Note:  Also frees all more recently allocated blocks!  */
00999 
01000 void
01001 bfd_release (bfd *abfd, void *block)
01002 {
01003   objalloc_free_block ((struct objalloc *) abfd->memory, block);
01004 }
01005 
01006 
01007 /*
01008    GNU Extension: separate debug-info files
01009 
01010    The idea here is that a special section called .gnu_debuglink might be
01011    embedded in a binary file, which indicates that some *other* file
01012    contains the real debugging information. This special section contains a
01013    filename and CRC32 checksum, which we read and resolve to another file,
01014    if it exists.
01015 
01016    This facilitates "optional" provision of debugging information, without
01017    having to provide two complete copies of every binary object (with and
01018    without debug symbols).
01019 */
01020 
01021 #define GNU_DEBUGLINK       ".gnu_debuglink"
01022 /*
01023 FUNCTION
01024        bfd_calc_gnu_debuglink_crc32
01025 
01026 SYNOPSIS
01027        unsigned long bfd_calc_gnu_debuglink_crc32
01028          (unsigned long crc, const unsigned char *buf, bfd_size_type len);
01029 
01030 DESCRIPTION
01031        Computes a CRC value as used in the .gnu_debuglink section.
01032        Advances the previously computed @var{crc} value by computing
01033        and adding in the crc32 for @var{len} bytes of @var{buf}.
01034 
01035 RETURNS
01036        Return the updated CRC32 value.
01037 */
01038 
01039 unsigned long
01040 bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
01041                            const unsigned char *buf,
01042                            bfd_size_type len)
01043 {
01044   static const unsigned long crc32_table[256] =
01045     {
01046       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
01047       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
01048       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
01049       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
01050       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
01051       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
01052       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
01053       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
01054       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
01055       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
01056       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
01057       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
01058       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
01059       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
01060       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
01061       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
01062       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
01063       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
01064       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
01065       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
01066       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
01067       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
01068       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
01069       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
01070       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
01071       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
01072       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
01073       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
01074       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
01075       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
01076       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
01077       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
01078       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
01079       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
01080       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
01081       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
01082       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
01083       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
01084       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
01085       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
01086       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
01087       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
01088       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
01089       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
01090       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
01091       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
01092       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
01093       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
01094       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
01095       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
01096       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
01097       0x2d02ef8d
01098     };
01099   const unsigned char *end;
01100 
01101   crc = ~crc & 0xffffffff;
01102   for (end = buf + len; buf < end; ++ buf)
01103     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
01104   return ~crc & 0xffffffff;;
01105 }
01106 
01107 
01108 /*
01109 INTERNAL_FUNCTION
01110        get_debug_link_info
01111 
01112 SYNOPSIS
01113        char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
01114 
01115 DESCRIPTION
01116        fetch the filename and CRC32 value for any separate debuginfo
01117        associated with @var{abfd}. Return NULL if no such info found,
01118        otherwise return filename and update @var{crc32_out}.
01119 */
01120 
01121 static char *
01122 get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
01123 {
01124   asection *sect;
01125   unsigned long crc32;
01126   bfd_byte *contents;
01127   int crc_offset;
01128   char *name;
01129 
01130   BFD_ASSERT (abfd);
01131   BFD_ASSERT (crc32_out);
01132 
01133   sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
01134 
01135   if (sect == NULL)
01136     return NULL;
01137 
01138   if (!bfd_malloc_and_get_section (abfd, sect, &contents))
01139     {
01140       if (contents != NULL)
01141        free (contents);
01142       return NULL;
01143     }
01144 
01145   /* Crc value is stored after the filename, aligned up to 4 bytes.  */
01146   name = (char *) contents;
01147   crc_offset = strlen (name) + 1;
01148   crc_offset = (crc_offset + 3) & ~3;
01149 
01150   crc32 = bfd_get_32 (abfd, contents + crc_offset);
01151 
01152   *crc32_out = crc32;
01153   return name;
01154 }
01155 
01156 /*
01157 INTERNAL_FUNCTION
01158        separate_debug_file_exists
01159 
01160 SYNOPSIS
01161        bfd_boolean separate_debug_file_exists
01162          (char *name, unsigned long crc32);
01163 
01164 DESCRIPTION
01165        Checks to see if @var{name} is a file and if its contents
01166        match @var{crc32}.
01167 */
01168 
01169 static bfd_boolean
01170 separate_debug_file_exists (const char *name, const unsigned long crc)
01171 {
01172   static unsigned char buffer [8 * 1024];
01173   unsigned long file_crc = 0;
01174   int fd;
01175   bfd_size_type count;
01176 
01177   BFD_ASSERT (name);
01178 
01179   fd = open (name, O_RDONLY);
01180   if (fd < 0)
01181     return FALSE;
01182 
01183   while ((count = read (fd, buffer, sizeof (buffer))) > 0)
01184     file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
01185 
01186   close (fd);
01187 
01188   return crc == file_crc;
01189 }
01190 
01191 
01192 /*
01193 INTERNAL_FUNCTION
01194        find_separate_debug_file
01195 
01196 SYNOPSIS
01197        char *find_separate_debug_file (bfd *abfd);
01198 
01199 DESCRIPTION
01200        Searches @var{abfd} for a reference to separate debugging
01201        information, scans various locations in the filesystem, including
01202        the file tree rooted at @var{debug_file_directory}, and returns a
01203        filename of such debugging information if the file is found and has
01204        matching CRC32.  Returns NULL if no reference to debugging file
01205        exists, or file cannot be found.
01206 */
01207 
01208 static char *
01209 find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
01210 {
01211   char *basename;
01212   char *dir;
01213   char *debugfile;
01214   unsigned long crc32;
01215   int i;
01216 
01217   BFD_ASSERT (abfd);
01218   if (debug_file_directory == NULL)
01219     debug_file_directory = ".";
01220 
01221   /* BFD may have been opened from a stream.  */
01222   if (! abfd->filename)
01223     return NULL;
01224 
01225   basename = get_debug_link_info (abfd, & crc32);
01226   if (basename == NULL)
01227     return NULL;
01228 
01229   if (strlen (basename) < 1)
01230     {
01231       free (basename);
01232       return NULL;
01233     }
01234 
01235   dir = strdup (abfd->filename);
01236   if (dir == NULL)
01237     {
01238       free (basename);
01239       return NULL;
01240     }
01241   BFD_ASSERT (strlen (dir) != 0);
01242 
01243   /* Strip off filename part.  */
01244   for (i = strlen (dir) - 1; i >= 0; i--)
01245     if (IS_DIR_SEPARATOR (dir[i]))
01246       break;
01247 
01248   dir[i + 1] = '\0';
01249   BFD_ASSERT (dir[i] == '/' || dir[0] == '\0');
01250 
01251   debugfile = malloc (strlen (debug_file_directory) + 1
01252                     + strlen (dir)
01253                     + strlen (".debug/")
01254                     + strlen (basename)
01255                     + 1);
01256   if (debugfile == NULL)
01257     {
01258       free (basename);
01259       free (dir);
01260       return NULL;
01261     }
01262 
01263   /* First try in the same directory as the original file:  */
01264   strcpy (debugfile, dir);
01265   strcat (debugfile, basename);
01266 
01267   if (separate_debug_file_exists (debugfile, crc32))
01268     {
01269       free (basename);
01270       free (dir);
01271       return debugfile;
01272     }
01273 
01274   /* Then try in a subdirectory called .debug.  */
01275   strcpy (debugfile, dir);
01276   strcat (debugfile, ".debug/");
01277   strcat (debugfile, basename);
01278 
01279   if (separate_debug_file_exists (debugfile, crc32))
01280     {
01281       free (basename);
01282       free (dir);
01283       return debugfile;
01284     }
01285 
01286   /* Then try in the global debugfile directory.  */
01287   strcpy (debugfile, debug_file_directory);
01288   i = strlen (debug_file_directory) - 1;
01289   if (i > 0
01290       && debug_file_directory[i] != '/'
01291       && dir[0] != '/')
01292     strcat (debugfile, "/");
01293   strcat (debugfile, dir);
01294   strcat (debugfile, basename);
01295 
01296   if (separate_debug_file_exists (debugfile, crc32))
01297     {
01298       free (basename);
01299       free (dir);
01300       return debugfile;
01301     }
01302 
01303   free (debugfile);
01304   free (basename);
01305   free (dir);
01306   return NULL;
01307 }
01308 
01309 
01310 /*
01311 FUNCTION
01312        bfd_follow_gnu_debuglink
01313 
01314 SYNOPSIS
01315        char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
01316 
01317 DESCRIPTION
01318 
01319        Takes a BFD and searches it for a .gnu_debuglink section.  If this
01320        section is found, it examines the section for the name and checksum
01321        of a '.debug' file containing auxiliary debugging information.  It
01322        then searches the filesystem for this .debug file in some standard
01323        locations, including the directory tree rooted at @var{dir}, and if
01324        found returns the full filename.
01325 
01326        If @var{dir} is NULL, it will search a default path configured into
01327        libbfd at build time.  [XXX this feature is not currently
01328        implemented].
01329 
01330 RETURNS
01331        <<NULL>> on any errors or failure to locate the .debug file,
01332        otherwise a pointer to a heap-allocated string containing the
01333        filename.  The caller is responsible for freeing this string.
01334 */
01335 
01336 char *
01337 bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
01338 {
01339   return find_separate_debug_file (abfd, dir);
01340 }
01341 
01342 /*
01343 FUNCTION
01344        bfd_create_gnu_debuglink_section
01345 
01346 SYNOPSIS
01347        struct bfd_section *bfd_create_gnu_debuglink_section
01348          (bfd *abfd, const char *filename);
01349 
01350 DESCRIPTION
01351 
01352        Takes a @var{BFD} and adds a .gnu_debuglink section to it.  The section is sized
01353        to be big enough to contain a link to the specified @var{filename}.
01354 
01355 RETURNS
01356        A pointer to the new section is returned if all is ok.  Otherwise <<NULL>> is
01357        returned and bfd_error is set.
01358 */
01359 
01360 asection *
01361 bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename)
01362 {
01363   asection *sect;
01364   bfd_size_type debuglink_size;
01365   flagword flags;
01366 
01367   if (abfd == NULL || filename == NULL)
01368     {
01369       bfd_set_error (bfd_error_invalid_operation);
01370       return NULL;
01371     }
01372 
01373   /* Strip off any path components in filename.  */
01374   filename = lbasename (filename);
01375 
01376   sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
01377   if (sect)
01378     {
01379       /* Section already exists.  */
01380       bfd_set_error (bfd_error_invalid_operation);
01381       return NULL;
01382     }
01383 
01384   flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
01385   sect = bfd_make_section_with_flags (abfd, GNU_DEBUGLINK, flags);
01386   if (sect == NULL)
01387     return NULL;
01388 
01389   debuglink_size = strlen (filename) + 1;
01390   debuglink_size += 3;
01391   debuglink_size &= ~3;
01392   debuglink_size += 4;
01393 
01394   if (! bfd_set_section_size (abfd, sect, debuglink_size))
01395     /* XXX Should we delete the section from the bfd ?  */
01396     return NULL;
01397 
01398   return sect;
01399 }
01400 
01401 
01402 /*
01403 FUNCTION
01404        bfd_fill_in_gnu_debuglink_section
01405 
01406 SYNOPSIS
01407        bfd_boolean bfd_fill_in_gnu_debuglink_section
01408          (bfd *abfd, struct bfd_section *sect, const char *filename);
01409 
01410 DESCRIPTION
01411 
01412        Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
01413        and fills in the contents of the section to contain a link to the
01414        specified @var{filename}.  The filename should be relative to the
01415        current directory.
01416 
01417 RETURNS
01418        <<TRUE>> is returned if all is ok.  Otherwise <<FALSE>> is returned
01419        and bfd_error is set.
01420 */
01421 
01422 bfd_boolean
01423 bfd_fill_in_gnu_debuglink_section (bfd *abfd,
01424                                struct bfd_section *sect,
01425                                const char *filename)
01426 {
01427   bfd_size_type debuglink_size;
01428   unsigned long crc32;
01429   char * contents;
01430   bfd_size_type crc_offset;
01431   FILE * handle;
01432   static unsigned char buffer[8 * 1024];
01433   size_t count;
01434 
01435   if (abfd == NULL || sect == NULL || filename == NULL)
01436     {
01437       bfd_set_error (bfd_error_invalid_operation);
01438       return FALSE;
01439     }
01440 
01441   /* Make sure that we can read the file.
01442      XXX - Should we attempt to locate the debug info file using the same
01443      algorithm as gdb ?  At the moment, since we are creating the
01444      .gnu_debuglink section, we insist upon the user providing us with a
01445      correct-for-section-creation-time path, but this need not conform to
01446      the gdb location algorithm.  */
01447   handle = real_fopen (filename, FOPEN_RB);
01448   if (handle == NULL)
01449     {
01450       bfd_set_error (bfd_error_system_call);
01451       return FALSE;
01452     }
01453 
01454   crc32 = 0;
01455   while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
01456     crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
01457   fclose (handle);
01458 
01459   /* Strip off any path components in filename,
01460      now that we no longer need them.  */
01461   filename = lbasename (filename);
01462 
01463   debuglink_size = strlen (filename) + 1;
01464   debuglink_size += 3;
01465   debuglink_size &= ~3;
01466   debuglink_size += 4;
01467 
01468   contents = malloc (debuglink_size);
01469   if (contents == NULL)
01470     {
01471       /* XXX Should we delete the section from the bfd ?  */
01472       bfd_set_error (bfd_error_no_memory);
01473       return FALSE;
01474     }
01475 
01476   strcpy (contents, filename);
01477   crc_offset = debuglink_size - 4;
01478 
01479   bfd_put_32 (abfd, crc32, contents + crc_offset);
01480 
01481   if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
01482     {
01483       /* XXX Should we delete the section from the bfd ?  */
01484       free (contents);
01485       return FALSE;
01486     }
01487 
01488   return TRUE;
01489 }