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]

[RFC PATCH] BFD linker support for i?86-nacl and x86_64-nacl targets


I've so far given this only very light testing.  I intend to add some
ld/testsuite cases to cover somewhat more thorough testing before I
post this for actual approval.

But I'd appreciate any feedback you can give me now.  In particular, BFD
gurus should look at my modify_segment_map and modify_program_headers
hooks and tell me if there are any odd cases where BFD might do something
I don't want based on this trickery--or any suspicions thereof, i.e. so as
to suggest particular kinds of test cases I should try.

This touches generic code only in making elf.sc grok the new SEPARATE_CODE
parameter.  I verified with an --enable-targets=all build that ldscripts/*
all comes out identical before and after the change.


Thanks,
Roland


bfd/
2012-03-20  Roland McGrath  <mcgrathr@google.com>

	* elf-nacl.c: New file.
	* elf-nacl.h: New file.
	* elf32-i386.c (elf_backend_modify_segment_map): Define for
	bfd_elf32_i386_nacl_vec.
	(elf_backend_modify_program_headers): Likewise.
	* elf64-x86-64.c (elf_backend_modify_segment_map): Define for
	bfd_elf64_x86_64_nacl_vec and bfd_elf32_x86_64_nacl_vec.
	(elf_backend_modify_program_headers): Likewise.
	* Makefile.am (BFD32_BACKENDS, BFD64_BACKENDS): Add elf-nacl.lo here.
	(BFD32_BACKENDS_CFILES, BFD64_BACKENDS_CFILES): Add elf-nacl.c here.
	* Makefile.in: Regenerated.
	* configure.in (bfd_elf64_x86_64_nacl_vec): Add elf-nacl.o to tb here.
	(bfd_elf32_x86_64_nacl_vec): Likewise.
	(bfd_elf64_x86_64_vec, bfd_elf32_x86_64_vec): Likewise.
	(bfd_elf64_x86_64_freebsd_vec, bfd_elf64_x86_64_sol2_vec): Likewise.
	(bfd_elf64_l1om_vec, bfd_elf64_l1om_freebsd_vec): Likewise.
	(bfd_elf64_k1om_vec, bfd_elf64_k1om_freebsd_vec): Likewise.
	(bfd_elf32_i386_nacl_vec): Likewise.
	(bfd_elf32_i386_sol2_vec, bfd_elf32_i386_freebsd_vec): Likewise.
	(bfd_elf32_i386_vxworks_vec, bfd_elf32_i386_vec): Likewise.
	* configure: Regenerated.

ld/
2012-03-20  Roland McGrath  <mcgrathr@google.com>

	* configure.tgt (i[3-7]86-*-nacl*, x86_64-*-nacl*): Handle them.
	* emulparams/elf_nacl.sh: New file.
	* emulparams/elf_i386_nacl.sh: New file.
	* emulparams/elf32_x86_64_nacl.sh: New file.
	* emulparams/elf_x86_64_nacl.sh: New file.
	* Makefile.am (ALL_EMULATION_SOURCES): Add eelf_i386_nacl.c here.
	(ALL_64_EMULATION_SOURCES): Add eelf32_x86_64_nacl.c and
	eelf_x86_64_nacl.c here.
	(eelf_i386_nacl.c, eelf32_x86_64_nacl.c, eelf_x86_64_nacl.c):
	New targets.
	* Makefile.in: Regenerated.

	* scripttempl/elf.sc: Handle SEPARATE_CODE cases.

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 8f4fbee..50c84ee 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -275,6 +275,7 @@ BFD32_BACKENDS = \
 	elf-ifunc.lo \
 	elf-m10200.lo \
 	elf-m10300.lo \
+	elf-nacl.lo \
 	elf-strtab.lo \
 	elf-vxworks.lo \
 	elf.lo \
@@ -461,6 +462,7 @@ BFD32_BACKENDS_CFILES = \
 	elf-ifunc.c \
 	elf-m10200.c \
 	elf-m10300.c \
+	elf-nacl.c \
 	elf-strtab.c \
 	elf-vxworks.c \
 	elf.c \
@@ -609,6 +611,7 @@ BFD64_BACKENDS = \
 	coff-x86_64.lo \
 	coff64-rs6000.lo \
 	demo64.lo \
+	elf-nacl.lo \
 	elf32-ia64.lo \
 	elf32-score.lo \
 	elf32-score7.lo \
@@ -645,6 +648,7 @@ BFD64_BACKENDS_CFILES = \
 	coff-x86_64.c \
 	coff64-rs6000.c \
 	demo64.c \
+	elf-nacl.c \
 	elf32-score.c \
 	elf32-score7.c \
 	elf64-alpha.c \
diff --git a/bfd/configure.in b/bfd/configure.in
index f443915..af3622b 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -711,11 +711,11 @@ do
     bfd_elf32_hppa_nbsd_vec)	tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
     bfd_elf32_hppa_vec)		tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
     bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_sol2_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_sol2_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i860_vec)		tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i960_vec)		tb="$tb elf32-i960.lo elf32.lo $elf" ;;
@@ -850,16 +850,16 @@ do
 				tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_tradlittlemips_vec | bfd_elf64_tradlittlemips_freebsd_vec)
 				tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
-    bfd_elf64_x86_64_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_x86_64_sol2_vec)  tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf32_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
-    bfd_elf32_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
-    bfd_elf64_l1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_l1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_k1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
-    bfd_elf64_k1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_sol2_vec)  tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf32_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+    bfd_elf32_x86_64_nacl_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+    bfd_elf64_l1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_l1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_k1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_k1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
     bfd_mmo_vec)		tb="$tb mmo.lo" target_size=64 ;;
     bfd_powerpc_pe_vec)         tb="$tb pe-ppc.lo peigen.lo cofflink.lo" ;;
     bfd_powerpc_pei_vec)        tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
diff --git a/bfd/elf-nacl.c b/bfd/elf-nacl.c
new file mode 100644
index 0000000..fad15c4
--- /dev/null
+++ b/bfd/elf-nacl.c
@@ -0,0 +1,188 @@
+/* Native Client support for ELF
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "elf-nacl.h"
+#include "elf/common.h"
+#include "elf/internal.h"
+
+static bfd_boolean
+segment_executable (struct elf_segment_map *seg)
+{
+  if (seg->p_flags_valid)
+    return (seg->p_flags & PF_X) != 0;
+  else
+    {
+      /* The p_flags value has not been computed yet,
+         so we have to look through the sections.  */
+      unsigned int i;
+      for (i = 0; i < seg->count; ++i)
+        if (seg->sections[i]->flags & SEC_CODE)
+          return TRUE;
+    }
+  return FALSE;
+}
+
+/* We permute the segment_map to get BFD to do the file layout we want:
+   The first non-executable PT_LOAD segment appears first in the file
+   and contains the ELF file header and phdrs.  */
+bfd_boolean
+nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  struct elf_segment_map **m = &elf_tdata (abfd)->segment_map;
+  struct elf_segment_map **first_load = NULL;
+  struct elf_segment_map **last_load = NULL;
+  bfd_boolean moved_headers = FALSE;
+
+  while (*m != NULL)
+    {
+      struct elf_segment_map *seg = *m;
+
+      if (seg->p_type == PT_LOAD)
+        {
+          /* First, we're just finding the earliest PT_LOAD.
+             By the normal rules, this will be the lowest-addressed one.
+             We only have anything interesting to do if it's executable.  */
+          last_load = m;
+          if (first_load == NULL)
+            {
+              if (!segment_executable (*m))
+                return TRUE;
+              first_load = m;
+            }
+          /* Now that we've noted the first PT_LOAD, we're looking for
+             the first non-executable PT_LOAD.  */
+          else if (!moved_headers && !segment_executable (seg))
+            {
+              /* This is the one we were looking for!
+
+                 First, clear the flags on previous segments that
+                 say they include the file header and phdrs.  */
+              struct elf_segment_map *prevseg;
+              for (prevseg = *first_load;
+                   prevseg != seg;
+                   prevseg = prevseg->next)
+                if (prevseg->p_type == PT_LOAD)
+                  {
+                    prevseg->includes_filehdr = 0;
+                    prevseg->includes_phdrs = 0;
+                  }
+
+              /* This segment will include those headers instead.  */
+              seg->includes_filehdr = 1;
+              seg->includes_phdrs = 1;
+
+              moved_headers = TRUE;
+            }
+        }
+
+      m = &seg->next;
+    }
+
+  if (first_load != last_load && moved_headers)
+    {
+      /* Now swap the first and last PT_LOAD segments'
+         positions in segment_map.  */
+      struct elf_segment_map *first = *first_load;
+      struct elf_segment_map *last = *last_load;
+      *first_load = first->next;
+      first->next = last->next;
+      last->next = first;
+    }
+
+  return TRUE;
+}
+
+/* After nacl_modify_segment_map has done its work, the file layout has
+   been done as we wanted.  But the PT_LOAD phdrs are no longer in the
+   proper order for the ELF rule that they must appear in ascending address
+   order.  So find the two segments we swapped before, and swap them back.  */
+bfd_boolean
+nacl_modify_program_headers (bfd *abfd,
+                             struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  struct elf_segment_map **m = &elf_tdata (abfd)->segment_map;
+  Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
+  Elf_Internal_Phdr *p = phdr;
+
+  /* Find the PT_LOAD that contains the headers (should be the first).  */
+  while (*m != NULL)
+    {
+      if ((*m)->p_type == PT_LOAD && (*m)->includes_filehdr)
+        break;
+
+      m = &(*m)->next;
+      ++p;
+    }
+
+  if (*m != NULL)
+    {
+      struct elf_segment_map **first_load_seg = m;
+      Elf_Internal_Phdr *first_load_phdr = p;
+      struct elf_segment_map **next_load_seg = NULL;
+      Elf_Internal_Phdr *next_load_phdr = NULL;
+
+      /* Now move past that first one and find the PT_LOAD that should be
+         before it by address order.  */
+
+      m = &(*m)->next;
+      ++p;
+
+      while ((*m) != NULL)
+        {
+          if (p->p_type == PT_LOAD && p->p_vaddr < first_load_phdr->p_vaddr)
+            {
+              next_load_seg = m;
+              next_load_phdr = p;
+              break;
+            }
+
+          m = &(*m)->next;
+          ++p;
+        }
+
+      /* Swap their positions in the segment_map back to how they used to be.
+         The phdrs have already been set up by now, so we have to slide up
+         the earlier ones to insert the one that should be first.  */
+      if (next_load_seg != NULL)
+        {
+          Elf_Internal_Phdr move_phdr;
+          struct elf_segment_map *first_seg = *first_load_seg;
+          struct elf_segment_map *next_seg = *next_load_seg;
+          struct elf_segment_map *first_next = first_seg->next;
+          struct elf_segment_map *next_next = next_seg->next;
+
+          first_seg->next = next_next;
+          *first_load_seg = next_seg;
+
+          next_seg->next = first_next;
+          *next_load_seg = first_seg;
+
+          move_phdr = *next_load_phdr;
+          memmove (first_load_phdr + 1, first_load_phdr,
+                   (next_load_phdr - first_load_phdr) * sizeof move_phdr);
+          *first_load_phdr = move_phdr;
+        }
+    }
+
+  return TRUE;
+}
diff --git a/bfd/elf-nacl.h b/bfd/elf-nacl.h
new file mode 100644
index 0000000..417c7e3
--- /dev/null
+++ b/bfd/elf-nacl.h
@@ -0,0 +1,24 @@
+/* Native Client support for ELF
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+#include "bfd.h"
+
+bfd_boolean nacl_modify_segment_map (bfd *, struct bfd_link_info *);
+bfd_boolean nacl_modify_program_headers (bfd *, struct bfd_link_info *);
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f35e3c2..d5a2614 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -25,6 +25,7 @@
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "bfd_stdint.h"
 #include "objalloc.h"
@@ -5207,8 +5208,17 @@ static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
 #undef	elf_backend_arch_data
 #define elf_backend_arch_data	&elf_i386_nacl_arch_bed
 
+#undef	elf_backend_modify_segment_map
+#define	elf_backend_modify_segment_map		nacl_modify_segment_map
+#undef	elf_backend_modify_program_headers
+#define	elf_backend_modify_program_headers	nacl_modify_program_headers
+
 #include "elf32-target.h"
 
+/* Restore defaults.  */
+#undef	elf_backend_modify_segment_map
+#undef	elf_backend_modify_program_headers
+
 /* VxWorks support.  */
 
 #undef	TARGET_LITTLE_SYM
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index cc5ee42..8ca811c 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -26,6 +26,7 @@
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf-nacl.h"
 #include "bfd_stdint.h"
 #include "objalloc.h"
 #include "hashtab.h"
