The attached patch adds a uclibc_printf_pointer_format target hook equivalent to the linux glibc_printf_pointer_format hook. I couldn't find a good uclibc-only file where to put the new definition of the hook so I conditionally added it to targethooks.c.
I tested the new hook by bootstrapping GCC for tic6x-uclinux and bfin-uclinux targets on x86_64. Martin
PR bootstrap/77819 - undefined reference to gnu_libc_printf_pointer_format with uClibc gcc/ChangeLog: 2016-10-02 Martin Sebor <mse...@redhat.com> PR bootstrap/77819 * config/linux.h [DEFAULT_LIBC == LIBC_UCLIBC) && SINGLE_LIBC] (TARGET_PRINTF_POINTER_FORMAT): Define macro. * targhooks.c [DEFAULT_LIBC == LIBC_UCLIBC) && SINGLE_LIBC] (default_printf_pointer_format): Define function. * targhooks.h (default_printf_pointer_format): Declare. diff --git a/gcc/config/linux.h b/gcc/config/linux.h index 3ff005b..1649b01 100644 --- a/gcc/config/linux.h +++ b/gcc/config/linux.h @@ -200,6 +200,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # undef TARGET_LIBC_HAS_FUNCTION # define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function +/* The format string to which "%p" corresponds. */ +# undef TARGET_PRINTF_POINTER_FORMAT +# define TARGET_PRINTF_POINTER_FORMAT uclibc_printf_pointer_format + #else /* !uClinux, i.e., normal Linux */ /* Determine what functions are present at the runtime; @@ -207,8 +211,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # undef TARGET_LIBC_HAS_FUNCTION # define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function -#endif - /* The format string to which "%p" corresponds. */ -#undef TARGET_PRINTF_POINTER_FORMAT -#define TARGET_PRINTF_POINTER_FORMAT gnu_libc_printf_pointer_format +# undef TARGET_PRINTF_POINTER_FORMAT +# define TARGET_PRINTF_POINTER_FORMAT gnu_libc_printf_pointer_format + +#endif diff --git a/gcc/targhooks.c b/gcc/targhooks.c index d75650f..77b4a18 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1523,6 +1523,26 @@ default_printf_pointer_format (tree, const char **flags) return "%zx"; } +#if (DEFAULT_LIBC == LIBC_UCLIBC) && defined (SINGLE_LIBC) /* uClinux */ + +/* For *uclibc* targets only, define the hook here because otherwise + it would have to be duplicated in each target's .c file (such as + in bfin/bfin.c and c6x/c6x.c, etc.) + uClibc (and Glibc) format pointers as if by "%zx" except for the null + pointer which outputs "(nil)". It ignores the pound ('#') format + flag but interprets the space and plus flags the same as in the integer + directive. */ + +const char* +uclibc_printf_pointer_format (tree arg, const char **flags) +{ + *flags = " +"; + + return arg && integer_zerop (arg) ? "(nil)" : "%#zx"; +} + +#endif + tree default_builtin_tm_load_store (tree ARG_UNUSED (type)) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 3356f0a..52d36e0 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -194,6 +194,7 @@ extern bool gnu_libc_has_function (enum function_class); extern const char* default_printf_pointer_format (tree, const char **); extern const char* gnu_libc_printf_pointer_format (tree, const char **); extern const char* solaris_printf_pointer_format (tree, const char **); +extern const char* uclibc_printf_pointer_format (tree, const char **); extern tree default_builtin_tm_load_store (tree);