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.
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 `/`
(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
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