This is the mail archive of the binutils@sources.redhat.com 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]

RFA: Support for Thumb in dynamic objects


This patch adds limited support for Thumb in dynamic objects.  It causes the
glue stubs not to be exported from the object, and uses a prefix to the PLT
entry to change mode instead of a glue stub off somewhere else.  It also
fixes objdump to display thumb functions using the STT_ARM_TFUNC type as
functions.

It's easy to stop using STT_ARM_TFUNC and start using an odd symbol value
for dynamic objects; but I didn't want to mix it with this patch.  So that's
a TODO.  Other TODOs are:
  - some kind of mappng symbols in the .plt section so that the disassembler
    knows what to do (we can't easily generate new local symbols from the
    backend, but I'm sure there's a way around it); this is very important
    for GDB.
  - Related, synthetic named symbols for the .plt as implemented for other
    architectures.
  - BLX support.  The only reason I didn't do this is that there's no easy
    way to tell if using BLX is OK; i.e. whether we can assume the presence
    of ARM v5t.

OK?  Comments?

-- 
Daniel Jacobowitz

2004-11-16  Daniel Jacobowitz  <dan@codesourcery.com>

	* elf32-arm.c (PLT_THUMB_STUB_SIZE): Define.
	(elf32_arm_plt_thumb_stub): New.
	(struct elf32_arm_link_hash_entry): Add plt_thumb_refcount
	and plt_got_offset.
	(elf32_arm_link_hash_traverse): Fix typo.
	(elf32_arm_link_hash_table): Add obfd.
	(elf32_arm_link_hash_newfunc): Initialize new fields.
	(elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount.
	(elf32_arm_link_hash_table_create): Initialize obfd.
	(record_arm_to_thumb_glue): Mark the glue as a local ARM function.
	(record_thumb_to_arm_glue): Mark the glue as a local Thumb function.
	(bfd_elf32_arm_get_bfd_for_interworking): Verify that the
	interworking BFD is not dynamic.
	(bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32.  Do
	not emit glue for PLT references.
	(elf32_arm_final_link_relocate): Handle Thumb functions.  Do not
	emit glue for PLT references.  Support the Thumb PLT prefix.
	(elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and
	plt_thumb_refcount.
	(elf32_arm_check_relocs): Likewise.
	(elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and
	plt_thumb_refcount.
	(allocate_dynrelocs): Handle Thumb PLT references.
	(elf32_arm_finish_dynamic_symbol): Likewise.
	(elf32_arm_symbol_processing): New function.
	(elf_backend_symbol_processing): Define.

2004-11-16  Daniel Jacobowitz  <dan@codesourcery.com>

	* gas/arm/mapping.d: Expect F markers for Thumb code.

2004-11-16  Daniel Jacobowitz  <dan@codesourcery.com>

	* emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use
	a dynamic object for stubs.

2004-11-16  Daniel Jacobowitz  <dan@codesourcery.com>

	* ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s,
	ld-arm/mixed-app.sym, ld-arm/mixed-lib.d, ld-arm/mixed-lib.r,
	ld-arm/mixed-lib.s, ld-arm/mixed-lib.sym: New files.
	* ld-arm/arm-elf.exp: Run them.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/bfd/elf32-arm.c,v
retrieving revision 1.7
diff -u -p -r1.7 elf32-arm.c
--- bfd/elf32-arm.c	13 Nov 2004 13:38:15 -0000	1.7
+++ bfd/elf32-arm.c	16 Nov 2004 21:13:20 -0000
@@ -1063,6 +1063,13 @@ static const bfd_vma elf32_arm_plt_entry
 
 #endif
 
+/* An initial stub used if the PLT entry is referenced from Thumb code.  */
+#define PLT_THUMB_STUB_SIZE 4
+static const bfd_vma elf32_arm_plt_thumb_stub [1] =
+  {
+    0x46c04778		/* bx pc; nop (in Thumb mode) */
+  };
+
 /* The entries in a PLT when using a DLL-based target with multiple
    address spaces.  */
 static const bfd_vma elf32_arm_symbian_plt_entry [] = 
@@ -1116,13 +1123,22 @@ struct elf32_arm_link_hash_entry
 
     /* Number of PC relative relocs copied for this symbol.  */
     struct elf32_arm_relocs_copied * relocs_copied;
+
+    /* We reference count Thumb references to a PLT entry separately,
+       so that we can emit the Thumb trampoline only if needed.  */
+    bfd_signed_vma plt_thumb_refcount;
+
+    /* Since PLT entries have variable size if the Thumb prologue is
+       used, we need to record the index into .got.plt instead of
+       recomputing it from the PLT offset.  */
+    bfd_signed_vma plt_got_offset;
   };
 
 /* Traverse an arm ELF linker hash table.  */
 #define elf32_arm_link_hash_traverse(table, func, info)			\
   (elf_link_hash_traverse						\
    (&(table)->root,							\
-    (bfd_boolean (*) (struct elf_link_hash_entry *, void *))) (func), \
+    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),	\
     (info)))
 
 /* Get the ARM elf linker hash table from a link_info structure.  */
@@ -1178,6 +1194,9 @@ struct elf32_arm_link_hash_table
 
     /* Small local sym to section mapping cache.  */
     struct sym_sec_cache sym_sec;
+
+    /* For convenience in allocate_dynrelocs.  */
+    bfd * obfd;
   };
 
 /* Create an entry in an ARM ELF linker hash table.  */