@@ -5227,6 +5228,11 @@ static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
 #undef	elf_backend_arch_data
 #define	elf_backend_arch_data	&elf_x86_64_nacl_arch_bed
 
+#undef	elf_backend_modify_segment_map
+#define	elf_backend_modify_segment_map		nacl_modify_segment_map
+#undef	elf_backend_modify_program_headers
+#define	elf_backend_modify_program_headers	nacl_modify_program_headers
+
 #include "elf64-target.h"
 
 /* Native Client x32 support.  */
@@ -5268,6 +5274,8 @@ static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
 #define elf_backend_object_p		    elf64_x86_64_elf_object_p
 #undef elf_backend_bfd_from_remote_memory
 #undef elf_backend_size_info
+#undef	elf_backend_modify_segment_map
+#undef	elf_backend_modify_program_headers
 
 /* Intel L1OM support.  */
 
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 37f8d1f..524350e 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -263,6 +263,7 @@ ALL_EMULATION_SOURCES = \
 	eelf_i386_chaos.c \
 	eelf_i386_fbsd.c \
 	eelf_i386_ldso.c \
+	eelf_i386_nacl.c \
 	eelf_i386_sol2.c \
 	eelf_i386_vxworks.c \
 	eelf_s390.c \
@@ -462,6 +463,7 @@ ALL_EMULATIONS = $(ALL_EMULATION_SOURCES:.c=.@OBJEXT@)
 
 ALL_64_EMULATION_SOURCES = \
 	eelf32_x86_64.c \
