Linker magic for aliases an external symbol... how to?

Philip Prindeville philipp_subx@redfish-solutions.com
Fri Sep 2 03:29:00 GMT 2016


On 09/01/2016 06:09 PM, Alan Modra wrote:
> On Thu, Sep 01, 2016 at 01:45:24PM -0600, Philip Prindeville wrote:
>> I've tried in main.c:
>>
>> void logmsg(int, const char *, ...)    asm("syslog");
>>
>> and:
>>
>> void logmsg(int, const char *, ...) __attribute__ ((weak, alias
>> ("syslog")));
>>
>> as well as various link-time options like:
>>
>> -Wl,--defsym=logmsg=syslog
>>
>> as well as:
>>
>> -Wl,-Map=ld.map
>>
>> where ld.map contains:
>>
>> SECTIONS {
>>    .text :
>>    {
>>        logmsg = syslog;
>>
>>    }
>> }
> No, none of these ideas will work because you don't have a place in
> the executable to define logmsg.
>
> Old C hackers would just write this in the executable
>
> void logmsg (void)
> {
>    extern void syslog (void);
>    syslog (void);
> }
>
> trusting that the compiler will turn this into a sibling call, leaving
> the args in place.  This works for most architectures and some
> compiler optimization levels..
>
> It would be safer to write the assembly version of the above, or
> binary edit the shared lib.
>

Yeah, binary editing the shared lib isn't an option...  That would break 
all sorts of things.

I tried the hack you mention above and it worked for x86_64, but it 
bothers me that it won't work for other platforms (even though it will 
compile) so it's a ticking time bomb.

What would the assembler look like to have an entry point called 
"logmsg" which jumps (not calls, i.e. no push of a return address) to 
syslog()?

Thanks,

-Philip



More information about the Binutils mailing list