https://sourceware.org/bugzilla/show_bug.cgi?id=17205
Bug ID: 17205 Summary: alpha procedure call invalid relaxation Product: binutils Version: 2.23 Status: NEW Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: martin at NetBSD dot org On the alpha elf target there are basically two types of functions, they are marked with .prologue 0 or .prologue 1 by the compiler. The difference is setup of the gp register for access to variables via GOT. The caller restores this register after the call, but in some cases setup can be skipped and restoration NOP'd. I think we are hitting a case where such an optimization is erroneously applied in NetBSD when linking threaded programs statically. The original bug report is here: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=48709 The problem happens with a weak symbol function of type ".prologue 0" being overwritten by another implementation of type ".prologue 1". In the NetBSD case the issue is obscured a bit more by symbol renaming, but I think the below code demonstrates the mis-relaxation already (unless I misunderstand something). With this code in "main.c": --8<-- #include <stdio.h> int external_init_used = 0; __attribute__((weak)) void subsys_init(void) { /* do nothing */ } int main(int argc, char **argv) { subsys_init(); if (external_init_used) printf("something overwrote subsys_init\n"); else printf("our own subsys_init stub has been used\n"); return 0; } -->8-- and this in "extern.c": --8<-- #include <stdio.h> extern int external_init_used; void subsys_init(void) { external_init_used = 1; printf("initializing...\n"); } -->8-- use this command line: cc -static -Wall -O2 main.c extern.c For details, check with -S and see that .prologue values differ between the stub in main.c and the overwrite in extern.c. Also note that gcc did generate correct code (including restoring gp after the call to subsys_init). Now invoke gdb on the resulting binary and look at the call to subsys_init: (gdb) x/16i main 0x120026d40 <main>: ldah gp,2(t12) 0x120026d44 <main+4>: lda gp,11112(gp) 0x120026d48 <main+8>: lda sp,-16(sp) 0x120026d4c <main+12>: stq ra,0(sp) 0x120026d50 <main+16>: unop 0x120026d54 <main+20>: bsr ra,0x1200003d8 <subsys_init+8> 0x120026d58 <main+24>: unop 0x120026d5c <main+28>: unop Note the +8 offset for the subsys_init call, which means gp setup will be skipped. The last two lines are stubbed out reload instructions for the gp register ldah $29,0($26) !gpdisp!7 lda $29,0($29) !gpdisp!7 This relaxation would be valid if the final call target would be the stub in main.c, but as the weak symbol is overwritten they are invalid. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils