From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19689 invoked by alias); 21 Dec 2011 21:36:54 -0000 Received: (qmail 19067 invoked by uid 22791); 21 Dec 2011 21:36:51 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.windriver.com (HELO mail.windriver.com) (147.11.1.11) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 21 Dec 2011 21:36:36 +0000 Received: from ALA-HCA.corp.ad.wrs.com (ala-hca [147.11.189.40]) by mail.windriver.com (8.14.3/8.14.3) with ESMTP id pBLLaXnq018487 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=FAIL); Wed, 21 Dec 2011 13:36:33 -0800 (PST) Received: from Macintosh-5.local (172.25.36.232) by ALA-HCA.corp.ad.wrs.com (147.11.189.50) with Microsoft SMTP Server id 14.1.255.0; Wed, 21 Dec 2011 13:36:31 -0800 Message-ID: <4EF2515E.3090302@windriver.com> Date: Wed, 21 Dec 2011 21:36:00 -0000 From: Mark Hatle User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:8.0) Gecko/20111105 Thunderbird/8.0 MIME-Version: 1.0 To: CC: Subject: Add x32 support to prelink Content-Type: multipart/mixed; boundary="------------050700090004090800050701" X-IsSubscribed: yes Mailing-List: contact prelink-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: prelink-owner@sourceware.org X-SW-Source: 2011-q4/txt/msg00002.txt.bz2 --------------050700090004090800050701 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 973 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 --------------050700090004090800050701 Content-Type: text/plain; x-mac-type=0; x-mac-creator=0; name="0001-Implement-PL_ARCH-arch.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Implement-PL_ARCH-arch.patch" Content-length: 7169 >From 948e632f0957b8456b02a393772c9d1c904a2505 Mon Sep 17 00:00:00 2001 Message-Id: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com> From: Mark Hatle 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 --- 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 + * 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 * 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 --------------050700090004090800050701 Content-Type: text/plain; x-mac-type=0; x-mac-creator=0; name="0002-Add-support-for-new-X86_64-x32-ABI.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-Add-support-for-new-X86_64-x32-ABI.patch" Content-length: 8640 >From bbce695157e8a88e0e9899908b0cd911dbe7dfbd Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com> References: <948e632f0957b8456b02a393772c9d1c904a2505.1324503450.git.mark.hatle@windriver.com> From: Mark Hatle 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 --- 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 + * 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 , 2001. + Copyright (C) 2011 Wind River Systems, Inc. + x32 support by Mark Hatle 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 --------------050700090004090800050701--