This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH:


We need dynamic relocation for STT_GNU_IFUNC symbol only when there is a
non-GOT reference in a shared object.

For STT_GNU_IFUNC symbol, .got.plt has the real function addres and
.got has the PLT entry adddress.  We will load the GOT entry with the
PLT entry if it used.  For branch, it uses .got.plt.  For symbol value,

1. Use .got.plt in a shared object if it is forced local or not dynamic.
2. Use .got.plt in a non-shared object if pointer equality isn't needed.
3. Use .got.plt if .got isn't used.
4. Otherwise use .got so that the single copy will be used among different
objects at run-time.

We only need to relocate .got entry in shared object.

I am checking in this patch to fix it.

H.J.
----
2009-06-06  H.J. Lu  <hongjiu.lu@intel.com>

	* elf32-i386.c (elf_i386_check_relocs): Make room for dynamic
	relocation for R_386_32 against STT_GNU_IFUNC symbol when
	building shared object.  Check info->executable instead of
	!info->shared when setting non_got_ref.
	(elf_i386_allocate_dynrelocs): Allocate dynamic relocation
	for non-GOT reference of STT_GNU_IFUNC symbol in shared
	object. Allocate GOT relocation agsinst STT_GNU_IFUNC
	symbol if needed.
	(elf_i386_relocate_section): Output dynamic relocation for
	R_386_32 against STT_GNU_IFUNC symbol to get the real
	function address when building shared object.
	(elf_i386_finish_dynamic_symbol): Output R_386_GLOB_DAT
	relocation for STT_GNU_IFUNC symbol in shared object.

	* elf64-x86-64.c (elf64_x86_64_check_relocs): Make room for
	dynamic relocation for R_X86_64_64 against STT_GNU_IFUNC
	symbol when building shared object.  Check info->executable
	instead of !info->shared when setting non_got_ref.
	(elf64_x86_64_allocate_dynrelocs): Allocate dynamic relocation
	for non-GOT reference of STT_GNU_IFUNC symbol in shared
	library. Allocate GOT relocation agsinst STT_GNU_IFUNC symbol
	if needed.
	(elf64_x86_64_relocate_section): Output dynamic relocation
	for R_X86_64_64 against STT_GNU_IFUNC symbol to get the real
	function address when building shared object.
	(elf64_x86_64_finish_dynamic_symbol): Output R_X86_64_GLOB_DAT
	relocation for STT_GNU_IFUNC symbol in shared object.

