Bug 28485 - ar and objcopy stuck,failing on object name containing '/' inside an archive
Summary: ar and objcopy stuck,failing on object name containing '/' inside an archive
Status: UNCONFIRMED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.35
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-10-21 16:42 UTC by Andrew Pullin
Modified: 2022-06-22 06:48 UTC (History)
0 users

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 Andrew Pullin 2021-10-21 16:42:07 UTC
I am trying to localize some symbols in objects inside an archive.
Ultimately, it seems like the tools are failing because the .a appears to contain an object with the name "bin/thumbv7em-none-eabihf.o".

This all started from trying:

    arm-none-eabi-objcopy --localize-hidden librustlib.a


So operations like:

    arm-none-eabi-objcopy -L __aeabi_dcmpgt librustlib.a 


result in the error:

    arm-none-eabi-objcopy: stsJ3ObR/bin/thumbv7em-none-eabihf.o: No such file or directory


with apparently no change to the archive file.

The symbol is definitely in there:

    arm-none-eabi-objdump -x librustlib.a

gives

    compiler_builtins-2ff80b98fa64b741.compiler_builtins.6207f1bb-cgu.122.rcgu.o:     file format elf32-littlearm
    
    rw-r--r-- 0/0  10176 Dec 31 16:00 1969 compiler_builtins-2ff80b98fa64b741.compiler_builtins.6207f1bb-cgu.122.rcgu.o
    
    architecture: armv7e-m, flags 0x00000011:
    
    ...
    
    SYMBOL TABLE:
    
    00000000 l    df *ABS*  00000000 compiler_builtins.6207f1bb-cgu.122
    
    00000000 l    d  .text.__aeabi_dcmpgt   00000000 .text.__aeabi_dcmpgt
    
    ...
    
    00000000 g     F .text.__aeabi_dcmpgt   00000078 .hidden __aeabi_dcmpgt


So the symbol is there, flagged as a Function, .hidden, but still global.


Checking the contents of the archive:

    arm-none-eabi-ar tv librustlib.a | grep thumb

it does appear that something is there:

    rw-r--r-- 0/0  22732 Dec 31 16:00 1969 bin/thumbv7em-none-eabihf.o


When I try to extract everything in the archive:

    arm-none-eabi-ar x librustlib.a 

it extracts all objects up to that problem object with the '/' in the name, but none after it.
Comment 1 Andrew Pullin 2021-10-21 22:33:09 UTC
This appears to originate from here:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=binutils/ar.c;h=8885585ef7537450f0f0990a5eeea7eb16bcad8f;hb=refs/heads/master#l1157

As far as I can tell, there is no defined behavior for how archive files with a path containing a directory should behavior with the ar utility.

afaik, `fopen()` has no facility for creating directories.

Notably, if I do `mkdir bin` first, then the observed "No such file or directory" error will NOT be hit when using ar to extract, as now the pathname becomes valid.

However: the issue remains with objcopy, since it apparently uses a temporary directory when doing an operation like `--localize-hidden`.

Also of note:
This appears to arise due to this archive file being created with `llvm-ar`, which does explicitely allow slashes in path name:

https://releases.llvm.org/2.8/docs/CommandGuide/html/llvm-ar.html#:~:text=The%20path%20name%20is%20null%20terminated%20and%20may%20contain%20the%20slash%20(/)%20character.

Using llvm-objcopy yields different behavior: the --localize-hidden operation succeeds without issue, despite the pathname containing a `/`
Comment 2 Alan Modra 2021-10-22 01:34:12 UTC
(In reply to Andrew Pullin from comment #1)
> As far as I can tell, there is no defined behavior for how archive files
> with a path containing a directory should behavior with the ar utility.

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ar.html
Comment 3 Andrew Pullin 2022-06-22 06:48:44 UTC
Ultimately, the workaround for this was to use the llvm/clang version of objcopy to do the operation I needed to do to weaken symbols. Since the path handling is consistent within their ecosystem, it was able to deal with the '/'.

So, this is probably not a bug at all, just two different teams' implementations of AR.



And not that it is terribly important to this issue, but for a little elucidation of the case where this arose:

This all came up when I was trying to use Rust FFI to include some Rust fuctions into a C codebase, targeting an embedded microcontroller target.
There was a collision of libc builtins, and reimplementations in the core rust libraries/runtime.

As far as I have seen, the C99 embedded world has not switched to clang/llvm yet (except Apple), but in various pieces of documentation and hacks to get Rust+C working, crossover into GNU tools does arise in a few places.

Ultimately, I am able to use gnu arm-none-eabi-ld to link in the staticlib build by llvm+lld, after the localization step was done on the .a output from the Rust toolchain.

https://github.com/rust-lang/compiler-builtins/issues/345