+	eelf32_x86_64_nacl.c \
 	eelf64_aix.c \
 	eelf64_ia64.c \
 	eelf64_ia64_fbsd.c \
@@ -490,6 +492,7 @@ ALL_64_EMULATION_SOURCES = \
 	eelf_k1om_fbsd.c \
 	eelf_x86_64.c \
 	eelf_x86_64_fbsd.c \
+	eelf_x86_64_nacl.c \
 	eelf_x86_64_sol2.c \
 	ehppa64linux.c \
 	emmo.c \
@@ -1202,6 +1205,11 @@ eelf_i386_fbsd.c: $(srcdir)/emulparams/elf_i386_fbsd.sh \
 eelf_i386_ldso.c: $(srcdir)/emulparams/elf_i386_ldso.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_i386_ldso "$(tdir_elf_i386_ldso)"
+eelf_i386_nacl.c: $(srcdir)/emulparams/elf_i386_nacl.sh \
+  $(srcdir)/emulparams/elf_i386.sh \
+  $(srcdir)/emulparams/elf_nacl.sh \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf_i386_nacl "$(tdir_elf_i386_nacl)"
 eelf_i386_sol2.c: $(srcdir)/emulparams/elf_i386_sol2.sh \
   $(srcdir)/emulparams/solaris2.sh \
   $(srcdir)/emultempl/solaris2.em \
