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]

Empty ARM/THUMB interworking stubs


Hi there,

The link editor can output empty (zero) ARM/THUMB interworking stubs. See the attached archive for the test case.  Running ``arm-elf-objdump -S x'' produces

x:     file format elf32-littlearm

Disassembly of section .text:

00008000 <__foo_from_thumb>:
    8000:	0000      	lsl	r0, r0, #0
	...

00008004 <__foo_change_to_arm>:
    8004:	00000000 	andeq	r0, r0, r0

00008008 <__foo1_from_thumb>:
    8008:	4778      	bx	pc
    800a:	46c0      	nop			(mov r8, r8)

etc...

The problem is that the glue sections are output by
``elf_link_input_bfd'' before the .text sections relocation has
written the interworking stubs.

My "solution" so far is to delay the output of the sections having
SEC_IN_MEMORY flags set until all the other sections are relocated and
output. The idea is that SEC_IN_MEMORY sections generally depend upon
the other ones, thus it makes sense to delay writing them until all
the other section's processing has finished.

Patch against elfink.h attached. 

Comments ?

Regards,
-velco

P.S. And there's another thing, relocations are not generated for glue
sections, which is OK, unless the linker is to output relocateable
executables file (--emit-relocs). I'd appreciate guidance how to fix
this (or the fix itself :).

Attachment: zero-stub.tar.gz
Description: Binary data

--- elflink.h.orig	Mon Apr 15 10:35:28 2002
+++ elflink.h	Mon Apr 15 10:43:10 2002
@@ -4519,6 +4519,8 @@ static boolean elf_link_sec_merge_syms
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static boolean elf_link_input_bfd
   PARAMS ((struct elf_final_link_info *, bfd *));
+static boolean elf_link_in_memory_sections
+  PARAMS ((struct elf_final_link_info *, bfd *));
 static boolean elf_reloc_link_order
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
 	   struct bfd_link_order *));
@@ -5383,6 +5385,38 @@ elf_bfd_final_link (abfd, info)
 	}
     }
 
+  /* Traverse the input bfds again and write in-memory sections.  */
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+    sub->output_has_begun = false;
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      for (p = o->link_order_head; p != NULL; p = p->next)
+	{
+	  Elf_Internal_Shdr *rhdr;
+
+	  if (p->type == bfd_indirect_link_order
+	      && (bfd_get_flavour (p->u.indirect.section->owner)
+		  == bfd_target_elf_flavour)
+	      && (((rhdr = &elf_section_data (p->u.indirect.section)->rel_hdr)
+		   ->sh_entsize == 0)
+		  || rhdr->sh_entsize == sizeof (Elf_External_Rel)
+		  || rhdr->sh_entsize == sizeof (Elf_External_Rela))
+	      && (((rhdr = elf_section_data (p->u.indirect.section)->rel_hdr2)
+		   == NULL)
+		  || rhdr->sh_entsize == sizeof (Elf_External_Rel)
+		  || rhdr->sh_entsize == sizeof (Elf_External_Rela)))
+	    {
+	      sub = p->u.indirect.section->owner;
+	      if (! sub->output_has_begun)
+		{
+		  if (! elf_link_in_memory_sections (&finfo, sub))
+		    goto error_return;
+		  sub->output_has_begun = true;
+		}
+	    }
+	}
+    }
+
   /* Output any global symbols that got converted to local in a
      version script or due to symbol visibility.  We do this in a
      separate step since ELF requires all local symbols to appear
@@ -6924,6 +6958,9 @@ elf_link_input_bfd (finfo, input_bfd)
 	    }
 	}
 
+      if (o->flags & SEC_IN_MEMORY)
+	continue;
+
       /* Write out the modified section contents.  */
       if (bed->elf_backend_write_section
 	  && (*bed->elf_backend_write_section) (output_bfd, o, contents))
@@ -6972,6 +7009,93 @@ elf_link_input_bfd (finfo, input_bfd)
 	}
     }
 
+  return true;
+}
+
+static boolean
+elf_link_in_memory_sections (finfo, input_bfd)
+     struct elf_final_link_info *finfo;
+     bfd *input_bfd;
+{
+  struct elf_backend_data *bed;
+  bfd *output_bfd;
+  asection *o;
+
+  output_bfd = finfo->output_bfd;
+  bed = get_elf_backend_data (output_bfd);
+
+  for (o = input_bfd->sections; o != NULL; o = o->next)
+    {
+      if (! o->linker_mark)
+	{
+	  /* This section was omitted from the link.  */
+	  continue;
+	}
+
+      if ((o->flags & SEC_HAS_CONTENTS) == 0
+	  || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
+	continue;
+
+      if ((o->flags & SEC_LINKER_CREATED) != 0)
+	{
+	  /* Section was created by elf_link_create_dynamic_sections
+	     or somesuch.  */
+	  continue;
+	}
+
+      if ((o->flags & SEC_IN_MEMORY) == 0)
+	{
+	  /* Already output.   */
+	  continue;
+	}
+
+      BFD_ASSERT (o->contents != NULL);
+
+      if (bed->elf_backend_write_section
+	  && (*bed->elf_backend_write_section) (output_bfd, o, o->contents))
+	{
+	  /* Section written out.  */
+	}
+      else switch (elf_section_data (o)->sec_info_type)
+	{
+	case ELF_INFO_TYPE_STABS:
+	  if (! (_bfd_write_section_stabs (output_bfd,
+					   &elf_hash_table (finfo->info)->stab_info,
+					   o, &elf_section_data (o)->sec_info,
+					   o->contents)))
+	    return false;
+	  break;
+	case ELF_INFO_TYPE_MERGE:
+	  if (! (_bfd_write_merged_section (output_bfd, o,
+					    elf_section_data (o)->sec_info)))
+	    return false;
+	  break;
+	case ELF_INFO_TYPE_EH_FRAME:
+	  {
+	    asection *ehdrsec;
+
+	    ehdrsec
+	      = bfd_get_section_by_name (elf_hash_table (finfo->info)->dynobj,
+					 ".eh_frame_hdr");
+	    if (! (_bfd_elf_write_section_eh_frame (output_bfd, o, ehdrsec,
+						    o->contents)))
+	      return false;
+	  }
+	  break;
+	default:
+	  {
+	    bfd_size_type sec_size;
+
+	    sec_size = (o->_cooked_size != 0 ? o->_cooked_size : o->_raw_size);
+	    if (! (o->flags & SEC_EXCLUDE)
+		&& ! bfd_set_section_contents (output_bfd, o->output_section,
+					       o->contents,
+					       (file_ptr) o->output_offset,
+					       sec_size))
+	      return false;
+	  }
+	}
+    }
   return true;
 }
 



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