GCC Weak Symbols

GNU’s GCC has a useful (and perhaps not very well known) feature known as ‘weak symbols’. I first discovered this a while back when building a Linux kernel – however unbeknown to me the Linux kernel makes great use of weak symbols yet the compiler I used did not correctly support them. Rather than a failed build the kernel built fine and even run – I was instead presented with a number of interesting bugs, but more on this later.

In a nutshell weak symbols permit you to define a symbol that doesn’t need to be resolved at link time, i.e. it allows you to tell the compiler that this function may not have a body and that is OK. Furthermore, if later the compiler comes across another symbol with the same name that doesn’t have the weak attribute the original symbol will be overwritten with the stronger symbol (Without getting a multiple defination linker error). And finally you can also use the symbol to determine, at run-time, if such a body exists.

To give you an example of its use let’s refer back to my original bug…
v2.6.27/arch/sh/kernel/cpu/clock.c:

...
void __init __attribute__ ((weak))
arch_init_clk_ops(struct clk_ops **ops, int type)
{
}

This function is part of the architecture specific (SH) code for setting up the various clocks of the device. The function defined above is used to return a structure of clock operations (struct clk_ops) which is later used to register the clock within the kernel. As you can see the function is declared with a weak symbol via the “weak” attribute. Therefore, when built correctly, the function can be overridden.

The design of this part of the kernel is such that generic clock operations are defined in clock.c and can be later overridden via weak symbols by implementations for specific CPU subtypes – for example this function is overriden in the clock-sh7712.c file…
v2.6.27/arch/sh/kernel/cpu/clock-sh7712.c;

...
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
{
...

The function hasn’t been defined as a weak symbol and so will override the weak symbol. In this case the function will provide the caller with the clock operations specific to the SH7712. In this manner the existing generic clock support code has been designed such that it can be easily extended to support future SH subtypes. Likewise weak symbols are used elsewhere in the kernel (since 2.4.0) for similar effect.

Whilst my version of GCC claimed to support weak symbols there was a known GCC bug that prevented this from working correctly. I found that the code would only work correctly if the weak arch_init_clk_ops function had code in it’s body – what was happening was that the compiler was optimising out the function all together (with the -O2 optimisation GCC flag) and resulted in the non-weak symbol not being called (There is a quick hack to fix this which is to use the -fno-unit-at-a-time flag, however this is expected to be removed from GCC in the future.)

It’s always worth looking at the “/Documentation/Changes” file included with the kernel, it contains a list of the tools required and the minimal version of each tool. Just because the kernel builds doesn’t mean that it has built in the way intended by the Linux contributors!

References:

GCC Function Attributes (gnu.org)
GCC Help Mailing List Archive – Discussing weak symbols and optimisation (gnu.org)
Further Discussion of this bug in KGDB – Here (osdir.com) and Here (lkml.org)

[© 2011 embedded-bits.co.uk]

, , , , , , , ,

About Andrew Murray

Andrew is an experienced commercial Linux developer with a first class degree in Software Engineering and is the founder of Embedded Bits Limited. His day-to-day role fulfils his passion for learning and provides him with plenty of embedded Linux experience including kernel and embedded applications development on a wide variety of platforms. He loves to talk about boot time reduction and has performed a number of presentations on the topic at technical conferences - he has also been successful in achieving sub-second cold boot on Linux based products. Feel free to drop him an email at amurray@embedded-bits.co.uk

3 Responses to “GCC Weak Symbols”

  1. actinium December 12, 2008 at 9:10 am # Reply

    hey…i read both ur posts. agreed, support for weak symbols is great, but it does create problems sometimes. i guess you should be able to ask the complier to generate a normal linkage instead of weak. gcc has -fno-weak option for accomplishing this but it is experimental, breaks exception handling and rtti, and gcc man page mentions it as deprecated.

Trackbacks/Pingbacks

  1. Embedded Bits » Blog Archive » GCC Compiler Warnings - November 28, 2009

    […] may provide warnings about things that we know about and are happy with. This post revisits GCC attributes to see how we can supress such […]

  2. UK Embedded » Blog Archive » GCC Compiler Warnings - November 29, 2009

    […] may provide warnings about things that we know about and are happy with. This post revisits GCC attributes to see how we can supress such […]

Leave a Reply