@@ -1901,6 +1909,11 @@ ez8002.c: $(srcdir)/emulparams/z8002.sh \
 eelf32_x86_64.c: $(srcdir)/emulparams/elf32_x86_64.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf32_x86_64 "$(tdir_elf32_x86_64)"
+eelf32_x86_64_nacl.c: $(srcdir)/emulparams/elf32_x86_64_nacl.sh \
+  $(srcdir)/emulparams/elf32_x86_64.sh \
+  $(srcdir)/emulparams/elf_nacl.sh \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf32_x86_64_nacl "$(tdir_elf32_x86_64_nacl)"
 eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf64_aix "$(tdir_elf64_aix)"
@@ -2020,6 +2033,11 @@ eelf_x86_64_fbsd.c: $(srcdir)/emulparams/elf_x86_64_fbsd.sh \
   $(srcdir)/emulparams/elf_x86_64.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_x86_64_fbsd "$(tdir_elf_x86_64_fbsd)"
+eelf_x86_64_nacl.c: $(srcdir)/emulparams/elf_x86_64_nacl.sh \
+  $(srcdir)/emulparams/elf_x86_64.sh \
+  $(srcdir)/emulparams/elf_nacl.sh \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf_x86_64_nacl "$(tdir_elf_x86_64_nacl)"
 eelf_x86_64_sol2.c: $(srcdir)/emulparams/elf_x86_64_sol2.sh \
   $(srcdir)/emulparams/elf_x86_64.sh \
   $(srcdir)/emulparams/solaris2.sh \
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 8cd2915..6418768 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -281,6 +281,15 @@ i[3-7]86-*-beos*)	targ_emul=elf_i386_be ;;
 i[3-7]86-*-vxworks*)	targ_emul=elf_i386_vxworks ;;
 i[3-7]86-*-chaos)	targ_emul=elf_i386_chaos
 			;;
