https://gcc.gnu.org/g:72274d0a421785ed38ad704af1192a7578660e7f
commit r16-6489-g72274d0a421785ed38ad704af1192a7578660e7f Author: Keith Packard <[email protected]> Date: Sun Jan 4 11:56:24 2026 -0700 [PATCH] Add support for using picolibc Selected for *-picolibc-* targets or when --with-picolibc is passed to configure. Add custom options for use with picolibc: * '--oslib='. Allows targets to insert an OS library after the C library in the LIB_PATH spec file fragment. This library maps a few POSIX APIs used by picolibc to underlying system capabilities. * '--crt0='. Allows targets to use an alternate crt0 in place of the usual one as provided by Picolibc. Picolibc provides a range of crt0 versions which this can be used to select among. * '--printf=' and '--scanf='. Allows targets to customize the version of printf and scanf linked from the C library. Adds some new preprocessor variables allowing the C library to adjust the specfile generation process without affecting target changes: * LIBC_CPP_SPEC. A specfile fragment appended to cpp_spec. Picolibc uses this to add preprocessor definitions when the --printf and --scanf options are provided so that applications can detect the available printf and scanf versions. * LIBC_LINK_SPEC. A specfile fragment appended to link_spec. Picolibc uses this to implement the --printf and --scanf options, passing suitable --defsym options to the linker. Documents the new driver options and target macros. gcc/ * config.gcc: Add clause for picolibc. * config/picolibc-spec.h: New file. * config/picolibc.opt: Likewise. * config/picolibc.opt.urls: Likewise. * configure.ac: Add support for --with-picolibc. * configure: Rebuilt. * doc/invoke.texi: Document picolibc options. * doc/tm.texi.in (LIBC_CPP_SPEC): Document. (LIBC_LINK_SPEC): Similarly. * doc/tm.texi: Rebuilt. * gcc.cc (LIBC_CPP_SPEC): Provide default definition. (LIBC_LINK_SPEC): Likewise. (cpp_spec): Include LIBC_CPP_SPEC. (link_spec): Similarly for LIBC_LINK_SPEC. Signed-off-by: Keith Packard <[email protected]> Diff: --- gcc/config.gcc | 18 ++++++++++++ gcc/config/picolibc-spec.h | 57 ++++++++++++++++++++++++++++++++++++ gcc/config/picolibc.opt | 47 ++++++++++++++++++++++++++++++ gcc/config/picolibc.opt.urls | 2 ++ gcc/configure | 24 ++++++++++----- gcc/configure.ac | 3 ++ gcc/doc/invoke.texi | 69 ++++++++++++++++++++++++++++++++++++++++++++ gcc/doc/tm.texi | 16 ++++++++++ gcc/doc/tm.texi.in | 16 ++++++++++ gcc/gcc.cc | 17 +++++++++-- 10 files changed, 260 insertions(+), 9 deletions(-) diff --git a/gcc/config.gcc b/gcc/config.gcc index 939ed109c744..b2a48c02d3be 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3697,6 +3697,24 @@ case ${target} in ;; esac +# picolibc systems +case "${target}_${with_picolibc}" in +*-picolibc-*|*_yes) + default_use_cxa_atexit=yes + use_gcc_stdint=none + # add newlib-stdint.h if not already present + case "${tm_file}" in + *newlib-stdint.h*) + ;; + *) + tm_file="${tm_file} newlib-stdint.h" + ;; + esac + tm_file="${tm_file} picolibc-spec.h" + extra_options="${extra_options} picolibc.opt" + ;; +esac + # Assume the existence of indirect function support and allow the use of the # resolver attribute. case ${target} in diff --git a/gcc/config/picolibc-spec.h b/gcc/config/picolibc-spec.h new file mode 100644 index 000000000000..d1024ced3e7f --- /dev/null +++ b/gcc/config/picolibc-spec.h @@ -0,0 +1,57 @@ +/* Configuration common to all targets running Picolibc. + Copyright (C) 2026 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#define PICOLIBC_LD "picolibc.ld" + +/* Default to local-exec TLS model. */ +#undef OS_CC1_SPEC +#define OS_CC1_SPEC " %{!ftls-model=*:-ftls-model=local-exec}" + +/* Pass along preprocessor definitions when --printf or --scanf are specified */ +#define LIBC_CPP_SPEC \ + " %{-printf=*: -D_PICOLIBC_PRINTF='%*'}" \ + " %{-scanf=*: -D_PICOLIBC_SCANF='%*'}" + +/* + * Add picolibc.ld if not using -shared, -r or -T and we can find it. + * Define vfprintf if --printf is set + * Define vfscanf if --scanf is set + */ +#define LIBC_LINK_SPEC \ + " %{!shared:%{!r:%{!T*: %:if-exists-then-else(%:find-file(" PICOLIBC_LD ") -T" PICOLIBC_LD ")}}}" \ + " %{-printf=*:--defsym=" USER_LABEL_PREFIX "vfprintf=" USER_LABEL_PREFIX "__%*_vfprintf}" \ + " %{-scanf=*:--defsym=" USER_LABEL_PREFIX "vfscanf=" USER_LABEL_PREFIX "__%*_vfscanf}" + +/* + * Place the C library, libgcc and any oslib in a link group to resolve + * interdependencies + */ +#undef LIB_SPEC +#define LIB_SPEC "--start-group -lc %{-oslib=*:-l%*} %(libgcc) --end-group" + +/* Select alternate crt0 version if --crt0 is specified */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{-crt0=*:crt0-%*%O%s; :crt0%O%s}" + +#define EH_TABLES_CAN_BE_READ_ONLY 1 diff --git a/gcc/config/picolibc.opt b/gcc/config/picolibc.opt new file mode 100644 index 000000000000..e68e5d00016d --- /dev/null +++ b/gcc/config/picolibc.opt @@ -0,0 +1,47 @@ +; Processor-independent options for picolibc. +; +; Copyright (C) 2026 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; <http://www.gnu.org/licenses/>. + +-oslib +Driver Separate Alias(-oslib=) + +-oslib= +Driver Joined +Specify an OS support library to load after libc. + +-crt0 +Driver Separate Alias(-crt0=) + +-crt0= +Driver Joined +Specify an alternate startup file. + +-printf +Driver Separate Alias(-printf=) + +-printf= +Driver Joined +Specify the printf version linked from libc. + +-scanf +Driver Separate Alias(-scanf=) + +-scanf= +Driver Joined +Specify the scanf version linked from libc. diff --git a/gcc/config/picolibc.opt.urls b/gcc/config/picolibc.opt.urls new file mode 100644 index 000000000000..b3a57d15a396 --- /dev/null +++ b/gcc/config/picolibc.opt.urls @@ -0,0 +1,2 @@ +; Autogenerated by regenerate-opt-urls.py from gcc/config/picolibc.opt and generated HTML + diff --git a/gcc/configure b/gcc/configure index 826ac310949f..c975d59a7b20 100755 --- a/gcc/configure +++ b/gcc/configure @@ -1006,6 +1006,7 @@ with_changes_root_url enable_languages with_multilib_list with_multilib_generator +with_picolibc with_zstd with_zstd_include with_zstd_lib @@ -1896,6 +1897,8 @@ Optional Packages: RISC-V, SH and x86-64 only) --with-multilib-generator Multi-libs configuration string (RISC-V only) + --with-picolibc Support for picolibc, including command line options + and spec rules --with-zstd=PATH specify prefix directory for installed zstd library. Equivalent to --with-zstd-include=PATH/include plus --with-zstd-lib=PATH/lib @@ -6291,7 +6294,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -6337,7 +6340,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -6361,7 +6364,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -6406,7 +6409,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -6430,7 +6433,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -8405,6 +8408,13 @@ else fi + +# Check whether --with-picolibc was given. +if test "${with_picolibc+set}" = set; then : + withval=$with_picolibc; +fi + + # ------------------------- # Checks for other programs # ------------------------- @@ -21925,7 +21935,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21928 "configure" +#line 21938 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -22031,7 +22041,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 22034 "configure" +#line 22044 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/configure.ac b/gcc/configure.ac index 9ad611b925bc..458f5c990287 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1221,6 +1221,9 @@ AC_ARG_WITH(multilib-generator, :, with_multilib_generator=default) +AC_ARG_WITH(picolibc, +[AS_HELP_STRING([--with-picolibc], [Support for picolibc, including command line options and spec rules])]) + # ------------------------- # Checks for other programs # ------------------------- diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a25b43b3e85c..79107f2dbcd8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -164,6 +164,7 @@ listing and explanation of the binary and decimal byte size prefixes. * Link Options:: Specifying libraries and so on. * Directory Options:: Where to find header files and libraries. Where to find the compiler executable files. +* Picolibc Options:: Select compile and link options when using picolibc. * Code Gen Options:: Specifying conventions for function calls, data layout and register usage. * Developer Options:: Printing GCC configuration info, statistics, and @@ -803,6 +804,11 @@ Objective-C and Objective-C++ Dialects}. --no-canonical-prefixes --no-standard-includes --prefix=@var{prefix} --sysroot=@var{dir}} +@item Picolibc Options +@xref{Picolibc Options,,Options for use with Picolibc}. +@gccoptlist{--oslib=@var{library} --crt0=@r{[}none@r{|}minimal@r{|}hosted@r{|}semihost@r{]} +--printf=@r{[}d@r{|}f@r{|}l@r{|}i@r{|}m@r{]} --scanf=@r{[}d@r{|}f@r{|}l@r{|}i@r{|}m@r{]}} + @item Code Generation Options @xref{Code Gen Options,,Options for Code Generation Conventions}. @gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @@ -20264,6 +20270,69 @@ such a suffix. @end table +@node Picolibc Options +@section Options for use with Picolibc +@cindex picolibc options +@cindex options, picolibc + +These options control compilation and linking when using picolibc: + +@table @gcctabopt +@opindex oslib +@item --oslib=@var{library} +Search the library named @var{library} after the C library, permitting +symbols undefined by the C library to be defined by this library. The +C library, libgcc and this library are placed between +@option{--start-group} and @option{--end-group} flags so that each can +refer to symbols in the others. For many targets, picolibc provides a +@samp{semihost} variant (specified with @option{--oslib=semihost}) +which provides enough basic OS functionality to support console and +file I/O when run in an emulator or when using an in-circuit debugger. + +@opindex crt0 +@item --crt0=@r{[}none@r{|}minimal@r{|}hosted@r{|}semihost@r{]} +Replace the default @file{crt0.o} name with +@file{crt0-@var{variant}.o}. The @samp{none} variant provides no +startup code at all, allowing the user to supply their +own. @samp{minimal} performs basic memory setup but does not invoke +any constructors. When no @option{-crt0} option is provided, the +default initialization code adds calls to all +constructors. @samp{hosted} adds a call to @code{exit} when +@code{main} returns. @samp{semihost} accesses a command line parameter +supplied via the semihosting interface and splits that into arguments +at whitespace boundaries, passing the resulting array of strings to +main in @code{argc} and @code{argv}. On some targets, including +aarch64, arc, arm, loongarch, m68k, riscv, super-h and x86, +@samp{semihost} also traps hardware exceptions and prints information +to the console. Note that @option{--crt0=semihost} depends upon APIs +provided by @option{--oslib=semihost}. + +@opindex printf +@item --printf=@r{[}d@r{|}f@r{|}l@r{|}i@r{|}m@r{]} +Select the printf variant. Picolibc provides five different printf +variants which offer decreasing levels of functionality along with +decreasing code size. @samp{d} is the default level, offering full C17 +and POSIX.1-2024 conformance. @samp{f} provides the same feature set, +but supports @code{float} values instead of @code{double} which are +passed using the @code{printf_float} macro. @samp{l} elides all +floating point and POSIX positional parameter support. @samp{i} limits +integers to those no larger than @code{long}. @samp{m} removes support +for most formatting options including width and precision. The formats +and arguments are still parsed correctly, but output does not respect +those parameters. + +@opindex scanf +@item --scanf=@r{[}d@r{|}f@r{|}l@r{|}i@r{|}m@r{]} +Select the scanf variant. Picolibc provides five different scanf +variants which offer decreasing levels of functionality along with +decreasing code size. @samp{d} is the default level, offering full C17 +and POSIX.1-2024 conformance. @samp{f} removes support for +@code{double} values. @samp{l} elides all floating point +support. @samp{i} limits integers to those no larger than +@code{long}. @samp{m} removes support for @code{%[} conversion specifiers. + +@end table + @node Code Gen Options @section Options for Code Generation Conventions @cindex code generation conventions diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 19b8907c0d7c..4a6aa7bfa4d0 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -188,6 +188,14 @@ give to GCC into options for GCC to pass to the CPP@. Do not define this macro if it does not need to do anything. @end defmac +@defmac LIBC_CPP_SPEC +A C string constant which is appended to the value of +@code{CPP_SPEC}. @code{LIBC_CPP_SPEC} is intended to depend upon the +C library in use. + +Do not define this macro if it does not need to do anything. +@end defmac + @defmac CPLUSPLUS_CPP_SPEC This macro is just like @code{CPP_SPEC}, but is used for C++, rather than C@. If you do not define this macro, then the value of @@ -254,6 +262,14 @@ give to GCC into options for GCC to pass to the linker. Do not define this macro if it does not need to do anything. @end defmac +@defmac LIBC_LINK_SPEC +A C string constant which is appended to the value of +@code{LINK_SPEC}. @code{LIBC_LINK_SPEC} is intended to depend upon the +C library in use. + +Do not define this macro if it does not need to do anything. +@end defmac + @defmac LIB_SPEC Another C string constant used much like @code{LINK_SPEC}. The difference between the two is that @code{LIB_SPEC} is used at the end of the diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index b755ee1f6d4c..274bb899d0cb 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -188,6 +188,14 @@ give to GCC into options for GCC to pass to the CPP@. Do not define this macro if it does not need to do anything. @end defmac +@defmac LIBC_CPP_SPEC +A C string constant which is appended to the value of +@code{CPP_SPEC}. @code{LIBC_CPP_SPEC} is intended to depend upon the +C library in use. + +Do not define this macro if it does not need to do anything. +@end defmac + @defmac CPLUSPLUS_CPP_SPEC This macro is just like @code{CPP_SPEC}, but is used for C++, rather than C@. If you do not define this macro, then the value of @@ -254,6 +262,14 @@ give to GCC into options for GCC to pass to the linker. Do not define this macro if it does not need to do anything. @end defmac +@defmac LIBC_LINK_SPEC +A C string constant which is appended to the value of +@code{LINK_SPEC}. @code{LIBC_LINK_SPEC} is intended to depend upon the +C library in use. + +Do not define this macro if it does not need to do anything. +@end defmac + @defmac LIB_SPEC Another C string constant used much like @code{LINK_SPEC}. The difference between the two is that @code{LIB_SPEC} is used at the end of the diff --git a/gcc/gcc.cc b/gcc/gcc.cc index 6b6ad86c81b6..d63e863d2bef 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -727,6 +727,13 @@ proper position among the other output files. */ #define CPP_SPEC "" #endif +/* libc can define LIBC_CPP_SPEC to provide extra args to the C preprocessor + or extra switch-translations. */ + +#ifndef LIBC_CPP_SPEC +#define LIBC_CPP_SPEC "" +#endif + /* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and cc1plus or extra switch-translations. The OS_CC1_SPEC is appended to CC1_SPEC in the initialization of cc1_spec. */ @@ -752,6 +759,12 @@ proper position among the other output files. */ #define LINK_SPEC "" #endif +/* libc can define LIBC_LINK_SPEC to provide extra args to the linker + or extra switch-translations. */ +#ifndef LIBC_LINK_SPEC +#define LIBC_LINK_SPEC "" +#endif + /* config.h can define LIB_SPEC to override the default libraries. */ #ifndef LIB_SPEC #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" @@ -1212,14 +1225,14 @@ proper position among the other output files. */ static const char *asm_debug = ASM_DEBUG_SPEC; static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC; -static const char *cpp_spec = CPP_SPEC; +static const char *cpp_spec = CPP_SPEC LIBC_CPP_SPEC; static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC; static const char *cc1plus_spec = CC1PLUS_SPEC; static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC; static const char *link_ssp_spec = LINK_SSP_SPEC; static const char *asm_spec = ASM_SPEC; static const char *asm_final_spec = ASM_FINAL_SPEC; -static const char *link_spec = LINK_SPEC; +static const char *link_spec = LINK_SPEC LIBC_LINK_SPEC; static const char *lib_spec = LIB_SPEC; static const char *link_gomp_spec = ""; static const char *libgcc_spec = LIBGCC_SPEC;
