[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r9966 - in /fsf/trunk/libc: ./ math/ sysdeps/sparc/sparc32/ sysdeps/sparc/sparc64/ sysdeps/unix/sysv/linux/sparc/sparc64/
- To: commits@xxxxxxxxxx
- Subject: [commits] r9966 - in /fsf/trunk/libc: ./ math/ sysdeps/sparc/sparc32/ sysdeps/sparc/sparc64/ sysdeps/unix/sysv/linux/sparc/sparc64/
- From: eglibc@xxxxxxxxxx
- Date: Thu, 04 Mar 2010 08:03:46 -0000
Author: eglibc
Date: Thu Mar 4 00:03:43 2010
New Revision: 9966
Log:
Import glibc-mainline for 2010-03-04
Added:
fsf/trunk/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/math/math_private.h
fsf/trunk/libc/sysdeps/sparc/sparc32/dl-machine.h
fsf/trunk/libc/sysdeps/sparc/sparc32/dl-plt.h
fsf/trunk/libc/sysdeps/sparc/sparc64/dl-machine.h
fsf/trunk/libc/sysdeps/sparc/sparc64/dl-plt.h
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Mar 4 00:03:43 2010
@@ -1,3 +1,27 @@
+2010-03-03 David S. Miller <davem@xxxxxxxxxxxxx>
+
+ * math/math_private.h (INSERT_WORDS64): Fix argument order.
+
+2010-03-03 Aurelien Jarno <aurelien@xxxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c: New file.
+
+2010-03-03 David S. Miller <davem@xxxxxxxxxxxxx>
+
+ * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_lazy_rel): Must
+ pass '1' for 't' argument to sparc_fixup_plt.
+ * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_lazy_rel):
+ Likewise.
+ * sysdeps/sparc/sparc32/dl-plt.h (OPCODE_BA_PT): Define.
+ (sparc_fixup_plt): Document 't' argument. Enable branch
+ optimization and use v9 branches when possible. Explain why we
+ cannot unconditionally patch the branch into the first PLT
+ instruction.
+ * sysdeps/sparc/sparc64/dl-plt.h (sparc64_fixup_plt): Document 't'
+ argument. Use v9 branches when possible. Explain why we can in
+ fact unconditionally use a branch in the first PLT instruction
+ here.
+
2010-02-28 Roland McGrath <roland@xxxxxxxxxx>
* elf/elf.h (NT_X86_XSTATE): New macro.
Modified: fsf/trunk/libc/math/math_private.h
==============================================================================
--- fsf/trunk/libc/math/math_private.h (original)
+++ fsf/trunk/libc/math/math_private.h Thu Mar 4 00:03:43 2010
@@ -111,7 +111,7 @@
} while (0)
/* Get all in one, efficient on 64-bit machines. */
-#define INSERT_WORDS64(i,d) \
+#define INSERT_WORDS64(d,i) \
do { \
ieee_double_shape_type iw_u; \
iw_u.word = (i); \
Modified: fsf/trunk/libc/sysdeps/sparc/sparc32/dl-machine.h
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/sparc32/dl-machine.h (original)
+++ fsf/trunk/libc/sysdeps/sparc/sparc32/dl-machine.h Thu Mar 4 00:03:43 2010
@@ -563,7 +563,7 @@
{
Elf32_Addr value = map->l_addr + reloc->r_addend;
value = ((Elf32_Addr (*) (void)) value) ();
- sparc_fixup_plt (reloc, reloc_addr, value, 0, 1);
+ sparc_fixup_plt (reloc, reloc_addr, value, 1, 1);
}
else if (r_type == R_SPARC_NONE)
;
Modified: fsf/trunk/libc/sysdeps/sparc/sparc32/dl-plt.h
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/sparc32/dl-plt.h (original)
+++ fsf/trunk/libc/sysdeps/sparc/sparc32/dl-plt.h Thu Mar 4 00:03:43 2010
@@ -25,19 +25,55 @@
#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */
+#define OPCODE_BA_PT 0x30480000 /* ba,a,pt %icc, ?; add PC-rel word address */
static inline __attribute__ ((always_inline)) Elf32_Addr
sparc_fixup_plt (const Elf32_Rela *reloc, Elf32_Addr *reloc_addr,
Elf32_Addr value, int t, int do_flush)
{
- Elf32_Sword disp = value - (Elf32_Addr) reloc_addr;
+ Elf32_Sword disp;
- if (0 && disp >= -0x800000 && disp < 0x800000)
+ /* 't' is '0' if we are resolving this PLT entry for RTLD bootstrap,
+ in which case we'll be resolving all PLT entries and thus can
+ optimize by overwriting instructions starting at the first PLT entry
+ instruction and we need not be mindful of thread safety.
+
+ Otherwise, 't' is '1'. */
+ reloc_addr += t;
+ disp = value - (Elf32_Addr) reloc_addr;
+
+ if (disp >= -0x800000 && disp < 0x800000)
{
- /* Don't need to worry about thread safety. We're writing just one
- instruction. */
+ unsigned int insn = OPCODE_BA | ((disp >> 2) & 0x3fffff);
- reloc_addr[0] = OPCODE_BA | ((disp >> 2) & 0x3fffff);
+#ifdef __sparc_v9__
+ /* On V9 we can do even better by using a branch with
+ prediction if we fit into the even smaller 19-bit
+ displacement field. */
+ if (disp >= -0x100000 && disp < 0x100000)
+ insn = OPCODE_BA_PT | ((disp >> 2) & 0x07ffff);
+#endif
+
+ /* Even if we are writing just a single branch, we must not
+ ignore the 't' offset. Consider a case where we have some
+ PLT slots which can be optimized into a single branch and
+ some which cannot. Then we can end up with a PLT which looks
+ like:
+
+ PLT4.0: sethi %(PLT_4_INDEX), %g1
+ sethi %(fully_resolved_sym_4), %g1
+ jmp %g1 + %lo(fully_resolved_sym_4)
+ PLT5.0: ba,a fully_resolved_sym_5
+ ba,a PLT0.0
+ ...
+
+ The delay slot of that jmp must always be either a sethi to
+ %g1 or a nop. But if we try to place this displacement
+ branch there, PLT4.0 will jump to fully_resolved_sym_4 for 1
+ instruction and then go immediately to
+ fully_resolved_sym_5. */
+
+ reloc_addr[0] = insn;
if (do_flush)
__asm __volatile ("flush %0" : : "r"(reloc_addr));
}
@@ -48,7 +84,6 @@
need not be done during bootstrapping, since there are no threads.
But we also can't tell if we _can_ use flush, so don't. */
- reloc_addr += t;
reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff);
if (do_flush)
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
Modified: fsf/trunk/libc/sysdeps/sparc/sparc64/dl-machine.h
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/sparc64/dl-machine.h (original)
+++ fsf/trunk/libc/sysdeps/sparc/sparc64/dl-machine.h Thu Mar 4 00:03:43 2010
@@ -661,7 +661,7 @@
{
/* 'high' is always zero, for large PLT entries the linker
emits an R_SPARC_IRELATIVE. */
- sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 0);
+ sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 1);
}
else
*reloc_addr = value;
Modified: fsf/trunk/libc/sysdeps/sparc/sparc64/dl-plt.h
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/sparc64/dl-plt.h (original)
+++ fsf/trunk/libc/sysdeps/sparc/sparc64/dl-plt.h Thu Mar 4 00:03:43 2010
@@ -28,7 +28,14 @@
Elf64_Addr plt_vaddr = (Elf64_Addr) reloc_addr;
Elf64_Sxword disp = value - plt_vaddr;
- /* Now move plt_vaddr up to the call instruction. */
+ /* 't' is '0' if we are resolving this PLT entry for RTLD bootstrap,
+ in which case we'll be resolving all PLT entries and thus can
+ optimize by overwriting instructions starting at the first PLT entry
+ instruction and we need not be mindful of thread safety.
+
+ Otherwise, 't' is '1'.
+
+ Now move plt_vaddr up to the call instruction. */
plt_vaddr += ((t + 1) * 4);
/* PLT entries .PLT32768 and above look always the same. */
@@ -39,10 +46,22 @@
/* Near destination. */
else if (disp >= -0x800000 && disp < 0x800000)
{
- /* As this is just one instruction, it is thread safe and so
- we can avoid the unnecessary sethi FOO, %g1.
- b,a target */
- insns[0] = 0x30800000 | ((disp >> 2) & 0x3fffff);
+ unsigned int insn;
+
+ /* ba,a */
+ insn = 0x30800000 | ((disp >> 2) & 0x3fffff);
+
+ if (disp >= -0x100000 && disp < 0x100000)
+ {
+ /* ba,a,pt %icc */
+ insn = 0x30480000 | ((disp >> 2) & 0x07ffff);
+ }
+
+ /* As this is just one instruction, it is thread safe and so we
+ can avoid the unnecessary sethi FOO, %g1. Each 64-bit PLT
+ entry is 8 instructions long, so we can't run into the 'jmp'
+ delay slot problems 32-bit PLTs can. */
+ insns[0] = insn;
__asm __volatile ("flush %0" : : "r" (insns));
}
/* 32-bit Sparc style, the target is in the lower 32-bits of
Added: fsf/trunk/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c (added)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c Thu Mar 4 00:03:43 2010
@@ -1,0 +1,49 @@
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#include <bp-checks.h>
+
+ssize_t
+__libc_msgrcv (msqid, msgp, msgsz, msgtyp, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ long int msgtyp;
+ int msgflg;
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (ipc, 6, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ CHECK_N (msgp, msgsz), msgtyp);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = INLINE_SYSCALL (ipc, 6, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ CHECK_N (msgp, msgsz), msgtyp);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_msgrcv, msgrcv)