@@ -1202,7 +1221,11 @@ elf32_arm_link_hash_newfunc (struct bfd_
 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
 				     table, string));
   if (ret != NULL)
-    ret->relocs_copied = NULL;
+    {
+      ret->relocs_copied = NULL;
+      ret->plt_thumb_refcount = 0;
+      ret->plt_got_offset = -1;
+    }
 
   return (struct bfd_hash_entry *) ret;
 }
@@ -1315,6 +1338,17 @@ elf32_arm_copy_indirect_symbol (const st
       eind->relocs_copied = NULL;
     }
 
+  /* If the direct symbol already has an associated PLT entry, the
+     indirect symbol should not.  If it doesn't, swap refcount information
+     from the indirect symbol.  */
+  if (edir->plt_thumb_refcount == 0)
+    {
+      edir->plt_thumb_refcount = eind->plt_thumb_refcount;
+      eind->plt_thumb_refcount = 0;
+    }
+  else
+    BFD_ASSERT (eind->plt_thumb_refcount == 0);
+
   _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
@@ -1360,6 +1394,7 @@ elf32_arm_link_hash_table_create (bfd *a
 #endif
   ret->symbian_p = 0;
   ret->sym_sec.abfd = NULL;
+  ret->obfd = abfd;
 
   return &ret->root.root;
 }
@@ -1559,6 +1594,10 @@ record_arm_to_thumb_glue (struct bfd_lin
 				    tmp_name, BSF_GLOBAL, s, val,
 				    NULL, TRUE, FALSE, &bh);
 
+  myh = (struct elf_link_hash_entry *) bh;
+  myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+  myh->forced_local = 1;
+
   free (tmp_name);
 
   globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
