[PATCH] D31682: Fix PLT and GOTPLT entries for x86 PIC.

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 07:24:59 PDT 2017


LGTM

On 4 April 2017 at 18:21, Rui Ueyama via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> ruiu created this revision.
> Herald added a subscriber: emaste.
>
> Previously, the code we set to our .got.plt entries expected that
> .got and .got.plt are consecutive in the virtual address space.
> Since %ebx points to the last entry of .got for position-independent
> code, it assumed that .got is accessible with small negative
> displacements and .got.plt are accessible with small positive
> displacements.
>
> That assumption was simply wrong. We don't impose any restrictions on
> relative layout of .got and .got.plt. As a result, the control is
> transferred to a bogus address from .plt at runtime, which resulted in
> segfaults.
>
> This patch removes that wrong assumption. We still assume that .got.plt
> has a fixed relative address to .got, but we no longer assume that they
> are consecutive in memory.
>
> With this change, a "hello world" program compiled with -fPIC works.
>
> Fixes https://bugs.llvm.org/show_bug.cgi?id=31332.
>
>
> https://reviews.llvm.org/D31682
>
> Files:
>   lld/ELF/Target.cpp
>   lld/test/ELF/plt-i686.s
>
>
> Index: lld/test/ELF/plt-i686.s
> ===================================================================
> --- lld/test/ELF/plt-i686.s
> +++ lld/test/ELF/plt-i686.s
> @@ -135,23 +135,23 @@
>  // DISASMSHARED-NEXT:  1013: e9 e8 ff ff ff jmp -24
>  // DISASMSHARED-NEXT:  Disassembly of section .plt:
>  // DISASMSHARED-NEXT:  .plt:
> -// DISASMSHARED-NEXT:  1020: ff b3 04 00 00 00  pushl 4(%ebx)
> -// DISASMSHARED-NEXT:  1026: ff a3 08 00 00 00  jmpl *8(%ebx)
> +// DISASMSHARED-NEXT:  1020: ff b3 04 20 00 00 pushl 8196(%ebx)
> +// DISASMSHARED-NEXT:  1026: ff a3 08 20 00 00 jmpl *8200(%ebx)
>  // DISASMSHARED-NEXT:  102c: 90 nop
>  // DISASMSHARED-NEXT:  102d: 90 nop
>  // DISASMSHARED-NEXT:  102e: 90 nop
>  // DISASMSHARED-NEXT:  102f: 90 nop
> -// DISASMSHARED-NEXT:  1030: ff a3 0c 00 00 00  jmpl *12(%ebx)
> +// DISASMSHARED-NEXT:  1030: ff a3 0c 20 00 00 jmpl *8204(%ebx)
>  // DISASMSHARED-NEXT:  1036: 68 00 00 00 00     pushl $0
>  // DISASMSHARED-NEXT:  103b: e9 e0 ff ff ff     jmp -32 <.plt>
> -// DISASMSHARED-NEXT:  1040: ff a3 10 00 00 00  jmpl *16(%ebx)
> +// DISASMSHARED-NEXT:  1040: ff a3 10 20 00 00 jmpl *8208(%ebx)
>  // DISASMSHARED-NEXT:  1046: 68 08 00 00 00     pushl $8
>  // DISASMSHARED-NEXT:  104b: e9 d0 ff ff ff     jmp -48 <.plt>
>
>  // DISASMPIE:      Disassembly of section .plt:
>  // DISASMPIE-NEXT: .plt:
> -// DISASMPIE-NEXT:   1020:     ff b3 04 00 00 00 pushl 4(%ebx)
> -// DISASMPIE-NEXT:   1026:     ff a3 08 00 00 00 jmpl *8(%ebx)
> +// DISASMPIE-NEXT:   1020:     ff b3 04 20 00 00 pushl 8196(%ebx)
> +// DISASMPIE-NEXT:   1026:     ff a3 08 20 00 00 jmpl *8200(%ebx)
>  // DISASMPIE-NEXT:   102c:     90 nop
>  // DISASMPIE-NEXT:   102d:     90 nop
>  // DISASMPIE-NEXT:   102e:     90 nop
> Index: lld/ELF/Target.cpp
> ===================================================================
> --- lld/ELF/Target.cpp
> +++ lld/ELF/Target.cpp
> @@ -444,30 +444,33 @@
>  }
>
>  void X86TargetInfo::writePltHeader(uint8_t *Buf) const {
> -  // Executable files and shared object files have
> -  // separate procedure linkage tables.
>    if (Config->Pic) {
>      const uint8_t V[] = {
>          0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx)
>          0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp   *8(%ebx)
> -        0x90, 0x90, 0x90, 0x90              // nop; nop; nop; nop
> +        0x90, 0x90, 0x90, 0x90              // nop
>      };
>      memcpy(Buf, V, sizeof(V));
> +
> +    uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize();
> +    uint32_t GotPlt = In<ELF32LE>::GotPlt->getVA() - Ebx;
> +    write32le(Buf + 2, GotPlt + 4);
> +    write32le(Buf + 8, GotPlt + 8);
>      return;
>    }
>
>    const uint8_t PltData[] = {
>        0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOT+4)
>        0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp   *(GOT+8)
> -      0x90, 0x90, 0x90, 0x90              // nop; nop; nop; nop
> +      0x90, 0x90, 0x90, 0x90              // nop
>    };
>    memcpy(Buf, PltData, sizeof(PltData));
>    uint32_t Got = In<ELF32LE>::GotPlt->getVA();
>    write32le(Buf + 2, Got + 4);
>    write32le(Buf + 8, Got + 8);
>  }
>
> -void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
> +void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
>                               uint64_t PltEntryAddr, int32_t Index,
>                               unsigned RelOff) const {
>    const uint8_t Inst[] = {
> @@ -477,10 +480,17 @@
>    };
>    memcpy(Buf, Inst, sizeof(Inst));
>
> -  // jmp *foo at GOT(%ebx) or jmp *foo_in_GOT
> -  Buf[1] = Config->Pic ? 0xa3 : 0x25;
> -  uint32_t Got = In<ELF32LE>::GotPlt->getVA();
> -  write32le(Buf + 2, Config->Shared ? GotEntryAddr - Got : GotEntryAddr);
> +  if (Config->Pic) {
> +    // jmp *foo at GOT(%ebx)
> +    uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize();
> +    Buf[1] = 0xa3;
> +    write32le(Buf + 2, GotPltEntryAddr - Ebx);
> +  } else {
> +    // jmp *foo_in_GOT
> +    Buf[1] = 0x25;
> +    write32le(Buf + 2, GotPltEntryAddr);
> +  }
> +
>    write32le(Buf + 7, RelOff);
>    write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16);
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>


More information about the llvm-commits mailing list