X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcache.c;h=b1dcd5a745b63f282308066ce98df7cc20baba27;hb=95830fd17d6ae253d8f6c2595188cadd59058799;hp=c6873a96de5ce324a3d2f0b10b09ab77b0f3f829;hpb=25b88f335af1b8c7a4428710ffd9066338b167c0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cache.c b/bfd/cache.c index c6873a96de..b1dcd5a745 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -1,7 +1,7 @@ /* BFD library -- caching of file descriptors. Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, - 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). @@ -45,6 +45,7 @@ SUBSECTION #include "bfd.h" #include "libbfd.h" #include "libiberty.h" +#include "bfd_stdint.h" #ifdef HAVE_MMAP #include @@ -144,33 +145,33 @@ bfd_cache_delete (bfd *abfd) static bfd_boolean close_one (void) { - register bfd *kill; + register bfd *to_kill; if (bfd_last_cache == NULL) - kill = NULL; + to_kill = NULL; else { - for (kill = bfd_last_cache->lru_prev; - ! kill->cacheable; - kill = kill->lru_prev) + for (to_kill = bfd_last_cache->lru_prev; + ! to_kill->cacheable; + to_kill = to_kill->lru_prev) { - if (kill == bfd_last_cache) + if (to_kill == bfd_last_cache) { - kill = NULL; + to_kill = NULL; break; } } } - if (kill == NULL) + if (to_kill == NULL) { /* There are no open cacheable BFD's. */ return TRUE; } - kill->where = real_ftell ((FILE *) kill->iostream); + to_kill->where = real_ftell ((FILE *) to_kill->iostream); - return bfd_cache_delete (kill); + return bfd_cache_delete (to_kill); } /* Check to see if the required BFD is the same as the last one @@ -197,7 +198,7 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag) if ((abfd->flags & BFD_IN_MEMORY) != 0) abort (); - if (abfd->my_archive) + while (abfd->my_archive) abfd = abfd->my_archive; if (abfd->iostream != NULL) @@ -240,7 +241,7 @@ cache_btell (struct bfd *abfd) static int cache_bseek (struct bfd *abfd, file_ptr offset, int whence) { - FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : 0); + FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL); if (f == NULL) return -1; return real_fseek (f, offset, whence); @@ -270,7 +271,7 @@ cache_bread_1 (struct bfd *abfd, void *buf, file_ptr nbytes) if (nbytes == 0) return 0; - f = bfd_cache_lookup (abfd, 0); + f = bfd_cache_lookup (abfd, CACHE_NORMAL); if (f == NULL) return 0; @@ -345,7 +346,7 @@ static file_ptr cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes) { file_ptr nwrite; - FILE *f = bfd_cache_lookup (abfd, 0); + FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL); if (f == NULL) return 0; @@ -358,7 +359,7 @@ cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes) return nwrite; } -static int +static bfd_boolean cache_bclose (struct bfd *abfd) { return bfd_cache_close (abfd); @@ -398,7 +399,9 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, - file_ptr offset ATTRIBUTE_UNUSED) + file_ptr offset ATTRIBUTE_UNUSED, + void **map_addr ATTRIBUTE_UNUSED, + bfd_size_type *map_len ATTRIBUTE_UNUSED) { void *ret = (void *) -1; @@ -407,13 +410,35 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, #ifdef HAVE_MMAP else { - FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); + static uintptr_t pagesize_m1; + FILE *f; + file_ptr pg_offset; + bfd_size_type pg_len; + + f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); if (f == NULL) return ret; - ret = mmap (addr, len, prot, flags, fileno (f), offset); + if (pagesize_m1 == 0) + pagesize_m1 = getpagesize () - 1; + + /* Handle archive members. */ + if (abfd->my_archive != NULL) + offset += abfd->origin; + + /* Align. */ + pg_offset = offset & ~pagesize_m1; + pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1; + + ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset); if (ret == (void *) -1) bfd_set_error (bfd_error_system_call); + else + { + *map_addr = ret; + *map_len = pg_len; + ret = (char *) ret + (offset & pagesize_m1); + } } #endif @@ -538,15 +563,15 @@ bfd_open_file (bfd *abfd) { case read_direction: case no_direction: - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RB); + abfd->iostream = real_fopen (abfd->filename, FOPEN_RB); break; case both_direction: case write_direction: if (abfd->opened_once) { - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RUB); + abfd->iostream = real_fopen (abfd->filename, FOPEN_RUB); if (abfd->iostream == NULL) - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); + abfd->iostream = real_fopen (abfd->filename, FOPEN_WUB); } else { @@ -576,7 +601,7 @@ bfd_open_file (bfd *abfd) if (stat (abfd->filename, &s) == 0 && s.st_size != 0) unlink_if_ordinary (abfd->filename); #endif - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); + abfd->iostream = real_fopen (abfd->filename, FOPEN_WUB); abfd->opened_once = TRUE; } break;