From: Yasir-Khan <yasir_k...@mentor.com> >From Julian Brown, see http://sourcery.sje.mentorg.com/pipermail/gnu-arm-releases/2014-April/015072.html.
Signed-off-by: Christopher Larson <kerg...@gmail.com> Signed-off-by: Yasir-Khan <yasir_k...@mentor.com> --- .../prelink/prelink/arm-ifunc.patch | 264 ++++++++++++++++++++ meta/recipes-devtools/prelink/prelink_git.bb | 4 +- 2 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 meta/recipes-devtools/prelink/prelink/arm-ifunc.patch diff --git a/meta/recipes-devtools/prelink/prelink/arm-ifunc.patch b/meta/recipes-devtools/prelink/prelink/arm-ifunc.patch new file mode 100644 index 0000000..b63affc --- /dev/null +++ b/meta/recipes-devtools/prelink/prelink/arm-ifunc.patch @@ -0,0 +1,264 @@ +Kyle McMartin <kmcmar...@redhat.com> +Jakub Jelinek <ja...@redhat.com> +Julian Brown <jul...@codesourcery.com> + +* testsuite/ifunc.h: Add ARM support. +* src/prelink.h (R_ARM_IRELATIVE): Define. +* src/arch-arm.c (arm_adjust_rel, arm_adjust_rela) +(arm_prelink_rel, arm_prelink_rela, arm_apply_conflict_rela) +(arm_rela_to_rel, arm_rel_to_rela, arm_undo_prelink_rel): +Handle R_ARM_IRELATIVE. +(arm_prelink_conflict_rel, arm_prelink_conflict_rela): Handle +R_ARM_IRELATIVE, ifunc conflicts. + +Upstream-Status: Pending [This is applied to the CodeBench toolchain, but not to upstream prelink, nor to prelink-cross] + +Index: trunk/src/arch-arm.c +=================================================================== +--- trunk.orig/src/arch-arm.c 2014-04-25 16:07:02.190843841 -0700 ++++ trunk/src/arch-arm.c 2014-04-25 16:08:12.211355745 -0700 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2001, 2002, 2004, 2009, 2011 Red Hat, Inc. ++/* Copyright (C) 2001, 2002, 2004, 2009, 2011, 2013 Red Hat, Inc. + Written by Jakub Jelinek <ja...@redhat.com>, 2001. + + This program is free software; you can redistribute it and/or modify +@@ -80,6 +80,7 @@ + { + case R_ARM_RELATIVE: + case R_ARM_JUMP_SLOT: ++ case R_ARM_IRELATIVE: + data = read_une32 (dso, rel->r_offset); + if (data >= start) + write_ne32 (dso, rel->r_offset, data + adjust); +@@ -97,6 +98,7 @@ + switch (GELF_R_TYPE (rela->r_info)) + { + case R_ARM_RELATIVE: ++ case R_ARM_IRELATIVE: + if ((Elf32_Addr) rela->r_addend >= start) + { + rela->r_addend += (Elf32_Sword) adjust; +@@ -123,6 +125,7 @@ + Elf32_Sword val; + + if (GELF_R_TYPE (rel->r_info) == R_ARM_RELATIVE ++ || GELF_R_TYPE (rel->r_info) == R_ARM_IRELATIVE + || GELF_R_TYPE (rel->r_info) == R_ARM_NONE) + /* Fast path: nothing to do. */ + return 0; +@@ -212,6 +215,7 @@ + Elf32_Sword val; + + if (GELF_R_TYPE (rela->r_info) == R_ARM_RELATIVE ++ || GELF_R_TYPE (rela->r_info) == R_ARM_IRELATIVE + || GELF_R_TYPE (rela->r_info) == R_ARM_NONE) + /* Fast path: nothing to do. */ + return 0; +@@ -293,6 +297,8 @@ + arm_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, + char *buf, GElf_Addr dest_addr) + { ++ GElf_Rela *ret; ++ + switch (GELF_R_TYPE (rela->r_info)) + { + case R_ARM_GLOB_DAT: +@@ -300,6 +306,16 @@ + case R_ARM_ABS32: + buf_write_ne32 (info->dso, buf, rela->r_addend); + break; ++ case R_ARM_IRELATIVE: ++ if (dest_addr == 0) ++ return 5; ++ ret = prelink_conflict_add_rela (info); ++ if (ret == NULL) ++ return 1; ++ ret->r_offset = dest_addr; ++ ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); ++ ret->r_addend = rela->r_addend; ++ break; + default: + abort (); + } +@@ -399,35 +415,31 @@ + GElf_Rela *ret; + + if (GELF_R_TYPE (rel->r_info) == R_ARM_RELATIVE +- || GELF_R_TYPE (rel->r_info) == R_ARM_NONE +- || info->dso == dso) ++ || GELF_R_TYPE (rel->r_info) == R_ARM_NONE) + /* Fast path: nothing to do. */ + return 0; + conflict = prelink_conflict (info, GELF_R_SYM (rel->r_info), + GELF_R_TYPE (rel->r_info)); + if (conflict == NULL) + { +- if (info->curtls == NULL) +- return 0; +- + switch (GELF_R_TYPE (rel->r_info)) + { + /* Even local DTPMOD and TPOFF relocs need conflicts. */ + case R_ARM_TLS_DTPMOD32: + case R_ARM_TLS_TPOFF32: ++ if (info->curtls == NULL || info->dso == dso) ++ return 0; ++ break; ++ /* Similarly IRELATIVE relocations always need conflicts. */ ++ case R_ARM_IRELATIVE: + break; +- + default: + return 0; + } + value = 0; + } +- else if (conflict->ifunc) +- { +- error (0, 0, "%s: STT_GNU_IFUNC not handled on ARM yet", +- dso->filename); +- return 1; +- } ++ else if (info->dso == dso && !conflict->ifunc) ++ return 0; + else + { + /* DTPOFF32 wants to see only real conflicts, not lookups +@@ -450,6 +462,11 @@ + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + ret->r_addend = (Elf32_Sword) value; ++ if (conflict != NULL && conflict->ifunc) ++ ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); ++ break; ++ case R_ARM_IRELATIVE: ++ ret->r_addend = (Elf32_Sword) read_une32 (dso, rel->r_offset); + break; + case R_ARM_ABS32: + case R_ARM_PC24: +@@ -508,8 +525,7 @@ + Elf32_Sword val; + + if (GELF_R_TYPE (rela->r_info) == R_ARM_RELATIVE +- || GELF_R_TYPE (rela->r_info) == R_ARM_NONE +- || info->dso == dso) ++ || GELF_R_TYPE (rela->r_info) == R_ARM_NONE) + /* Fast path: nothing to do. */ + return 0; + conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), +@@ -517,27 +533,24 @@ + + if (conflict == NULL) + { +- if (info->curtls == NULL) +- return 0; +- + switch (GELF_R_TYPE (rela->r_info)) + { + /* Even local DTPMOD and TPOFF relocs need conflicts. */ + case R_ARM_TLS_DTPMOD32: + case R_ARM_TLS_TPOFF32: ++ if (info->curtls == NULL || info->dso == dso) ++ return 0; ++ break; ++ /* Similarly IRELATIVE relocations always need conflicts. */ ++ case R_ARM_IRELATIVE: + break; +- + default: + return 0; + } + value = 0; + } +- else if (conflict->ifunc) +- { +- error (0, 0, "%s: STT_GNU_IFUNC not handled on ARM yet", +- dso->filename); +- return 1; +- } ++ else if (info->dso == dso && !conflict->ifunc) ++ return 0; + else + { + /* DTPOFF32 wants to see only real conflicts, not lookups +@@ -560,7 +573,10 @@ + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + case R_ARM_ABS32: ++ case R_ARM_IRELATIVE: + ret->r_addend = (Elf32_Sword) (value + rela->r_addend); ++ if (conflict && conflict->ifunc) ++ ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); + break; + case R_ARM_PC24: + val = value + rela->r_addend - rela->r_offset; +@@ -625,6 +641,7 @@ + /* We should be never converting .rel.plt into .rela.plt. */ + abort (); + case R_ARM_RELATIVE: ++ case R_ARM_IRELATIVE: + case R_ARM_ABS32: + case R_ARM_TLS_TPOFF32: + case R_ARM_TLS_DTPOFF32: +@@ -656,6 +673,7 @@ + and thus never .rela.plt back to .rel.plt. */ + abort (); + case R_ARM_RELATIVE: ++ case R_ARM_IRELATIVE: + case R_ARM_ABS32: + case R_ARM_TLS_TPOFF32: + case R_ARM_TLS_DTPOFF32: +@@ -794,6 +812,7 @@ + switch (GELF_R_TYPE (rel->r_info)) + { + case R_ARM_RELATIVE: ++ case R_ARM_IRELATIVE: + case R_ARM_NONE: + break; + case R_ARM_JUMP_SLOT: +Index: trunk/src/prelink.h +=================================================================== +--- trunk.orig/src/prelink.h 2014-04-25 16:07:02.000000000 -0700 ++++ trunk/src/prelink.h 2014-04-25 16:08:12.235355916 -0700 +@@ -145,6 +145,10 @@ + #define R_390_IRELATIVE 61 + #endif + ++#ifndef R_ARM_IRELATIVE ++#define R_ARM_IRELATIVE 160 ++#endif ++ + struct prelink_entry; + struct prelink_info; + struct PLArch; +Index: trunk/testsuite/ifunc.h +=================================================================== +--- trunk.orig/testsuite/ifunc.h 2014-04-25 16:07:02.000000000 -0700 ++++ trunk/testsuite/ifunc.h 2014-04-25 16:08:43.831585698 -0700 +@@ -35,6 +35,25 @@ + IFUNC_ASM (PICK (fn1, fn2)) \ + "\t.size " #name ", .-.L" #name "\n") + # endif ++#elif defined __arm__ ++# ifdef __thumb__ ++# define PIPE_OFFSET "4" ++# else ++# define PIPE_OFFSET "8" ++# endif ++# define IFUNC_ASM(fn) \ ++ "\tldr r0, .L" fn "\n" \ ++ "1:\tadd r0, pc, r0\n" \ ++ "\tmov pc, lr\n" \ ++ ".L" fn ": .long " fn " - 1b - " PIPE_OFFSET "\n" ++# define IFUNC_DECL(name, hidden, fn1, fn2) \ ++asm (".text\n" \ ++ "\t.globl " #name "\n" \ ++ "\t" hidden " " #name "\n" \ ++ "\t.type " #name ", %gnu_indirect_function\n" \ ++ #name ":\n" \ ++ IFUNC_ASM (PICK (fn1, fn2)) \ ++ "\t.size " #name ", .-" #name "\n") + #else + # error Architecture not supported + #endif diff --git a/meta/recipes-devtools/prelink/prelink_git.bb b/meta/recipes-devtools/prelink/prelink_git.bb index 3288822..5aa850d 100644 --- a/meta/recipes-devtools/prelink/prelink_git.bb +++ b/meta/recipes-devtools/prelink/prelink_git.bb @@ -30,7 +30,9 @@ SRC_URI = "git://git.yoctoproject.org/prelink-cross.git;branch=cross_prelink \ file://prelink.conf \ file://prelink.cron.daily \ file://prelink.default \ - file://macros.prelink" + file://macros.prelink \ + file://arm-ifunc.patch \ +" TARGET_OS_ORIG := "${TARGET_OS}" OVERRIDES_append = ":${TARGET_OS_ORIG}" -- 1.7.9.5 -- _______________________________________________ Openembedded-core mailing list Openembedded-core@lists.openembedded.org http://lists.openembedded.org/mailman/listinfo/openembedded-core