Bug 20246 - script_test_2 fails for glibc without PLT
Summary: script_test_2 fails for glibc without PLT
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: 2.27
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-12 16:06 UTC by H.J. Lu
Modified: 2016-06-22 21:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2016-06-12 16:06:19 UTC
For glibc with:

From ac187dc4abde9ca6504c646106e2a7f7b2806262 Mon Sep 17 00:00:00 2001
From: H.J. Lu <hjl.tools@gmail.com>
Date: Thu, 9 Jun 2016 04:43:16 -0700
Subject: [PATCH] Always indirect branch to __libc_start_main via GOT

Since __libc_start_main in libc.so is called very early, lazy binding
isn't relevant.  Always call __libc_start_main with indirect branch via
GOT to avoid extra branch to PLT slot.  In case of static executable,
ld in binutils 2.26 or above can convert indirect branch into direct
branch:

0000000000400a80 <_start>:
  400a80:       31 ed                   xor    %ebp,%ebp
  400a82:       49 89 d1                mov    %rdx,%r9
  400a85:       5e                      pop    %rsi
  400a86:       48 89 e2                mov    %rsp,%rdx
  400a89:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  400a8d:       50                      push   %rax
  400a8e:       54                      push   %rsp
  400a8f:       49 c7 c0 20 1b 40 00    mov    $0x401b20,%r8
  400a96:       48 c7 c1 90 1a 40 00    mov    $0x401a90,%rcx
  400a9d:       48 c7 c7 c0 03 40 00    mov    $0x4003c0,%rdi
  400aa4:       67 e8 96 09 00 00       addr32 callq 401440 <__libc_start_main>
  400aaa:       f4                      hlt

	* sysdeps/x86_64/start.S (_start): Always indirect branch to
	__libc_start_main via GOT.

I got

(gdb) r
Starting program: /export/build/gnu/binutils-gold/build-x86_64-linux/gold/testsuite/script_test_2
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.22-17.1.fc23.x86_64

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x000000001000002a in _start ()
(gdb) disass _start
Dump of assembler code for function _start:
   0x0000000010000000 <+0>:     xor    %ebp,%ebp
   0x0000000010000002 <+2>:     mov    %rdx,%r9
   0x0000000010000005 <+5>:     pop    %rsi
   0x0000000010000006 <+6>:     mov    %rsp,%rdx
   0x0000000010000009 <+9>:     and    $0xfffffffffffffff0,%rsp
   0x000000001000000d <+13>:    push   %rax
   0x000000001000000e <+14>:    push   %rsp
   0x000000001000000f <+15>:    mov    $0x10000170,%r8
   0x0000000010000016 <+22>:    mov    $0x10000100,%rcx
   0x000000001000001d <+29>:    mov    $0x100001a0,%rdi
   0x0000000010000024 <+36>:    callq  *0x100ee6(%rip)        # 0x10100f10 <_DYNAMIC+496>
                                                               ^^^^^^^^^^^ GOT offset is wrong

It should be 0x10100f50.

   0x000000001000002a <+42>:    hlt
End of assembler dump.
(gdb)

