Add patch to extend GCC format string argument consistency checks to include the UEFI EDK2 PrintLib and ShellLib format strings. The patch adds GCC predefined compiler macro __GCC_EDK2_FORMATS__ for identification of the feature. EDK2 format string of type CHAR8[] and CHAR16[] can be checked.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Scott Duplichan <sc...@notabs.org> --- BaseTools/gcc/gcc-4.9.3_format.patch | 240 +++++++++++++++++++++++++++++++++++ BaseTools/gcc/gcc-5.2.0_format.patch | 240 +++++++++++++++++++++++++++++++++++ 2 files changed, 480 insertions(+) diff --git a/BaseTools/gcc/gcc-4.9.3_format.patch b/BaseTools/gcc/gcc-4.9.3_format.patch new file mode 100644 index 0000000..65f56ba --- /dev/null +++ b/BaseTools/gcc/gcc-4.9.3_format.patch @@ -0,0 +1,240 @@ +[PATCH] Extend gcc format string argument consistency checks to +include the UEFI EDK2 PrintLib and ShellLib format strings. +For PrintLib format checking, use: +__attribute__((format (edk2_printf, FormatPosition, FormatPosition+1))) +For ShellLib format checking, use: +__attribute__((format (edk2_shell_printf, FormatPosition, FormatPosition+1))) + + +diff -rupN gcc-4.9.3/gcc/c-family/c-cppbuiltin.c gcc-4.9.3-patched/gcc/c-family/c-cppbuiltin.c +--- gcc-4.9.3/gcc/c-family/c-cppbuiltin.c 2014-10-08 06:05:43.000000000 -0500 ++++ gcc-4.9.3-patched/gcc/c-family/c-cppbuiltin.c 2015-08-02 11:44:01.445024600 -0500 +@@ -782,6 +782,9 @@ c_cpp_builtins (cpp_reader *pfile) + if (flag_undef) + return; + ++ /* identify presence of edk2_printf and edk2_shell_printf format checking */ ++ cpp_define (pfile, "__GCC_EDK2_FORMATS__"); ++ + define_language_independent_builtin_macros (pfile); + + if (c_dialect_cxx ()) +diff -rupN gcc-4.9.3/gcc/c-family/c-format.c gcc-4.9.3-patched/gcc/c-family/c-format.c +--- gcc-4.9.3/gcc/c-family/c-format.c 2014-01-02 16:23:26.000000000 -0600 ++++ gcc-4.9.3-patched/gcc/c-family/c-format.c 2015-08-02 11:44:01.445024600 -0500 +@@ -33,6 +33,140 @@ along with GCC; see the file COPYING3. + #include "alloc-pool.h" + #include "c-target.h" + ++//---------------------------------------------------------------------------- ++ ++/* format attributes for edk2_printf */ ++#undef TARGET_FORMAT_TYPES ++#define TARGET_FORMAT_TYPES targetFormatTypes() ++ ++//---------------------------------------------------------------------------- ++/* format attributes edk2_printf */ ++ ++#define DIMENSION(array) (sizeof (array) / sizeof (array [0])) ++ ++static format_length_info edk2_printf_length_specs[] = ++{ ++ { "L", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, ++ { "l", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, ++ { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } ++}; ++ ++static const format_flag_spec edk2_printf_flag_specs[] = ++{ ++ { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, ++ { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, ++ { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, ++ { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, ++ { ',', 0, 0, N_("',' flag"), N_("the ',' printf flag"), STD_C89 }, ++ { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, ++ { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, ++ { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, ++ { 'l', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, ++ { 0, 0, 0, NULL, NULL, STD_C89 } ++}; ++ ++static const format_flag_pair edk2_printf_flag_pairs[] = ++{ ++ { ' ', '+', 1, 0 }, ++ { '0', '-', 1, 0 }, { '0', 'p', 1, 'i' }, ++ { 0, 0, 0, 0 } ++}; ++ ++static const format_char_info edk2_print_char_table_template[] = ++{ ++ /* C89 conversion specifiers. */ ++// none hh h l ll L z t j H D DD ++ { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "i", NULL }, ++ { "d", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +,", "i", NULL }, ++ { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, ++ { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "i", NULL }, ++ { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, ++ { "a", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, ++ { "sS", 1, STD_C89, { T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, ++ { "g", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "cR", NULL }, ++ { "t", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, ++ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, ++ { "N", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "H", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "E", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "B", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "V", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } ++}; ++ ++static format_char_info edk2_print_char_table[DIMENSION (edk2_print_char_table_template)]; ++static format_char_info edk2_shell_print_char_table[DIMENSION (edk2_print_char_table_template)]; ++ ++static const format_kind_info edk2_format_attributes32[] = ++{ ++ { "edk2_printf", edk2_printf_length_specs, edk2_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &integer_type_node, &integer_type_node ++ }, ++ { "edk2_shell_printf", edk2_printf_length_specs, edk2_shell_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &integer_type_node, &integer_type_node ++ }, ++}; ++ ++static const format_kind_info edk2_format_attributes64[] = ++{ ++ { "edk2_printf", edk2_printf_length_specs, edk2_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &long_long_integer_type_node, &long_long_integer_type_node ++ }, ++ { "edk2_shell_printf", edk2_printf_length_specs, edk2_shell_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &long_long_integer_type_node, &long_long_integer_type_node ++ }, ++}; ++ ++#undef TARGET_N_FORMAT_TYPES ++#define TARGET_N_FORMAT_TYPES DIMENSION (edk2_format_attributes32) ++ ++static const format_kind_info *targetFormatTypes (void) ++ { ++ int pointerSizeInBits = TYPE_PRECISION(integer_ptr_type_node); ++ int templateElements = DIMENSION (edk2_print_char_table_template); ++ ++ // initialize both tables from template ++ memcpy (edk2_print_char_table, edk2_print_char_table_template, sizeof edk2_print_char_table_template); ++ memcpy (edk2_shell_print_char_table, edk2_print_char_table_template, sizeof edk2_print_char_table_template); ++ ++ // remove shell extensions (N, H, E, B, V) from standard table ++ edk2_print_char_table [templateElements - 6] = edk2_print_char_table [templateElements - 1]; ++ ++ if (pointerSizeInBits == 32) ++ { ++ edk2_print_char_table[0].types[FMT_LEN_none].std = STD_C89; ++ edk2_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_print_char_table[0].types[FMT_LEN_none].type = T_I; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].std = STD_C89; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].type = T_I; ++ return edk2_format_attributes32; ++ } ++ else // pointerSizeInBits == 64 ++ { ++ edk2_print_char_table[0].types[FMT_LEN_none].std = STD_EXT; ++ edk2_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_print_char_table[0].types[FMT_LEN_none].type = T_LL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].std = STD_EXT; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].type = T_LL; ++ return edk2_format_attributes64; ++ } ++ } ++ ++//---------------------------------------------------------------------------- + /* Handle attributes associated with format checking. */ + + /* This must be in the same order as format_types, except for +@@ -82,9 +216,10 @@ static int format_flags (int format_num) + static bool + valid_stringptr_type_p (tree strref) + { ++ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (strref)); + return (strref != NULL + && TREE_CODE (strref) == POINTER_TYPE +- && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node ++ && ((type == char_type_node || type == short_unsigned_type_node) + || objc_string_ref_type_p (strref) + || (*targetcm.string_object_ref_type_p) ((const_tree) strref))); + } +@@ -162,7 +297,8 @@ check_format_string (tree fntype, unsign + + /* Now check that the arg matches the expected type. */ + is_char_ref = +- (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node); ++ (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node) || ++ (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == short_unsigned_type_node); + + fmt_flags = format_flags (expected_format_type); + is_objc_sref = is_target_sref = false; +@@ -1416,6 +1552,7 @@ check_format_arg (void *ctx, tree format + format_check_results *res = format_ctx->res; + function_format_info *info = format_ctx->info; + tree params = format_ctx->params; ++ char convertedFormat [1000]; + + int format_length; + HOST_WIDE_INT offset; +@@ -1526,13 +1663,34 @@ check_format_arg (void *ctx, tree format + res->number_non_literal++; + return; + } +- if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node) ++ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node && ++ TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != short_unsigned_type_node) + { + res->number_wide++; + return; + } + format_chars = TREE_STRING_POINTER (format_tree); + format_length = TREE_STRING_LENGTH (format_tree); ++ ++ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) == short_unsigned_type_node) ++ { ++ int index = 0; ++ unsigned short *ptr = (unsigned short *)(void *) format_chars; ++ while (ptr [index]) ++ { ++ if (index + 1 == sizeof convertedFormat) ++ { ++ warning (OPT_Wformat_, "format too long to check"); ++ break; ++ } ++ convertedFormat [index] = ptr [index]; ++ index++; ++ } ++ convertedFormat [index++] = '\0'; ++ format_length = index; ++ format_chars = convertedFormat; ++ } ++ + if (array_size != 0) + { + /* Variable length arrays can't be initialized. */ +@@ -2845,7 +3003,7 @@ init_dynamic_diag_info (void) + } + + #ifdef TARGET_FORMAT_TYPES +-extern const format_kind_info TARGET_FORMAT_TYPES[]; ++//extern const format_kind_info TARGET_FORMAT_TYPES[]; + #endif + + #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES diff --git a/BaseTools/gcc/gcc-5.2.0_format.patch b/BaseTools/gcc/gcc-5.2.0_format.patch new file mode 100644 index 0000000..251fa8c --- /dev/null +++ b/BaseTools/gcc/gcc-5.2.0_format.patch @@ -0,0 +1,240 @@ +[PATCH] Extend gcc format string argument consistency checks to +include the UEFI EDK2 PrintLib and ShellLib format strings. +For PrintLib format checking, use: +__attribute__((format (edk2_printf, FormatPosition, FormatPosition+1))) +For ShellLib format checking, use: +__attribute__((format (edk2_shell_printf, FormatPosition, FormatPosition+1))) + + +diff -rupN gcc-5.2.0/gcc/c-family/c-cppbuiltin.c gcc-5.2.0-patched/gcc/c-family/c-cppbuiltin.c +--- gcc-5.2.0/gcc/c-family/c-cppbuiltin.c 2015-02-12 23:26:37.000000000 -0600 ++++ gcc-5.2.0-patched/gcc/c-family/c-cppbuiltin.c 2015-08-02 10:40:33.057135500 -0500 +@@ -791,6 +791,9 @@ c_cpp_builtins (cpp_reader *pfile) + if (flag_undef) + return; + ++ /* identify presence of edk2_printf and edk2_shell_printf format checking */ ++ cpp_define (pfile, "__GCC_EDK2_FORMATS__"); ++ + define_language_independent_builtin_macros (pfile); + + if (c_dialect_cxx ()) +diff -rupN gcc-5.2.0/gcc/c-family/c-format.c gcc-5.2.0-patched/gcc/c-family/c-format.c +--- gcc-5.2.0/gcc/c-family/c-format.c 2015-02-16 05:16:33.000000000 -0600 ++++ gcc-5.2.0-patched/gcc/c-family/c-format.c 2015-08-01 22:50:06.826212000 -0500 +@@ -43,6 +43,140 @@ along with GCC; see the file COPYING3. + #include "alloc-pool.h" + #include "c-target.h" + ++//---------------------------------------------------------------------------- ++ ++/* format attributes for edk2_printf */ ++#undef TARGET_FORMAT_TYPES ++#define TARGET_FORMAT_TYPES targetFormatTypes() ++ ++//---------------------------------------------------------------------------- ++/* format attributes edk2_printf */ ++ ++#define DIMENSION(array) (sizeof (array) / sizeof (array [0])) ++ ++static format_length_info edk2_printf_length_specs[] = ++{ ++ { "L", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, ++ { "l", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, ++ { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } ++}; ++ ++static const format_flag_spec edk2_printf_flag_specs[] = ++{ ++ { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, ++ { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, ++ { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, ++ { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, ++ { ',', 0, 0, N_("',' flag"), N_("the ',' printf flag"), STD_C89 }, ++ { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, ++ { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, ++ { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, ++ { 'l', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, ++ { 0, 0, 0, NULL, NULL, STD_C89 } ++}; ++ ++static const format_flag_pair edk2_printf_flag_pairs[] = ++{ ++ { ' ', '+', 1, 0 }, ++ { '0', '-', 1, 0 }, { '0', 'p', 1, 'i' }, ++ { 0, 0, 0, 0 } ++}; ++ ++static const format_char_info edk2_print_char_table_template[] = ++{ ++ /* C89 conversion specifiers. */ ++// none hh h l ll L z t j H D DD ++ { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "i", NULL }, ++ { "d", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +,", "i", NULL }, ++ { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, ++ { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "i", NULL }, ++ { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, ++ { "a", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, ++ { "sS", 1, STD_C89, { T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, ++ { "g", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "cR", NULL }, ++ { "t", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, ++ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, ++ { "N", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "H", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "E", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "B", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { "V", 0, STD_C89, NOARGUMENTS, "", "", NULL }, ++ { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } ++}; ++ ++static format_char_info edk2_print_char_table[DIMENSION (edk2_print_char_table_template)]; ++static format_char_info edk2_shell_print_char_table[DIMENSION (edk2_print_char_table_template)]; ++ ++static const format_kind_info edk2_format_attributes32[] = ++{ ++ { "edk2_printf", edk2_printf_length_specs, edk2_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &integer_type_node, &integer_type_node ++ }, ++ { "edk2_shell_printf", edk2_printf_length_specs, edk2_shell_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &integer_type_node, &integer_type_node ++ }, ++}; ++ ++static const format_kind_info edk2_format_attributes64[] = ++{ ++ { "edk2_printf", edk2_printf_length_specs, edk2_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &long_long_integer_type_node, &long_long_integer_type_node ++ }, ++ { "edk2_shell_printf", edk2_printf_length_specs, edk2_shell_print_char_table, " +0-,", NULL, ++ edk2_printf_flag_specs, edk2_printf_flag_pairs, ++ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, ++ 'w', 0, 'p', 0, 'L', 0, ++ &long_long_integer_type_node, &long_long_integer_type_node ++ }, ++}; ++ ++#undef TARGET_N_FORMAT_TYPES ++#define TARGET_N_FORMAT_TYPES DIMENSION (edk2_format_attributes32) ++ ++static const format_kind_info *targetFormatTypes (void) ++ { ++ int pointerSizeInBits = TYPE_PRECISION(integer_ptr_type_node); ++ int templateElements = DIMENSION (edk2_print_char_table_template); ++ ++ // initialize both tables from template ++ memcpy (edk2_print_char_table, edk2_print_char_table_template, sizeof edk2_print_char_table_template); ++ memcpy (edk2_shell_print_char_table, edk2_print_char_table_template, sizeof edk2_print_char_table_template); ++ ++ // remove shell extensions (N, H, E, B, V) from standard table ++ edk2_print_char_table [templateElements - 6] = edk2_print_char_table [templateElements - 1]; ++ ++ if (pointerSizeInBits == 32) ++ { ++ edk2_print_char_table[0].types[FMT_LEN_none].std = STD_C89; ++ edk2_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_print_char_table[0].types[FMT_LEN_none].type = T_I; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].std = STD_C89; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].type = T_I; ++ return edk2_format_attributes32; ++ } ++ else // pointerSizeInBits == 64 ++ { ++ edk2_print_char_table[0].types[FMT_LEN_none].std = STD_EXT; ++ edk2_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_print_char_table[0].types[FMT_LEN_none].type = T_LL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].std = STD_EXT; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].name = NULL; ++ edk2_shell_print_char_table[0].types[FMT_LEN_none].type = T_LL; ++ return edk2_format_attributes64; ++ } ++ } ++ ++//---------------------------------------------------------------------------- + /* Handle attributes associated with format checking. */ + + /* This must be in the same order as format_types, except for +@@ -92,9 +226,10 @@ static int format_flags (int format_num) + static bool + valid_stringptr_type_p (tree strref) + { ++ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (strref)); + return (strref != NULL + && TREE_CODE (strref) == POINTER_TYPE +- && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node ++ && ((type == char_type_node || type == short_unsigned_type_node) + || objc_string_ref_type_p (strref) + || (*targetcm.string_object_ref_type_p) ((const_tree) strref))); + } +@@ -172,7 +307,8 @@ check_format_string (tree fntype, unsign + + /* Now check that the arg matches the expected type. */ + is_char_ref = +- (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node); ++ (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node) || ++ (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == short_unsigned_type_node); + + fmt_flags = format_flags (expected_format_type); + is_objc_sref = is_target_sref = false; +@@ -1435,6 +1571,7 @@ check_format_arg (void *ctx, tree format + format_check_results *res = format_ctx->res; + function_format_info *info = format_ctx->info; + tree params = format_ctx->params; ++ char convertedFormat [1000]; + + int format_length; + HOST_WIDE_INT offset; +@@ -1563,13 +1700,34 @@ check_format_arg (void *ctx, tree format + res->number_non_literal++; + return; + } +- if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node) ++ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node && ++ TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != short_unsigned_type_node) + { + res->number_wide++; + return; + } + format_chars = TREE_STRING_POINTER (format_tree); + format_length = TREE_STRING_LENGTH (format_tree); ++ ++ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) == short_unsigned_type_node) ++ { ++ int index = 0; ++ unsigned short *ptr = (unsigned short *)(void *) format_chars; ++ while (ptr [index]) ++ { ++ if (index + 1 == sizeof convertedFormat) ++ { ++ warning (OPT_Wformat_, "format too long to check"); ++ break; ++ } ++ convertedFormat [index] = ptr [index]; ++ index++; ++ } ++ convertedFormat [index++] = '\0'; ++ format_length = index; ++ format_chars = convertedFormat; ++ } ++ + if (array_size != 0) + { + /* Variable length arrays can't be initialized. */ +@@ -2927,7 +3085,7 @@ init_dynamic_diag_info (void) + } + + #ifdef TARGET_FORMAT_TYPES +-extern const format_kind_info TARGET_FORMAT_TYPES[]; ++//extern const format_kind_info TARGET_FORMAT_TYPES[]; + #endif + + #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel