public inbox for prelink@sourceware.org
 help / color / mirror / Atom feed
From: Mark Hatle <mark.hatle@windriver.com>
To: <prelink@sourceware.org>
Cc: <jakub@redhat.com>
Subject: Add x32 support to prelink
Date: Wed, 21 Dec 2011 21:36:00 -0000	[thread overview]
Message-ID: <4EF2515E.3090302@windriver.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 973 bytes --]

Attached are two patches required to enable x32 support in the prelinker.  (And 
of course updates to your the local prelink.conf to add the x32 library directory.)

The first change 0001-... modifies the way the PL_ARCH is defined.  This patch 
has been used for a long time in the cross-prelinker work.  The patch was 
originally written as part of some Code Sourcery, LLC (now part of Mentor 
Graphics) work.  The purpose of it is to enable multiple architecture 
definitions within a single arch-...c file.

The second change relies on the first, and implements the x32 ABI specs.  Within 
the specs "https://sites.google.com/site/x32abi/documents/abi.pdf", both x86-64 
and x86-64 x32 are defined.  A new local define was added to switch between 
32-bit and 64-bit read/write operations based on the value of ELFCLASS32.

Please let me know if you have any questions, or if either of these needs any 
refactoring to be accepted in the upstream source.

Thanks!
--Mark

[-- Attachment #2: 0001-Implement-PL_ARCH-arch.patch --]
[-- Type: text/plain, Size: 7168 bytes --]

From 948e632f0957b8456b02a393772c9d1c904a2505 Mon Sep 17 00:00:00 2001
Message-Id: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com>
From: Mark Hatle <mark.hatle@windriver.com>
Date: Wed, 21 Dec 2011 12:55:34 -0600
Subject: [PATCH 1/2] Implement PL_ARCH(arch)

In order to allow for multiple (related) architectures to be defined
in the same file, we allow an arch setting for each PL_ARCH string.

The code is based on work originally done by Code Sourcery, LLC.
(Now part of Mentor Graphics.)

Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
---
 trunk/ChangeLog          |   19 +++++++++++++++++++
 trunk/src/arch-alpha.c   |    2 +-
 trunk/src/arch-arm.c     |    2 +-
 trunk/src/arch-cris.c    |    2 +-
 trunk/src/arch-i386.c    |    2 +-
 trunk/src/arch-ia64.c    |    2 +-
 trunk/src/arch-mips.c    |    2 +-
 trunk/src/arch-ppc.c     |    2 +-
 trunk/src/arch-ppc64.c   |    2 +-
 trunk/src/arch-s390.c    |    2 +-
 trunk/src/arch-s390x.c   |    2 +-
 trunk/src/arch-sh.c      |    2 +-
 trunk/src/arch-sparc.c   |    2 +-
 trunk/src/arch-sparc64.c |    2 +-
 trunk/src/arch-x86_64.c  |    2 +-
 trunk/src/prelink.h      |    4 ++--
 16 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/trunk/ChangeLog b/trunk/ChangeLog
index 2ab86ce..ce51553 100644
--- a/trunk/ChangeLog
+++ b/trunk/ChangeLog
@@ -1,3 +1,22 @@
+2011-12-21  Mark Hatle  <mark@hatle.net>
+	* Following code is based on work originally by
+          Code Sourcery, LLC.  (Now part of Mentor Graphics)
+	* prelink.h: Change definition of PL_ARCH
+	* src/arch-alpha.c: Rename PL_ARCH to PL_ARCH(alpha)
+	* src/arch-arm.c: Likewise
+	* src/arch-cris.c: Likewise
+	* src/arch-i386.c: Likewise
+	* src/arch-ia64.c: Likewise
+	* src/arch-mips.c: Likewise
+	* src/arch-ppc.c: Likewise
+	* src/arch-ppc64.c: Likewise
+	* src/arch-s390.c: Likewise
+	* src/arch-s390x.c: Likewise
+	* src/arch-sh.c: Likewise
+	* src/arch-sparc.c: Likewise
+	* src/arch-sparc64.c: Likewise
+	* src/arch-x86_64.c: Likewise
+
 2011-10-12  Jakub Jelinek  <jakub@redhat.com>
 
 	* src/main.c (layout_page_size): New variable.
diff --git a/trunk/src/arch-alpha.c b/trunk/src/arch-alpha.c
index b326b0b..7802a3e 100644
--- a/trunk/src/arch-alpha.c
+++ b/trunk/src/arch-alpha.c
@@ -466,7 +466,7 @@ alpha_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(alpha) = {
   .name = "Alpha",
   .class = ELFCLASS64,
   .machine = EM_ALPHA,
diff --git a/trunk/src/arch-arm.c b/trunk/src/arch-arm.c
index 30a8259..17c7507 100644
--- a/trunk/src/arch-arm.c
+++ b/trunk/src/arch-arm.c
@@ -823,7 +823,7 @@ arm_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(arm) = {
   .name = "ARM",
   .class = ELFCLASS32,
   .machine = EM_ARM,
diff --git a/trunk/src/arch-cris.c b/trunk/src/arch-cris.c
index d70260a..3272779 100644
--- a/trunk/src/arch-cris.c
+++ b/trunk/src/arch-cris.c
@@ -374,7 +374,7 @@ cris_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(cris) = {
   .name = "CRIS",
   .class = ELFCLASS32,
   .machine = EM_CRIS,
diff --git a/trunk/src/arch-i386.c b/trunk/src/arch-i386.c
index aae68f9..a1e0fcc 100644
--- a/trunk/src/arch-i386.c
+++ b/trunk/src/arch-i386.c
@@ -1089,7 +1089,7 @@ i386_layout_libs_post (struct layout_libs *l)
   return 0;
 }
 
-PL_ARCH = {
+PL_ARCH(i386) = {
   .name = "i386",
   .class = ELFCLASS32,
   .machine = EM_386,
diff --git a/trunk/src/arch-ia64.c b/trunk/src/arch-ia64.c
index 2573d69..6039115 100644
--- a/trunk/src/arch-ia64.c
+++ b/trunk/src/arch-ia64.c
@@ -492,7 +492,7 @@ ia64_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(ia64) = {
   .name = "IA-64",
   .class = ELFCLASS64,
   .machine = EM_IA_64,
diff --git a/trunk/src/arch-mips.c b/trunk/src/arch-mips.c
index 3e39f03..0c6fddc 100644
--- a/trunk/src/arch-mips.c
+++ b/trunk/src/arch-mips.c
@@ -995,7 +995,7 @@ mips_undo_prelink_rel (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr)
   return 0;
 }
 
-PL_ARCH = {
+PL_ARCH(mips) = {
   .name = "MIPS",
   .class = ELFCLASS32,
   .machine = EM_MIPS,
diff --git a/trunk/src/arch-ppc.c b/trunk/src/arch-ppc.c
index cb0c5f8..e22e5d5 100644
--- a/trunk/src/arch-ppc.c
+++ b/trunk/src/arch-ppc.c
@@ -1150,7 +1150,7 @@ ppc_layout_libs_post (struct layout_libs *l)
   return 0;
 }
 
-PL_ARCH = {
+PL_ARCH(ppc) = {
   .name = "PowerPC",
   .class = ELFCLASS32,
   .machine = EM_PPC,
diff --git a/trunk/src/arch-ppc64.c b/trunk/src/arch-ppc64.c
index 351fab1..a764b99 100644
--- a/trunk/src/arch-ppc64.c
+++ b/trunk/src/arch-ppc64.c
@@ -859,7 +859,7 @@ ppc64_free_opd (struct prelink_entry *ent)
   return 0;
 }
 
-PL_ARCH = {
+PL_ARCH(ppc64) = {
   .name = "PowerPC",
   .class = ELFCLASS64,
   .machine = EM_PPC64,
diff --git a/trunk/src/arch-s390.c b/trunk/src/arch-s390.c
index 829392e..fd076b1 100644
--- a/trunk/src/arch-s390.c
+++ b/trunk/src/arch-s390.c
@@ -567,7 +567,7 @@ s390_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(s390) = {
   .name = "S390",
   .class = ELFCLASS32,
   .machine = EM_S390,
diff --git a/trunk/src/arch-s390x.c b/trunk/src/arch-s390x.c
index a0321ef..8676fff 100644
--- a/trunk/src/arch-s390x.c
+++ b/trunk/src/arch-s390x.c
@@ -597,7 +597,7 @@ s390x_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(s390x) = {
   .name = "S390",
   .class = ELFCLASS64,
   .machine = EM_S390,
diff --git a/trunk/src/arch-sh.c b/trunk/src/arch-sh.c
index 095ed58..f5b0636 100644
--- a/trunk/src/arch-sh.c
+++ b/trunk/src/arch-sh.c
@@ -413,7 +413,7 @@ sh_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(sh) = {
   .name = "SuperH",
   .class = ELFCLASS32,
   .machine = EM_SH,
diff --git a/trunk/src/arch-sparc.c b/trunk/src/arch-sparc.c
index 7a3c8db..e016a79 100644
--- a/trunk/src/arch-sparc.c
+++ b/trunk/src/arch-sparc.c
@@ -606,7 +606,7 @@ sparc_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(sparc) = {
   .name = "SPARC",
   .class = ELFCLASS32,
   .machine = EM_SPARC,
diff --git a/trunk/src/arch-sparc64.c b/trunk/src/arch-sparc64.c
index 63e107f..aee4601 100644
--- a/trunk/src/arch-sparc64.c
+++ b/trunk/src/arch-sparc64.c
@@ -806,7 +806,7 @@ sparc64_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(sparc64) = {
   .name = "SPARC",
   .class = ELFCLASS64,
   .machine = EM_SPARCV9,
diff --git a/trunk/src/arch-x86_64.c b/trunk/src/arch-x86_64.c
index 3c760ed..3830f84 100644
--- a/trunk/src/arch-x86_64.c
+++ b/trunk/src/arch-x86_64.c
@@ -523,7 +523,7 @@ x86_64_reloc_class (int reloc_type)
     }
 }
 
-PL_ARCH = {
+PL_ARCH(x86_64) = {
   .name = "x86-64",
   .class = ELFCLASS64,
   .machine = EM_X86_64,
diff --git a/trunk/src/prelink.h b/trunk/src/prelink.h
index c223d4b..eceb2b6 100644
--- a/trunk/src/prelink.h
+++ b/trunk/src/prelink.h
@@ -312,8 +312,8 @@ unsigned char *get_data_from_iterator (struct data_iterator *it,
 				       GElf_Addr size);
 int get_sym_from_iterator (struct data_iterator *it, GElf_Sym *sym);
 
-#define PL_ARCH \
-static struct PLArch plarch __attribute__((section("pl_arch"),used))
+#define PL_ARCH(F) \
+static struct PLArch plarch_##F __attribute__((section("pl_arch"),used))
 
 #define addr_adjust(addr, start, adjust)	\
   do {						\
-- 
1.7.3.4


[-- Attachment #3: 0002-Add-support-for-new-X86_64-x32-ABI.patch --]
[-- Type: text/plain, Size: 8639 bytes --]

From bbce695157e8a88e0e9899908b0cd911dbe7dfbd Mon Sep 17 00:00:00 2001
Message-Id: <bbce695157e8a88e0e9899908b0cd911dbe7dfbd.1324503450.git.mark.hatle@windriver.com>
In-Reply-To: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com>
References: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com>
From: Mark Hatle <mark.hatle@windriver.com>
Date: Mon, 31 Oct 2011 18:14:37 -0500
Subject: [PATCH 2/2] Add support for new X86_64 - x32 ABI.

Experimental support for x32, based on the existing X86_64 support.

While this has been tested, I consider it experimental, like the x32 ABI.

See https://sites.google.com/site/x32abi/home for the ABI
document.  All work based on version 0.6 -- August 13, 2011

Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
---
 trunk/ChangeLog         |    1 +
 trunk/src/arch-x86_64.c |  102 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/trunk/ChangeLog b/trunk/ChangeLog
index ce51553..a4e09da 100644
--- a/trunk/ChangeLog
+++ b/trunk/ChangeLog
@@ -1,4 +1,5 @@
 2011-12-21  Mark Hatle  <mark@hatle.net>
+	* src/arch-x86_64.c: Add support for x32 ABI
 	* Following code is based on work originally by
           Code Sourcery, LLC.  (Now part of Mentor Graphics)
 	* prelink.h: Change definition of PL_ARCH
diff --git a/trunk/src/arch-x86_64.c b/trunk/src/arch-x86_64.c
index 3830f84..4fb3efb 100644
--- a/trunk/src/arch-x86_64.c
+++ b/trunk/src/arch-x86_64.c
@@ -1,5 +1,7 @@
 /* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009 Red Hat, Inc.
    Written by Jakub Jelinek <jakub@redhat.com>, 2001.
+   Copyright (C) 2011 Wind River Systems, Inc.
+   x32 support by Mark Hatle <mark.hatle@windriver.com>
 
    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
@@ -28,6 +30,22 @@
 
 #include "prelink.h"
 
+/* The x32 ABI: https://sites.google.com/site/x32abi/documents/abi.pdf
+ * documents a "class" value for specific reads and writes.  All this
+ * indicates is that we should be using the ELFCLASS to determine if
+ * this should be a 32/64 bit read/write.  (See table 4.9)
+ *
+ * We emulate this behavior below...
+ */
+#define read_uleclass(DSO, ADDR) \
+( gelf_getclass(DSO->elf) == ELFCLASS32 ? read_ule32(DSO, ADDR) : read_ule64(DSO, ADDR) )
+
+#define write_leclass(DSO, ADDR, VAL) \
+( gelf_getclass(DSO->elf) == ELFCLASS32 ? write_le32(DSO, ADDR, VAL) : write_le64(DSO, ADDR, VAL) )
+
+#define buf_write_leclass(DSO, BUF, VAL) \
+( gelf_getclass(DSO->elf) == ELFCLASS32 ? buf_write_le32(BUF, VAL) : buf_write_le64(BUF, VAL) )
+
 static int
 x86_64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start,
 		   GElf_Addr adjust)
@@ -84,8 +102,8 @@ x86_64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start,
     case R_X86_64_RELATIVE:
       if (rela->r_addend >= start)
 	{
-	  if (read_ule64 (dso, rela->r_offset) == rela->r_addend)
-	    write_le64 (dso, rela->r_offset, rela->r_addend + adjust);
+	  if (read_uleclass (dso, rela->r_offset) == rela->r_addend)
+	    write_leclass (dso, rela->r_offset, rela->r_addend + adjust);
 	  rela->r_addend += adjust;
 	}
       break;
@@ -94,9 +112,9 @@ x86_64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start,
 	rela->r_addend += adjust;
       /* FALLTHROUGH */
     case R_X86_64_JUMP_SLOT:
-      addr = read_ule64 (dso, rela->r_offset);
+      addr = read_uleclass (dso, rela->r_offset);
       if (addr >= start)
-	write_le64 (dso, rela->r_offset, addr + adjust);
+	write_leclass (dso, rela->r_offset, addr + adjust);
       break;
     }
   return 0;
@@ -122,7 +140,7 @@ x86_64_prelink_rela (struct prelink_info *info, GElf_Rela *rela,
     return 0;
   else if (GELF_R_TYPE (rela->r_info) == R_X86_64_RELATIVE)
     {
-      write_le64 (dso, rela->r_offset, rela->r_addend);
+      write_leclass (dso, rela->r_offset, rela->r_addend);
       return 0;
     }
   value = info->resolve (info, GELF_R_SYM (rela->r_info),
@@ -131,6 +149,8 @@ x86_64_prelink_rela (struct prelink_info *info, GElf_Rela *rela,
     {
     case R_X86_64_GLOB_DAT:
     case R_X86_64_JUMP_SLOT:
+      write_leclass (dso, rela->r_offset, value + rela->r_addend);
+      break;
     case R_X86_64_64:
       write_le64 (dso, rela->r_offset, value + rela->r_addend);
       break;
@@ -181,6 +201,8 @@ x86_64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela,
     {
     case R_X86_64_GLOB_DAT:
     case R_X86_64_JUMP_SLOT:
+      buf_write_leclass (info->dso, buf, rela->r_addend);
+      break;
     case R_X86_64_64:
       buf_write_le64 (buf, rela->r_addend);
       break;
@@ -223,6 +245,8 @@ x86_64_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf)
       break;
     case R_X86_64_GLOB_DAT:
     case R_X86_64_JUMP_SLOT:
+      buf_write_leclass (info->dso, buf, value + rela->r_addend);
+      break;
     case R_X86_64_64:
       buf_write_le64 (buf, value + rela->r_addend);
       break;
@@ -305,15 +329,19 @@ x86_64_prelink_conflict_rela (DSO *dso, struct prelink_info *info,
   switch (GELF_R_TYPE (rela->r_info))
     {
     case R_X86_64_GLOB_DAT:
-      ret->r_info = GELF_R_INFO (0, R_X86_64_64);
+      ret->r_info = GELF_R_INFO (0, (gelf_getclass (dso->elf) == ELFCLASS32 ? R_X86_64_32 : R_X86_64_64));
       /* FALLTHROUGH */
     case R_X86_64_JUMP_SLOT:
-    case R_X86_64_64:
     case R_X86_64_IRELATIVE:
       ret->r_addend = value + rela->r_addend;
       if (conflict != NULL && conflict->ifunc)
 	ret->r_info = GELF_R_INFO (0, R_X86_64_IRELATIVE);
       break;
+    case R_X86_64_64:
+      ret->r_addend = value + rela->r_addend;
+      if (conflict != NULL && conflict->ifunc)
+	ret->r_info = GELF_R_INFO (0, R_X86_64_64);
+      break;
     case R_X86_64_32:
       value += rela->r_addend;
       ret->r_addend = value;
@@ -459,16 +487,18 @@ x86_64_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr)
 	}
       else
 	{
-	  Elf64_Addr data = read_ule64 (dso, dso->shdr[sec].sh_addr + 8);
+	  Elf64_Addr data = read_uleclass (dso, dso->shdr[sec].sh_addr + 8);
 
 	  assert (rela->r_offset >= dso->shdr[sec].sh_addr + 24);
 	  assert (((rela->r_offset - dso->shdr[sec].sh_addr) & 7) == 0);
-	  write_le64 (dso, rela->r_offset,
+	  write_leclass (dso, rela->r_offset,
 		      2 * (rela->r_offset - dso->shdr[sec].sh_addr - 24)
 		      + data);
 	}
       break;
     case R_X86_64_GLOB_DAT:
+      write_leclass (dso, rela->r_offset, 0);
+      break;
     case R_X86_64_64:
     case R_X86_64_DTPMOD64:
     case R_X86_64_DTPOFF64:
@@ -509,6 +539,21 @@ x86_64_reloc_size (int reloc_type)
 }
 
 static int
+x86_64_x32_reloc_size (int reloc_type)
+{
+  switch (reloc_type)
+    {
+    case R_X86_64_64:
+      return 8;
+    case R_X86_64_GLOB_DAT:
+    case R_X86_64_JUMP_SLOT:
+    case R_X86_64_IRELATIVE:
+    default:
+      return 4;
+    }
+}
+
+static int
 x86_64_reloc_class (int reloc_type)
 {
   switch (reloc_type)
@@ -523,6 +568,45 @@ x86_64_reloc_class (int reloc_type)
     }
 }
 
+PL_ARCH(x32) = {
+  .name = "x32",
+  .class = ELFCLASS32,
+  .machine = EM_X86_64,
+  .alternate_machine = { EM_NONE },
+  .R_JMP_SLOT = R_X86_64_JUMP_SLOT,
+  .R_COPY = R_X86_64_COPY,
+  .R_RELATIVE = R_X86_64_RELATIVE,
+  .rtype_class_valid = RTYPE_CLASS_VALID,
+  .dynamic_linker = "/libx32/ld-linux-x32.so.2",
+  .adjust_dyn = x86_64_adjust_dyn,
+  .adjust_rel = x86_64_adjust_rel,
+  .adjust_rela = x86_64_adjust_rela,
+  .prelink_rel = x86_64_prelink_rel,
+  .prelink_rela = x86_64_prelink_rela,
+  .prelink_conflict_rel = x86_64_prelink_conflict_rel,
+  .prelink_conflict_rela = x86_64_prelink_conflict_rela,
+  .apply_conflict_rela = x86_64_apply_conflict_rela,
+  .apply_rel = x86_64_apply_rel,
+  .apply_rela = x86_64_apply_rela,
+  .rel_to_rela = x86_64_rel_to_rela,
+  .need_rel_to_rela = x86_64_need_rel_to_rela,
+  .reloc_size = x86_64_x32_reloc_size,
+  .reloc_class = x86_64_reloc_class,
+  .max_reloc_size = 8,
+  .arch_prelink = x86_64_arch_prelink,
+  .arch_undo_prelink = x86_64_arch_undo_prelink,
+  .undo_prelink_rela = x86_64_undo_prelink_rela,
+  /* Although TASK_UNMAPPED_BASE is 0x40000000, we leave some
+     area so that mmap of /etc/ld.so.cache and ld.so's malloc
+     does not take some library's VA slot.
+     Also, if this guard area isn't too small, typically
+     even dlopened libraries will get the slots they desire.  */
+  .mmap_base = 0x41000000,
+  .mmap_end =  0x50000000,
+  .max_page_size = 0x200000,
+  .page_size = 0x1000
+};
+
 PL_ARCH(x86_64) = {
   .name = "x86-64",
   .class = ELFCLASS64,
-- 
1.7.3.4


                 reply	other threads:[~2011-12-21 21:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EF2515E.3090302@windriver.com \
    --to=mark.hatle@windriver.com \
    --cc=jakub@redhat.com \
    --cc=prelink@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).