There are 44 section headers, starting at offset 0x3af8:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000010000000 001000 000172 00  AX  0   0 16
  [ 2] .init             PROGBITS        0000000010000174 001174 000017 00  AX  0   0  4
  [ 3] .fini             PROGBITS        000000001000018c 00118c 000009 00  AX  0   0  4
  [ 4] .text.unlikely    PROGBITS        0000000010000195 001195 000000 00  AX  0   0  1
  [ 5] .text.startup     PROGBITS        00000000100001a0 0011a0 0002dd 00  AX  0   0 16
  [ 6] .plt              PROGBITS        0000000010000480 001480 000040 10  AX  0   0 16
  [ 7] .rela.plt         RELA            00000000100004c0 0014c0 000048 18  AI 15   6  8
  [ 8] .rela.dyn         RELA            0000000010000508 001508 000030 18   A 15   0  8
  [ 9] .rodata.cst4      PROGBITS        0000000010000538 001538 000004 04  AM  0   0  4
  [10] .eh_frame         PROGBITS        0000000010000540 001540 0000f4 00   A  0   0  8
  [11] .eh_frame_hdr     PROGBITS        0000000010000634 001634 000034 00   A  0   0  4
  [12] .rodata           PROGBITS        0000000010000670 001670 000056 00   A  0   0 16
  [13] .rodata.str1.8    PROGBITS        00000000100006c8 0016c8 000287 01 AMS  0   0  8
  [14] .rodata.str1.1    PROGBITS        000000001000094f 00194f 0000af 01 AMS  0   0  1
  [15] .dynsym           DYNSYM          0000000010000a00 001a00 0000c0 18   A 16   1  8
  [16] .dynstr           STRTAB          0000000010000ac0 001ac0 0000ae 00   A  0   0  1
  [17] .gnu.hash         GNU_HASH        0000000010000b70 001b70 00001c 00   A 15   0  8
  [18] .interp           PROGBITS        0000000010000b8c 001b8c 00001c 00   A  0   0  1
  [19] .gnu.version      VERSYM          0000000010000ba8 001ba8 000010 02   A 15   0  2
  [20] .gnu.version_r    VERNEED         0000000010000bb8 001bb8 000020 00   A 16   1  4
  [21] .note.ABI-tag     NOTE            0000000010000bd8 001bd8 000020 00   A  0   0  4
  [22] .note.gnu.build-id NOTE            0000000010000bf8 001bf8 000024 00   A  0   0  4
  [23] .data             PROGBITS        0000000010100d00 001d00 000004 00  WA  0   0  1
  [24] .jcr              PROGBITS        0000000010100d08 001d08 000008 00  WA  0   0  8
  [25] .tm_clone_table   PROGBITS        0000000010100d10 001d10 000000 00  WA  0   0  8
  [26] .fini_array       FINI_ARRAY      0000000010100d10 001d10 000008 00  WA  0   0  8
  [27] .init_array       INIT_ARRAY      0000000010100d18 001d18 000008 00  WA  0   0  8
  [28] .dynamic          DYNAMIC         0000000010100d20 001d20 000200 10  WA 16   0  8
  [29] .got.plt          PROGBITS        0000000010100f20 001f20 000030 00  WA  0   0  8
  [30] .got              PROGBITS        0000000010100f50 001f50 000010 00  WA  0   0  8
  [31] .bss              NOBITS          0000000010100f60 001f60 000001 00  WA  0   0  1
  [32] .gold_test        PROGBITS        0000000020000010 002010 000053 00  WA  0   0 32
  [33] .comment          PROGBITS        0000000000000000 002063 00002d 01  MS  0   0  1
  [34] .debug_info       PROGBITS        0000000000000000 002090 0007d0 00      0   0  1
  [35] .debug_abbrev     PROGBITS        0000000000000000 002860 0001f9 00      0   0  1
  [36] .debug_aranges    PROGBITS        0000000000000000 002a59 000070 00      0   0  1
  [37] .debug_ranges     PROGBITS        0000000000000000 002ac9 000080 00      0   0  1
  [38] .debug_line       PROGBITS        0000000000000000 002b49 0002c5 00      0   0  1
  [39] .debug_str        PROGBITS        0000000000000000 002e0e 000326 01  MS  0   0  1
  [40] .note.gnu.gold-version NOTE            0000000000000000 003134 00001c 00      0   0  4
  [41] .symtab           SYMTAB          0000000000000000 003150 0004c8 18     42  24  8
  [42] .strtab           STRTAB          0000000000000000 003618 00030a 00      0   0  1
  [43] .shstrtab         STRTAB          0000000000000000 003922 0001d0 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Relocation section '.rela.plt' at offset 0x14c0 contains 3 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000010100f38  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
0000000010100f40  0000000600000007 R_X86_64_JUMP_SLOT     0000000000000000 memcmp@GLIBC_2.2.5 + 0
0000000010100f48  0000000700000007 R_X86_64_JUMP_SLOT     0000000000000000 __assert_fail@GLIBC_2.2.5 + 0

Relocation section '.rela.dyn' at offset 0x1508 contains 2 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000010100f50  0000000100000006 R_X86_64_GLOB_DAT      0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
0000000010100f58  0000000200000006 R_X86_64_GLOB_DAT      0000000000000000 __gmon_start__ + 0
gnu-6:pts/33[6]>
Comment 1 Sourceware Commits 2016-06-13 18:16:05 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3328c04b103286c3422aed59b97595bbbd9bbef5

commit 3328c04b103286c3422aed59b97595bbbd9bbef5
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jun 13 11:14:57 2016 -0700

    Add .got.plt to testsuite/script_test_2.t
    
    The .got.plt section must be placed right after the .got section.
    Otherwise, GOT offset will be wrong.
    
    	PR gold/20246
    	* testsuite/script_test_2.t: Add .got.plt after .got.
Comment 2 H.J. Lu 2016-06-22 21:34:33 UTC
Fixed