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