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)) {