X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=bfd%2Fopncls.c;fp=bfd%2Fopncls.c;h=3337efe0e89099bf5ab8669b0a7e6af2fbe6c444;hp=26e139b1ca31fee6940a11726ddf92ea0cf8a52d;hb=88750007d7869f178f0ba528f41efd3b74c424cf;hpb=6df9443a374e2b81278c61b8afc0a1eef7db280b diff --git a/bfd/opncls.c b/bfd/opncls.c index 26e139b..3337efe 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -1,6 +1,6 @@ /* opncls.c -- open and close a BFD. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Cygnus Support. @@ -52,7 +52,7 @@ _bfd_new_bfd (void) { bfd *nbfd; - nbfd = bfd_zmalloc (sizeof (bfd)); + nbfd = (bfd *) bfd_zmalloc (sizeof (bfd)); if (nbfd == NULL) return NULL; @@ -342,7 +342,7 @@ DESCRIPTION bfd * bfd_openstreamr (const char *filename, const char *target, void *streamarg) { - FILE *stream = streamarg; + FILE *stream = (FILE *) streamarg; bfd *nbfd; const bfd_target *target_vec; @@ -438,14 +438,14 @@ struct opncls static file_ptr opncls_btell (struct bfd *abfd) { - struct opncls *vec = abfd->iostream; + struct opncls *vec = (struct opncls *) abfd->iostream; return vec->where; } static int opncls_bseek (struct bfd *abfd, file_ptr offset, int whence) { - struct opncls *vec = abfd->iostream; + struct opncls *vec = (struct opncls *) abfd->iostream; switch (whence) { case SEEK_SET: vec->where = offset; break; @@ -458,7 +458,7 @@ opncls_bseek (struct bfd *abfd, file_ptr offset, int whence) static file_ptr opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes) { - struct opncls *vec = abfd->iostream; + struct opncls *vec = (struct opncls *) abfd->iostream; file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where); if (nread < 0) return nread; @@ -477,7 +477,7 @@ opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED, static int opncls_bclose (struct bfd *abfd) { - struct opncls *vec = abfd->iostream; + struct opncls *vec = (struct opncls *) abfd->iostream; /* Since the VEC's memory is bound to the bfd deleting the bfd will free it. */ int status = 0; @@ -496,7 +496,7 @@ opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED) static int opncls_bstat (struct bfd *abfd, struct stat *sb) { - struct opncls *vec = abfd->iostream; + struct opncls *vec = (struct opncls *) abfd->iostream; memset (sb, 0, sizeof (*sb)); if (vec->stat == NULL) @@ -505,9 +505,20 @@ opncls_bstat (struct bfd *abfd, struct stat *sb) return (vec->stat) (abfd, vec->stream, sb); } +static void * +opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, + void *addr ATTRIBUTE_UNUSED, + bfd_size_type len ATTRIBUTE_UNUSED, + int prot ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + file_ptr offset ATTRIBUTE_UNUSED) +{ + return (void *) -1; +} + static const struct bfd_iovec opncls_iovec = { &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek, - &opncls_bclose, &opncls_bflush, &opncls_bstat + &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap }; bfd * @@ -545,14 +556,15 @@ bfd_openr_iovec (const char *filename, const char *target, nbfd->filename = filename; nbfd->direction = read_direction; - stream = open (nbfd, open_closure); + /* `open (...)' would get expanded by an the open(2) syscall macro. */ + stream = (*open) (nbfd, open_closure); if (stream == NULL) { _bfd_delete_bfd (nbfd); return NULL; } - vec = bfd_zalloc (nbfd, sizeof (struct opncls)); + vec = (struct opncls *) bfd_zalloc (nbfd, sizeof (struct opncls)); vec->stream = stream; vec->pread = pread; vec->close = close; @@ -617,6 +629,32 @@ bfd_openw (const char *filename, const char *target) return nbfd; } +static inline void +_maybe_make_executable (bfd * abfd) +{ + /* If the file was open for writing and is now executable, + make it so. */ + if (abfd->direction == write_direction + && abfd->flags & EXEC_P) + { + struct stat buf; + + if (stat (abfd->filename, &buf) == 0 + /* Do not attempt to change non-regular files. This is + here especially for configure scripts and kernel builds + which run tests with "ld [...] -o /dev/null". */ + && S_ISREG(buf.st_mode)) + { + unsigned int mask = umask (0); + + umask (mask); + chmod (abfd->filename, + (0777 + & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); + } + } +} + /* FUNCTION @@ -646,6 +684,8 @@ bfd_boolean bfd_close (bfd *abfd) { bfd_boolean ret; + bfd *nbfd; + bfd *next; if (bfd_write_p (abfd)) { @@ -653,34 +693,33 @@ bfd_close (bfd *abfd) return FALSE; } + /* Close nested archives (if this bfd is a thin archive). */ + for (nbfd = abfd->nested_archives; nbfd; nbfd = next) + { + next = nbfd->archive_next; + bfd_close (nbfd); + } + if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) return FALSE; - /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io - vector. */ - if (!(abfd->flags & BFD_IN_MEMORY)) - ret = abfd->iovec->bclose (abfd); - else - ret = TRUE; - - /* If the file was open for writing and is now executable, - make it so. */ - if (ret - && abfd->direction == write_direction - && abfd->flags & EXEC_P) + if ((abfd->flags & BFD_IN_MEMORY) != 0) { - struct stat buf; - - if (stat (abfd->filename, &buf) == 0) - { - unsigned int mask = umask (0); - - umask (mask); - chmod (abfd->filename, - (0777 - & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); - } + /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io + vector. + Until that's done, at least don't leak memory. */ + struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; + + if (bim->buffer != NULL) + free (bim->buffer); + free (bim); + ret = TRUE; } + else + ret = abfd->iovec->bclose (abfd); + + if (ret) + _maybe_make_executable (abfd); _bfd_delete_bfd (abfd); @@ -716,24 +755,8 @@ bfd_close_all_done (bfd *abfd) ret = bfd_cache_close (abfd); - /* If the file was open for writing and is now executable, - make it so. */ - if (ret - && abfd->direction == write_direction - && abfd->flags & EXEC_P) - { - struct stat buf; - - if (stat (abfd->filename, &buf) == 0) - { - unsigned int mask = umask (0); - - umask (mask); - chmod (abfd->filename, - (0777 - & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); - } - } + if (ret) + _maybe_make_executable (abfd); _bfd_delete_bfd (abfd); @@ -798,7 +821,7 @@ bfd_make_writable (bfd *abfd) return FALSE; } - bim = bfd_malloc (sizeof (struct bfd_in_memory)); + bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); if (bim == NULL) return FALSE; /* bfd_error already set. */ abfd->iostream = bim; @@ -896,7 +919,7 @@ bfd_alloc (bfd *abfd, bfd_size_type size) return NULL; } - ret = objalloc_alloc (abfd->memory, (unsigned long) size); + ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); if (ret == NULL) bfd_set_error (bfd_error_no_memory); return ret; @@ -935,7 +958,7 @@ bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size) return NULL; } - ret = objalloc_alloc (abfd->memory, (unsigned long) size); + ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); if (ret == NULL) bfd_set_error (bfd_error_no_memory); return ret; @@ -1174,19 +1197,19 @@ separate_debug_file_exists (const char *name, const unsigned long crc) { static unsigned char buffer [8 * 1024]; unsigned long file_crc = 0; - int fd; + FILE *f; bfd_size_type count; BFD_ASSERT (name); - fd = open (name, O_RDONLY); - if (fd < 0) + f = real_fopen (name, FOPEN_RB); + if (f == NULL) return FALSE; - while ((count = read (fd, buffer, sizeof (buffer))) > 0) + while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0) file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count); - close (fd); + fclose (f); return crc == file_crc; } @@ -1214,9 +1237,10 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory) char *basename; char *dir; char *debugfile; + char *canon_dir; unsigned long crc32; - int i; size_t dirlen; + size_t canon_dirlen; BFD_ASSERT (abfd); if (debug_file_directory == NULL) @@ -1244,7 +1268,7 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory) if (IS_DIR_SEPARATOR (abfd->filename[dirlen - 1])) break; - dir = bfd_malloc (dirlen + 1); + dir = (char *) bfd_malloc (dirlen + 1); if (dir == NULL) { free (basename); @@ -1253,15 +1277,25 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory) memcpy (dir, abfd->filename, dirlen); dir[dirlen] = '\0'; - debugfile = bfd_malloc (strlen (debug_file_directory) + 1 - + dirlen - + strlen (".debug/") - + strlen (basename) - + 1); + /* Compute the canonical name of the bfd object with all symbolic links + resolved, for use in the global debugfile directory. */ + canon_dir = lrealpath (abfd->filename); + for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--) + if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1])) + break; + canon_dir[canon_dirlen] = '\0'; + + debugfile = (char *) + bfd_malloc (strlen (debug_file_directory) + 1 + + (canon_dirlen > dirlen ? canon_dirlen : dirlen) + + strlen (".debug/") + + strlen (basename) + + 1); if (debugfile == NULL) { free (basename); free (dir); + free (canon_dir); return NULL; } @@ -1273,6 +1307,7 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory) { free (basename); free (dir); + free (canon_dir); return debugfile; } @@ -1285,29 +1320,32 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory) { free (basename); free (dir); + free (canon_dir); return debugfile; } /* Then try in the global debugfile directory. */ strcpy (debugfile, debug_file_directory); - i = strlen (debug_file_directory) - 1; - if (i > 0 - && debug_file_directory[i] != '/' - && dir[0] != '/') + dirlen = strlen (debug_file_directory) - 1; + if (dirlen > 0 + && debug_file_directory[dirlen] != '/' + && canon_dir[0] != '/') strcat (debugfile, "/"); - strcat (debugfile, dir); + strcat (debugfile, canon_dir); strcat (debugfile, basename); if (separate_debug_file_exists (debugfile, crc32)) { free (basename); free (dir); + free (canon_dir); return debugfile; } free (debugfile); free (basename); free (dir); + free (canon_dir); return NULL; } @@ -1472,7 +1510,7 @@ bfd_fill_in_gnu_debuglink_section (bfd *abfd, debuglink_size &= ~3; debuglink_size += 4; - contents = bfd_malloc (debuglink_size); + contents = (char *) bfd_malloc (debuglink_size); if (contents == NULL) { /* XXX Should we delete the section from the bfd ? */