#9612 closed defect (needs_more_info)
--enable-pic flag doesn't affect the object files from assembly
Reported by: | Tuğrul | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | undetermined |
Version: | unspecified | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Summary of the bug:
I was trying to link a shared library to use with Node.JS.
It was failing for following error message.
/usr/bin/ld: libavcodec.a(cavsdsp.o): relocation R_X86_64_PC32 against symbol `ff_pw_5' can not be used when making a shared object; recompile with -fPIC
Then I tried to use --disable-asm and it built successfully.
How to reproduce:
Build with asm and no asm versions of static libraries.
With asm:
% make clean && ./configure --prefix="/tmp/deploy-asm" --pkg-config-flags="--static" --extra-cflags="-fPIC" --extra-libs="-lpthread -lm" --enable-gpl --enable-nonfree --disable-doc --enable-pic && make && make install
Without asm:
% make clean && ./configure --prefix="/tmp/deploy-no-asm" --pkg-config-flags="--static" --extra-cflags="-fPIC" --extra-libs="-lpthread -lm" --enable-gpl --enable-nonfree --disable-doc --enable-pic --disable-asm && make && make install
Combine static libraries into a shared library
With asm:
% cd /tmp/deploy-asm/lib && gcc -shared -o libav-combined.so -Wl,--whole-archive libavcodec.a libavdevice.a libavfilter.a libavformat.a libavutil.a libpostproc.a libswresample.a libswscale.a -Wl,--no-whole-archive
Gives following error:
/usr/bin/ld: libavcodec.a(cavsdsp.o): relocation R_X86_64_PC32 against symbol `ff_pw_5' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: bad value collect2: error: ld returned 1 exit status
Without asm:
% cd /tmp/deploy-no-asm/lib && gcc -shared -o libav-combined.so -Wl,--whole-archive libavcodec.a libavdevice.a libavfilter.a libavformat.a libavutil.a libpostproc.a libswresample.a libswscale.a -Wl,--no-whole-archive
It is successfully linked.
I'm not expert but I'm able to imagine the problem by this Q&A https://stackoverflow.com/questions/38192735/generating-position-independent-code-with-gas-fpic
Change History (2)
comment:1 by , 2 years ago
Resolution: | → needs_more_info |
---|---|
Status: | new → closed |
comment:2 by , 2 years ago
When the compiler builds code, it presumes that every symbol that is not local (static) to one file has default elf visibility and therefore might come from a different library at runtime (due to interposing); yet our assembly never uses objects from different libraries and always creates functions in such a way that they expect these objects to be in the same library. Some of these objects used by assembly are created by non-assembly and therefore have default visibility (because we don't use -fvisibility at all). Instead we typically use -Bsymbolic and also a linker version script telling to mark the symbols that are intended to be exported. This informs the linker that objects like ff_pw_5 will always come from the same library, so that a R_X86_64_PC32 relocation is permissible.
So you should use a linker script like
{ global: av*; postproc_*; pp_*; swr_*; swresample_*; swscale_*; sws_*; local: *; };
by adding "-Wl,--version-script=<name of the file containing the above>" to your command line. You can also add "-Wl,--Bsymbolic" to bind functions from your library local if possible (i.e. ignore interposing for them; actually either of these options is sufficient to make the link succeed, but using a version script has the advantage of not exporting stuff that is not meant to be exported, whereas Bsymbolic speeds up calls to functions that are exported, but are also called from within the newly created library). You will also have to add "-Wl,--allow-multiple-definition" due to the half2float stuff being duplicated into multiple libraries (the linker ordinarily only uses the one from the first library, but your --whole-archive overrides it).
Please reopen this ticket if you can explain how exactly the issue you see can be reproduced. Many people constantly build shared FFmpeg libraries with assembler optimizations for a long time.