+i[3-7]86-*-nacl*)	targ_emul=elf_i386_nacl
+			targ64_extra_emuls="elf32_x86_64_nacl elf_x86_64_nacl"
+			targ64_extra_libpath="elf32_x86_64_nacl elf_x86_64_nacl"
+			;;
+x86_64-*-nacl*)		targ_emul=elf32_x86_64_nacl
+			targ_extra_emuls="elf_i386_nacl elf_x86_64_nacl"
+			targ_extra_libpath="elf_i386_nacl elf_x86_64_nacl"
+			tdir_elf_i386_nacl=`echo ${targ_alias} | sed -e 's/x86_64/i386/'`
+			;;
 i860-*-coff)		targ_emul=coff_i860 ;;
 i860-stardent-sysv4* | i860-stardent-elf*)
 			targ_emul=elf32_i860
diff --git a/ld/emulparams/elf32_x86_64_nacl.sh b/ld/emulparams/elf32_x86_64_nacl.sh
new file mode 100644
index 0000000..4570ef9
--- /dev/null
+++ b/ld/emulparams/elf32_x86_64_nacl.sh
@@ -0,0 +1,3 @@
+. ${srcdir}/emulparams/elf32_x86_64.sh
+. ${srcdir}/emulparams/elf_nacl.sh
+OUTPUT_FORMAT="elf32-x86-64-nacl"
diff --git a/ld/emulparams/elf_i386_nacl.sh b/ld/emulparams/elf_i386_nacl.sh
new file mode 100644
index 0000000..81992d7
--- /dev/null
+++ b/ld/emulparams/elf_i386_nacl.sh
@@ -0,0 +1,3 @@
+. ${srcdir}/emulparams/elf_i386.sh
+. ${srcdir}/emulparams/elf_nacl.sh
+OUTPUT_FORMAT="elf32-i386-nacl"
diff --git a/ld/emulparams/elf_nacl.sh b/ld/emulparams/elf_nacl.sh
new file mode 100644
index 0000000..c530664
--- /dev/null
+++ b/ld/emulparams/elf_nacl.sh
@@ -0,0 +1,5 @@
+ENABLE_INITFINI_ARRAY=yes
+SEPARATE_CODE=yes
+TEXT_START_ADDR=0x20000
+RODATA_ADDR="0x11000000 + SIZEOF_HEADERS"
+SHLIB_RODATA_ADDR="0x10000000 + SIZEOF_HEADERS"
diff --git a/ld/emulparams/elf_x86_64_nacl.sh b/ld/emulparams/elf_x86_64_nacl.sh
new file mode 100644
index 0000000..7c79eee
--- /dev/null
+++ b/ld/emulparams/elf_x86_64_nacl.sh
@@ -0,0 +1,3 @@
+. ${srcdir}/emulparams/elf_x86_64.sh
+. ${srcdir}/emulparams/elf_nacl.sh
+OUTPUT_FORMAT="elf64-x86-64-nacl"
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 7994b5f..bebe075 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -300,9 +300,15 @@ STACK="  .stack        ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
 TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})"
 SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})"
 
