Opened 2 years ago

Closed 16 months ago

Last modified 16 months ago

#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 Carl Eugen Hoyos, 16 months ago

Resolution: needs_more_info
Status: newclosed

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.

comment:2 by mkver, 16 months 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).

Note: See TracTickets for help on using tickets.