RFD: selective linking of floating point support for *printf / *scanf

Joey Ye joey.ye.cc@gmail.com
Mon Aug 18 10:35:00 GMT 2014

Joern, there is https://sourceware.org/ml/newlib/2014/msg00166.html,
which is already in newlib mainline. I think it solves the same issue
in a slight different approach.

Does it work for you?


On Thu, Aug 14, 2014 at 4:52 PM, Joern Rennecke
<joern.rennecke@embecosm.com> wrote:
> For embedded targets with small memories and static linking, the size of
> functions like *printf and their dependencies is painful, particularily for
> targets that need software floating point.
> avr-libc has long had a printf / scanf implementation that by default does not
> include floating point support.  There's a library that can be liked to provide
> the floating-point enabled functions, but the required functions have
> to be pulled
> in manually with -Wl,-u if they are otherwise only referenced from libc, lest
> these symbols got resolved with the integer-only implementations from
> libc itself.
> All in all, a rather unsatisfying state of affairs when trying to run the
> gcc regression test suite.
> Newlib also has an integer-only printf implementation, but in this case,
> the default is the other way round - you have to use functions with nonstandard
> names to use the integer-only implementations.  And a half-hearted approach to
> use this can easily end up with linking in both the integer-only version and the
> floating-point enabled one, resulting in increased executable size instead of
> a saving.
> I think we can do better with integrated compiler/linker support.
> Trying to do a perfect job i of course impossible because of Rice's theorem,
> but it doesn't have to be perfect to be useful.
> Just looking statically at each *printf statement, we can look at the format
> strings and/or the passed arguments.
> Floating point arguments are easier to check for by the compiler than parsing
> the format string.  There is already code that parses the format strings for the
> purpose of warnings, but it would be a somewhat intrusive change to add this
> functionality there, and the information is not available where a variable
> format is used anyway.
> In a standards-conformant application, floating point formats can only be used
> with floating point arguments, so checking for the latter seems most effective.
> So my idea is to make the compile emit special calls when there are no floating
> point arguments.  A library that provides the floating point enabled
> *printf/*scanf
> precedes libc in link order.
> Libc contains the integer-only implementations of *scanf/*printf, in two parts:
> entry points with the special function name, which in the same object file
> also contain a reference to the ordinary function name, and another object file
> with the ordinary symbol and the integer-only implementation.
> Thus, if any application translation unit has pulled in a floating-point enabled
> implementation, this is the one that'll be used.  Otherwise, the integer-only
> one will be used.
> Use of special sections and alphasorting of these in the linker script
> ensures that the integer-only entry points appear in the right place at
> the start of the chosen implementation.
> If vfprintf is used
> I've implemented this for AVR with these commits:
> https://github.com/embecosm/avr-gcc/commit/3b3bfe33fe29b6d29d8fb96e5d57ee025adf7af0
> https://github.com/embecosm/avr-libc/commit/c55eba74838635613c8b80d86a85ed605a79d337
> https://github.com/embecosm/avr-binutils-gdb/commit/72b3a1ea3659577198838a7149c6882a079da403
> Although it could use some more testing, and thought how to best
> introduce the change as to avoid getting broken toolchains when components
> are out-of-sync.
> Now Joerg Wunsch suggested we might want to facto out more pieces, like the
> long long support.  This quickly leads to a combinatorial explosion.
> If we want to support a more modular *printf / *scanf, than maybe a different
> approach is warranted.
> Say, if we could give a symbol and section attribute and/or pragma to individual
> case labels of a switch, and put the different pieces into separate object
> files (maybe with a bit of objcopy massaging).
> The symbols references to trigger the inclusion of the case objects could be
> generated by the gcc backend by processing suitably annotated function calls.
> E.g. we might put something into CALL_FUNCTION_USAGE, or play with

More information about the Newlib mailing list