[PATCH] D46544: Set DF_TEXTREL only if text relocations are really needed.

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 7 13:31:44 PDT 2018


MaskRay added a comment.

The root cause is that IFUNC (e.g. R_X86_64_IRELATIVE) is incompatible with DF_TEXTREL.

bfd will error when both IFUNC and DF_TEXTREL are used in non-writable segments.

  // bfd/elfxx-x86.c:1291
    if ((info->flags & DF_TEXTREL) != 0)
      {
        if (htab->readonly_dynrelocs_against_ifunc)
          {
            info->callbacks->einfo
              (_("%P%X: read-only segment has dynamic IFUNC relocations;"
                " recompile with -fPIC\n"));
            bfd_set_error (bfd_error_bad_value);
            return FALSE;
          }
  
        if (!add_dynamic_entry (DT_TEXTREL, 0))
          return FALSE;
      }

gold does not error. But glibc ld.so will crash when IFUNC relocations are resolved in runtime

  // elf/get-dynamic-info.h  DF_TEXTREL implies DT_TEXTREL
  if (l->l_flags & DF_TEXTREL)
      info[DT_TEXTREL] = info[DT_FLAGS];
  
  // elf/dl-reloc.c
    if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0))
    {
      /////////// the program text segment is remapped as read+write
      ///// PROT_EXEC should also be set if ifunc is used
      if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0)
    
      ////// IFUNC (R_X86_64_IRELATIVE) is resolved in this call
      /// Code in the program segment is executed while the map is non-executable
      ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D46544





More information about the llvm-commits mailing list