[x264-devel] [PATCH] Mark functions/variables directly accessed by assembly as HIDDEN

Fāng-ruì Sòng maskray at google.com
Tue Mar 19 10:42:33 CET 2019


Assembly code accesses symbols (variables/functions) such as
x264_8_cabac_trnsition_unary and x264_10_cabac_encode_ue_bypass PC
relatively, without going through GOT entries. This implies these
symbols must be non-preemptible (cannot be provided by main executable
or another DSO).

Any DSO (including libx264.so or application DSO linking libx264.a)
linked from such object files requires -Bsymbolic to make the symbols
non-preemptive. However, -Bsymbolic is dangerous as it breaks C++
semantics about address uniqueness of inline functions, type_info (used
by exceptions). This means libx264.a can not be safely linked into a C++
application DSO.

This patch adds the macro HIDDEN and marks symbols referenced by
assembly as HIDDEN. Without -Bsymbolic, the following command won't fail
with link errors like "relocation R_X86_64_PC32 cannot be used against
symbol ...":

ld --whole-archive libx264.a -shared -o /dev/null

Another advantage is that even in PIC mode, a C compiler will access
such symbols directly instead of going through a GOT entry.
---
 common/cabac.h  |   2 +-
 common/osdep.h  |   3 ++
 common/tables.c |   1 +
 common/tables.h | 116 ++++++++++++++++++++++++------------------------
 encoder/rdo.c   |   4 +-
 5 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/common/cabac.h b/common/cabac.h
index 8b4d9301..041c1d29 100644
--- a/common/cabac.h
+++ b/common/cabac.h
@@ -72,7 +72,7 @@ void x264_cabac_encode_terminal_c( x264_cabac_t *cb );
 #define x264_cabac_encode_terminal_asm x264_template(cabac_encode_terminal_asm)
 void x264_cabac_encode_terminal_asm( x264_cabac_t *cb );
 #define x264_cabac_encode_ue_bypass x264_template(cabac_encode_ue_bypass)
-void x264_cabac_encode_ue_bypass( x264_cabac_t *cb, int exp_bits, int val );
+HIDDEN void x264_cabac_encode_ue_bypass( x264_cabac_t *cb, int exp_bits, int val );
 #define x264_cabac_encode_flush x264_template(cabac_encode_flush)
 void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb );
 
diff --git a/common/osdep.h b/common/osdep.h
index 90067210..5fda5fed 100644
--- a/common/osdep.h
+++ b/common/osdep.h
@@ -170,6 +170,9 @@ int x264_is_pipe( const char *path );
 #define MAY_ALIAS __attribute__((may_alias))
 #define x264_constant_p(x) __builtin_constant_p(x)
 #define x264_nonconstant_p(x) (!__builtin_constant_p(x))
+#if __GNUC__ >= 4
+#define HIDDEN __attribute__((visibility("hidden")))
+#endif
 #else
 #ifdef _MSC_VER
 #define ALWAYS_INLINE __forceinline
diff --git a/common/tables.c b/common/tables.c
index 0e827927..7f3197b9 100644
--- a/common/tables.c
+++ b/common/tables.c
@@ -25,6 +25,7 @@
  *****************************************************************************/
 
 #include "base.h"
+#include "tables.h"
 
 const x264_level_t x264_levels[] =
 {
diff --git a/common/tables.h b/common/tables.h
index 4c869932..b16cb8b7 100644
--- a/common/tables.h
+++ b/common/tables.h
@@ -33,67 +33,67 @@ typedef struct
     uint8_t i_size;
 } vlc_t;
 
-extern const x264_level_t x264_levels[];
+HIDDEN extern const x264_level_t x264_levels[];
 
-extern const uint8_t x264_exp2_lut[64];
-extern const float   x264_log2_lut[128];
-extern const float   x264_log2_lz_lut[32];
+HIDDEN extern const uint8_t x264_exp2_lut[64];
+HIDDEN extern const float   x264_log2_lut[128];
+HIDDEN extern const float   x264_log2_lz_lut[32];
 
 #define QP_MAX_MAX (51+6*2+18)
