zero index dynamic tls relocs generated for the GOT.  Tidy code.
	Set "relocation" to 1 on DTPMOD32 relocs.  Optimize HA adjustment.
	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
	* ld-powerpc/tlsso.r: Adjust for corrected zero symbol index relocs.
	* ld-powerpc/tlsso32.r: Likewise.
+2003-03-11  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-ppc.c (ppc_elf_relocate_section): Subtract tls seg vma from
+       zero index dynamic tls relocs generated for the GOT.  Tidy code.
+       Set "relocation" to 1 on DTPMOD32 relocs.  Optimize HA adjustment.
+       * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
 2003-03-07  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-ppc.c (ppc_elf_relocate_section): Don't look for a nop after
 
                        outrel.r_offset = (htab->got->output_section->vma
                                           + htab->got->output_offset
                                           + off);
+                       outrel.r_addend = 0;
                        if (tls_ty & (TLS_LD | TLS_GD))
                          {
                            outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPMOD32);
-                           outrel.r_addend = 0;
                            if (tls_ty == (TLS_TLS | TLS_GD))
                              {
                                loc = htab->relgot->contents;
                                        * sizeof (Elf32_External_Rela));
                                bfd_elf32_swap_reloca_out (output_bfd,
                                                           &outrel, loc);
+                               outrel.r_offset += 4;
                                outrel.r_info
                                  = ELF32_R_INFO (indx, R_PPC_DTPREL32);
-                               outrel.r_offset += 4;
                              }
                          }
                        else if (tls_ty == (TLS_TLS | TLS_DTPREL))
                          outrel.r_info = ELF32_R_INFO (indx, R_PPC_RELATIVE);
                        else
                          outrel.r_info = ELF32_R_INFO (indx, R_PPC_GLOB_DAT);
-                       outrel.r_addend = 0;
                        if (indx == 0)
-                         outrel.r_addend += relocation;
+                         {
+                           outrel.r_addend += relocation;
+                           if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
+                             outrel.r_addend -= htab->tls_sec->vma;
+                         }
                        loc = htab->relgot->contents;
                        loc += (htab->relgot->reloc_count++
                                * sizeof (Elf32_External_Rela));
          addend -= htab->tls_sec->vma + DTP_OFFSET;
          goto dodyn;
 
+       case R_PPC_DTPMOD32:
+         relocation = 1;
+         addend = 0;
+         goto dodyn;
+
        case R_PPC_REL24:
        case R_PPC_REL32:
        case R_PPC_REL14:
        case R_PPC_ADDR14_BRNTAKEN:
        case R_PPC_UADDR32:
        case R_PPC_UADDR16:
-       case R_PPC_DTPMOD32:
          /* r_symndx will be zero only for relocs against symbols
             from removed linkonce sections, or sections discarded by
             a linker script.  */
             'sec' would be NULL, and we should leave the symbol
             alone (it will be set to zero elsewhere in the link).  */
          if (sec != NULL)
-           /* Add 0x10000 if sign bit in 0:15 is set.  */
-           addend += ((relocation + addend) & 0x8000) << 1;
+           /* Add 0x10000 if sign bit in 0:15 is set.
+              Bits 0:15 are not used.  */
+           addend += 0x8000;
          break;
        }
 
 
                                       + off);
                    if (tls_type & (TLS_LD | TLS_GD))
                      {
-                       outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
                        outrel.r_addend = 0;
+                       outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
                        if (tls_type == (TLS_TLS | TLS_GD))
                          {
                            loc = htab->srelgot->contents;
                                    * sizeof (Elf64_External_Rela));
                            bfd_elf64_swap_reloca_out (output_bfd,
                                                       &outrel, loc);
+                           outrel.r_offset += 8;
                            outrel.r_info
                              = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
-                           outrel.r_offset += 8;
                          }
                      }
                    else if (tls_type == (TLS_TLS | TLS_DTPREL))
                      outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT);
                    outrel.r_addend = rel->r_addend;
                    if (indx == 0)
-                     outrel.r_addend += relocation;
+                     {
+                       outrel.r_addend += relocation;
+                       if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
+                         outrel.r_addend -= htab->tls_sec->vma;
+                     }
                    loc = htab->srelgot->contents;
                    loc += (htab->srelgot->reloc_count++
                            * sizeof (Elf64_External_Rela));
          addend -= htab->tls_sec->vma + DTP_OFFSET;
          break;
 
+       case R_PPC64_DTPMOD64:
+         relocation = 1;
+         addend = 0;
+         goto dodyn;
+
        case R_PPC64_TPREL64:
          addend -= htab->tls_sec->vma + TP_OFFSET;
          goto dodyn;
 
          /* Relocations that may need to be propagated if this is a
             dynamic object.  */
-       case R_PPC64_DTPMOD64:
        case R_PPC64_REL30:
        case R_PPC64_REL32:
        case R_PPC64_REL64:
             'sec' would be NULL, and we should leave the symbol
             alone (it will be set to zero elsewhere in the link).  */
          if (sec != NULL)
-           /* Add 0x10000 if sign bit in 0:15 is set.  */
-           addend += ((relocation + addend) & 0x8000) << 1;
+           /* Add 0x10000 if sign bit in 0:15 is set.
+              Bits 0:15 are not used.  */
+           addend += 0x8000;
          break;
 
        case R_PPC64_ADDR16_DS:
 
+2003-03-11  Alan Modra  <amodra@bigpond.net.au>
+
+       * ld-powerpc/tlsso.r: Adjust for corrected zero symbol index relocs.
+       * ld-powerpc/tlsso32.r: Likewise.
+
 2003-02-18  Alan Modra  <amodra@bigpond.net.au>
 
        * ld-powerpc/tlsexe.d: Update for changed handling of invalid LD
 
 0+7ca +0+900000046 R_PPC64_TPREL16_LO +0+107f8 \.tdata \+ 30
 0+10988 +0+44 R_PPC64_DTPMOD64 +0+
 0+10998 +0+44 R_PPC64_DTPMOD64 +0+
-0+109a0 +0+4e R_PPC64_DTPREL64 +0+107f8
-0+109a8 +0+4e R_PPC64_DTPREL64 +0+10810
+0+109a0 +0+4e R_PPC64_DTPREL64 +0+
+0+109a8 +0+4e R_PPC64_DTPREL64 +0+18
 0+109b0 +0+1300000044 R_PPC64_DTPMOD64 +0+ gd \+ 0
 0+109b8 +0+130000004e R_PPC64_DTPREL64 +0+ gd \+ 0
 0+109c0 +0+1b0000004e R_PPC64_DTPREL64 +0+50 ld2 \+ 0
 
 0+5a6 +0+846 R_PPC_TPREL16_LO +0+105a8 +\.tdata \+ 105c0
 0+10674 +0+44 R_PPC_DTPMOD32 +0+
 0+1067c +0+44 R_PPC_DTPMOD32 +0+
-0+10680 +0+4e R_PPC_DTPREL32 +0+105a8
+0+10680 +0+4e R_PPC_DTPREL32 +0+
 0+10684 +0+1244 R_PPC_DTPMOD32 +0+ +gd \+ 0
 0+10688 +0+124e R_PPC_DTPREL32 +0+ +gd \+ 0
 0+1068c +0+2144 R_PPC_DTPMOD32 +0+1c +gd0 \+ 0