tag 350501 + patch
thanks

Hi,

The problem is that since version all network daemons, including nscd,
are built with -fPIE, thanks to RedHat. GCC treats this flag just as
-fPIC, but binutils generates relocs of type R_PARISC_PLABEL14 and 
R_PARISC_PLABEL21. Glibc does not handle those relocs.

Currently we have the choice of building them with -fPIE or not building
them at all.

The workaround would be to build snscd without -fPIE, but that would say
hacking nscd/Makefile, as Gentoo does. There is a proper fix that has
been comitted on cvs.parisc-linux.org last July. It adds support for
those relocs. 

Please find attached the patch that could be put in debian/patches. I 
have tested it successfully on a 2.3.6 glibc (SVN r1164).

Bye,
Aurelien

-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [EMAIL PROTECTED]         | [EMAIL PROTECTED]
   `-    people.debian.org/~aurel32 | www.aurel32.net
2005-06-10  Randolph Chung  <[EMAIL PROTECTED]>

        * elf/elf.h (R_PARISC_PLABEL21L, R_PARISC_PLABEL14R): Define.
        * sysdeps/hppa/dl-machine.h (reassemble_21, reassemble_14): Define.
        (elf_machine_rela): Handle R_PARISC_DIR21L/14R and
        R_PARISC_PLABEL21L/14R relocations.

===================================================================
RCS file: /var/lib/cvs/glibc/elf/elf.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- glibc/elf/elf.h     2005/06/09 01:14:04     1.3
+++ glibc/elf/elf.h     2005/06/10 23:41:20     1.4
@@ -1703,6 +1703,8 @@
 #define R_PARISC_LTOFF_FPTR14R 62      /* LT-rel. fct ptr, right 14 bits. */
 #define R_PARISC_FPTR64                64      /* 64 bits function address.  */
 #define R_PARISC_PLABEL32      65      /* 32 bits function address.  */
+#define R_PARISC_PLABEL21L     66      /* Left 21 bits of fct ptr.  */
+#define R_PARISC_PLABEL14R     70      /* Left 21 bits of fct ptr.  */
 #define R_PARISC_PCREL64       72      /* 64 bits PC-rel. address.  */
 #define R_PARISC_PCREL22F      74      /* 22 bits PC-rel. address.  */
 #define R_PARISC_PCREL14WR     75      /* PC-rel. address, right 14 bits.  */

===================================================================
RCS file: /var/lib/cvs/glibc/sysdeps/hppa/dl-machine.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- glibc/sysdeps/hppa/dl-machine.h     2005/06/09 04:27:13     1.3
+++ glibc/sysdeps/hppa/dl-machine.h     2005/06/10 23:41:20     1.4
@@ -223,7 +223,8 @@
                 }
               else
                {
-                 if (_dl_name_match_p (GLRO(dl_profile), l))
+                 if (GLRO(dl_profile) != NULL
+                     && _dl_name_match_p (GLRO(dl_profile), l))
                    {
                      /* This is the object we are looking for.  Say that
                         we really want profiling and the timers are
@@ -514,6 +515,18 @@
 /* These are only actually used where RESOLVE_MAP is defined, anyway. */
 #ifdef RESOLVE_MAP
 
+
+#define reassemble_21(as21) \
+  (  (((as21) & 0x100000) >> 20) \
+   | (((as21) & 0x0ffe00) >> 8) \
+   | (((as21) & 0x000180) << 7) \
+   | (((as21) & 0x00007c) << 14) \
+   | (((as21) & 0x000003) << 12))
+
+#define reassemble_14(as14) \
+  (  (((as14) & 0x1fff) << 1) \
+   | (((as14) & 0x2000) >> 13))
+
 auto void __attribute__((always_inline))
 elf_machine_rela (struct link_map *map, 
                  const Elf32_Rela *reloc,
@@ -573,6 +586,27 @@
        }
       break;
 
+    case R_PARISC_DIR21L:
+      {
+       unsigned int insn = *(unsigned int *)reloc_addr;
+        value = sym_map->l_addr + sym->st_value 
+               + ((reloc->r_addend + 0x1000) & -0x2000);
+       value = value >> 11;
+       insn = (insn &~ 0x1fffff) | reassemble_21 (value);
+       *(unsigned int *)reloc_addr = insn;
+      }
+      return;
+
+    case R_PARISC_DIR14R:
+      {
+       unsigned int insn = *(unsigned int *)reloc_addr;
+       value = ((sym_map->l_addr + sym->st_value) & 0x7ff) 
+               + (((reloc->r_addend & 0x1fff) ^ 0x1000) - 0x1000);
+       insn = (insn &~ 0x3fff) | reassemble_14 (value);
+       *(unsigned int *)reloc_addr = insn;
+      }
+      return;
+
     case R_PARISC_PLABEL32:
       /* Easy rule: If there is a symbol and it is global, then we
          need to make a dynamic function descriptor.  Otherwise we
@@ -591,6 +625,31 @@
       value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 
2);
       break;
 
+    case R_PARISC_PLABEL21L:
+    case R_PARISC_PLABEL14R:
+      {
+       unsigned int insn = *(unsigned int *)reloc_addr;
+
+        if (__builtin_expect (sym == NULL, 0))
+          break;
+
+        value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) 
| 2);
+
+        if (r_type == R_PARISC_PLABEL21L)
+         {
+           value >>= 11;
+           insn = (insn &~ 0x1fffff) | reassemble_21 (value);
+         }
+        else
+         {
+           value &= 0x7ff;
+           insn = (insn &~ 0x3fff) | reassemble_14 (value);
+         }
+
+       *(unsigned int *)reloc_addr = insn;
+      }
+      return;
+
     case R_PARISC_IPLT:
       if (__builtin_expect (sym_map != NULL, 1))
         {

Reply via email to