Using linker directives to conditionally choose code

Nicholas Clifton nickc@redhat.com
Mon Sep 8 09:36:00 GMT 2014


Hi Chris,

> I could easily accomplish this by defining strong symbols for all of
> the interrupt handlers, but that would eat up a bunch of flash space
> for interrupts I don't use.  What I would like instead is to use the
> default handler for all interrupts, *unless* someone called
> register_isr{1,2}_cb(), at which point it would switch to the strong
> ISR_Handler() symbol for just that interrupt.

Have you tried using symbol aliases and archives ?  Eg something like:


   % cat isr1.c

   void register_isr1_cb (void (*cb)(void)) { ... }

   void (*isr1_handler)(void) __attribute__((alias ("ISR_Handler")));


   % cat isr2.c

   void register_isr2_cb (void (*cb)(void)) { ... }

   void (*isr2_handler)(void) __attribute__((alias ("ISR_Handler")));


   % gcc -c isr1.c isr2.c
   % ar cr libisr.a isr1.o isr2.o

   % cat foo.c

   int global = 0'
   void bar (void) { global = 1; }
   void (main) { register_isr1_cb (bar); ... }

   % gcc foo.c libisr.a


So that when register_isr1_cb() is pulled into the application from 
libisr.a the (strong) definition of isr1_handler is also brought in.
This  overrides the weak default definition of isr1_handler and results 
in ISR_Handler being called directly.  Since register_isr2_cb is not 
called however the strong version of isr2_handler is not pulled out of 
libisr.a and so the weak, default handler is used instead.

Cheers
   Nick



More information about the Binutils mailing list