RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Sunday, November 02, 2014 4:34 PM Sorry for the late reply, I was on vacation, and then I meant to flesh out a suitable solution for the macro/hook problem to test it, but the more I think about it, the more questions arise how this is best structured... No problem, I'm pretty busy myself with other stuff as well. First, the interface of your hook: you say it returns a bool, but that bool is not used. Indeed. I just though it could be used later but since it's an internal interface it could be removed for now and added later. You leave the case to fall through to the default case, thus emitting the expression unchanged. For my purposes, I have to change the expression. Oh yes my apologize. The hook should return the next expression. Note how my original patch had: + exp = copy_node (exp); + CALL_EXPR_FN (exp) = build_addr (decl, current_function_decl); I don't think changing the existing expression destructively is safe, so the return value should be the - possibly changed - expression. You can just explain in the hook description that this return value may be changed and/or additional target-specific output may be emitted. Agreed. The auto-float-io option description dos not match what I intended the hook to do on the avr. The idea was to have standard behaviour as default, i.e. printf knows about float, and have the hook change the function name to the integer-specific function if the arguments don't mention float and the function is not a v* function. Changing the default to auto-float-io should be ok. All we need is a way to build newlib without this option since newlib contains some call to vprintf and this would define the _printf_float symbol (and thus pulling code to printf float) in any program using newlib. Having the default to be off would ease the transition. It would be possible to add the -fno-auto-float-io switch automatically in newlib when gcc is detected to be recent enough but then compiling old newlib with a recent gcc would always pull support for printing float values. So, if we want to have a versatile hook and describe the option specifically, it should be a target option. OTOH, that complicate the implementation of a generic hook even more... Well the hook doesn't have to be different, just the default (auto Vs no auto). Isn't it possible to define different default value for different backend? targhooks.c is not entirely target-independent code, so on one level we could say it's OK to customize it with macros, and we don't want to stuff the target vector with a gazillion settings that only very few targets use, but OTOH, if one target has multiple libraries, it might want multile variants of this hook. In fact, having sub-hooks for that hook wouldn't work if they were POD-kind hooks, and way overcomplicate the target if they weren't... [SNIP explanation of how to do it with hook with template] This all look complicated when in fact what we want is C target hook that can be invoked from the middle end. Couldn't we use some kind of weak symbol so that when no C library is linked in it compiles but nothing happens? Thanks for all your comments Joern. Much appreciated. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 24 October 2014 09:06, Thomas Preud'homme thomas.preudho...@arm.com wrote: From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf Of Joseph S. Myers I'm not clear if you're proposing such a patch for review, but note: Yep but not yet for inclusion as I'm waiting to see if this would suit the use case of avr people. Sorry for the late reply, I was on vacation, and then I meant to flesh out a suitable solution for the macro/hook problem to test it, but the more I think about it, the more questions arise how this is best structured... First, the interface of your hook: you say it returns a bool, but that bool is not used. You leave the case to fall through to the default case, thus emitting the expression unchanged. For my purposes, I have to change the expression. Note how my original patch had: + exp = copy_node (exp); + CALL_EXPR_FN (exp) = build_addr (decl, current_function_decl); I don't think changing the existing expression destructively is safe, so the return value should be the - possibly changed - expression. You can just explain in the hook description that this return value may be changed and/or additional target-specific output may be emitted. The auto-float-io option description dos not match what I intended the hook to do on the avr. The idea was to have standard behaviour as default, i.e. printf knows about float, and have the hook change the function name to the integer-specific function if the arguments don't mention float and the function is not a v* function. So, if we want to have a versatile hook and describe the option specifically, it should be a target option. OTOH, that complicate the implementation of a generic hook even more... (a) you mean DEF_EXT_LIB_BUILTIN (since asprintf and vasprintf aren't in ISO C); Ok. (b) please don't add new target macros such as CUSTOM_STDI_WEAK_SYM_PATTERN and CUSTOM_STDO_WEAK_SYM_PATTERN (if something is defined in tm_defines and used in architecture- independent code, it's effectively a target macro), find a way to implement these as hooks instead. targhooks.c is not entirely target-independent code, so on one level we could say it's OK to customize it with macros, and we don't want to stuff the target vector with a gazillion settings that only very few targets use, but OTOH, if one target has multiple libraries, it might want multile variants of this hook. In fact, having sub-hooks for that hook wouldn't work if they were POD-kind hooks, and way overcomplicate the target if they weren't... Considering we mean to move to C++, making the hook a template seems the proper thing to do. Prima facie I would say it should be templated on the two strings that you want to use. However, C++ won't allow to use string literals as template parameters. So you need to stuff the strings as return values into class member functions. Which means that there has to be a class definition somewhere in tm.h ... which, unfortunately, we can't expand in the same macro that is used to assigning the function instantiation to the target vector element initializer, because you can't have a class definition in a template argument, nor can you have a statement expression outside of functions. So we need two macros, one to define the class, one to provide the function pointer for the target vector element. To illustrate, here are a few snippets of code that do TemPlated Printing of input/output string, in parts meant model code for hook(?) include file, builtins.c:expand_builtin code, and target vector (hook) setting: == tpp.h == extern C void printf (const char *fmt, ...); templatetypename t void print_str (void) { t dummy; printf (%s\n, dummy.in()); printf (%s\n, dummy.out()); } #define PRINT_STR_DEF(S1,S2) \ class __FILE__##inout##S1##S2\ { \ public: \ const char *in (void) { return #S1; } \ const char *out (void) { return #S2; } \ }; #define PRINT_STR(S1,S2) print_str__FILE__##inout##S1##S2 extern void (*fp) (void); == tpp-exp.cc == #include tpp.h int main (void) { (*fp)(); return 0; } == tpp-tv.cc == #include tpp.h PRINT_STR_DEF(scanf,printf) void (*fp) (void) = PRINT_STR(scanf,printf); Now, are we actually OK with having a template in an include file? I think C++11 has extern templates, but then, that's probably too new for our purposes. Would we want to use an existing include file, or a new special-purpose one? Also, that '__FILE__' is not actually expanded - I think we have to hand to through some more macro invocations to expand it. And then the expansion will cause trouble with quotes and the dot from the filename... But how should clashes between multiple such classes be avoided? That would happen if your hook is actually a wrapper to use different template instantiations of the generic templated hook depending on the subtarget - should the port writer use namespaces there?
RE: selective linking of floating point support for *printf / *scanf
From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf Of Joseph S. Myers I'm not clear if you're proposing such a patch for review, but note: Yep but not yet for inclusion as I'm waiting to see if this would suit the use case of avr people. (a) you mean DEF_EXT_LIB_BUILTIN (since asprintf and vasprintf aren't in ISO C); Ok. (b) please don't add new target macros such as CUSTOM_STDI_WEAK_SYM_PATTERN and CUSTOM_STDO_WEAK_SYM_PATTERN (if something is defined in tm_defines and used in architecture- independent code, it's effectively a target macro), find a way to implement these as hooks instead. Oh right, indeed. I didn't realize. Thanks for the review. Joern feel free to give your opinion about whether such an approach would be alright for you. Best regards, Thomas
RE: selective linking of floating point support for *printf / *scanf
Hi all, I changed the target hook somehow so that more code run in the backend since depending on the target (avr-libc Vs newlib) two different schemes are used: printf - iprintf renaming or defining _printf_float as a global symbol. I thus renamed the target hook to match such a usage. The proposed patch is attached to this email (otherwise it would be mangled). Joern, would such a scheme be ok for you? You could add another function in targhooks.c for doing the renaming as it could be useful for other targets. Best regards, Thomas gcc32rm-191.4.1.diff Description: Binary data
RE: selective linking of floating point support for *printf / *scanf
On Thu, 23 Oct 2014, Thomas Preud'homme wrote: Hi all, I changed the target hook somehow so that more code run in the backend since depending on the target (avr-libc Vs newlib) two different schemes are used: printf - iprintf renaming or defining _printf_float as a global symbol. I thus renamed the target hook to match such a usage. The proposed patch is attached to this email (otherwise it would be mangled). I'm not clear if you're proposing such a patch for review, but note: (a) you mean DEF_EXT_LIB_BUILTIN (since asprintf and vasprintf aren't in ISO C); (b) please don't add new target macros such as CUSTOM_STDI_WEAK_SYM_PATTERN and CUSTOM_STDO_WEAK_SYM_PATTERN (if something is defined in tm_defines and used in architecture-independent code, it's effectively a target macro), find a way to implement these as hooks instead. -- Joseph S. Myers jos...@codesourcery.com
Re: RFD: selective linking of floating point support for *printf / *scanf
On 18 August 2014 11:35, Joey Ye joey.ye...@gmail.com wrote: 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? No, this is completely besides the point. avr-libc has had manual printf variant selection (requiring -u and -l options to the linker) for quite some time. But this requirement for manual selection means that lots of dejagnu tests fail; it also means that a lot of software fails to work properly out of the box. The point of my patch is to do an automatic selection inasmuch as this is possible with gcc noting where floating point is being used from looking at *printf* / *scanf* calls in isolation and passing the information gained to the linker to figure out which implementation to use.
RE: selective linking of floating point support for *printf / *scanf
From: Joseph S. Myers [mailto:jos...@codesourcery.com] Sent: Tuesday, September 02, 2014 11:29 PM Identifiers beginning with a single underscore are reserved with file scope. This means an application cannot provide an external definition of them, because such an external definition would have file scope. So it's fine for the implementation to define such identifiers and use them in the implementation of standard functions. Ah yes, I mistook file scope with file scope with internal linkage. So then there shouldn't be any problem since _printf_float and _scanf_float are only used for external linkage, no macro refer to them. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 2 September 2014 16:28, Joseph S. Myers jos...@codesourcery.com wrote: On Tue, 2 Sep 2014, Joey Ye wrote: Apparently newlib is not following this specification very well, as there are symbols like _abc_r defined every where in current newlib. I am not implying the spec should not be followed, but is newlib designed to have a loose spec for the single underscore? Identifiers beginning with a single underscore are reserved with file scope. This means an application cannot provide an external definition of them, because such an external definition would have file scope. So it's fine for the implementation to define such identifiers and use them in the implementation of standard functions. Hmm, this trows up another question how in GNU C, extensions interact with the putatively unchanged parts of the standard. If a user program defines an assembler name for a global function which is different from the name used in the source code, is that assembler name used at file scope? It would seem to me it's only used at global/link scope. As such, is the use of _[a-z].* as assembly names then part of the user namespace?
Re: selective linking of floating point support for *printf / *scanf
On Wed, 3 Sep 2014, Joern Rennecke wrote: On 2 September 2014 16:28, Joseph S. Myers jos...@codesourcery.com wrote: On Tue, 2 Sep 2014, Joey Ye wrote: Apparently newlib is not following this specification very well, as there are symbols like _abc_r defined every where in current newlib. I am not implying the spec should not be followed, but is newlib designed to have a loose spec for the single underscore? Identifiers beginning with a single underscore are reserved with file scope. This means an application cannot provide an external definition of them, because such an external definition would have file scope. So it's fine for the implementation to define such identifiers and use them in the implementation of standard functions. Hmm, this trows up another question how in GNU C, extensions interact with the putatively unchanged parts of the standard. If a user program defines an assembler name for a global function which is different from the name used in the source code, is that assembler name used at file scope? It would seem to me it's only used at global/link scope. As such, is the use of _[a-z].* as assembly names then part of the user namespace? I see no reason a standard header shouldn't be able to define _[a-z] static functions at file scope, so I think it should be presumed that such names as assembly names are part of the implementation namespace. That's certainly the case for names such as _a.1 that GCC can generate for block-scope static variables called _a: if you generate such assembler names yourself, you risk conflicting with ones generated by GCC for block-scope statics. -- Joseph S. Myers jos...@codesourcery.com
Re: selective linking of floating point support for *printf / *scanf
On Sat, Aug 30, 2014 at 12:26 PM, Thomas Preud'homme thomas.preudho...@arm.com wrote: From: Grissiom [mailto:chaos.pro...@gmail.com] Sent: Friday, August 29, 2014 11:51 PM Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. Mmmh indeed. I checked C99 and section 7.1.3 paragraph 1 third clause states: All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. Next clause express how single underscore not followed by a capital letter is reserved: All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Apparently newlib is not following this specification very well, as there are symbols like _abc_r defined every where in current newlib. I am not implying the spec should not be followed, but is newlib designed to have a loose spec for the single underscore? - Joey Since here we are talking about linkage, _printf_float is not safe according to the standard. Sigh. Ok I need to think about it. Thank you all for pointing out the problem with the current scheme. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 09/02/2014 08:33 AM, Joey Ye wrote: On Sat, Aug 30, 2014 at 12:26 PM, Thomas Preud'homme thomas.preudho...@arm.com wrote: From: Grissiom [mailto:chaos.pro...@gmail.com] Sent: Friday, August 29, 2014 11:51 PM Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. Mmmh indeed. I checked C99 and section 7.1.3 paragraph 1 third clause states: All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. Next clause express how single underscore not followed by a capital letter is reserved: All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Apparently newlib is not following this specification very well, as there are symbols like _abc_r defined every where in current newlib. newlib is part of the implementation, so it's allowed to do this. Andrew.
Re: selective linking of floating point support for *printf / *scanf
On Tue, 2 Sep 2014, Joey Ye wrote: Apparently newlib is not following this specification very well, as there are symbols like _abc_r defined every where in current newlib. I am not implying the spec should not be followed, but is newlib designed to have a loose spec for the single underscore? Identifiers beginning with a single underscore are reserved with file scope. This means an application cannot provide an external definition of them, because such an external definition would have file scope. So it's fine for the implementation to define such identifiers and use them in the implementation of standard functions. You do still need to be more careful with them than with _[_A-Z]* identifiers. For example, you can't do #define standard_function(x) _standard_function(x) in your libc headers, because the user's application could legitimately define a variable called _standard_function at block scope, then try to call standard_function within that block. So in general it's safer to use the double underscore in the implementation, unless there is some clear reason to use the single underscore. -- Joseph S. Myers jos...@codesourcery.com
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Thursday, August 28, 2014 9:48 PM Right now I'm having trouble to define stdio_altname in newlib-c.c since this would require it to be a C target hook but such a hook cannot be called from middle end. Hmm, yes, this is not exactly C specific. Although printf / scanf are part of the C library, other languages may use the C runtime library. Likewise, builtin functions are not considered exclusive to C. So it should be a general target hook, in a target-, but not language-specific file. Ok, it still feels to me this should not be target specific but since there is no other way I'll keep it this way and create a utility function that do the detection about whether float support is needed so as to factorize this part between all targets. So are you saying you are stuck with printf_float? It's not printf_float but _printf_float. I was told double underscore is only necessary with old toolchain as they might add a leading underscore. So _printf_float should not pose any kind of problem. It's been reviewed by many people, including newlib maintainers and we had this symbol for quite some time in our own toolchain without anybody raising any concern about it. But at least for iprintf and friends, the only requirement is that newlib provides a definition. There is no need for gcc to use these symbols to implement ISO C *printf functions. Right. The user writing including stdio.h, using iprintf, and not defining is one thing; in this case, the expectation is that the definition comes from newlib. However, when the user uses printf, (s)he is still entitles to define a function iprintf and is entitled to expect that these don't interfere with each other; hence, gcc should not emit calls to iprintf when it sees a call to printf; using a name in the implementation namespace solves this issue. However, defining this in the same file as iprintf is not safe, as then you'd pull in the iprintf definition as well. Even if it's a weak alias, what if the user defined a weak iprintf? Ah yes, good point. Well I can do without function renaming then, we just need to define _printf_float. That's enough to pull in float support. About the extra call instruction this creates, we believe it's not a problem in practice as printf is not such a sensitive function that one instruction makes a difference for performance or size. Then maybe we need to think at a better name for the hook as for newlib we will not change the function name but just define a global symbol. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 08/29/2014 12:04 AM, Thomas Preud'homme wrote: So are you saying you are stuck with printf_float? It's not printf_float but _printf_float. I was told double underscore is only necessary with old toolchain as they might add a leading underscore. So _printf_float should not pose any kind of problem. Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: selective linking of floating point support for *printf / *scanf
On 08/29/2014 09:51 AM, Grissiom wrote: Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. You mean _[_a-z] (lower case) is the namespace reserved for implementation, right? No, I spoke correctly. The namespace reserved for the implementation is all double underscores, and all single underscore followed by a capital. Single underscore followed by a lower case is NOT reserved for the implementation, and is therefore free for use by the user, and therefore the implementation must not interfere with the user's use of that namespace. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: selective linking of floating point support for *printf / *scanf
On 08/29/2014 10:03 AM, Eric Blake wrote: On 08/29/2014 09:51 AM, Grissiom wrote: Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. You mean _[_a-z] (lower case) is the namespace reserved for implementation, right? No, I spoke correctly. The namespace reserved for the implementation is all double underscores, and all single underscore followed by a capital. Single underscore followed by a lower case is NOT reserved for the implementation, and is therefore free for use by the user, and therefore the implementation must not interfere with the user's use of that namespace. Quoting POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm The following identifiers are reserved regardless of the inclusion of headers: 1. With the exception of identifiers beginning with the prefix _POSIX_, all identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use by the implementation. 2. All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary identifier and tag name spaces. ... Of course, that list feels a bit too restrictive in light of existing standardized uses of underscore followed by capital. such as _Bool and _Exit in C99; and C11 has introduced even more things like _Noreturn. But the REASON that C has been able to extend the language and add more keywords beginning with underscore-capital is precisely because those names were reserved for the implementation, not the user, so it can't break any user code. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
RE: selective linking of floating point support for *printf / *scanf
From: Grissiom [mailto:chaos.pro...@gmail.com] Sent: Friday, August 29, 2014 11:51 PM Yes, it does. The namespace reserved for the implementation is _[_A-Z]. The namespace _[a-z] is still available for the user. Which means the user can declare their own _printf_float, and WE (as the implementation) MUST NOT INTERFERE with it. Since WE are the implementation, we should use the namespace reserved for us, namely __printf_float. Mmmh indeed. I checked C99 and section 7.1.3 paragraph 1 third clause states: All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. Next clause express how single underscore not followed by a capital letter is reserved: All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Since here we are talking about linkage, _printf_float is not safe according to the standard. Sigh. Ok I need to think about it. Thank you all for pointing out the problem with the current scheme. Best regards, Thomas
RE: selective linking of floating point support for *printf / *scanf
-Original Message- From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf Of Thomas Preud'homme Sent: Saturday, August 30, 2014 12:27 PM Mmmh indeed. I checked C99 and section 7.1.3 paragraph 1 third clause states: All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. Next clause express how single underscore not followed by a capital letter is reserved: All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Since here we are talking about linkage, _printf_float is not safe according to the standard. Sorry for restating what Eric Blake already said, I didn't see his message at first as it was (surprisingly) classified as spam. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 28 August 2014 06:30, Thomas Preud'homme thomas.preudho...@arm.com wrote: Yes. I'll have to adjust the avr hook that it'll leave the v*printf / v*scanf functions alone - at least by default / for ISO C behaviour - but it'll give me an easy way to add a switch to tweak the behaviour. Or maybe we can use a -f option to select the v*printf / v*scanf default and put the a stdio_altname__int_ target hook in targhooks.c, to be shared by all configs that want an __int_ prefix. Are you aware of other C libraries that would benefit from such a default No. I haven't been looking for it, either. (newlib wouldn't)? Well, to avoid namespace pollution, you need a different name used by the compiler than iprintf - see below. Right now I'm having trouble to define stdio_altname in newlib-c.c since this would require it to be a C target hook but such a hook cannot be called from middle end. Hmm, yes, this is not exactly C specific. Although printf / scanf are part of the C library, other languages may use the C runtime library. Likewise, builtin functions are not considered exclusive to C. So it should be a general target hook, in a target-, but not language-specific file. FWIW, to safely shift the symbol into the implementation namespace you need a prefix that starts with two underbars or one underbar and a capital letter. Or use some funny non-standard character in the symbol - but that's asking for more portability issues. For references made automatically by gcc, it's a good idea not to impinge on the application namespace. I'll consider about renaming the symbol but we've been using this one for some time in our toolchain so it might not be possible to change. So are you saying you are stuck with printf_float? But at least for iprintf and friends, the only requirement is that newlib provides a definition. There is no need for gcc to use these symbols to implement ISO C *printf functions. An application might use printf from stdio.h, but define its own functions iprintf, printf_float and _printf_float. Therefore, it's a good idea to put the definition of newlib's iprintf in a separate file from __int_printf. Having essentialy the same contents, but defining a different symbol, and let the linker match them up to the definition. I'm confused here. Why would we have a __int_printf? Right now we only have iprintf as an alias to printf, _printf_float being a weakly defined function called from printf for the float support. The user writing including stdio.h, using iprintf, and not defining is one thing; in this case, the expectation is that the definition comes from newlib. However, when the user uses printf, (s)he is still entitles to define a function iprintf and is entitled to expect that these don't interfere with each other; hence, gcc should not emit calls to iprintf when it sees a call to printf; using a name in the implementation namespace solves this issue. However, defining this in the same file as iprintf is not safe, as then you'd pull in the iprintf definition as well. Even if it's a weak alias, what if the user defined a weak iprintf?
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Tuesday, August 26, 2014 6:44 PM Due to the library order defined in the specs, the float-enbled printf definition will be picked up from libprintf_flt.a . It seems to me that it relies heavily on how symbol resolution works. If I understand correctly all undefined symbols (for instance __int_printf) in object files are processed first. Symbols definition are search in the order in which libraries are given in the command line (this part seems pretty reliable since it's at least documented in ld's manual). When doing so, if a symbol definition reference an undefined symbol (like __int_printf referencing printf), it is left aside until all undefined symbol from object files have been processed. At some point printf from object file will be processed and will pull the printf with float support since it's the first one encountered. Then the undefined reference discovered when pulling symbols from library will be processed and since printf with float was already pulled in that's the one being used. Is this behavior the same for all linker? It sounds like a reasonable algorithm but I don't know well the variety of linkers out there. That testcase is not valid. You'd to use one of the v*printf functions. Solving the general problem for these is not computable; for specific cases, it would be possible, but at the cost of varying degrees of complexity. So I let this for manual selection: it's not handled with the calls.stdio_altname hook, and you have to use a special link line to use the integer-only implementations. Well, if desired, a spec change could give an option to do that. Right, my bad, no problem indeed. What general problem are you referring too that is not solved with this patch? That can be implemented with suitable *newlib*.[ch] files that are selected in config.gcc, akin to newlib-stdint.h and glibc-c.c . Absolutely, that was the approach I followed in my own patch. Well, all the *printf functions are variadic, and as stated above, your example is invalid. The wildcard are va_list taking functions. You first have to decide what you want to happen with these by default, and what kind of non-default behaviour you'd like to be able to select, and how; than we can talk about if this neeeds any extra infrastructure to implement. Yes my apologize, it was a mistake from me. I'll now do a more thorough testing and report back to you how it works for us. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 27 August 2014 08:02, Thomas Preud'homme thomas.preudho...@arm.com wrote: From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Tuesday, August 26, 2014 6:44 PM Due to the library order defined in the specs, the float-enbled printf definition will be picked up from libprintf_flt.a . It seems to me that it relies heavily on how symbol resolution works. I don't see how it can be any other way. We want to be able to compile translation units individually, and then let the linker sort out if we need the floating point enabled implementation(s), and skip the integer-only ones if so. If I understand correctly all undefined symbols (for instance __int_printf) in object files are processed first. Symbols definition are search in the order in which libraries are given in the command line (this part seems pretty reliable since it's at least documented in ld's manual). When doing so, if a symbol definition reference an undefined symbol (like __int_printf referencing printf), it is left aside until all undefined symbol from object files have been processed. At some point printf from object file will be processed and will pull the printf with float support since it's the first one encountered. Then the undefined reference discovered when pulling symbols from library will be processed and since printf with float was already pulled in that's the one being used. Is this behavior the same for all linker? It sounds like a reasonable algorithm but I don't know well the variety of linkers out there. Well, the part of processing libraries in order is pretty much universal, although there are options to change that behaviour. I'd say you really have to know what you are doing when using these options. Now, to make the __int_printf function entry line up with the printf implementation, I'm relying on GNU AS (gas) linker scripts. That part is unfortunately not so portable, so this trick has to be restricted to targets/configurations that use gas, or another linker (if any) that allows to alphasort the relevant sections. That testcase is not valid. You'd to use one of the v*printf functions. Solving the general problem for these is not computable; for specific cases, it would be possible, but at the cost of varying degrees of complexity. So I let this for manual selection: it's not handled with the calls.stdio_altname hook, and you have to use a special link line to use the integer-only implementations. Well, if desired, a spec change could give an option to do that. Right, my bad, no problem indeed. What general problem are you referring too that is not solved with this patch? The general problem also includes trying to decide definitely if we need a/any floating point enabled implementation(s) in cases with calls of va_list taking functions, (which. while not always, but usually also take the format as a variable), and have no non-va_list calls to decide the matter in favour of needing floating point. The question if any floating-point indicating actual format string and/or(*) va_list arguments reach the v*printf / v*scanf calls is non-trivial and respects functions (in the computability theory sense), hence, this is not computable according to Rice's theorem. (*) Any way you language lawyer it, you can only chip away at the set of programs you can compute the answer for, but can never do it for the whole set.
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Wednesday, August 27, 2014 6:13 PM I don't see how it can be any other way. We want to be able to compile translation units individually, and then let the linker sort out if we need the floating point enabled implementation(s), and skip the integer-only ones if so. Consider the new scheme in newlib when printf calls another function for handling floating point formats. This other function is weakly defined so that it's not pulled by default and printf is effectively integer only. You just need to link with an extra -u option to pull in the float support. Well, the part of processing libraries in order is pretty much universal, although there are options to change that behaviour. I'd say you really have to know what you are doing when using these options. Now, to make the __int_printf function entry line up with the printf implementation, I'm relying on GNU AS (gas) linker scripts. That part is unfortunately not so portable, so this trick has to be restricted to targets/configurations that use gas, or another linker (if any) that allows to alphasort the relevant sections. Yes, I don't see the order of libraries as a problem for portability. I was concerned of the following possible algorithm: __int_printf is processed first and is found in libc. The linker sees that __int_printf needs printf and search for printf according to libraries order and so will find it in the next section. This printf doesn't provide float support. Then the linker proceeds to process the next undefined symbol in the object file that is printf and use the one already found. I concede that such an algorithm looks more convoluted as it implies some form of recursion instead of just having a queue where you put the undefined symbol. Indeed I missed the linker script which is the most obvious problem. The general problem also includes trying to decide definitely if we need a/any floating point enabled implementation(s) in cases with calls of va_list taking functions, (which. while not always, but usually also take the format as a variable), and have no non-va_list calls to decide the matter in favour of needing floating point. The question if any floating-point indicating actual format string and/or(*) va_list arguments reach the v*printf / v*scanf calls is non-trivial and respects functions (in the computability theory sense), hence, this is not computable according to Rice's theorem. (*) Any way you language lawyer it, you can only chip away at the set of programs you can compute the answer for, but can never do it for the whole set. Ok. Of course detecting more cases where an integer version of IO functions would be enough would be nice but I'm already satisfied with the current scheme. I'm wondering what's happening for v*printf: are they only defined in the libc_float? Would you accept a patch that would turn this solution into something also suitable for newlib? For instance we would need to also include v*printf and v*scanf functions into builtin as well. A new switch would also be needed so that compiling newlib doesn't define the _printf_float and _scanf_float symbols because of calls to v*printf and v*scanf functions. I need to check if these calls are made in the same file in which case I could maybe just guard the function call rewriting by a test checking if the caller is itself a builtin. Best regards, Thomas
Re: selective linking of floating point support for *printf / *scanf
On 27 August 2014 11:41, Thomas Preud'homme thomas.preudho...@arm.com wrote: From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Wednesday, August 27, 2014 6:13 PM I don't see how it can be any other way. We want to be able to compile translation units individually, and then let the linker sort out if we need the floating point enabled implementation(s), and skip the integer-only ones if so. Consider the new scheme in newlib when printf calls another function for handling floating point formats. This other function is weakly defined so that it's not pulled by default and printf is effectively integer only. You just need to link with an extra -u option to pull in the float support. Well, my goal was to have the selection be automatic for most use cases. That you can do a manual selection by providing -u / -l arguments to the linker is pretty much a given. Hmm, instead of needing -u you could make gcc spit out definitions of a dummy local symbol to the trigger symbol in question (forcing a non-weak reference), using SET_ASM_OP (assuming it's defined). But you'd still be left with the extra call overhead, increasing code size no matter if float is needed or not. I'm relying on GNU AS (gas) linker scripts. That part is unfortunately not so portable, Oops, of course that should read GNU LD. Ok. Of course detecting more cases where an integer version of IO functions would be enough would be nice but I'm already satisfied with the current scheme. I'm wondering what's happening for v*printf: are they only defined in the libc_float? It's defined in both. The way i wrote the avr gcc specs / avr-libc makefile rules, this will result in the floating point enabled implementation to be used by default. Which makes the gcc test results so much nicer... Would you accept a patch that would turn this solution into something also suitable for newlib? For instance we would need to also include v*printf and v*scanf functions into builtin as well. Yes. I'll have to adjust the avr hook that it'll leave the v*printf / v*scanf functions alone - at least by default / for ISO C behaviour - but it'll give me an easy way to add a switch to tweak the behaviour. Or maybe we can use a -f option to select the v*printf / v*scanf default and put the a stdio_altname__int_ target hook in targhooks.c, to be shared by all configs that want an __int_ prefix. A new switch would also be needed so that compiling newlib doesn't define the _printf_float and _scanf_float symbols because of calls to v*printf and v*scanf functions. I need to check if these calls are made in the same file in which case I could maybe just guard the function call rewriting by a test checking if the caller is itself a builtin. FWIW, to safely shift the symbol into the implementation namespace you need a prefix that starts with two underbars or one underbar and a capital letter. Or use some funny non-standard character in the symbol - but that's asking for more portability issues. For references made automatically by gcc, it's a good idea not to impinge on the application namespace. An application might use printf from stdio.h, but define its own functions iprintf, printf_float and _printf_float. Therefore, it's a good idea to put the definition of newlib's iprintf in a separate file from __int_printf. Having essentialy the same contents, but defining a different symbol, and let the linker match them up to the definition.
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Wednesday, August 27, 2014 7:54 PM Well, my goal was to have the selection be automatic for most use cases. That you can do a manual selection by providing -u / -l arguments to the linker is pretty much a given. Hmm, instead of needing -u you could make gcc spit out definitions of a dummy local symbol to the trigger symbol in question (forcing a non-weak reference), using SET_ASM_OP (assuming it's defined). But you'd still be left with the extra call overhead, increasing code size no matter if float is needed or not. That's indeed the approach I took in my own patch. Yes. I'll have to adjust the avr hook that it'll leave the v*printf / v*scanf functions alone - at least by default / for ISO C behaviour - but it'll give me an easy way to add a switch to tweak the behaviour. Or maybe we can use a -f option to select the v*printf / v*scanf default and put the a stdio_altname__int_ target hook in targhooks.c, to be shared by all configs that want an __int_ prefix. Are you aware of other C libraries that would benefit from such a default (newlib wouldn't)? Right now I'm having trouble to define stdio_altname in newlib-c.c since this would require it to be a C target hook but such a hook cannot be called from middle end. Did I mis(understood|s) something? FWIW, to safely shift the symbol into the implementation namespace you need a prefix that starts with two underbars or one underbar and a capital letter. Or use some funny non-standard character in the symbol - but that's asking for more portability issues. For references made automatically by gcc, it's a good idea not to impinge on the application namespace. I'll consider about renaming the symbol but we've been using this one for some time in our toolchain so it might not be possible to change. An application might use printf from stdio.h, but define its own functions iprintf, printf_float and _printf_float. Therefore, it's a good idea to put the definition of newlib's iprintf in a separate file from __int_printf. Having essentialy the same contents, but defining a different symbol, and let the linker match them up to the definition. I'm confused here. Why would we have a __int_printf? Right now we only have iprintf as an alias to printf, _printf_float being a weakly defined function called from printf for the float support. Best regards, Thomas
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Thursday, August 14, 2014 4:52 PM 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 What happens in the case that a program contains both some printf and __int_printf call? If the undefined printf is resolved first then everything is fine but if it's the other way around and __int_printf is resolved first the printf implementation that will be pulled will not have float support and all the call that needs float support will fail. Did I miss something? 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. I didn't do extensive yet but it seems you miss the case of variadic functions. Consider the example in attachment: two calls to __int_printf will be generated yet my_printf could be called with the format string %f\n. As to the patch it seems to me the macro should be per library, not per backend. Else two backend supporting newlib would need to write the same code twice. I'll also try to think how to support the new scheme for printf with float in newlib. As I said it relies on printf calling _printf_float that is a weak symbol. Previous scheme could pull 2 implementations of printf and consume more size. The problem is that compiling newlib with automatic selection would detect some case where float might be needed (variadic functions) and define _printf_float accordingly. Best regards, Thomas auto-float-io-failure_1.c Description: Binary data
Re: selective linking of floating point support for *printf / *scanf
On 26 August 2014 07:48, Thomas Preud'homme thomas.preudho...@arm.com wrote: What happens in the case that a program contains both some printf and __int_printf call? Due to the library order defined in the specs, the float-enbled printf definition will be picked up from libprintf_flt.a . I didn't do extensive yet but it seems you miss the case of variadic functions. Consider the example in attachment: two calls to __int_printf will be generated yet my_printf could be called with the format string %f\n. That testcase is not valid. You'd to use one of the v*printf functions. Solving the general problem for these is not computable; for specific cases, it would be possible, but at the cost of varying degrees of complexity. So I let this for manual selection: it's not handled with the calls.stdio_altname hook, and you have to use a special link line to use the integer-only implementations. Well, if desired, a spec change could give an option to do that. Another extension possibility in this area is to have the library also provide forwarder stubs for __int_v*printf in libc, so you could use the latter function whenever you deem fit, and the linker will sort out which implementation you get. As to the patch it seems to me the macro should be per library, not per backend. Else two backend supporting newlib would need to write the same code twice. That can be implemented with suitable *newlib*.[ch] files that are selected in config.gcc, akin to newlib-stdint.h and glibc-c.c . I'll also try to think how to support the new scheme for printf with float in newlib. As I said it relies on printf calling _printf_float that is a weak symbol. Previous scheme could pull 2 implementations of printf and consume more size. The problem is that compiling newlib with automatic selection would detect some case where float might be needed (variadic functions) and define _printf_float accordingly. Well, all the *printf functions are variadic, and as stated above, your example is invalid. The wildcard are va_list taking functions. You first have to decide what you want to happen with these by default, and what kind of non-default behaviour you'd like to be able to select, and how; than we can talk about if this neeeds any extra infrastructure to implement.
Re: RFD: selective linking of floating point support for *printf / *scanf
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? Thanks, Joey On Thu, Aug 14, 2014 at 4:52 PM, Joern Rennecke joern.renne...@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 TARGET_ENCODE_SECTION_INFO.
RFD: selective linking of floating point support for *printf / *scanf
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 TARGET_ENCODE_SECTION_INFO.
RE: selective linking of floating point support for *printf / *scanf
From: Joern Rennecke [mailto:joern.renne...@embecosm.com] Sent: Thursday, August 14, 2014 4:52 PM 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. A recent commit in newlib also added a configure option that split the float support into weak functions such that they are not pulled by default. The user then just need to define the symbol for the float support to be pulled in. This allow the user to make the decision at link time rather than compile time. 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. We worked on some similar feature but looking at the format string as I was not aware of the necessity that types of argument match the format string. The result is not very intrusive. However indeed checking the argument works in more cases as it would only fail when a va_list is passed. 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 As said above, we had our own approach which we intended to post now that float support in newlib can be put in weak function (the patch depends on this) but since your patch does not require any change to newlib it might be interesting to follow your approach instead. 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. I'll give your patch a try and see if everything works fine. 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 TARGET_ENCODE_SECTION_INFO. Couldn't this be done as a second step? This is internal detail of GCC and thus it should be fine to go forward with the current patch and change the mechanic later. Best regards, Thomas