@@ -1576,7 +1615,6 @@ record_thumb_to_arm_glue (struct bfd_lin
   struct elf_link_hash_entry *myh;
   struct bfd_link_hash_entry *bh;
   struct elf32_arm_link_hash_table *hash_table;
-  char bind;
   bfd_vma val;
 
   hash_table = elf32_arm_hash_table (link_info);
@@ -1614,8 +1652,8 @@ record_thumb_to_arm_glue (struct bfd_lin
 
   /* If we mark it 'Thumb', the disassembler will do a better job.  */
   myh = (struct elf_link_hash_entry *) bh;
-  bind = ELF_ST_BIND (myh->type);
-  myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
+  myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC);
+  myh->forced_local = 1;
 
   free (tmp_name);
 
@@ -1713,6 +1751,9 @@ bfd_elf32_arm_get_bfd_for_interworking (
   if (info->relocatable)
     return TRUE;
 
+  /* Make sure we don't attach the glue sections to a dynamic object.  */
+  BFD_ASSERT (!(abfd->flags & DYNAMIC));
+
   globals = elf32_arm_hash_table (info);
 
   BFD_ASSERT (globals != NULL);
@@ -1796,6 +1837,7 @@ bfd_elf32_arm_process_before_allocation 
 
 	  /* These are the only relocation types we care about.  */
 	  if (   r_type != R_ARM_PC24
+	      && r_type != R_ARM_PLT32
 #ifndef OLD_ARM_ABI
 	      && r_type != R_ARM_CALL
 	      && r_type != R_ARM_JUMP24
@@ -1834,6 +1876,11 @@ bfd_elf32_arm_process_before_allocation 
 	  if (h == NULL)
 	    continue;
 
+	  /* If the call will go through a PLT entry then we do not need
+	     glue.  */
+	  if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1)
+	    continue;
+
 	  switch (r_type)
 	    {
 	    case R_ARM_PC24:
@@ -2374,6 +2421,8 @@ elf32_arm_final_link_relocate (reloc_how
 
 	      /* This symbol is local, or marked to become local.  */
 	      relocate = TRUE;
+	      if (sym_flags == STT_ARM_TFUNC)
+		value |= 1;
 	      if (globals->symbian_p)
 		{
 		  /* On Symbian OS, the data segment and text segement
@@ -2652,8 +2701,11 @@ elf32_arm_final_link_relocate (reloc_how
 	  {
 	    /* If it is not a call to Thumb, assume call to Arm.
 	       If it is a call relative to a section name, then it is not a
-	       function call at all, but rather a long jump.  */
-	    if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
+	       function call at all, but rather a long jump.  Calls through
+	       the PLT do not require stubs.  */
+	    if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION
+		&& (h == NULL || splt == NULL
+		    || h->plt.offset == (bfd_vma) -1))
 	      {
 		if (elf32_thumb_to_arm_stub
 		    (info, sym_name, input_bfd, output_bfd, input_section,
@@ -2664,6 +2716,16 @@ elf32_arm_final_link_relocate (reloc_how
 	      }
 	  }
 
+	/* Handle calls via the PLT.  */
+	if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
+	  {
+	    value = (splt->output_section->vma
+		     + splt->output_offset
+		     + h->plt.offset);
+	    /* Target the Thumb stub before the ARM PLT entry.  */
+	    value -= 4;
+	  }
+
 	relocation = value + signed_addend;
 
 	relocation -= (input_section->output_section->vma
@@ -2911,6 +2973,13 @@ elf32_arm_final_link_relocate (reloc_how
 	    off &= ~1;
 	  else
 	    {
+	      /* If we are addressing a Thumb function, we need to
+		 adjust the address by one, so that attempts to
+		 call the function pointer will correctly
+		 interpret it as Thumb code.  */
+	      if (sym_flags == STT_ARM_TFUNC)
+		value |= 1;
+
 	      bfd_put_32 (output_bfd, value, sgot->contents + off);
 
 	      if (info->shared)
@@ -3873,6 +3942,9 @@ elf32_arm_gc_sweep_hook (bfd *          
 	case R_ARM_JUMP24:
 	case R_ARM_PREL31:
 #endif
+	case R_ARM_THM_PC22:
+	  /* Should the interworking branches be here also?  */
+
 	  r_symndx = ELF32_R_SYM (rel->r_info);
 	  if (r_symndx >= symtab_hdr->sh_info)
 	    {
@@ -3881,15 +3953,18 @@ elf32_arm_gc_sweep_hook (bfd *          
 	      struct elf32_arm_relocs_copied *p;
 
 	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	      eh = (struct elf32_arm_link_hash_entry *) h;
 
 	      if (h->plt.refcount > 0)
-		h->plt.refcount -= 1;
+		{
+		  h->plt.refcount -= 1;
+		  if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
+		    eh->plt_thumb_refcount--;
+		}
 
 	      if (r_type == R_ARM_ABS32
 		  || r_type == R_ARM_REL32)
 		{
-		  eh = (struct elf32_arm_link_hash_entry *) h;
-
 		  for (pp = &eh->relocs_copied; (p = *pp) != NULL;
 		       pp = &p->next)
 		  if (p->section == sec)
@@ -3948,6 +4023,7 @@ elf32_arm_check_relocs (bfd *abfd, struc
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
+      struct elf32_arm_link_hash_entry *eh;
       unsigned long r_symndx;
       int r_type;
 
@@ -3961,6 +4037,8 @@ elf32_arm_check_relocs (bfd *abfd, struc
       else
         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
+      eh = (struct elf32_arm_link_hash_entry *) h;
+
       switch (r_type)
         {
 	  case R_ARM_GOT32:
@@ -4015,6 +4093,8 @@ elf32_arm_check_relocs (bfd *abfd, struc
 	  case R_ARM_JUMP24:
 	  case R_ARM_PREL31:
 #endif
+	  case R_ARM_THM_PC22:
+	    /* Should the interworking branches be listed here?  */
 	    if (h != NULL)
 	      {
 		/* If this reloc is in a read-only section, we might
@@ -4036,12 +4116,16 @@ elf32_arm_check_relocs (bfd *abfd, struc
 		    || r_type == R_ARM_JUMP24
 		    || r_type == R_ARM_PREL31
 #endif
-		    || r_type == R_ARM_PLT32)
+		    || r_type == R_ARM_PLT32
+		    || r_type == R_ARM_THM_PC22)
 		  h->needs_plt = 1;
 
 		/* If we create a PLT entry, this relocation will reference
 		   it, even if it's an ABS32 relocation.  */
 		h->plt.refcount += 1;
+
+		if (r_type == R_ARM_THM_PC22)
+		  eh->plt_thumb_refcount += 1;
 	      }
 
 	    /* If we are creating a shared library, and this is a reloc
@@ -4065,7 +4149,8 @@ elf32_arm_check_relocs (bfd *abfd, struc
 		     && r_type != R_ARM_JUMP24
 		     && r_type != R_ARM_PREL31
 #endif
-		     && r_type != R_ARM_REL32)
+		     && r_type != R_ARM_REL32
+		     && r_type != R_ARM_THM_PC22)
 		    || (h != NULL
 			&& (! info->symbolic
 			    || !h->def_regular))))
@@ -4314,6 +4399,7 @@ elf32_arm_adjust_dynamic_symbol (struct 
   bfd * dynobj;
   asection * s;
   unsigned int power_of_two;
+  struct elf32_arm_link_hash_entry * eh;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -4325,10 +4411,12 @@ elf32_arm_adjust_dynamic_symbol (struct 
 		      && h->ref_regular
 		      && !h->def_regular)));
 
+  eh = (struct elf32_arm_link_hash_entry *) h;
+
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
      when we know the address of the .got section.  */
-  if (h->type == STT_FUNC
+  if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC
       || h->needs_plt)
     {
       if (h->plt.refcount <= 0
@@ -4342,18 +4430,22 @@ elf32_arm_adjust_dynamic_symbol (struct 
 	     such a case, we don't actually need to build a procedure
 	     linkage table, and we can just do a PC24 reloc instead.  */
 	  h->plt.offset = (bfd_vma) -1;
+	  eh->plt_thumb_refcount = 0;
 	  h->needs_plt = 0;
 	}
 
       return TRUE;
     }
   else
-    /* It's possible that we incorrectly decided a .plt reloc was
-       needed for an R_ARM_PC24 or similar reloc to a non-function sym
-       in check_relocs.  We can't decide accurately between function
-       and non-function syms in check-relocs; Objects loaded later in
-       the link may change h->type.  So fix it now.  */
-    h->plt.offset = (bfd_vma) -1;
+    {
+      /* It's possible that we incorrectly decided a .plt reloc was
+	 needed for an R_ARM_PC24 or similar reloc to a non-function sym
+	 in check_relocs.  We can't decide accurately between function
+	 and non-function syms in check-relocs; Objects loaded later in
+	 the link may change h->type.  So fix it now.  */
+      h->plt.offset = (bfd_vma) -1;
+      eh->plt_thumb_refcount = 0;
+    }
 
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
@@ -4438,6 +4530,8 @@ allocate_dynrelocs (struct elf_link_hash
   struct elf32_arm_link_hash_entry *eh;
   struct elf32_arm_relocs_copied *p;
 
+  eh = (struct elf32_arm_link_hash_entry *) h;
+
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
@@ -4474,6 +4568,14 @@ allocate_dynrelocs (struct elf_link_hash
 
 	  h->plt.offset = s->size;
 
+	  /* If we will insert a Thumb trampoline before this PLT, leave room
+	     for it.  */
+	  if (!htab->symbian_p && eh->plt_thumb_refcount > 0)
+	    {
+	      h->plt.offset += PLT_THUMB_STUB_SIZE;
+	      s->size += PLT_THUMB_STUB_SIZE;
+	    }
+
 	  /* If this symbol is not defined in a regular file, and we are
 	     not generating a shared library, then set the symbol to this
 	     location in the .plt.  This is required to make function
@@ -4484,15 +4586,24 @@ allocate_dynrelocs (struct elf_link_hash
 	    {
 	      h->root.u.def.section = s;
 	      h->root.u.def.value = h->plt.offset;
+
+	      /* Make sure the function is not marked as Thumb, in case
+		 it is the target of an ABS32 relocation, which will
+		 point to the PLT entry.  */
+	      if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
+		h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
 	    }
 
 	  /* Make room for this entry.  */
 	  s->size += htab->plt_entry_size;
 
 	  if (!htab->symbian_p)
-	    /* We also need to make an entry in the .got.plt section, which
-	       will be placed in the .got section by the linker script.  */
-	    htab->sgotplt->size += 4;
+	    {
+	      /* We also need to make an entry in the .got.plt section, which
+		 will be placed in the .got section by the linker script.  */
+	      eh->plt_got_offset = htab->sgotplt->size;
+	      htab->sgotplt->size += 4;
+	    }
 
 	  /* We also need to make an entry in the .rel.plt section.  */
 	  htab->srelplt->size += sizeof (Elf32_External_Rel);
@@ -4539,7 +4650,6 @@ allocate_dynrelocs (struct elf_link_hash
   else
     h->got.offset = (bfd_vma) -1;
 
-  eh = (struct elf32_arm_link_hash_entry *) h;
   if (eh->relocs_copied == NULL)
     return TRUE;
 
@@ -4864,9 +4974,11 @@ elf32_arm_finish_dynamic_symbol (bfd * o
 {
   bfd * dynobj;
   struct elf32_arm_link_hash_table *htab;
+  struct elf32_arm_link_hash_entry *eh;
 
   dynobj = elf_hash_table (info)->dynobj;
   htab = elf32_arm_hash_table (info);
+  eh = (struct elf32_arm_link_hash_entry *) h;
 
   if (h->plt.offset != (bfd_vma) -1)
     {
@@ -4885,13 +4997,6 @@ elf32_arm_finish_dynamic_symbol (bfd * o
       srel = bfd_get_section_by_name (dynobj, ".rel.plt");
       BFD_ASSERT (splt != NULL && srel != NULL);
 
-      /* Get the index in the procedure linkage table which
-	 corresponds to this symbol.  This is the index of this symbol
-	 in all the symbols for which we are making plt entries.  The
-	 first entry in the procedure linkage table is reserved.  */
-      plt_index = ((h->plt.offset - htab->plt_header_size) 
-		   / htab->plt_entry_size);
-
       /* Fill in the entry in the procedure linkage table.  */
       if (htab->symbian_p)
 	{
@@ -4906,6 +5011,13 @@ elf32_arm_finish_dynamic_symbol (bfd * o
 			  + splt->output_offset
 			  + h->plt.offset + 4 * (i - 1));
 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
+
+	  /* Get the index in the procedure linkage table which
+	     corresponds to this symbol.  This is the index of this symbol
+	     in all the symbols for which we are making plt entries.  The
+	     first entry in the procedure linkage table is reserved.  */
+	  plt_index = ((h->plt.offset - htab->plt_header_size) 
+		       / htab->plt_entry_size);
 	}
       else
 	{
@@ -4916,13 +5028,21 @@ elf32_arm_finish_dynamic_symbol (bfd * o
 	  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
 	  BFD_ASSERT (sgot != NULL);
 
-	  /* Get the offset into the .got table of the entry that
-	     corresponds to this function.  Each .got entry is 4 bytes.
-	     The first three are reserved.  */
-	  got_offset = (plt_index + 3) * 4;
+	  /* Get the offset into the .got.plt table of the entry that
+	     corresponds to this function.  */
+	  got_offset = eh->plt_got_offset;
+
+	  /* Get the index in the procedure linkage table which
+	     corresponds to this symbol.  This is the index of this symbol
+	     in all the symbols for which we are making plt entries.  The
+	     first three entries in .got.plt are reserved; after that
+	     symbols appear in the same order as in .plt.  */
+	  plt_index = (got_offset - 12) / 4;
 
 	  /* Calculate the displacement between the PLT slot and the
-	     entry in the GOT.  */
+	     entry in the GOT.  The eight-byte offset accounts for the
+	     value produced by adding to pc in the first instruction
+	     of the PLT stub.  */
 	  got_displacement = (sgot->output_section->vma
 			      + sgot->output_offset
 			      + got_offset
@@ -4933,6 +5053,10 @@ elf32_arm_finish_dynamic_symbol (bfd * o
 
 	  BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
 
+	  if (eh->plt_thumb_refcount > 0)
+	    bfd_put_32 (output_bfd, elf32_arm_plt_thumb_stub[0],
+			splt->contents + h->plt.offset - 4);
+
 	  bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),
 		      splt->contents + h->plt.offset + 0);
 	  bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12),
@@ -5518,6 +5642,18 @@ elf32_arm_write_section (bfd *output_bfd
   return FALSE;
 }
 
+/* Display STT_ARM_TFUNC symbols as functions.  */
+
+static void
+elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+			     asymbol *asym)
+{
+  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+
+  if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_ARM_TFUNC)
+    elfsym->symbol.flags |= BSF_FUNCTION;
+}
+
 #define ELF_ARCH			bfd_arch_arm
 #define ELF_MACHINE_CODE		EM_ARM
 #ifdef __QNXTARGET__
@@ -5556,6 +5692,7 @@ elf32_arm_write_section (bfd *output_bfd
 #define elf_backend_section_from_shdr  		elf32_arm_section_from_shdr
 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
+#define elf_backend_symbol_processing		elf32_arm_symbol_processing
 
 #define elf_backend_can_refcount    1
 #define elf_backend_can_gc_sections 1
@@ -5688,4 +5825,3 @@ elf32_arm_symbian_modify_segment_map (bf
 #define elf_backend_want_got_plt 0
 
 #include "elf32-target.h"
-
Index: gas/testsuite/gas/arm/mapping.d
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gas/testsuite/gas/arm/mapping.d,v
retrieving revision 1.2
diff -u -p -r1.2 mapping.d
--- gas/testsuite/gas/arm/mapping.d	14 Oct 2004 16:04:09 -0000	1.2
+++ gas/testsuite/gas/arm/mapping.d	16 Nov 2004 21:15:21 -0000
@@ -10,9 +10,9 @@ SYMBOL TABLE:
 0+00 l    d  .data	0+0 
 0+00 l    d  .bss	0+0 
 0+00 l     F .text	0+0 \$a
-0+08 l       .text	0+0 \$t
+0+08 l     F .text	0+0 \$t
 0+00 l     O .data	0+0 \$d
 0+00 l    d  foo	0+0 
-0+00 l       foo	0+0 \$t
+0+00 l     F foo	0+0 \$t
 0+00 g       .text	0+0 mapping
-0+08 g       .text	0+0 thumb_mapping
+0+08 g     F .text	0+0 thumb_mapping
Index: ld/emultempl/armelf.em
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/ld/emultempl/armelf.em,v
retrieving revision 1.40
diff -u -p -r1.40 armelf.em
--- ld/emultempl/armelf.em	17 Sep 2004 12:18:18 -0000	1.40
+++ ld/emultempl/armelf.em	16 Nov 2004 20:52:24 -0000
@@ -78,8 +78,11 @@ arm_elf_set_bfd_for_interworking (lang_s
 
       ASSERT (output_section->owner == output_bfd);
 
+      /* Don't attach the interworking stubs to a dynamic object, to
+	 an empty section, etc.  */
       if ((output_section->flags & SEC_HAS_CONTENTS) != 0
 	  && (i->flags & SEC_NEVER_LOAD) == 0
+	  && ! (i->owner->flags & DYNAMIC)
 	  && ! i->owner->output_has_begun)
 	{
 	  bfd_for_interwork = i->owner;
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.5
diff -u -p -r1.5 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	30 Sep 2004 17:03:52 -0000	1.5
+++ ld/testsuite/ld-arm/arm-elf.exp	16 Nov 2004 22:32:55 -0000
@@ -47,6 +47,15 @@ set armelftests {
     {"Non-pcrel function reference" "tmpdir/arm-lib.so" "" {arm-app-abs32.s}
      {{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}}
      "arm-app-abs32"}
+    {"Mixed ARM/Thumb shared library" "-shared" "" {mixed-lib.s}
+     {{objdump -fdw mixed-lib.d} {objdump -Rw mixed-lib.r}
+      {readelf -Ds mixed-lib.sym}}
+     "mixed-lib.so"}
+    {"Mixed ARM/Thumb dynamic application" "tmpdir/mixed-lib.so" ""
+     {mixed-app.s}
+     {{objdump -fdw mixed-app.d} {objdump -Rw mixed-app.r}
+      {readelf -Ds mixed-app.sym}}
+     "mixed-app"}
     {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s}
      {{objdump -s arm-target1-abs.d}}
      "arm-target1-abs"}
Index: ld/testsuite/ld-arm/mixed-app.d
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-app.d
diff -N ld/testsuite/ld-arm/mixed-app.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-app.d	16 Nov 2004 22:29:37 -0000
@@ -0,0 +1,57 @@
+
+tmpdir/mixed-app:     file format elf32-littlearm
+architecture: arm, flags 0x00000112:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	str	lr, \[sp, #-4\]!
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <.plt\+0x10>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	46c04778 	undefined
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+Disassembly of section .text:
+
+.* <_start>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
+ .*:	eb000004 	bl	.* <app_func>
+ .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_func>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
+ .*:	ebffffef 	bl	.* <.text-0x14>
+ .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_func2>:
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <app_tfunc>:
+ .*:	b500      	push	{lr}
+ .*:	ffc3f7ff 	bl	.* <.text-0x24>
+ .*:	bd00      	pop	{pc}
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
Index: ld/testsuite/ld-arm/mixed-app.r
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-app.r
diff -N ld/testsuite/ld-arm/mixed-app.r
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-app.r	16 Nov 2004 22:29:52 -0000
@@ -0,0 +1,10 @@
+
+tmpdir/mixed-app:     file format elf32-littlearm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+.* R_ARM_COPY        data_obj
+.* R_ARM_JUMP_SLOT   lib_func2
+.* R_ARM_JUMP_SLOT   lib_func1
+
+
Index: ld/testsuite/ld-arm/mixed-app.s
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-app.s
diff -N ld/testsuite/ld-arm/mixed-app.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-app.s	16 Nov 2004 22:33:55 -0000
@@ -0,0 +1,39 @@
+	.text
+	.p2align 4
+	.globl _start
+_start:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	app_func
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+
+	.p2align 4
+	.globl app_func
+	.type app_func,%function
+app_func:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	lib_func1
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+
+	.p2align 4
+	.globl app_func2
+	.type app_func2,%function
+app_func2:
+	bx	lr
+
+	.p2align 4
+	.globl app_tfunc
+	.type app_tfunc,%function
+	.thumb_func
+	.code 16
+app_tfunc:
+	push	{lr}
+	bl	lib_func2
+	pop	{pc}
+	bx	lr
+
+	.data
+	.long data_obj
Index: ld/testsuite/ld-arm/mixed-app.sym
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-app.sym
diff -N ld/testsuite/ld-arm/mixed-app.sym
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-app.sym	16 Nov 2004 22:32:02 -0000
@@ -0,0 +1,16 @@
+
+Symbol table for image:
+  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+   11   0: .*     0  NOTYPE GLOBAL DEFAULT ABS _edata
+    3   0: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_start__
+   12   1: .*     0  NOTYPE GLOBAL DEFAULT ABS _end
+   10   1: .*     4  OBJECT GLOBAL DEFAULT  12 data_obj
+    7   1: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_end__
+    5   1: 0*[^0]*.*    20    FUNC GLOBAL DEFAULT UND lib_func1
+    1   1: .*     0  OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+   13   2: .*     0  NOTYPE GLOBAL DEFAULT  11 __data_start
+    9   2: .*     0  NOTYPE GLOBAL DEFAULT ABS __end__
+    8   2: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_start
+    6   2: .*     0    FUNC GLOBAL DEFAULT   8 app_func2
+    4   2: 0*[^0]*.*     2    FUNC GLOBAL DEFAULT UND lib_func2
+    2   2: .*     0  NOTYPE GLOBAL DEFAULT ABS _bss_end__
Index: ld/testsuite/ld-arm/mixed-lib.d
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-lib.d
diff -N ld/testsuite/ld-arm/mixed-lib.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-lib.d	16 Nov 2004 21:49:33 -0000
@@ -0,0 +1,38 @@
+
+tmpdir/mixed-lib.so:     file format elf32-littlearm
+architecture: arm, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*:	e52de004 	str	lr, \[sp, #-4\]!
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x1c>
+ .*:	e08fe00e 	add	lr, pc, lr
+ .*:	e5bef008 	ldr	pc, \[lr, #8\]!
+ .*:	.*
+ .*:	e28fc6.* 	add	ip, pc, #.*	; 0x.*
+ .*:	e28cca.* 	add	ip, ip, #.*	; 0x.*
+ .*:	e5bcf.* 	ldr	pc, \[ip, #.*\]!
+Disassembly of section .text:
+
+.* <lib_func1>:
+ .*:	e1a0c00d 	mov	ip, sp
+ .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
+ .*:	ebfffff6 	bl	.* <lib_func1-0x18>
+ .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
+ .*:	e12fff1e 	bx	lr
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+ .*:	e1a00000 	nop			\(mov r0,r0\)
+
+.* <lib_func2>:
+ .*:	4770      	bx	lr
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
+ .*:	46c0      	nop			\(mov r8, r8\)
Index: ld/testsuite/ld-arm/mixed-lib.r
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-lib.r
diff -N ld/testsuite/ld-arm/mixed-lib.r
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-lib.r	16 Nov 2004 21:34:59 -0000
@@ -0,0 +1,8 @@
+
+tmpdir/mixed-lib.so:     file format elf32-littlearm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+.* R_ARM_JUMP_SLOT   app_func2
+
+
Index: ld/testsuite/ld-arm/mixed-lib.s
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-lib.s
diff -N ld/testsuite/ld-arm/mixed-lib.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-lib.s	16 Nov 2004 21:45:17 -0000
@@ -0,0 +1,28 @@
+	.text
+
+	.p2align 4
+	.globl lib_func1
+	.type lib_func1, %function
+lib_func1:
+	mov	ip, sp
+	stmdb	sp!, {r11, ip, lr, pc}
+	bl	app_func2
+	ldmia	sp, {r11, sp, lr}
+	bx lr
+	.size lib_func1, . - lib_func1
+
+	.p2align 4
+	.globl lib_func2
+	.type lib_func2, %function
+	.thumb_func
+	.code 16
+lib_func2:
+	bx lr
+	.size lib_func2, . - lib_func2
+
+	.data
+	.globl data_obj
+	.type data_obj, %object
+data_obj:
+	.long 0
+	.size data_obj, . - data_obj
Index: ld/testsuite/ld-arm/mixed-lib.sym
===================================================================
RCS file: ld/testsuite/ld-arm/mixed-lib.sym
diff -N ld/testsuite/ld-arm/mixed-lib.sym
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-arm/mixed-lib.sym	16 Nov 2004 21:44:37 -0000
@@ -0,0 +1,16 @@
+
+Symbol table for image:
+  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
+   14   1: .*     0  NOTYPE GLOBAL DEFAULT ABS _edata
+    8   1: .*0    20    FUNC GLOBAL DEFAULT   6 lib_func1
+    7   2: .*0     2  THUMB_FUNC GLOBAL DEFAULT   6 lib_func2
+    5   2: .*     0  NOTYPE GLOBAL DEFAULT ABS _bss_end__
+    4   4: .*     0  OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+   10   5: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_end__
+   13  10: .*     4  OBJECT GLOBAL DEFAULT   9 data_obj
+    6  10: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_start__
+   11  11: .*     0  NOTYPE GLOBAL DEFAULT ABS __bss_start
+   15  13: .*     0  NOTYPE GLOBAL DEFAULT ABS _end
+    9  13: 00000000     0  NOTYPE GLOBAL DEFAULT UND app_func2
+   16  14: .*     0  NOTYPE GLOBAL DEFAULT   9 __data_start
+   12  14: .*     0  NOTYPE GLOBAL DEFAULT ABS __end__


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