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

Reply via email to