From b02a90be74718a290b0c1eb32526295a9766fcba Mon Sep 17 00:00:00 2001 From: Pranav Kant <prka@google.com> Date: Tue, 11 Mar 2025 19:54:48 +0000 Subject: [PATCH] Mark C globals with assembly reference to small code model By default, all globals in C/C++ compiled by clang are allocated in non-large data sections. See [1] for background on code models. For PIC (Position independent code), this is fine as long as binary is small but as binary size increases, users maybe want to use medium/large code models (-mcmodel=medium) which moves data in to large sections. As data in these large sections cannot be accessed using PIC code anymore (as it's too far away), compiler ends up using a different instruction sequence when building C/C++ code -- using GOT to access these globals (which can be relaxed by linker at link time if binary ends up being small). However, assembly files continue to access these globals defined in C/C++ files using older (and invalid instruction sequence). So, we mark all such globals with an attribute that forces them to be allocated in small sections allowing them to validly be accessed from the assembly code. This patch should not have any affect on builds that use small code model, which is the default mode. [1] https://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models There is similar patch in dav1d which inspired this patch: https://code.videolan.org/videolan/dav1d/-/merge_requests/1785 --- common/osdep.h | 6 ++++++ common/tables.c | 6 ++++++ encoder/rdo.c | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/common/osdep.h b/common/osdep.h index 23739b7a..c3c0e9e5 100644 --- a/common/osdep.h +++ b/common/osdep.h @@ -363,6 +363,12 @@ static inline int x264_is_regular_file( FILE *filehandle ) #define x264_nonconstant_p(x) 0 #endif +#if ARCH_X86_64 && SYS_LINUX && __has_attribute(model) +#define ATTR_MCMODEL_SMALL __attribute__((model("small"))) +#else +#define ATTR_MCMODEL_SMALL +#endif + /* threads */ #if HAVE_BEOSTHREAD #include <kernel/OS.h> diff --git a/common/tables.c b/common/tables.c index c6095be7..99df7185 100644 --- a/common/tables.c +++ b/common/tables.c @@ -370,10 +370,12 @@ const uint8_t x264_cqm_avci300_2160p_8iy[64] = * QUANT *****************************************************************************/ +ATTR_MCMODEL_SMALL const uint8_t x264_decimate_table4[16] = { 3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0 }; +ATTR_MCMODEL_SMALL const uint8_t x264_decimate_table8[64] = { 3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1, @@ -1665,6 +1667,7 @@ const int8_t x264_cabac_context_init_PB[3][1024][2] = } }; +ATTR_MCMODEL_SMALL const uint8_t x264_cabac_range_lps[64][4] = { { 2, 2, 2, 2}, { 6, 7, 8, 9}, { 6, 7, 9, 10}, { 6, 8, 9, 11}, @@ -1685,6 +1688,7 @@ const uint8_t x264_cabac_range_lps[64][4] = {123, 150, 178, 205}, {128, 158, 187, 216}, {128, 167, 197, 227}, {128, 176, 208, 240} }; +ATTR_MCMODEL_SMALL const uint8_t x264_cabac_transition[128][2] = { { 0, 0}, { 1, 1}, { 2, 50}, { 51, 3}, { 2, 50}, { 51, 3}, { 4, 52}, { 53, 5}, @@ -1705,6 +1709,7 @@ const uint8_t x264_cabac_transition[128][2] = {118, 122}, {123, 119}, {120, 124}, {125, 121}, {122, 126}, {127, 123}, {124, 127}, {126, 125} }; +ATTR_MCMODEL_SMALL const uint8_t x264_cabac_renorm_shift[64] = { 6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2, @@ -1775,6 +1780,7 @@ const uint8_t x264_last_coeff_flag_offset_8x8[63] = 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 }; const uint8_t x264_coeff_flag_offset_chroma_422_dc[7] = { 0, 0, 1, 1, 2, 2, 2 }; /* MIN( i/2, 2 ) */ +ATTR_MCMODEL_SMALL const uint16_t x264_significant_coeff_flag_offset[2][16] = { { 105+0, 105+15, 105+29, 105+44, 105+47, 402, 484+0, 484+15, 484+29, 660, 528+0, 528+15, 528+29, 718, 0, 0 }, diff --git a/encoder/rdo.c b/encoder/rdo.c index 9fc67610..61734f49 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]; +ATTR_MCMODEL_SMALL 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]; +ATTR_MCMODEL_SMALL 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]; -- GitLab