aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog9
-rw-r--r--binutils/ar.c15
-rw-r--r--binutils/doc/binutils.texi9
-rw-r--r--binutils/testsuite/ChangeLog4
-rw-r--r--binutils/testsuite/binutils-all/ar.exp45
5 files changed, 82 insertions, 0 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 880d6e4..b5a7f6c 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
+2009-03-11 Chris Demetriou <cgd@google.com>
+
+ * ar.c (deterministic): New global variable.
+ (main): Recognize new 'D' option, which enables 'deterministic mode'.
+ (usage): Document new 'D' option.
+ (write_archive): Set BFD_DETERMINISTIC_OUTPUT in output archive's
+ flags if deterministic mode was requested.
+ * doc/binutils.texi (ar): Document deterministic mode ('D' option).
+
2009-03-09 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/9933
diff --git a/binutils/ar.c b/binutils/ar.c
index f493221..73ab1d4 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -99,6 +99,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;
@@ -240,6 +245,7 @@ usage (int help)
fprintf (s, _(" command specific modifiers:\n"));
fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
+ fprintf (s, _(" [D] - use zero for timestamps and uids/gids\n"));
fprintf (s, _(" [N] - use instance [count] of name\n"));
fprintf (s, _(" [f] - truncate inserted file names\n"));
fprintf (s, _(" [P] - use full path names when matching\n"));
@@ -572,6 +578,9 @@ main (int argc, char **argv)
case 'T':
make_thin_archive = TRUE;
break;
+ case 'D':
+ deterministic = TRUE;
+ break;
default:
/* xgettext:c-format */
non_fatal (_("illegal option -- %c"), c);
@@ -622,6 +631,9 @@ 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++];
@@ -972,6 +984,9 @@ 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;
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index bd9a04c..009577f 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -396,6 +396,15 @@ created if it did not exist, when you request an update. But a warning is
issued unless you specify in advance that you expect to create it, by
using this modifier.
+@item D
+@cindex deterministic archives
+Operate in @emph{deterministic} mode. When adding files and the archive
+index use zero for UIDs, GIDs, timestamps, and use consistent file modes
+for all files. When this option is used, if @command{ar} is used with
+identical options and identical input files, multiple runs will create
+identical output files regardless of the input files' owners, groups,
+file modes, or modification times.
+
@item f
Truncate names in the archive. @sc{gnu} @command{ar} will normally permit file
names of any length. This will cause it to create archives which are
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 81e6c17..1bca1a4 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-11 Chris Demetriou <cgd@google.com>
+
+ * binutils-all/ar.exp (deterministic_archive): New test.
+
2009-03-09 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/9933
diff --git a/binutils/testsuite/binutils-all/ar.exp b/binutils/testsuite/binutils-all/ar.exp
index 21a39f4..e852014 100644
--- a/binutils/testsuite/binutils-all/ar.exp
+++ b/binutils/testsuite/binutils-all/ar.exp
@@ -354,6 +354,50 @@ proc argument_parsing { } {
pass $testname
}
+# Test building a deterministic archive.
+
+proc deterministic_archive { } {
+ global AR
+ global AS
+ global NM
+ global srcdir
+ global subdir
+
+ set testname "ar deterministic archive"
+
+ if ![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o] {
+ unresolved $testname
+ return
+ }
+
+ if [is_remote host] {
+ set archive artest.a
+ set objfile [remote_download host tmpdir/bintest.o]
+ remote_file host delete $archive
+ } else {
+ set archive tmpdir/artest.a
+ set objfile tmpdir/bintest.o
+ }
+
+ remote_file build delete tmpdir/artest.a
+
+ set got [binutils_run $AR "rcD $archive ${objfile}"]
+ if ![string match "" $got] {
+ fail $testname
+ return
+ }
+
+ set got [binutils_run $AR "tv $archive"]
+ # This only checks the file mode and uid/gid. We can't easily match
+ # date because it's printed with the user's timezone.
+ if ![string match "rw-r--r-- 0/0 *bintest.o*" $got] {
+ fail $testname
+ return
+ }
+
+ pass $testname
+}
+
# Run the tests.
long_filenames
@@ -361,3 +405,4 @@ symbol_table
thin_archive
thin_archive_with_nested
argument_parsing
+deterministic_archive