X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Far.c;h=a08a991290a5426ff69b08aded871525347e4d85;hb=cc5914eb31109a6481682d9bc5dc7c23fccc024c;hp=720ced73e9828c269f5302a8e777150bc2c6545e;hpb=3db64b009284dda3a1ce10a91beb1297475e60a7;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/ar.c b/binutils/ar.c index 720ced73e9..a08a991290 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -1,13 +1,13 @@ /* ar.c - Archive modify and extract. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,7 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ /* Bugs: should use getopt the way tar does (complete w/optional -) and @@ -36,26 +37,16 @@ #include "arsup.h" #include "filenames.h" #include "binemul.h" +#include "plugin.h" #include #ifdef __GO32___ -#define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */ +#define EXT_NAME_LEN 3 /* Bufflen of addition to name if it's MS-DOS. */ #else -#define EXT_NAME_LEN 6 /* ditto for *NIX */ +#define EXT_NAME_LEN 6 /* Ditto for *NIX. */ #endif -/* We need to open files in binary modes on system where that makes a - difference. */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* Kludge declaration from BFD! This is ugly! FIXME! XXX */ - -struct ar_hdr * - bfd_special_undocumented_glue (bfd * abfd, const char *filename); - -/* Static declarations */ +/* Static declarations. */ static void mri_emul (void); static const char *normalize (const char *, bfd *); @@ -73,7 +64,7 @@ static int ranlib_only (const char *archname); static int ranlib_touch (const char *archname); static void usage (int); -/** Globals and flags */ +/** Globals and flags. */ static int mri_mode; @@ -104,6 +95,11 @@ int newer_only = 0; if any of the members are object files. */ int write_armap = 0; +/* Operate in deterministic mode: write zero for timestamps, uids, + and gids for archive members and the archive symbol table, and write + consistent file modes. */ +int deterministic = 0; + /* Nonzero means it's the name of an existing member; position new or moved files with respect to this one. */ char *posname = NULL; @@ -133,6 +129,11 @@ static bfd_boolean ar_truncate = FALSE; program. */ static bfd_boolean full_pathname = FALSE; +/* Whether to create a "thin" archive (symbol index only -- no files). */ +static bfd_boolean make_thin_archive = FALSE; + +static const char *plugin_target = NULL; + int interactive = 0; static void @@ -154,7 +155,7 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count) if (count == 0) { - for (head = arch->next; head; head = head->next) + for (head = arch->archive_next; head; head = head->archive_next) { PROGRESS (1); function (head); @@ -173,18 +174,27 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count) bfd_boolean found = FALSE; match_count = 0; - for (head = arch->next; head; head = head->next) + for (head = arch->archive_next; head; head = head->archive_next) { + const char * filename; + PROGRESS (1); - if (head->filename == NULL) + filename = head->filename; + if (filename == NULL) { /* Some archive formats don't get the filenames filled in until the elements are opened. */ struct stat buf; bfd_stat_arch_elt (head, &buf); } - if ((head->filename != NULL) && - (!FILENAME_CMP (normalize (*files, arch), head->filename))) + else if (bfd_is_thin_archive (arch)) + { + /* Thin archives store full pathnames. Need to normalize. */ + filename = normalize (filename, arch); + } + + if ((filename != NULL) && + (!FILENAME_CMP (normalize (*files, arch), filename))) { ++match_count; if (counted_name_mode @@ -199,6 +209,7 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count) function (head); } } + if (!found) /* xgettext:c-format */ fprintf (stderr, _("no entry %s in archive\n"), *files); @@ -217,8 +228,14 @@ usage (int help) if (! is_ranlib) { /* xgettext:c-format */ - fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"), - program_name); + const char * command_line = +#if BFD_SUPPORTS_PLUGINS + _("Usage: %s [emulation options] [--plugin ] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"); +#else + _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"); +#endif + fprintf (s, command_line, program_name); + /* xgettext:c-format */ fprintf (s, _(" %s -M [ - read options from \n")); - +#if BFD_SUPPORTS_PLUGINS + fprintf (s, _(" optional:\n")); + fprintf (s, _(" --plugin

