This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH][x86_64] Convert indirect call via GOT to direct when possible
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Sriraman Tallam <tmsriram at google dot com>
- Cc: binutils <binutils at sourceware dot org>, Cary Coutant <ccoutant at gmail dot com>, David Li <davidxl at google dot com>
- Date: Wed, 8 Jun 2016 15:34:22 -0700
- Subject: Re: [PATCH][x86_64] Convert indirect call via GOT to direct when possible
- Authentication-results: sourceware.org; auth=none
- References: <CAAs8HmxxdBpS7w8udZgK0QFi5TnenU3wGhpPfhWeKE8Tr=thvA at mail dot gmail dot com> <CAMe9rOpk3aOK5mMkKvYQyzeQxJ-h8o+3KjLRikKSkLmMfqoUtg at mail dot gmail dot com> <CAAs8Hmw2KQ2neDNP5cnQPBVBZMJthvQGTARPiwa-NfAx5R6ugw at mail dot gmail dot com> <CAMe9rOrOyYv0+svcObyaBcoYbAWZTadEPm-mAGQUFFyNjPgctg at mail dot gmail dot com> <CAAs8HmzoxWe2YpvjviV-bs2BRotGa_WFWbCyyLh-_L=s00yxjQ at mail dot gmail dot com> <CAAs8Hmyvm4+GiYCPCXft09ozeLdMqideToMbFHho1z7O9EQAYQ at mail dot gmail dot com> <CAAs8Hmw1gR-5G-LCbGVKRd2q6h45aU_FWi3ekqm_DXnQT3dDDQ at mail dot gmail dot com>
On Wed, Jun 8, 2016 at 3:22 PM, Sriraman Tallam <tmsriram@google.com> wrote:
> On Mon, Jun 6, 2016 at 1:50 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>> On Tue, May 31, 2016 at 11:02 AM, Sriraman Tallam <tmsriram@google.com> wrote:
>>> On Sat, May 28, 2016 at 10:44 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> On Fri, May 27, 2016 at 3:14 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>>>> On Fri, May 20, 2016 at 1:32 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>>> On Fri, May 20, 2016 at 1:27 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> GCC has option -fno-plt which converts all extern calls to indirect
>>>>>>> calls via GOT to prevent the linker for generating any PLT stubs.
>>>>>>> However, if the function ends up defined in the executable this patch
>>>>>>> will convert those indirect calls/jumps to direct. Since the indirect
>>>>>>> calls are one byte longer, an extra nop is needed at the beginning.
>>>>>>>
>>>>>>> Here is a simple example:
>>>>>>>
>>>>>>> main.c
>>>>>>> ---------
>>>>>>> extern int foo();
>>>>>>> int main() {
>>>>>>> return foo();
>>>>>>> }
>>>>>>>
>>>>>>> deffoo.c
>>>>>>> -----------
>>>>>>> int foo() {
>>>>>>> return 0;
>>>>>>> }
>>>>>>>
>>>>>>> $ gcc -fno-plt main.c deffoo.c
>>>>>>> $objdump -d a.out
>>>>>>>
>>>>>>> 0000000000400626 <main>:
>>>>>>> ...
>>>>>>> 40062a: ff 15 28 14 00 00 callq *0x1428(%rip) #
>>>>>>> 401a58 <_DYNAMIC+0x1d8>
>>>>>>>
>>>>>>> The call is indirect even though foo is defined in the executable.
>>>>>>>
>>>>>>> With this patch,
>>>>>>> 0000000000400606 <main>:
>>>>>>> ....
>>>>>>> 40060a: 90 nop
>>>>>>> 40060b: e8 03 00 00 00 callq 400613 <foo>
>>>>>>>
>>>>>>> The call is now direct with an extra nop.
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> Please try ld, which uses 0x67 prefix (addr32) instead of nop.
>>>>>> Also for
>>>>>>
>>>>>> jmp *foo#GOTPCREL(%rip)
>>>>>>
>>>>>> ld converts it to
>>>>>>
>>>>>> jmp foo
>>>>>> nop
>>>>>
>>>>> I have modified the patch to keep it consistent with what ld produces.
>>>>>
>>>>> Please take another look.
>>>>>
>>>>> * x86_64.cc (can_convert_callq_to_direct): New function.
>>>>> Target_x86_64<size>::Scan::global: Check if an indirect call via
>>>>> GOT can be converted to direct.
>>>>> Target_x86_64<size>::Relocate::relocate: Change any indirect call
>>>>> via GOT that can be converted.
>>>>> * testsuite/Makefile.am (x86_64_indirect_call_to_direct.sh): New test.
>>>>> * testsuite/Makefile.in: Regenerate.
>>>>> * testsuite/x86_64_indirect_call_to_direct1.s: New file.
>>>>> * testsuite/x86_64_indirect_jump_to_direct1.s: New file.
>>>>>
>>>>
>>>> Do you need to check R_X86_64_REX_GOTPCRELX for branch?
>>>
>>> Ok, patch changed to not check for this and refactored a bit.
>>
>> Ping, Is this patch ok now?
>
> Ping. H.J. / Cary, is this good to go now?
>
> * x86_64.cc (can_convert_callq_to_direct): New function.
> Target_x86_64<size>::Scan::global: Check if an indirect call via
> GOT can be converted to direct.
> Target_x86_64<size>::Relocate::relocate: Change any indirect call
> via GOT that can be converted.
> * testsuite/Makefile.am (x86_64_indirect_call_to_direct.sh): New test.
> * testsuite/Makefile.in: Regenerate.
> * testsuite/x86_64_indirect_call_to_direct1.s: New file.
> * testsuite/x86_64_indirect_jump_to_direct1.s: New file.
>
>
Looks good to me. But I can't approve it.
--
H.J.