This is the mail archive of the 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]

[PATCH] [MIPS] Ensure that local GOT entries accessed via a 16-bit index come first


We have a "canadian_cross" build of LLVM and have been getting off and on link time errors from one of the input object files RecursiveASTVisitorTest.o. :

(.text._ZN4llvm25SmallVectorTemplateCommonIN5clang19RecursiveASTVisitorINS1_11AttrVisitorEE10EnqueueJobEvE4backEv[_ZN4llvm25SmallVectorTemplateCommonIN5clang19RecursiveASTVisitorINS1_11AttrVisitorEE10EnqueueJobEvE4backEv]+0x64): relocation truncated to fit: R_MIPS_GOT16 against `no symbol'

Basically building LLVM with a MIPS GCC. I noticed that the section count was way above 16 bits and seized on that as being the culprit.

From the information you and H.J. have pointed me to, I need to dig further. Why I never knew about this trap door for section overflow is beyond me :-| Probably since I never hit the limit myself.

I have been investigating this issue with the LLVM Canadian Cross build on MIPS. The problem arises mainly because of the way GCC constructs calls to member functions of C++ classes in PIC code - each member function of each class is placed in a different section (which, coupled with the use of class templates, explains the huge number of sections in the problematic object file). A call to a member function generates this type of code (with -mxgot):

      2c:       3c020000        lui     v0,0x0
2c: R_MIPS_GOT_HI16 _ZN5clang33ParmVarDeclVisitorForImplicitCodeC1Ev
      30:       005c1021        addu    v0,v0,gp
      34:       8c420000        lw      v0,0(v0)
34: R_MIPS_GOT_LO16 _ZN5clang33ParmVarDeclVisitorForImplicitCodeC1Ev
      38:       0040c821        move    t9,v0
      3c:       0320f809        jalr    t9
3c: R_MIPS_JALR _ZN5clang33ParmVarDeclVisitorForImplicitCodeC1Ev
      40:       00000000        nop

meaning that each call to a member function may result in a new entry being placed in the local section of the GOT (if the symbol is local or mips_use_local_got_p() evaluates to true).

The other main type of local GOT entry is created by page+offset references - e.g.:

      50:       8f820000        lw      v0,0(gp)
                        50: R_MIPS_GOT16        .rodata
      54:       24450488        addiu   a1,v0,1160
                        54: R_MIPS_LO16 .rodata
      58:       3c020000        lui     v0,0x0

The GOT entry for the page is always accessed using a 16-bit lookup even with -mxgot - I believe the reasoning for this was because with each page covering 64KB, the addressable 16K GOT page entries would be enough to cover ~1GB of address space?

Unfortunately, since local GOT entries are allocated on-the-fly as they are encountered in the code, this means that the initial 16K entries are filled with a mixture of entries for member functions and pages (in this case, mainly the former). This means that there is the possibility that a page entry will be allocated outside of the addressable first 16K entries, resulting in a reloc overflow. However, with -mxgot, there is no problem calling member functions with entries after the first 16K entries (without -mxgot, these would also eventually result in overflows).

I have created this patch to ensure that GOT page entries come before the member function entries. The idea is to fill the local GOT space from both ends at once, with entries accessed via 16-bit indexing being added on the lower end, and those with 32-bit indexing on the upper end. If the size of the local GOT is overestimated, this results in a gap in the middle of the local GOT area that must be accounted for when iterating over the local part of the GOT.

This patch has only been lightly tested. I can confirm that the reloc overflow on building LLVM/Clang no longer occurs, and have tried running some of the generated LLVM and Clang binaries on QEMU and a real MIPS board. The ld testsuite has a couple of new failures due to the change in the GOT layout, so the expected outputs need to be updated (included in the patch).

Kwok Cheung Yeung

Attachment: mips_reloc_overflow.patch
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]