- load the specified plugin\n")); +#endif ar_emul_usage (s); } else @@ -253,9 +276,15 @@ usage (int help) fprintf (s, _("Usage: %s [options] archive\n"), program_name); fprintf (s, _(" Generate an index to speed access to archives\n")); fprintf (s, _(" The options are:\n\ - @ Read options from \n\ + @ Read options from \n")); +#if BFD_SUPPORTS_PLUGINS + fprintf (s, _("\ + --plugin Load the specified plugin\n")); +#endif + fprintf (s, _("\ + -t Update the archive's symbol map timestamp\n\ -h --help Print this help message\n\ - -V --version Print version information\n")); + -v --version Print version information\n")); } list_supported_targets (program_name, s); @@ -277,21 +306,7 @@ normalize (const char *file, bfd *abfd) if (full_pathname) return file; - filename = strrchr (file, '/'); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - { - /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ - char *bslash = strrchr (file, '\\'); - if (filename == NULL || (bslash != NULL && bslash > filename)) - filename = bslash; - if (filename == NULL && file[0] != '\0' && file[1] == ':') - filename = file + 1; - } -#endif - if (filename != (char *) NULL) - filename++; - else - filename = file; + filename = lbasename (file); if (ar_truncate && abfd != NULL @@ -340,7 +355,7 @@ main (int argc, char **argv) char c; enum { - none = 0, delete, replace, print_table, + none = 0, del, replace, print_table, print_files, extract, move, quick_append } operation = none; int arg_index; @@ -362,28 +377,16 @@ main (int argc, char **argv) program_name = argv[0]; xmalloc_set_program_name (program_name); +#if BFD_SUPPORTS_PLUGINS + bfd_plugin_set_program_name (program_name); +#endif expandargv (&argc, &argv); if (is_ranlib < 0) { - char *temp; + const char *temp = lbasename (program_name); - temp = strrchr (program_name, '/'); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - { - /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ - char *bslash = strrchr (program_name, '\\'); - if (temp == NULL || (bslash != NULL && bslash > temp)) - temp = bslash; - if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':') - temp = program_name + 1; - } -#endif - if (temp == NULL) - temp = program_name; - else - ++temp; if (strlen (temp) >= 6 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0) is_ranlib = 1; @@ -462,6 +465,24 @@ main (int argc, char **argv) arg_index = 1; arg_ptr = argv[arg_index]; + if (strcmp (arg_ptr, "--plugin") == 0) + { +#if BFD_SUPPORTS_PLUGINS + if (argc < 4) + usage (1); + + bfd_plugin_set_plugin (argv[2]); + + arg_index += 2; + arg_ptr = argv[arg_index]; + + plugin_target = "plugin"; +#else + fprintf (stderr, _("sorry - this program has been built without plugin support\n")); + xexit (1); +#endif + } + if (*arg_ptr == '-') { /* When the first option starts with '-' we support POSIX-compatible @@ -488,7 +509,7 @@ main (int argc, char **argv) switch (c) { case 'd': - operation = delete; + operation = del; operation_alters_arch = TRUE; break; case 'm': @@ -557,6 +578,12 @@ main (int argc, char **argv) case 'P': full_pathname = TRUE; break; + case 'T': + make_thin_archive = TRUE; + break; + case 'D': + deterministic = TRUE; + break; default: /* xgettext:c-format */ non_fatal (_("illegal option -- %c"), c); @@ -607,12 +634,15 @@ main (int argc, char **argv) if (newer_only && operation != replace) fatal (_("`u' is only meaningful with the `r' option.")); + if (newer_only && deterministic) + fatal (_("`u' is not meaningful with the `D' option.")); + if (postype != pos_default) posname = argv[arg_index++]; if (counted_name_mode) { - if (operation != extract && operation != delete) + if (operation != extract && operation != del) fatal (_("`N' is only meaningful with the `x' and `d' options.")); counted_name_counter = atoi (argv[arg_index++]); if (counted_name_counter <= 0) @@ -627,6 +657,9 @@ main (int argc, char **argv) arch = open_inarch (inarch_filename, files == NULL ? (char *) NULL : files[0]); + if (operation == extract && bfd_is_thin_archive (arch)) + fatal (_("`x' cannot be used on thin archives.")); + switch (operation) { case print_table: @@ -641,7 +674,7 @@ main (int argc, char **argv) map_over_members (arch, extract_file, files, file_count); break; - case delete: + case del: if (files != NULL) delete_members (arch, files); else @@ -688,7 +721,7 @@ open_inarch (const char *archive_filename, const char *file) bfd_set_error (bfd_error_no_error); - target = NULL; + target = plugin_target; if (stat (archive_filename, &sbuf) != 0) { @@ -719,7 +752,7 @@ open_inarch (const char *archive_filename, const char *file) { bfd *obj; - obj = bfd_openr (file, NULL); + obj = bfd_openr (file, target); if (obj != NULL) { if (bfd_check_format (obj, bfd_object)) @@ -759,7 +792,7 @@ open_inarch (const char *archive_filename, const char *file) xexit (1); } - last_one = &(arch->next); + last_one = &(arch->archive_next); /* Read all the contents right away, regardless. */ for (next_one = bfd_openr_next_archived_file (arch, NULL); next_one; @@ -767,7 +800,7 @@ open_inarch (const char *archive_filename, const char *file) { PROGRESS (1); *last_one = next_one; - last_one = &next_one->next; + last_one = &next_one->archive_next; } *last_one = (bfd *) NULL; if (bfd_get_error () != bfd_error_no_more_archived_files) @@ -779,7 +812,7 @@ static void print_contents (bfd *abfd) { size_t ncopied = 0; - char *cbuf = xmalloc (BUFSIZE); + char *cbuf = (char *) xmalloc (BUFSIZE); struct stat buf; size_t size; if (bfd_stat_arch_elt (abfd, &buf) != 0) @@ -787,8 +820,7 @@ print_contents (bfd *abfd) fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); if (verbose) - /* xgettext:c-format */ - printf (_("\n<%s>\n\n"), bfd_get_filename (abfd)); + printf ("\n<%s>\n\n", bfd_get_filename (abfd)); bfd_seek (abfd, (file_ptr) 0, SEEK_SET); @@ -831,7 +863,7 @@ void extract_file (bfd *abfd) { FILE *ostream; - char *cbuf = xmalloc (BUFSIZE); + char *cbuf = (char *) xmalloc (BUFSIZE); size_t nread, tocopy; size_t ncopied = 0; size_t size; @@ -923,15 +955,15 @@ write_archive (bfd *iarch) { bfd *obfd; char *old_name, *new_name; - bfd *contents_head = iarch->next; + bfd *contents_head = iarch->archive_next; - old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); + old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1); strcpy (old_name, bfd_get_filename (iarch)); new_name = make_tempname (old_name); if (new_name == NULL) bfd_fatal ("could not create temporary file whilst writing archive"); - + output_filename = new_name; obfd = bfd_openw (new_name, bfd_get_target (iarch)); @@ -954,6 +986,12 @@ write_archive (bfd *iarch) obfd->flags |= BFD_TRADITIONAL_FORMAT; } + if (deterministic) + obfd->flags |= BFD_DETERMINISTIC_OUTPUT; + + if (make_thin_archive || bfd_is_thin_archive (iarch)) + bfd_is_thin_archive (obfd) = 1; + if (!bfd_set_archive_head (obfd, contents_head)) bfd_fatal (old_name); @@ -995,15 +1033,15 @@ get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname) if (realpos == pos_end) { while (*after_bfd) - after_bfd = &((*after_bfd)->next); + after_bfd = &((*after_bfd)->archive_next); } else { - for (; *after_bfd; after_bfd = &(*after_bfd)->next) + for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next) if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0) { if (realpos == pos_after) - after_bfd = &(*after_bfd)->next; + after_bfd = &(*after_bfd)->archive_next; break; } } @@ -1035,7 +1073,7 @@ delete_members (bfd *arch, char **files_to_delete) found = FALSE; match_count = 0; - current_ptr_ptr = &(arch->next); + current_ptr_ptr = &(arch->archive_next); while (*current_ptr_ptr) { if (FILENAME_CMP (normalize (*files_to_delete, arch), @@ -1055,12 +1093,12 @@ delete_members (bfd *arch, char **files_to_delete) if (verbose) printf ("d - %s\n", *files_to_delete); - *current_ptr_ptr = ((*current_ptr_ptr)->next); + *current_ptr_ptr = ((*current_ptr_ptr)->archive_next); goto next_file; } } - current_ptr_ptr = &((*current_ptr_ptr)->next); + current_ptr_ptr = &((*current_ptr_ptr)->archive_next); } if (verbose && !found) @@ -1089,7 +1127,7 @@ move_members (bfd *arch, char **files_to_move) for (; *files_to_move; ++files_to_move) { - current_ptr_ptr = &(arch->next); + current_ptr_ptr = &(arch->archive_next); while (*current_ptr_ptr) { bfd *current_ptr = *current_ptr_ptr; @@ -1098,14 +1136,14 @@ move_members (bfd *arch, char **files_to_move) { /* Move this file to the end of the list - first cut from where it is. */ - bfd *link; - *current_ptr_ptr = current_ptr->next; + bfd *link_bfd; + *current_ptr_ptr = current_ptr->archive_next; /* Now glue to end */ - after_bfd = get_pos_bfd (&arch->next, pos_end, NULL); - link = *after_bfd; + after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL); + link_bfd = *after_bfd; *after_bfd = current_ptr; - current_ptr->next = link; + current_ptr->archive_next = link_bfd; if (verbose) printf ("m - %s\n", *files_to_move); @@ -1113,7 +1151,7 @@ move_members (bfd *arch, char **files_to_move) goto next_file; } - current_ptr_ptr = &((*current_ptr_ptr)->next); + current_ptr_ptr = &((*current_ptr_ptr)->archive_next); } /* xgettext:c-format */ fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename); @@ -1138,7 +1176,7 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick) { if (! quick) { - current_ptr = &arch->next; + current_ptr = &arch->archive_next; while (*current_ptr) { current = *current_ptr; @@ -1168,26 +1206,27 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick) goto next_file; } - after_bfd = get_pos_bfd (&arch->next, pos_after, + after_bfd = get_pos_bfd (&arch->archive_next, pos_after, current->filename); if (ar_emul_replace (after_bfd, *files_to_move, - verbose)) + plugin_target, verbose)) { /* Snip out this entry from the chain. */ - *current_ptr = (*current_ptr)->next; + *current_ptr = (*current_ptr)->archive_next; changed = TRUE; } goto next_file; } - current_ptr = &(current->next); + current_ptr = &(current->archive_next); } } /* Add to the end of the archive. */ - after_bfd = get_pos_bfd (&arch->next, pos_end, NULL); + after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL); - if (ar_emul_append (after_bfd, *files_to_move, verbose)) + if (ar_emul_append (after_bfd, *files_to_move, plugin_target, + verbose, make_thin_archive)) changed = TRUE; next_file:;