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]

frv fdpic: don't mess with the stack segment when stripping


This patch arranges for strip and objcopy to propagate the stack size
and alignment information, that FRV FDPIC encodes in the PT_GNU_STACK
PHDR.  

The problem is that, since PT_GNU_STACK doesn't contain any sections,
when we compute the phdrs for the new executable, it comes out empty.

I was hoping the bfd_copy_private_bfd_data entry point would be able
to adjust it, but objcopy calls it too late for the changes to phdr to
have any effect: they've already been written out to disk.

I don't quite see how I could add a new bfd entry point to copy phdr
information at the point I'd need it: within
assign_file_positions_for_segments(), that creates the phdrs data
structure and writes them to disk, we don't have access to the phdrs
of the executable being copied.

So I figured the only ways I could make it work were to (i) arrange
for the entry point that modified the phdrs after they were written
out to write them again, or (ii) get objcopy to write the phdrs again
after calling copy_private_bfd_data (but how would it know how to do
it?).  I thought I'd limit my change to frv-specific files only, so I
the patch below does (i).  Is this approach reasonable?  It works, but
I'm a bit worried about seeking and modifying obfd's file within this
function.

Index: bfd/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* elf32-frv.c (elf32_frvfdpic_modify_segment_map): Return
	immediately if there's no link info.
	(elf32_frvfdpic_copy_private_bfd_data): New.
	(bfd_elf32_bfd_copy_private_bfd_data): Use it for frvfdpic.

Index: bfd/elf32-frv.c
===================================================================
RCS file: /cvs/uberbaum/bfd/elf32-frv.c,v
retrieving revision 1.22
diff -u -p -r1.22 elf32-frv.c
--- bfd/elf32-frv.c 6 May 2004 02:46:29 -0000 1.22
+++ bfd/elf32-frv.c 6 May 2004 02:50:18 -0000
@@ -3686,6 +3686,11 @@ elf32_frvfdpic_modify_segment_map (bfd *
 {
   struct elf_segment_map *m;
 
+  /* objcopy and strip preserve what's already there using
+     elf32_frvfdpic_copy_private_bfd_data ().  */
+  if (! info)
+    return TRUE;
+
   for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
     if (m->p_type == PT_GNU_STACK)
       break;
@@ -4311,6 +4316,50 @@ frv_elf_arch_extension_p (flagword base,
   return FALSE;
 }
 
+static bfd_boolean
+elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  unsigned i;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return TRUE;
+
+  if (! frv_elf_copy_private_bfd_data (ibfd, obfd))
+    return FALSE;
+
+  if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
+      || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
+    return TRUE;
+
+  /* Copy the stack size.  */
+  for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
+    if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
+      {
+	Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
+
+	for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
+	  if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
+	    {
+	      memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
+
+	      /* Rewrite the phdrs, since we're only called after they
+		 were first written.  */
+	      if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
+			    ->s->sizeof_ehdr, SEEK_SET) != 0
+		  || get_elf_backend_data (obfd)->s
+		  ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
+				     elf_elfheader (obfd)->e_phnum) != 0)
+		return FALSE;
+	      break;
+	    }
+
+	break;
+      }
+
+  return TRUE;
+}
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -4726,6 +4775,9 @@ frv_elf_print_private_bfd_data (abfd, pt
 #undef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map \
 		elf32_frvfdpic_modify_segment_map
+#undef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+		elf32_frvfdpic_copy_private_bfd_data
 
 #undef elf_backend_create_dynamic_sections
 #define elf_backend_create_dynamic_sections \
-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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