Bug 28917 - ar: r does not replace objects specified multiple times on the command line
Summary: ar: r does not replace objects specified multiple times on the command line
Status: RESOLVED NOTABUG
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-02-21 19:43 UTC by Mike Frysinger
Modified: 2023-05-13 05:49 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Frysinger 2022-02-21 19:43:19 UTC
testing current tree (216722984fec8aa76e2d97d7b8fcc2fb1608825b).  seems to reproduce across many diff targets & config options, so i don't think they're related.

$ cd binutils

# Adding files one-at-a-time works correctly.
$ rm -f x.a
$ ./ar vrc x.a ar.o
a - ar.o
$ ./ar vrc x.a ar.o
r - ar.o
$ ./ar vrc x.a ar.o
r - ar.o
$ ./ar t x.a
ar.o

# Adding files many-at-a-time works incorrectly.
$ rm -f x.a
$ ./ar vrc x.a ar.o ar.o
a - ar.o
a - ar.o
$ ar t x.a
ar.o
ar.o

this came up because newlib uses archive-insertion-order to control overriding of common objects (i.e. C files) with machine-specific objects (i.e. asm files).  it used to add objects one directory at a time, but i switched it to add them all at once (with machine objects appearing last).  now we have duplicate objects in the archive.
Comment 1 Mike Frysinger 2022-02-21 20:15:15 UTC
ugh, this appears to be undocumented behavior.  i can't find anything in the man page or manual discussing this, and the commit history predates git.

--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1493,8 +1493,7 @@
          /* For compatibility with existing ar programs, we
             permit the same file to be added multiple times.  */
          if (FILENAME_CMP (normalize (*files_to_move, arch),
-                           normalize (bfd_get_filename (current), arch)) == 0
-             && current->arelt_data != NULL)
+                           normalize (bfd_get_filename (current), arch)) == 0)
            {
              bool replaced;
              if (newer_only)
Comment 2 Nick Clifton 2022-03-16 12:52:27 UTC
(In reply to Mike Frysinger from comment #1)
> ugh, this appears to be undocumented behavior.  i can't find anything in the
> man page or manual discussing this, and the commit history predates git.

Agreed.

Patch approved - please apply.
Comment 3 Alan Modra 2022-08-23 13:52:48 UTC
GNU ar was deliberately changed to allow multiple files with the same base name in commit 7f924d5516cf5 1996-10-01.  That's when the comment was added about "compatibility with existing ar programs" too.  I think we should leave things as they are.  Posix says "It is unspecified whether multiple files in the archive may be identically named."  Since we do allow that, it seems reasonable to make "ar -r archive.a a/foo.o b/foo.o" put both objects in the archive.
Comment 4 Alan Modra 2023-05-13 05:49:53 UTC
Closing