+if [ -z "$SEPARATE_CODE" ]; then
+  SIZEOF_HEADERS_CODE=" + SIZEOF_HEADERS"
+else
+  SIZEOF_HEADERS_CODE=
+fi
+
 # if this is for an embedded system, don't add SIZEOF_HEADERS.
 if [ -z "$EMBEDDED" ]; then
-   test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS"
+   test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}${SIZEOF_HEADERS_CODE}"
 else
    test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}"
 fi
@@ -325,11 +331,19 @@ SECTIONS
 {
   /* Read-only sections, merged into text segment: */
   ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}}
-  ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR} + SIZEOF_HEADERS;}}
-  ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+  ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR}${SIZEOF_HEADERS_CODE};}}
+  ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR}${SIZEOF_HEADERS_CODE};}}
+EOF
+
+emit_early_ro()
+{
+  cat <<EOF
   ${INITIAL_READONLY_SECTIONS}
   .note.gnu.build-id : { *(.note.gnu.build-id) }
 EOF
+}
+
+test -n "${SEPARATE_CODE}" || emit_early_ro
 
 test -n "${RELOCATING+0}" || unset NON_ALLOC_DYN
 test -z "${NON_ALLOC_DYN}" || TEXT_DYNAMIC=
@@ -424,7 +438,8 @@ cat >> ldscripts/dyntmp.$$ <<EOF
   ${OTHER_PLT_RELOC_SECTIONS}
 EOF
 
-if test -z "${NON_ALLOC_DYN}"; then
+emit_dyn()
+{
   if test -z "${NO_REL_RELOCS}${NO_RELA_RELOCS}"; then
     cat ldscripts/dyntmp.$$
   else
@@ -436,7 +451,9 @@ if test -z "${NON_ALLOC_DYN}"; then
     fi
   fi
   rm -f ldscripts/dyntmp.$$
-fi
+}
+
+test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
 
 cat <<EOF
   .init         ${RELOCATING-0} : 
@@ -469,6 +486,21 @@ cat <<EOF
   ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
   ${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
   ${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
+EOF
+
+if test -n "${SEPARATE_CODE}"; then
+  cat <<EOF
+  /* Adjust the address for the rodata segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}}
+  ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+  ${CREATE_PIE+${RELOCATING+. = ${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+EOF
+  emit_early_ro
+  emit_dyn
+fi
+
+cat <<EOF
   ${WRITABLE_RODATA-${RODATA}}
   .${RODATA_NAME}1      ${RELOCATING-0} : { *(.${RODATA_NAME}1) }
   ${CREATE_SHLIB-${SDATA2}}
@@ -565,19 +597,7 @@ cat <<EOF
   ${RELOCATING+${DATA_SEGMENT_END}}
 EOF
 
-if test -n "${NON_ALLOC_DYN}"; then
-  if test -z "${NO_REL_RELOCS}${NO_RELA_RELOCS}"; then
-    cat ldscripts/dyntmp.$$
-  else
-    if test -z "${NO_REL_RELOCS}"; then
-      sed -e '/^[ 	]*\.rela\.[^}]*$/,/}/d' -e '/^[ 	]*\.rela\./d' ldscripts/dyntmp.$$
-    fi
-    if test -z "${NO_RELA_RELOCS}"; then
-      sed -e '/^[ 	]*\.rel\.[^}]*$/,/}/d' -e '/^[ 	]*\.rel\./d' ldscripts/dyntmp.$$
-    fi
-  fi
-  rm -f ldscripts/dyntmp.$$
-fi
+test -z "${NON_ALLOC_DYN}" || emit_dyn
 
 cat <<EOF
   /* Stabs debugging sections.  */


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