ffmpeg 静态库链接到动态库的问题

首先编译好 ffmpeg 静态库,在libsav链接时提示

/usr/bin/ld: /opt/data/data/work/source/library/libSAV/../../public/lib/ffmpeg-94a52417/x64/lib/libavcodec.a(h264.o): relocation R_X86_64_PC32 against symbol `ff_h264_cabac_tables' can not be used when making a shared object; recompile with -fPIC

但是经查询,其实 ffmpeg编译时是加了-fPIC选项的。继续查找 在libavcodec/h264.c文件中引用了头文件libavcodec/cabac_functions.h,头文件中定义了如下字段

extern uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63];
static uint8_t * const ff_h264_norm_shift = ff_h264_cabac_tables + H264_NORM_SHIFT_OFFSET;
static uint8_t * const ff_h264_lps_range = ff_h264_cabac_tables + H264_LPS_RANGE_OFFSET;
static uint8_t * const ff_h264_mlps_state = ff_h264_cabac_tables + H264_MLPS_STATE_OFFSET;
static uint8_t * const ff_h264_last_coeff_flag_offset_8x8 = ff_h264_cabac_tables + H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET;

h264.c引用此头文件但并没有使用此定义的变量

通过readelf -r libavcodec/h264.o查询到变量ff_h264_cabac_tables.rela.text中,经单文件模拟测试,发现应该有.rela.data.rel.ro段,但此h264.o中并没有,于在编译flags中进行查找测试,发现-O选项使用此段不存在,故将其去除,有了此段,如下所示

Relocation section '.rela.data.rel.ro' at offset 0xa7550 contains 10 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  00a000000001 R_X86_64_64       0000000000000000 ff_h264_cabac_tables + 0
000000000008  00a000000001 R_X86_64_64       0000000000000000 ff_h264_cabac_tables + 200
000000000010  00a000000001 R_X86_64_64       0000000000000000 ff_h264_cabac_tables + 400
000000000018  00a000000001 R_X86_64_64       0000000000000000 ff_h264_cabac_tables + 500

但是这并没有解决问题,依然有提示,因为在此h264.o中存在

Relocation section '.rela.text' at offset 0xa2b10 contains 792 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000003e  009f00000004 R_X86_64_PLT32    0000000000000000 av_mallocz - 4
00000000038d  00a000000002 R_X86_64_PC32     0000000000000000 ff_h264_cabac_tables - 4
00000000047b  00a000000002 R_X86_64_PC32     0000000000000000 ff_h264_cabac_tables - 4

这个信息,其中R_X86_64_PC32为相对地址重定位,并非动态链接所用,怀疑是否是此问题。因为自测模拟程序中并没有.rela.text此段。

在编译ffmpeg时加入--disable-asm选项可以修正这个问题,使ff_h264_cabac_tables可重定位。

当使能 asm 的时候,会包含并没有文件libavcodec/x86/cabac.h ,其中有部分与此变量有关的汇编代码

#ifdef BROKEN_RELOCATIONS
    void *tables;

    __asm__ volatile(
        "lea    "MANGLE(ff_h264_cabac_tables)", %0      \n\t"
        : "=&r"(tables)
    );
#endif

在 64bit 中 MANGLE(X) 被定义为 #define MANGLE(X) #X "(%%rip)", 其中 %%rip 是intel 针对64bit的特殊功能,用于地址重定位等作用。 目前到此为止,猜测是否是此汇编代码强制将此变量的重定位信息改变。

转载于:https://my.oschina.net/u/145591/blog/792486

你可能感兴趣的:(ffmpeg 静态库链接到动态库的问题)