This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi Richard, The MIPS16 code has some complicated relations with LA25 stubs (LUI/ADDUI $25 sequences added by BFD when calling from non-PIC to PIC). Current PLT support is capable of adding (either prepending or separate stub) LA25 sequences to create $t9 on entry of a PIC callee. However, when the called routine is MIPS16 code with a FP-stub (stub is 32-bit), then we have, for example: int main (void) { return __fixdfdi (0.0); // libgcc function } Build as: mips-linux-gnu-gcc -c -O2 testcase.c # build as 32-bit mips-linux-gnu-gcc -mips16 testcase.o # link with MIPS16 libs ./a.out Segmentation fault Disassembly: 00400930 <__fn_stub___fixdfdi>: 400930: 3c1c0002 lui gp,0x2 400934: 279c8100 addiu gp,gp,-32512 400938: 0399e021 addu gp,gp,t9 40093c: 8f998024 lw t9,-32732(gp) <--segfault 400940: 27390621 addiu t9,t9,1569 400944: 44056000 mfc1 a1,$f12 400948: 03200008 jr t9 40094c: 44046800 mfc1 a0,$f13 The call is from main: 00400610 <main>: 400610: 44806000 mtc1 zero,$f12 400614: 0810024c j 400930 <__fn_stub___fixdfdi> 400618: 44806800 mtc1 zero,$f13 40061c: 00000000 nop The actual __fixdfdi body, which is MIPS16 code: 00400620 <__fixdfdi>: 400620: f000 6a02 li v0,2 400624: f410 0b0c la v1,3f8a30 <_DYNAMIC-0x774c> 400628: f400 3240 sll v0,16 40062c: e269 addu v0,v1 40062e: 659a move gp,v0 400630: 64f6 save 48,ra,s0-s1 ... The problem is that 'la $25' headers/trampolines are needed for the "stub", which is 32-bit code and calculates $gp using $t9, not the MIPS16 function itself (which as the BFD support already correctly determines, are never needed due to MIPS16's PC-relative capabilities). Also note that this problem is avoided when -mno-plt is used. My patch attached here modifies the LA25 insertion to accommodate the case where we have a "MIPS16 function with a kept 32-bit stub", and uses the stub as the point of insertion. The correctly linked results are now like: 00400610 <main>: 400610: 44806000 mtc1 zero,$f12 400614: 0810024c j 400930 <.pic.__fixdfdi> 400618: 44806800 mtc1 zero,$f13 40061c: 00000000 nop ... 00400930 <.pic.__fixdfdi>: 400930: 3c190040 lui t9,0x40 400934: 27390938 addiu t9,t9,2360 00400938 <__fn_stub___fixdfdi>: 400938: 3c1c0002 lui gp,0x2 40093c: 279c80f8 addiu gp,gp,-32520 400940: 0399e021 addu gp,gp,t9 400944: 8f998024 lw t9,-32732(gp) 400948: 27390621 addiu t9,t9,1569 40094c: 44056000 mfc1 a1,$f12 400950: 03200008 jr t9 400954: 44046800 mfc1 a0,$f13 Which should be correctly generated "stub of stub" code :) This is for the 32-bit->16-bit case. There's also some handling to skip the LA25 stub for 16-bit->16-bit case. Thanks, Chung-Lin 2011-12-10 Chung-Lin Tang <cltang@codesourcery.com> Catherine Moore <clm@codesourcery.com> Sandra Loosemore <sandra@codesourcery.com> * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when H is a MIPS16 function with a kept 32-bit stub. Update comments. (mips_elf_add_la25_intro): Use MIPS16 stub section as place of insertion when it exists. (mips_elf_add_la25_stub): Always use LUI/ADDIU prepending for MIPS16 stubs. Update comments. (mips_elf_calculate_relocation): Redirect relocation to point to the LA25 stub if it exists, instead of the MIPS16 stub. Don't use la25 stub for mips16->mips16 calls. (mips_elf_create_la25_stub): Change $25 target calculation to base on MIPS16 stub if it exists.
Attachment:
la25.diff
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |