You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
508 lines
17 KiB
508 lines
17 KiB
# commit 696caf1d002ff059ddd20fd5eaccd76229c14850 |
|
# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com> |
|
# Date: Wed Dec 4 06:51:11 2013 -0600 |
|
# |
|
# PowerPC64 ELFv2 ABI 2/6: Remove function descriptors |
|
# |
|
# This patch adds support for the ELFv2 ABI feature to remove function |
|
# descriptors. See this GCC patch for in-depth discussion: |
|
# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01141.html |
|
# |
|
# This mostly involves two types of changes: updating assembler source |
|
# files to the new logic, and updating the dynamic loader. |
|
# |
|
# After the refactoring in the previous patch, most of the assembler source |
|
# changes can be handled simply by providing ELFv2 versions of the |
|
# macros in sysdep.h. One somewhat non-obvious change is in __GI__setjmp: |
|
# this used to "fall through" to the immediately following __setjmp ENTRY |
|
# point. This is no longer safe in the ELFv2 since ENTRY defines both |
|
# a global and a local entry point, and you cannot simply fall through |
|
# to a global entry point as it requires r12 to be set up. |
|
# |
|
# Also, makecontext needs to be updated to set up registers according to |
|
# the new ABI for calling into the context's start routine. |
|
# |
|
# The dynamic linker changes mostly consist of removing special code |
|
# to handle function descriptors. We also need to support the new PLT |
|
# and glink format used by the the ELFv2 linker, see: |
|
# https://sourceware.org/ml/binutils/2013-10/msg00376.html |
|
# |
|
# In addition, the dynamic linker now verifies that the dynamic libraries |
|
# it loads match its own ABI. |
|
# |
|
# The hack in VDSO_IFUNC_RET to "synthesize" a function descriptor |
|
# for vDSO routines is also no longer necessary for ELFv2. |
|
# |
|
diff -urN glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h |
|
--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -2263,6 +2263,12 @@ |
|
#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ |
|
#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ |
|
|
|
+/* e_flags bits specifying ABI. |
|
+ 1 for original function descriptor using ABI, |
|
+ 2 for revised ABI without function descriptors, |
|
+ 0 for unspecified or not using any features affected by the differences. */ |
|
+#define EF_PPC64_ABI 3 |
|
+ |
|
/* PowerPC64 specific values for the Dyn d_tag field. */ |
|
#define DT_PPC64_GLINK (DT_LOPROC + 0) |
|
#define DT_PPC64_OPD (DT_LOPROC + 1) |
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S |
|
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -64,6 +64,7 @@ |
|
ENTRY_2(_init) |
|
.align ALIGNARG (2) |
|
BODY_LABEL (_init): |
|
+ LOCALENTRY(_init) |
|
mflr 0 |
|
std 0, 16(r1) |
|
stdu r1, -112(r1) |
|
@@ -81,6 +82,7 @@ |
|
ENTRY_2(_fini) |
|
.align ALIGNARG (2) |
|
BODY_LABEL (_fini): |
|
+ LOCALENTRY(_fini) |
|
mflr 0 |
|
std 0, 16(r1) |
|
stdu r1, -112(r1) |
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h |
|
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -50,7 +50,11 @@ |
|
{ |
|
Elf64_Addr *const reloc_addr = (void *) reloc->r_offset; |
|
Elf64_Addr value = elf_ifunc_invoke(reloc->r_addend); |
|
+#if _CALL_ELF != 2 |
|
*(Elf64_FuncDesc *) reloc_addr = *(Elf64_FuncDesc *) value; |
|
+#else |
|
+ *reloc_addr = value; |
|
+#endif |
|
} |
|
else |
|
__libc_fatal ("unexpected reloc type in static binary"); |
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h |
|
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:05:46.000000000 -0500 |
|
@@ -31,6 +31,7 @@ |
|
in l_info array. */ |
|
#define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM) |
|
|
|
+#if _CALL_ELF != 2 |
|
/* A PowerPC64 function descriptor. The .plt (procedure linkage |
|
table) and .opd (official procedure descriptor) sections are |
|
arrays of these. */ |
|
@@ -40,6 +41,7 @@ |
|
Elf64_Addr fd_toc; |
|
Elf64_Addr fd_aux; |
|
} Elf64_FuncDesc; |
|
+#endif |
|
|
|
#define ELF_MULT_MACHINES_SUPPORTED |
|
|
|
@@ -47,6 +49,18 @@ |
|
static inline int |
|
elf_machine_matches_host (const Elf64_Ehdr *ehdr) |
|
{ |
|
+ /* Verify that the binary matches our ABI version. */ |
|
+ if ((ehdr->e_flags & EF_PPC64_ABI) != 0) |
|
+ { |
|
+#if _CALL_ELF != 2 |
|
+ if ((ehdr->e_flags & EF_PPC64_ABI) != 1) |
|
+ return 0; |
|
+#else |
|
+ if ((ehdr->e_flags & EF_PPC64_ABI) != 2) |
|
+ return 0; |
|
+#endif |
|
+ } |
|
+ |
|
return ehdr->e_machine == EM_PPC64; |
|
} |
|
|
|
@@ -124,6 +138,7 @@ |
|
" .align 2\n" \ |
|
" " ENTRY_2(_start) "\n" \ |
|
BODY_PREFIX "_start:\n" \ |
|
+" " LOCALENTRY(_start) "\n" \ |
|
/* We start with the following on the stack, from top: \ |
|
argc (4 bytes); \ |
|
arguments for program (terminated by NULL); \ |
|
@@ -165,6 +180,7 @@ |
|
Changing these is strongly discouraged (not least because argc is \ |
|
passed by value!). */ \ |
|
BODY_PREFIX "_dl_start_user:\n" \ |
|
+" " LOCALENTRY(_dl_start_user) "\n" \ |
|
/* the address of _start in r30. */ \ |
|
" mr 30,3\n" \ |
|
/* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ \ |
|
@@ -256,8 +272,22 @@ |
|
relocations behave "normally", ie. always use the real address |
|
like PLT relocations. So always set ELF_RTYPE_CLASS_PLT. */ |
|
|
|
+#if _CALL_ELF != 2 |
|
#define elf_machine_type_class(type) \ |
|
(ELF_RTYPE_CLASS_PLT | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) |
|
+#else |
|
+/* And now that you have read that large comment, you can disregard it |
|
+ all for ELFv2. ELFv2 does need the special SHN_UNDEF treatment. */ |
|
+#define IS_PPC64_TLS_RELOC(R) \ |
|
+ (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) \ |
|
+ || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA)) |
|
+ |
|
+#define elf_machine_type_class(type) \ |
|
+ ((((type) == R_PPC64_JMP_SLOT \ |
|
+ || (type) == R_PPC64_ADDR24 \ |
|
+ || IS_PPC64_TLS_RELOC (type)) * ELF_RTYPE_CLASS_PLT) \ |
|
+ | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) |
|
+#endif |
|
|
|
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ |
|
#define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT |
|
@@ -266,8 +296,19 @@ |
|
#define ELF_MACHINE_NO_REL 1 |
|
|
|
/* Stuff for the PLT. */ |
|
+#if _CALL_ELF != 2 |
|
#define PLT_INITIAL_ENTRY_WORDS 3 |
|
+#define PLT_ENTRY_WORDS 3 |
|
#define GLINK_INITIAL_ENTRY_WORDS 8 |
|
+/* The first 32k entries of glink can set an index and branch using two |
|
+ instructions; past that point, glink uses three instructions. */ |
|
+#define GLINK_ENTRY_WORDS(I) (((I) < 0x8000)? 2 : 3) |
|
+#else |
|
+#define PLT_INITIAL_ENTRY_WORDS 2 |
|
+#define PLT_ENTRY_WORDS 1 |
|
+#define GLINK_INITIAL_ENTRY_WORDS 8 |
|
+#define GLINK_ENTRY_WORDS(I) 1 |
|
+#endif |
|
|
|
#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory") |
|
#define PPC_DCBT(where) asm volatile ("dcbt 0,%0" : : "r"(where) : "memory") |
|
@@ -312,17 +353,12 @@ |
|
|
|
if (lazy) |
|
{ |
|
- /* The function descriptor of the appropriate trampline |
|
- routine is used to set the 1st and 2nd doubleword of the |
|
- plt_reserve. */ |
|
- Elf64_FuncDesc *resolve_fd; |
|
Elf64_Word glink_offset; |
|
- /* the plt_reserve area is the 1st 3 doublewords of the PLT */ |
|
- Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt; |
|
Elf64_Word offset; |
|
+ Elf64_Addr dlrr; |
|
|
|
- resolve_fd = (Elf64_FuncDesc *) (profile ? _dl_profile_resolve |
|
- : _dl_runtime_resolve); |
|
+ dlrr = (Elf64_Addr) (profile ? _dl_profile_resolve |
|
+ : _dl_runtime_resolve); |
|
if (profile && GLRO(dl_profile) != NULL |
|
&& _dl_name_match_p (GLRO(dl_profile), map)) |
|
/* This is the object we are looking for. Say that we really |
|
@@ -330,20 +366,33 @@ |
|
GL(dl_profile_map) = map; |
|
|
|
|
|
+#if _CALL_ELF != 2 |
|
/* We need to stuff the address/TOC of _dl_runtime_resolve |
|
into doublewords 0 and 1 of plt_reserve. Then we need to |
|
stuff the map address into doubleword 2 of plt_reserve. |
|
This allows the GLINK0 code to transfer control to the |
|
correct trampoline which will transfer control to fixup |
|
in dl-machine.c. */ |
|
- plt_reserve->fd_func = resolve_fd->fd_func; |
|
- plt_reserve->fd_toc = resolve_fd->fd_toc; |
|
- plt_reserve->fd_aux = (Elf64_Addr) map; |
|
+ { |
|
+ /* The plt_reserve area is the 1st 3 doublewords of the PLT. */ |
|
+ Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt; |
|
+ Elf64_FuncDesc *resolve_fd = (Elf64_FuncDesc *) dlrr; |
|
+ plt_reserve->fd_func = resolve_fd->fd_func; |
|
+ plt_reserve->fd_toc = resolve_fd->fd_toc; |
|
+ plt_reserve->fd_aux = (Elf64_Addr) map; |
|
#ifdef RTLD_BOOTSTRAP |
|
- /* When we're bootstrapping, the opd entry will not have |
|
- been relocated yet. */ |
|
- plt_reserve->fd_func += l_addr; |
|
- plt_reserve->fd_toc += l_addr; |
|
+ /* When we're bootstrapping, the opd entry will not have |
|
+ been relocated yet. */ |
|
+ plt_reserve->fd_func += l_addr; |
|
+ plt_reserve->fd_toc += l_addr; |
|
+#endif |
|
+ } |
|
+#else |
|
+ /* When we don't have function descriptors, the first doubleword |
|
+ of the PLT holds the address of _dl_runtime_resolve, and the |
|
+ second doubleword holds the map address. */ |
|
+ plt[0] = dlrr; |
|
+ plt[1] = (Elf64_Addr) map; |
|
#endif |
|
|
|
/* Set up the lazy PLT entries. */ |
|
@@ -354,14 +403,8 @@ |
|
{ |
|
|
|
plt[offset] = (Elf64_Xword) &glink[glink_offset]; |
|
- offset += 3; |
|
- /* The first 32k entries of glink can set an index and |
|
- branch using two instructions; Past that point, |
|
- glink uses three instructions. */ |
|
- if (i < 0x8000) |
|
- glink_offset += 2; |
|
- else |
|
- glink_offset += 3; |
|
+ offset += PLT_ENTRY_WORDS; |
|
+ glink_offset += GLINK_ENTRY_WORDS (i); |
|
} |
|
|
|
/* Now, we've modified data. We need to write the changes from |
|
@@ -389,6 +432,7 @@ |
|
const Elf64_Rela *reloc, |
|
Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) |
|
{ |
|
+#if _CALL_ELF != 2 |
|
Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; |
|
Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; |
|
Elf64_Addr offset = 0; |
|
@@ -426,6 +470,9 @@ |
|
plt->fd_func = rel->fd_func + offset; |
|
PPC_DCBST (&plt->fd_func); |
|
PPC_ISYNC; |
|
+#else |
|
+ *reloc_addr = finaladdr; |
|
+#endif |
|
|
|
return finaladdr; |
|
} |
|
@@ -433,6 +480,7 @@ |
|
static inline void __attribute__ ((always_inline)) |
|
elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) |
|
{ |
|
+#if _CALL_ELF != 2 |
|
Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; |
|
Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; |
|
|
|
@@ -443,6 +491,9 @@ |
|
PPC_DCBST (&plt->fd_aux); |
|
PPC_DCBST (&plt->fd_toc); |
|
PPC_SYNC; |
|
+#else |
|
+ *reloc_addr = finaladdr; |
|
+#endif |
|
} |
|
|
|
/* Return the final value of a plt relocation. */ |
|
@@ -512,6 +563,7 @@ |
|
resolve_ifunc (Elf64_Addr value, |
|
const struct link_map *map, const struct link_map *sym_map) |
|
{ |
|
+#if _CALL_ELF != 2 |
|
#ifndef RESOLVE_CONFLICT_FIND_MAP |
|
/* The function we are calling may not yet have its opd entry relocated. */ |
|
Elf64_FuncDesc opd; |
|
@@ -529,6 +581,7 @@ |
|
value = (Elf64_Addr) &opd; |
|
} |
|
#endif |
|
+#endif |
|
return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap)); |
|
} |
|
|
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S |
|
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 14:00:27.000000000 -0500 |
|
@@ -55,21 +55,22 @@ |
|
that saves r2 since the call won't go via a plt call stub. See |
|
bugz #269. __GI__setjmp is used in csu/libc-start.c when |
|
HAVE_CLEANUP_JMP_BUF is defined. */ |
|
-ENTRY (BP_SYM (__GI__setjmp)) |
|
+ENTRY (__GI__setjmp) |
|
std r2,40(r1) /* Save the callers TOC in the save area. */ |
|
- cfi_endproc |
|
-END_2 (BP_SYM (__GI__setjmp)) |
|
-/* Fall thru. */ |
|
+ CALL_MCOUNT 1 |
|
+ li r4,0 /* Set second argument to 0. */ |
|
+ b JUMPTARGET (GLUE(__sigsetjmp,_ent)) |
|
+END (__GI__setjmp) |
|
#endif |
|
|
|
-ENTRY (BP_SYM (_setjmp)) |
|
+ENTRY (_setjmp) |
|
CALL_MCOUNT 1 |
|
li r4,0 /* Set second argument to 0. */ |
|
b JUMPTARGET (GLUE(__sigsetjmp,_ent)) |
|
-END (BP_SYM (_setjmp)) |
|
+END (_setjmp) |
|
libc_hidden_def (_setjmp) |
|
|
|
-ENTRY (BP_SYM (__sigsetjmp)) |
|
+ENTRY (__sigsetjmp) |
|
CALL_MCOUNT 2 |
|
JUMPTARGET(GLUE(__sigsetjmp,_ent)): |
|
CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) |
|
@@ -215,18 +216,18 @@ |
|
li r3,0 |
|
blr |
|
#elif defined SHARED |
|
- b JUMPTARGET (BP_SYM (__sigjmp_save)) |
|
+ b JUMPTARGET (__sigjmp_save) |
|
#else |
|
mflr r0 |
|
std r0,16(r1) |
|
stdu r1,-112(r1) |
|
cfi_adjust_cfa_offset(112) |
|
cfi_offset(lr,16) |
|
- bl JUMPTARGET (BP_SYM (__sigjmp_save)) |
|
+ bl JUMPTARGET (__sigjmp_save) |
|
nop |
|
ld r0,112+16(r1) |
|
addi r1,r1,112 |
|
mtlr r0 |
|
blr |
|
#endif |
|
-END (BP_SYM (__sigsetjmp)) |
|
+END (__sigsetjmp) |
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h |
|
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:58:25.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -74,6 +74,8 @@ |
|
#endif |
|
.endm |
|
|
|
+#if _CALL_ELF != 2 |
|
+ |
|
/* Macro to prepare for calling via a function pointer. */ |
|
.macro PPC64_LOAD_FUNCPTR PTR |
|
ld r12,0(\PTR) |
|
@@ -115,13 +117,37 @@ |
|
.size name,.-BODY_LABEL(name); \ |
|
.size BODY_LABEL(name),.-BODY_LABEL(name); |
|
#endif |
|
+#define LOCALENTRY(name) |
|
+ |
|
+#else /* _CALL_ELF */ |
|
+ |
|
+/* Macro to prepare for calling via a function pointer. */ |
|
+ .macro PPC64_LOAD_FUNCPTR PTR |
|
+ mr r12,\PTR |
|
+ mtctr r12 |
|
+ .endm |
|
+ |
|
+#define DOT_LABEL(X) X |
|
+#define BODY_LABEL(X) X |
|
+#define ENTRY_2(name) \ |
|
+ .globl name; \ |
|
+ .type name,@function; |
|
+#define END_2(name) \ |
|
+ .size name,.-name; |
|
+#define LOCALENTRY(name) \ |
|
+1: addis r2,r12,.TOC.-1b@ha; \ |
|
+ addi r2,r2,.TOC.-1b@l; \ |
|
+ .localentry name,.-name; |
|
+ |
|
+#endif /* _CALL_ELF */ |
|
|
|
#define ENTRY(name) \ |
|
.section ".text"; \ |
|
ENTRY_2(name) \ |
|
.align ALIGNARG(2); \ |
|
BODY_LABEL(name): \ |
|
- cfi_startproc; |
|
+ cfi_startproc; \ |
|
+ LOCALENTRY(name) |
|
|
|
#define EALIGN_W_0 /* No words to insert. */ |
|
#define EALIGN_W_1 nop |
|
@@ -140,7 +166,8 @@ |
|
.align ALIGNARG(alignt); \ |
|
EALIGN_W_##words; \ |
|
BODY_LABEL(name): \ |
|
- cfi_startproc; |
|
+ cfi_startproc; \ |
|
+ LOCALENTRY(name) |
|
|
|
/* Local labels stripped out by the linker. */ |
|
#undef L |
|
@@ -295,6 +322,8 @@ |
|
|
|
#else /* !__ASSEMBLER__ */ |
|
|
|
+#if _CALL_ELF != 2 |
|
+ |
|
#define PPC64_LOAD_FUNCPTR(ptr) \ |
|
"ld 12,0(" #ptr ");\n" \ |
|
"ld 2,8(" #ptr ");\n" \ |
|
@@ -335,5 +364,26 @@ |
|
".size " #name ",.-" BODY_PREFIX #name ";\n" \ |
|
".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";" |
|
#endif |
|
+#define LOCALENTRY(name) |
|
+ |
|
+#else /* _CALL_ELF */ |
|
+ |
|
+#define PPC64_LOAD_FUNCPTR(ptr) \ |
|
+ "mr 12," #ptr ";\n" \ |
|
+ "mtctr 12;" |
|
+ |
|
+#define DOT_PREFIX "" |
|
+#define BODY_PREFIX "" |
|
+#define ENTRY_2(name) \ |
|
+ ".type " #name ",@function;\n" \ |
|
+ ".globl " #name ";" |
|
+#define END_2(name) \ |
|
+ ".size " #name ",.-" #name ";" |
|
+#define LOCALENTRY(name) \ |
|
+ "1: addis 2,12,.TOC.-1b@ha;\n" \ |
|
+ "addi 2,2,.TOC.-1b@l;\n" \ |
|
+ ".localentry " #name ",.-" #name ";" |
|
+ |
|
+#endif /* _CALL_ELF */ |
|
|
|
#endif /* __ASSEMBLER__ */ |
|
diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h |
|
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h 2014-05-29 13:58:24.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -23,6 +23,8 @@ |
|
|
|
/* Now define our stuff. */ |
|
|
|
+#if _CALL_ELF != 2 |
|
+ |
|
static __always_inline bool |
|
_dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym) |
|
{ |
|
@@ -73,4 +75,6 @@ |
|
#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ |
|
_dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR) |
|
|
|
+#endif |
|
+ |
|
#endif /* ldsodefs.h */ |
|
diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S |
|
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:58:24.000000000 -0500 |
|
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:58:25.000000000 -0500 |
|
@@ -111,6 +111,7 @@ |
|
|
|
L(noparms): |
|
|
|
+#if _CALL_ELF != 2 |
|
/* Load the function address and TOC from the function descriptor |
|
and store them in the ucontext as NIP and r2. Store the 3rd |
|
field of the function descriptor into the ucontext as r11 in case |
|
@@ -121,6 +122,12 @@ |
|
std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) |
|
std r10,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) |
|
std r9,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3) |
|
+#else |
|
+ /* In the ELFv2 ABI, the function pointer is already the address. |
|
+ Store it as NIP and r12 as required by the ABI. */ |
|
+ std r4,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) |
|
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3) |
|
+#endif |
|
|
|
/* If the target function returns we need to do some cleanup. We use a |
|
code trick to get the address of our cleanup function into the link
|
|
|