-extern const uint16_t x264_lambda_tab[QP_MAX_MAX+1];
-extern const int      x264_lambda2_tab[QP_MAX_MAX+1];
-extern const int      x264_trellis_lambda2_tab[2][QP_MAX_MAX+1];
+HIDDEN extern const uint16_t x264_lambda_tab[QP_MAX_MAX+1];
+HIDDEN extern const int      x264_lambda2_tab[QP_MAX_MAX+1];
+HIDDEN extern const int      x264_trellis_lambda2_tab[2][QP_MAX_MAX+1];
 #define MAX_CHROMA_LAMBDA_OFFSET 36
-extern const uint16_t x264_chroma_lambda2_offset_tab[MAX_CHROMA_LAMBDA_OFFSET+1];
-
-extern const uint8_t x264_hpel_ref0[16];
-extern const uint8_t x264_hpel_ref1[16];
-
-extern const uint8_t x264_cqm_jvt4i[16];
-extern const uint8_t x264_cqm_jvt4p[16];
-extern const uint8_t x264_cqm_jvt8i[64];
-extern const uint8_t x264_cqm_jvt8p[64];
-extern const uint8_t x264_cqm_flat16[64];
-extern const uint8_t * const x264_cqm_jvt[8];
-extern const uint8_t x264_cqm_avci50_4ic[16];
-extern const uint8_t x264_cqm_avci50_p_8iy[64];
-extern const uint8_t x264_cqm_avci50_1080i_8iy[64];
-extern const uint8_t x264_cqm_avci100_720p_4ic[16];
-extern const uint8_t x264_cqm_avci100_720p_8iy[64];
-extern const uint8_t x264_cqm_avci100_1080_4ic[16];
-extern const uint8_t x264_cqm_avci100_1080i_8iy[64];
-extern const uint8_t x264_cqm_avci100_1080p_8iy[64];
-
-extern const uint8_t x264_decimate_table4[16];
-extern const uint8_t x264_decimate_table8[64];
-
-extern const uint32_t x264_dct4_weight_tab[16];
-extern const uint32_t x264_dct8_weight_tab[64];
-extern const uint32_t x264_dct4_weight2_tab[16];
-extern const uint32_t x264_dct8_weight2_tab[64];
-
-extern const int8_t   x264_cabac_context_init_I[1024][2];
-extern const int8_t   x264_cabac_context_init_PB[3][1024][2];
-extern const uint8_t  x264_cabac_range_lps[64][4];
-extern const uint8_t  x264_cabac_transition[128][2];
-extern const uint8_t  x264_cabac_renorm_shift[64];
-extern const uint16_t x264_cabac_entropy[128];
-
-extern const uint8_t  x264_significant_coeff_flag_offset_8x8[2][64];
-extern const uint8_t  x264_last_coeff_flag_offset_8x8[63];
-extern const uint8_t  x264_coeff_flag_offset_chroma_422_dc[7];
-extern const uint16_t x264_significant_coeff_flag_offset[2][16];
-extern const uint16_t x264_last_coeff_flag_offset[2][16];
-extern const uint16_t x264_coeff_abs_level_m1_offset[16];
-extern const uint8_t  x264_count_cat_m1[14];
-
-extern const vlc_t x264_coeff0_token[6];
-extern const vlc_t x264_coeff_token[6][16][4];
-extern const vlc_t x264_total_zeros[15][16];
-extern const vlc_t x264_total_zeros_2x2_dc[3][4];
-extern const vlc_t x264_total_zeros_2x4_dc[7][8];
-extern const vlc_t x264_run_before_init[7][16];
-
-extern uint8_t x264_zero[1024];
+HIDDEN extern const uint16_t x264_chroma_lambda2_offset_tab[MAX_CHROMA_LAMBDA_OFFSET+1];
+
+HIDDEN extern const uint8_t x264_hpel_ref0[16];
+HIDDEN extern const uint8_t x264_hpel_ref1[16];
+
+HIDDEN extern const uint8_t x264_cqm_jvt4i[16];
+HIDDEN extern const uint8_t x264_cqm_jvt4p[16];
+HIDDEN extern const uint8_t x264_cqm_jvt8i[64];
+HIDDEN extern const uint8_t x264_cqm_jvt8p[64];
+HIDDEN extern const uint8_t x264_cqm_flat16[64];
+HIDDEN extern const uint8_t * const x264_cqm_jvt[8];
+HIDDEN extern const uint8_t x264_cqm_avci50_4ic[16];
+HIDDEN extern const uint8_t x264_cqm_avci50_p_8iy[64];
+HIDDEN extern const uint8_t x264_cqm_avci50_1080i_8iy[64];
+HIDDEN extern const uint8_t x264_cqm_avci100_720p_4ic[16];
+HIDDEN extern const uint8_t x264_cqm_avci100_720p_8iy[64];
+HIDDEN extern const uint8_t x264_cqm_avci100_1080_4ic[16];
+HIDDEN extern const uint8_t x264_cqm_avci100_1080i_8iy[64];
+HIDDEN extern const uint8_t x264_cqm_avci100_1080p_8iy[64];
+
+HIDDEN extern const uint8_t x264_decimate_table4[16];
+HIDDEN extern const uint8_t x264_decimate_table8[64];
+
+HIDDEN extern const uint32_t x264_dct4_weight_tab[16];
+HIDDEN extern const uint32_t x264_dct8_weight_tab[64];
+HIDDEN extern const uint32_t x264_dct4_weight2_tab[16];
+HIDDEN extern const uint32_t x264_dct8_weight2_tab[64];
+
+HIDDEN extern const int8_t   x264_cabac_context_init_I[1024][2];
+HIDDEN extern const int8_t   x264_cabac_context_init_PB[3][1024][2];
+HIDDEN extern const uint8_t  x264_cabac_range_lps[64][4];
+HIDDEN extern const uint8_t  x264_cabac_transition[128][2];
+HIDDEN extern const uint8_t  x264_cabac_renorm_shift[64];
+HIDDEN extern const uint16_t x264_cabac_entropy[128];
+
+HIDDEN extern const uint8_t  x264_significant_coeff_flag_offset_8x8[2][64];
+HIDDEN extern const uint8_t  x264_last_coeff_flag_offset_8x8[63];
+HIDDEN extern const uint8_t  x264_coeff_flag_offset_chroma_422_dc[7];
+HIDDEN extern const uint16_t x264_significant_coeff_flag_offset[2][16];
+HIDDEN extern const uint16_t x264_last_coeff_flag_offset[2][16];
+HIDDEN extern const uint16_t x264_coeff_abs_level_m1_offset[16];
+HIDDEN extern const uint8_t  x264_count_cat_m1[14];
+
+HIDDEN extern const vlc_t x264_coeff0_token[6];
+HIDDEN extern const vlc_t x264_coeff_token[6][16][4];
+HIDDEN extern const vlc_t x264_total_zeros[15][16];
+HIDDEN extern const vlc_t x264_total_zeros_2x2_dc[3][4];
+HIDDEN extern const vlc_t x264_total_zeros_2x4_dc[7][8];
+HIDDEN extern const vlc_t x264_run_before_init[7][16];
+
+HIDDEN extern uint8_t x264_zero[1024];
 
 #endif
diff --git a/encoder/rdo.c b/encoder/rdo.c
index 743934fe..1c2e4291 100644
--- a/encoder/rdo.c
+++ b/encoder/rdo.c
@@ -33,9 +33,9 @@
 /* Transition and size tables for abs<9 MVD and residual coding */
 /* Consist of i_prefix-2 1s, one zero, and a bypass sign bit */
 #define x264_cabac_transition_unary x264_template(cabac_transition_unary)
-uint8_t x264_cabac_transition_unary[15][128];
+HIDDEN uint8_t x264_cabac_transition_unary[15][128];
 #define x264_cabac_size_unary x264_template(cabac_size_unary)
-uint16_t x264_cabac_size_unary[15][128];
+HIDDEN uint16_t x264_cabac_size_unary[15][128];
 /* Transition and size tables for abs>9 MVD */
 /* Consist of 5 1s and a bypass sign bit */
 static uint8_t cabac_transition_5ones[128];
-- 
2.20.1



More information about the x264-devel mailing list