Index: elf32-i386.c
===================================================================
--- elf32-i386.c	(revision 6072)
+++ elf32-i386.c	(working copy)
@@ -1325,10 +1325,48 @@ elf_i386_check_relocs (bfd *abfd,
 		   return FALSE;
 
 		case R_386_32:
+		  h->non_got_ref = 1;
+		  h->pointer_equality_needed = 1;
+		  if (info->shared)
+		    {
+		      struct elf_i386_dyn_relocs *p;
+		      struct elf_i386_dyn_relocs **head;
+
+		      /* We must copy these reloc types into the
+			 output file.  Create a reloc section in
+			 dynobj and make room for this reloc.  */
+		      if (sreloc == NULL)
+			{
+			  if (htab->elf.dynobj == NULL)
+			    htab->elf.dynobj = abfd;
+
+			  sreloc = _bfd_elf_make_dynamic_reloc_section
+			    (sec, htab->elf.dynobj, 2, abfd, FALSE);
+
+			  if (sreloc == NULL)
+			    return FALSE;
+			}
+
+		      head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs;
+		      p = *head;
+		      if (p == NULL || p->sec != sec)
+			{
+			  bfd_size_type amt = sizeof *p;
+			  p = bfd_alloc (htab->elf.dynobj, amt);
+			  if (p == NULL)
+			    return FALSE;
+			  p->next = *head;
+			  *head = p;
+			  p->sec = sec;
+			  p->count = 0;
+			  p->pc_count = 0;
+			}
+		      p->count += 1;
+		    }
+		  break;
+
 		case R_386_PC32:
 		  h->non_got_ref = 1;
-		  if (r_type != R_386_PC32)
-		    h->pointer_equality_needed = 1;
 		  break;
 
 		case R_386_PLT32:
@@ -1501,7 +1539,7 @@ elf_i386_check_relocs (bfd *abfd,
 
 	case R_386_32:
 	case R_386_PC32:
-	  if (h != NULL && !info->shared)
+	  if (h != NULL && info->executable)
 	    {
 	      /* If this reloc is in a read-only section, we might
 		 need a copy reloc.  We can't check reliably at this
@@ -1957,7 +1995,7 @@ elf_i386_allocate_dynrelocs (struct elf_
 
       /* When building a static executable, use .iplt, .igot.plt and
 	 .rel.iplt sections for STT_GNU_IFUNC symbols.  */
-      if (htab->splt != 0)
+      if (htab->splt != NULL)
 	{
 	  plt = htab->splt;
 	  gotplt = htab->sgotplt;
@@ -1992,34 +2030,50 @@ elf_i386_allocate_dynrelocs (struct elf_
       relplt->size += sizeof (Elf32_External_Rel);
       relplt->reloc_count++;
 
-      /* No need for dynamic relocation for local STT_GNU_IFUNC symbol.
-	 Discard space for relocations against it.  */
-      if (h->dynindx == -1 || h->forced_local)
+      /* We need dynamic relocation for STT_GNU_IFUNC symbol only
+	 when there is a non-GOT reference in a shared object.  */
+      if (!info->shared
+	  || !h->non_got_ref)
 	eh->dyn_relocs = NULL;
 
-      /* STT_GNU_IFUNC symbol uses .got.plt, not .got.  But for
-	 shared library, we must go through GOT and we can't
-	 use R_386_IRELATIVE unless it is forced local.   */
-      if (info->executable
-	  || info->symbolic
-	  || h->forced_local)
-	{
-	  if (h->pointer_equality_needed
-	      && htab->sgot != NULL)
-	    {
-	      /* We can't use .got.plt, which contains the real
-		 function addres, since we need pointer equality.
-		 We will load the GOT entry with the PLT entry
-		 in elf_i386_finish_dynamic_symbol and don't
-		 need GOT relocation.  */
-	      h->got.offset = htab->sgot->size;
-	      htab->sgot->size += 4;
-	      eh->tlsdesc_got = (bfd_vma) -1;
-	      goto skip_relgot;
-	    }
-	  else
-	    h->got.refcount = 0;
+      /* Finally, allocate space.  */
+      for (p = eh->dyn_relocs; p != NULL; p = p->next)
+	{
+	  asection * sreloc = elf_section_data (p->sec)->sreloc;
+	  sreloc->size += p->count * sizeof (Elf32_External_Rel);
+	}
+
+      /* For STT_GNU_IFUNC symbol, .got.plt has the real function
+	 addres and .got has the PLT entry adddress.  We will load
+	 the GOT entry with the PLT entry in finish_dynamic_symbol if
+	 it is used.  For branch, it uses .got.plt.  For symbol value,
+	 1. Use .got.plt in a shared object if it is forced local or
+	 not dynamic.
+	 2. Use .got.plt in a non-shared object if pointer equality 
+	 isn't needed.
+	 3. Use .got.plt if .got isn't used.
+	 4. Otherwise use .got so that it can be shared among different
+	 objects at run-time.
+	 We only need to relocate .got entry in shared object.  */
+      if ((info->shared
+	   && (h->dynindx == -1
+	       || h->forced_local))
+	  || (!info->shared
+	      && !h->pointer_equality_needed)
+	  || htab->sgot == NULL)
+	{
+	  /* Use .got.plt.  */
+	  h->got.offset = (bfd_vma) -1;
 	}
+      else
+	{
+	  h->got.offset = htab->sgot->size;
+	  htab->sgot->size += 4;
+	  if (info->shared)
+	    htab->srelgot->size += sizeof (Elf32_External_Rel);
+	}
+
+      return TRUE;
     }
   else if (htab->elf.dynamic_sections_created
 	   && h->plt.refcount > 0)
@@ -2166,7 +2220,6 @@ elf_i386_allocate_dynrelocs (struct elf_
   else
     h->got.offset = (bfd_vma) -1;
 
-skip_relgot:
   if (eh->dyn_relocs == NULL)
     return TRUE;
 
@@ -2920,6 +2973,57 @@ elf_i386_relocate_section (bfd *output_b
 	      return FALSE;
 
 	    case R_386_32:
+	      /* Generate dynamic relcoation only when there is a
+		 non-GOF reference in a shared object.  */
+	      if (info->shared && h->non_got_ref)
+		{
+		  Elf_Internal_Rela outrel;
+		  bfd_byte *loc;
+		  asection *sreloc;
+		  bfd_vma offset;
+
+		  /* Need a dynamic relocation get the the real
+		     function adddress.  */
+		  offset = _bfd_elf_section_offset (output_bfd,
+						    info,
+						    input_section,
+						    rel->r_offset);
+		  if (offset == (bfd_vma) -1
+		      || offset == (bfd_vma) -2)
+		    abort ();
+
+		  outrel.r_offset = (input_section->output_section->vma
+				     + input_section->output_offset
+				     + offset);
+
+		  if (h->dynindx == -1
+		      || h->forced_local)
+		    {
+		      /* This symbol is resolved locally.  */
+		      outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+		      bfd_put_32 (output_bfd,
+				  (h->root.u.def.value 
+				   + h->root.u.def.section->output_section->vma
+				   + h->root.u.def.section->output_offset),
+				  contents + offset);
+		    }
+		  else
+		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+
+		  sreloc = elf_section_data (input_section)->sreloc;
+		  loc = sreloc->contents;
+		  loc += (sreloc->reloc_count++
+			  * sizeof (Elf32_External_Rel));
+		  bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+
+		  /* If this reloc is against an external symbol, we
+		     do not want to fiddle with the addend.  Otherwise,
+		     we need to include the symbol value so that it
+		     becomes an addend for the dynamic reloc.  For an
+		     internal symbol, we have updated addend.  */
+		  continue;
+		}
+
 	    case R_386_PC32:
 	    case R_386_PLT32:
 	      goto do_relocation;
@@ -3950,7 +4054,7 @@ elf_i386_finish_dynamic_symbol (bfd *out
 
       /* When building a static executable, use .iplt, .igot.plt and
 	 .rel.iplt sections for STT_GNU_IFUNC symbols.  */
-      if (htab->splt != 0)
+      if (htab->splt != NULL)
 	{
 	  plt = htab->splt;
 	  gotplt = htab->sgotplt;
@@ -4132,25 +4236,29 @@ elf_i386_finish_dynamic_symbol (bfd *out
 	 of a version file, we just want to emit a RELATIVE reloc.
 	 The entry in the global offset table will already have been
 	 initialized in the relocate_section function.  */
-      if ((info->executable
-	   || info->symbolic
-	   || h->forced_local)
-	  && h->def_regular
-	  && h->pointer_equality_needed
+      if (h->def_regular
 	  && h->type == STT_GNU_IFUNC)
 	{
-	  /* The STT_GNU_IFUNC symbol is locally defined.  But we can't
-	     use .got.plt, which contains the real function addres,
-	     since we need pointer equality.  We load the GOT entry
-	     with the PLT entry without relocation.  */
-	  asection *plt = htab->splt ? htab->splt : htab->iplt;
-	  if (htab->sgot == NULL
-	      || h->plt.offset == (bfd_vma) -1)
-	    abort ();
-	  bfd_put_32 (output_bfd, (plt->output_section->vma
-				   + plt->output_offset + h->plt.offset),
-		      htab->sgot->contents + h->got.offset);
-	  return TRUE;
+	  if (info->shared)
+	    {
+	      /* Generate R_386_GLOB_DAT.  */
+	      goto do_glob_dat;
+	    }
+	  else
+	    {
+	      if (!h->pointer_equality_needed)
+		abort ();
+
+	      /* For non-shared object, we can't use .got.plt, which
+		 contains the real function addres if we need pointer
+		 equality.  We load the GOT entry with the PLT entry.  */
+	      asection *plt = htab->splt ? htab->splt : htab->iplt;
+	      bfd_put_32 (output_bfd,
+			  (plt->output_section->vma
+			   + plt->output_offset + h->plt.offset),
+			  htab->sgot->contents + h->got.offset);
+	      return TRUE;
+	    }
 	}
       else if (info->shared
 	       && SYMBOL_REFERENCES_LOCAL (info, h))
@@ -4161,6 +4269,7 @@ elf_i386_finish_dynamic_symbol (bfd *out
       else
 	{
 	  BFD_ASSERT((h->got.offset & 1) == 0);
+do_glob_dat:
 	  bfd_put_32 (output_bfd, (bfd_vma) 0,
 		      htab->sgot->contents + h->got.offset);
 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
Index: elf64-x86-64.c
===================================================================
--- elf64-x86-64.c	(revision 6072)
+++ elf64-x86-64.c	(working copy)
@@ -1110,9 +1110,51 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		   bfd_set_error (bfd_error_bad_value);
 		   return FALSE;
 
+		case R_X86_64_64:
+		  h->non_got_ref = 1;
+		  h->pointer_equality_needed = 1;
+		  if (info->shared)
+		    {
+		      struct elf64_x86_64_dyn_relocs *p;
+		      struct elf64_x86_64_dyn_relocs **head;
+
+		      /* We must copy these reloc types into the output
+			 file.  Create a reloc section in dynobj and
+			 make room for this reloc.  */
+		      if (sreloc == NULL)
+			{
+			  if (htab->elf.dynobj == NULL)
+			    htab->elf.dynobj = abfd;
+
+			  sreloc = _bfd_elf_make_dynamic_reloc_section
+			    (sec, htab->elf.dynobj, 3, abfd, TRUE);
+
+			  if (sreloc == NULL)
+			    return FALSE;
+			}
+		      
+		      head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs;
+		      p = *head;
+		      if (p == NULL || p->sec != sec)
+			{
+			  bfd_size_type amt = sizeof *p;
+
+			  p = ((struct elf64_x86_64_dyn_relocs *)
+			       bfd_alloc (htab->elf.dynobj, amt));
+			  if (p == NULL)
+			    return FALSE;
+			  p->next = *head;
+			  *head = p;
+			  p->sec = sec;
+			  p->count = 0;
+			  p->pc_count = 0;
+			}
+		      p->count += 1;
+		    }
+		  break;
+
 		case R_X86_64_32S:
 		case R_X86_64_32:
-		case R_X86_64_64:
 		case R_X86_64_PC32:
 		case R_X86_64_PC64:
 		  h->non_got_ref = 1;
@@ -1329,7 +1371,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	case R_X86_64_PC32:
 	case R_X86_64_PC64:
 	case R_X86_64_64:
-	  if (h != NULL && !info->shared)
+	  if (h != NULL && info->executable)
 	    {
 	      /* If this reloc is in a read-only section, we might
 		 need a copy reloc.  We can't check reliably at this
@@ -1795,7 +1837,7 @@ elf64_x86_64_allocate_dynrelocs (struct 
 
       /* When building a static executable, use .iplt, .igot.plt and
 	 .rela.iplt sections for STT_GNU_IFUNC symbols.  */
-      if (htab->splt != 0)
+      if (htab->splt != NULL)
 	{
 	  plt = htab->splt;
 	  gotplt = htab->sgotplt;
@@ -1830,34 +1872,50 @@ elf64_x86_64_allocate_dynrelocs (struct 
       relplt->size += sizeof (Elf64_External_Rela);
       relplt->reloc_count++;
 
-      /* No need for dynamic relocation for local STT_GNU_IFUNC symbol.
-	 Discard space for relocations against it.  */
-      if (h->dynindx == -1 || h->forced_local)
+      /* We need dynamic relocation for STT_GNU_IFUNC symbol only
+	 when there is a non-GOT reference in a shared object.  */
+      if (!info->shared
+	  || !h->non_got_ref)
 	eh->dyn_relocs = NULL;
 
-      /* STT_GNU_IFUNC symbol uses .got.plt, not .got.  But for
-	 shared library, we must go through GOT and we can't
-	 use R_X86_64_IRELATIVE unless it is forced local.   */
-      if (info->executable
-	  || info->symbolic
-	  || h->forced_local)
-	{
-	  if (h->pointer_equality_needed
-	      && htab->sgot != NULL)
-	    {
-	      /* We can't use .got.plt, which contains the real
-		 function addres, since we need pointer equality.
-		 We will load the GOT entry with the PLT entry
-		 in elf64_x86_64_finish_dynamic_symbol and don't
-		 need GOT relocation.  */
-	      h->got.offset = htab->sgot->size;
-	      htab->sgot->size += GOT_ENTRY_SIZE;
-	      eh->tlsdesc_got = (bfd_vma) -1;
-	      goto skip_relgot;
-	    }
-	  else
-	    h->got.refcount = 0;
+      /* Finally, allocate space.  */
+      for (p = eh->dyn_relocs; p != NULL; p = p->next)
+	{
+	  asection * sreloc = elf_section_data (p->sec)->sreloc;
+	  sreloc->size += p->count * sizeof (Elf64_External_Rela);
+	}
+
+      /* For STT_GNU_IFUNC symbol, .got.plt has the real function
+	 addres and .got has the PLT entry adddress.  We will load
+	 the GOT entry with the PLT entry in finish_dynamic_symbol if
+	 it is used.  For branch, it uses .got.plt.  For symbol value,
+	 1. Use .got.plt in a shared object if it is forced local or
+	 not dynamic.
+	 2. Use .got.plt in a non-shared object if pointer equality 
+	 isn't needed.
+	 3. Use .got.plt if .got isn't used.
+	 4. Otherwise use .got so that it can be shared among different
+	 objects at run-time.
+	 We only need to relocate .got entry in shared object.  */
+      if ((info->shared
+	   && (h->dynindx == -1
+	       || h->forced_local))
+	  || (!info->shared
+	      && !h->pointer_equality_needed)
+	  || htab->sgot == NULL)
+	{
+	  /* Use .got.plt.  */
+	  h->got.offset = (bfd_vma) -1;
 	}
+      else
+	{
+	  h->got.offset = htab->sgot->size;
+	  htab->sgot->size += GOT_ENTRY_SIZE;
+	  if (info->shared)
+	    htab->srelgot->size += sizeof (Elf64_External_Rela);
+	}
+
+      return TRUE;
     }
   else if (htab->elf.dynamic_sections_created
 	   && h->plt.refcount > 0)
@@ -1984,7 +2042,6 @@ elf64_x86_64_allocate_dynrelocs (struct 
   else
     h->got.offset = (bfd_vma) -1;
 
-skip_relgot:
   if (eh->dyn_relocs == NULL)
     return TRUE;
 
@@ -2621,11 +2678,73 @@ elf64_x86_64_relocate_section (bfd *outp
 	      return FALSE;
 
 	    case R_X86_64_32S:
-	      if (!info->executable)
+	      if (info->shared)
 		abort ();
+	      goto do_relocation;
+
+	    case R_X86_64_64: 
+	      if (rel->r_addend != 0)
+		{
+		  (*_bfd_error_handler)
+		    (_("%B: relocation %s against STT_GNU_IFUNC "
+		       "symbol `%s' has non-zero addend: %d"),
+		     input_bfd, x86_64_elf_howto_table[r_type].name,
+		     h->root.root.string, rel->r_addend);
+		  bfd_set_error (bfd_error_bad_value);
+		  return FALSE;
+		}
+
+	      /* Generate dynamic relcoation only when there is a
+		 non-GOF reference in a shared object.  */
+	      if (info->shared && h->non_got_ref)
+		{
+		  Elf_Internal_Rela outrel;
+		  bfd_byte *loc;
+		  asection *sreloc;
+
+		  /* Need a dynamic relocation get the the real
+		     function address. */
+		  outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+							     info,
+							     input_section,
+							     rel->r_offset);
+		  if (outrel.r_offset == (bfd_vma) -1
+		      || outrel.r_offset == (bfd_vma) -2)
+		    abort ();
+
+		  outrel.r_offset += (input_section->output_section->vma
+				      + input_section->output_offset);
+
+		  if (h->dynindx == -1
+		      || h->forced_local)
+		    {
+		      /* This symbol is resolved locally.  */
+		      outrel.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
+		      outrel.r_addend = (h->root.u.def.value
+					 + h->root.u.def.section->output_section->vma
+					 + h->root.u.def.section->output_offset);
+		    }
+		  else
+		    {
+		      outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+		      outrel.r_addend = 0;
+		    }
+
+		  sreloc = elf_section_data (input_section)->sreloc;
+		  loc = sreloc->contents;
+		  loc += (sreloc->reloc_count++
+			  * sizeof (Elf64_External_Rela));
+		  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+		  /* If this reloc is against an external symbol, we
+		     do not want to fiddle with the addend.  Otherwise,
+		     we need to include the symbol value so that it
+		     becomes an addend for the dynamic reloc.  For an
+		     internal symbol, we have updated addend.  */
+		  continue;
+		}
 
 	    case R_X86_64_32:
-	    case R_X86_64_64:
 	    case R_X86_64_PC32:
 	    case R_X86_64_PC64:
 	    case R_X86_64_PLT32:
@@ -3596,7 +3715,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
 
       /* When building a static executable, use .iplt, .igot.plt and
 	 .rela.iplt sections for STT_GNU_IFUNC symbols.  */
-      if (htab->splt != 0)
+      if (htab->splt != NULL)
 	{
 	  plt = htab->splt;
 	  gotplt = htab->sgotplt;
@@ -3741,25 +3860,29 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
 	 of a version file, we just want to emit a RELATIVE reloc.
 	 The entry in the global offset table will already have been
 	 initialized in the relocate_section function.  */
-      if ((info->executable
-	   || info->symbolic
-	   || h->forced_local)
-	  && h->def_regular
-	  && h->pointer_equality_needed
+      if (h->def_regular
 	  && h->type == STT_GNU_IFUNC)
 	{
-	  /* The STT_GNU_IFUNC symbol is locally defined.  But we can't
-	     use .got.plt, which contains the real function addres,
-	     since we need pointer equality.  We load the GOT entry
-	     with the PLT entry without relocation.  */
-	  asection *plt = htab->splt ? htab->splt : htab->iplt;
-	  if (htab->sgot == NULL
-	      || h->plt.offset == (bfd_vma) -1)
-	    abort ();
-	  bfd_put_64 (output_bfd, (plt->output_section->vma
-				   + plt->output_offset + h->plt.offset),
-		      htab->sgot->contents + h->got.offset);
-	  return TRUE;
+	  if (info->shared)
+	    {
+	      /* Generate R_X86_64_GLOB_DAT.  */
+	      goto do_glob_dat;
+	    }
+	  else
+	    {
+	      if (!h->pointer_equality_needed)
+		abort ();
+
+	      /* For non-shared object, we can't use .got.plt, which
+		 contains the real function addres if we need pointer
+		 equality.  We load the GOT entry with the PLT entry.  */
+	      asection *plt = htab->splt ? htab->splt : htab->iplt;
+	      bfd_put_64 (output_bfd, (plt->output_section->vma
+				       + plt->output_offset
+				       + h->plt.offset),
+			  htab->sgot->contents + h->got.offset);
+	      return TRUE;
+	    }
 	}
       else if (info->shared
 	       && SYMBOL_REFERENCES_LOCAL (info, h))
@@ -3775,6 +3898,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
       else
 	{
 	  BFD_ASSERT((h->got.offset & 1) == 0);
+do_glob_dat:
 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
 		      htab->sgot->contents + h->got.offset);
 	  rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]