cancel
Showing results for 
Search instead for 
Did you mean: 

Where is the .a file for the default printf family?

PHolt.1
Senior III

I believe it is in libc.a or some such, but I can't see the config in Cube (32F417) and gradually renaming all candidate files in c:\st\... has failed to locate it (by hopefully throwing up an error).

The project is in c:\xxxxxx\project1 but this library is a compiled one, with no .c source supplied, so it lives in c:\st\ where a new version gets loaded with each Cube installation.

The linker invocation is

arm-none-eabi-g++ -o "XXXXXX.elf" @"objects.list"  -mcpu=cortex-m4 -T"C:\XXXXXX\Project1\LinkerScript.ld" --specs=nosys.specs -Wl,-Map="XXXXXX.map" -Wl,--gc-sections -static -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group

and the Cube settings are

0693W00000QM4FmQAL.pngBackground: I need to replace some symbols in there (with objcopy) because the printf, if used for float or long, is calling a malloc and then some mutex functions, but the mutex functions are just empty. But they were not compiled as "weak" so I get duplicate symbol linker errors.

I think I found the C source for this printf, which closely resembles what I found stepping through the assembler, but I can't tell which options it was compiled with

https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/stdio/vfprintf.c;h=6a198e2c657e8cf44b720c8bec76b1121921a42d;hb=HEAD#l866

17 REPLIES 17

Apt to be an object bound into a library.

If I were fishing I'd be looking with objcopy or fromelf type tools, to disassemble / decompose the libraries.

Grep though the libraries directories.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
PHolt.1
Senior III

There must be a better way... It is probably one of these, but where in Cube is the config for which one?

0693W00000QM4lOQAT.png 

Then, when I have edited it to weaken the names of those empty functions, I need to put the edited copy of it somewhere, but I don't want to put it back in the same place because the next install of Cube will overwrite it.

Bob S
Principal

If you need to "replace" functions that exist in the libraries, you should be able to create your own version of those functions and link them to your code. For example, if you create your own vfprintf.c the linker will find those functions in your source and never go looking in them in the various libc.a libraries. Likewise the mutex functions. Doesn't matter if the library versions were compiled as "weak" or not. I've done this with all the printf functions - none of them come from libc.a or nano_libc.a.

[edit: or am I missing something in your original post?]

PHolt.1
Senior III

Thank you.

So you are saying that if the compiled printf is calling __retarget_lock_acquire, and __retarget_lock_acquire is inside the same library as printf (I am not sure it is actually but have no way of finding it anyway) then if I knock up a .c file containing that function __retarget_lock_acquire, it should just work?

That I understand, but it doesn't work. I get a duplicate symbol.

Lots of people have been up this path, and ended up using objcopy etc to weaken or rename those symbols, but of course they needed to know which actual file is used.

And the actual lib file used varies according to which of the options in my first post is selected. No idea where the rules are for that.

And to make life even more interesting, I have to machines, same Cube project, and on one of them I had to add -u _printf_float under linker options, to avoid a warning from the use of a %7.2 in a printf...

>>There must be a better way...

Does the .MAP file or linker hint when outputting verbosely?

Usually such things identify the source of sub-components pulled in, certainly does in all the tools I've even written. Should also be in the debug information too, often down to the source file and line numbers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

> I am not sure it is actually but have no way of finding it anyway

Look in the link command line for --specs=nano.specs 

The nano.specs is a file somewhere in the toolchain library dir, it specifies the actual library and various options.

Next, look at .... plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.../tools/arm-none-eabi/include/newlib-nano/newlib.h

This contains the configuration options used to build the newlib-nano in the toolchain.

Including the infamous _RETARGETABLE_LOCKING and _NANO_FORMATTED_IO

The GNU link also has a way to "wrap" any library function into your own wrapper. (IIRC, Mr. Nadler uses this somewhere in his newlib glue).

PHolt.1
Senior III

I found this under C/C++ Buil / Settings / Linker /

Command g++

-mcpu=cortex-m4 -T"C:\XXXXXX\Project1\LinkerScript.ld" --specs=nosys.specs -Wl,-Map="${BuildArtifactFileBaseName}.map" -Wl,--gc-sections -static -u _printf_float -mfpu=fpv4-

In c:\ST\...\plugins\... I find

com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127

under lib I find0693W00000QM6JWQA1.png 

and under lib I find newlib.h which is full of interesting #defines like

#define _RETARGETABLE_LOCKING 1

but all this stuff has already been compiled, and I have no sources (except that one from year 1990 which looks pretty similar, right down to using same mutex function call names, 32 years later!).

Also stdio.h is in there.

I see no way to alter any of the symbols already in the libs.

Note I am not using newlib-nano, due to lack of support for uint64 and some thread-safety issues. I am using standard C.

Currently I am investigating a linker (LD) option for suppressing the duplicate symbol warning on specified symbols (have not yet found one) but I have no way of knowing whether I will end up getting my version or the library version. Probably the latter, since it is linked second?

This could be a big job. And that assumes I find the right .a file. I did a string dump of that libc.a and it contains all the printf versions and a load of other stuff. It also contains the mutex functions seen while stepping through printf and malloc etc

 __retarget_lock_init __retarget_lock_init_recursive __retarget_lock_close __retarget_lock_close_recursive __retarget_lock_acquire __retarget_lock_acquire_recursive __retarget_lock_try_acquire __retarget_lock_try_acquire_recursive __retarget_lock_release __retarget_lock_release_recursive __lock___arc4random_mutex __lock___dd_hash_mutex __lock___tz_mutex __lock___env_recursive_mutex __lock___malloc_recursive_mutex __lock___at_quick_exit_mutex __lock___atexit_recursive_mutex __lock___sfp_recursive_mutex __lock___sinit_recursive_mutex

and probably all of those need to be replaced according to this

https://gist.github.com/thomask77/3a2d54a482c294beec5d87730e163bdd

But that still leaves me with the duplicate symbol errors.

> ... [two] machines, same Cube project

Then something is different. But that is (probably) a distraction.

The suplicate symbols when you create your own lock functions is interesting and unexpected (by me, anyway).

What happens if you create, say, "myprintf.c" that contains:

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h> 
 
int printf( char *pstr, size_t len, const char *pformat, ... )
{
   (void)pstr;   // same as UNUSED(pstr)
   (void)pformat;
 
   return( len );
}

And if you use fprintf() then maybe also a dummy version of that. Then add that to your build. Do you still get duplicate symbols? If you don't, then it might be easier/quicker to just add a 3rd party non-malloc printf library to your project, rather than all this work to modify your library files - work that you will need to apply again if/when you ever change compiler versions. Customizing the library BINARY files is a recipe for disaster in my book. Customizing and re-compiling the library from source is a much better alternative, though in this case not as good as using a different printf() implementation (IMHO).

Search the forums (yeah, I know, yuck) for printf libraries. I have a bunch of links at work, but I cannot access them right now.

PHolt.1
Senior III

I have apparently managed to use objcopy to weaken the list of symbols involved, according to a dump from objdump.

Now the Q is where to put the modified library. If I just replace the one in c:\ST\.... it will get overwritten next time Cube is installed.