aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h16
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h16
-rw-r--r--sysdeps/sparc/sparc64/strncmp.S11
-rw-r--r--sysdeps/unix/sysv/linux/sparc/fork.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sys/procfs.h69
5 files changed, 107 insertions, 6 deletions
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 4534464987..6977cdcd26 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -72,6 +72,17 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
return 0;
}
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+ invoked from functions that have no GOT references, and thus the compiler
+ has no obligation to load the PIC register. */
+#define LOAD_PIC_REG(PIC_REG) \
+do { register Elf32_Addr pc __asm("o7"); \
+ __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+ "call 1f\n\t" \
+ "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \
+ "1:\tadd %1, %0, %1" \
+ : "=r" (pc), "=r" (PIC_REG)); \
+} while (0)
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
first element of the GOT. This must be inlined in a function which
@@ -80,6 +91,9 @@ static inline Elf32_Addr
elf_machine_dynamic (void)
{
register Elf32_Addr *got asm ("%l7");
+
+ LOAD_PIC_REG (got);
+
return *got;
}
@@ -89,6 +103,8 @@ elf_machine_load_address (void)
{
register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got;
+ LOAD_PIC_REG (pic);
+
/* Utilize the fact that a local .got entry will be partially
initialized at startup awaiting its RELATIVE fixup. */
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 4ced7deef8..fba323dece 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -39,6 +39,18 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
return ehdr->e_machine == EM_SPARCV9;
}
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+ invoked from functions that have no GOT references, and thus the compiler
+ has no obligation to load the PIC register. */
+#define LOAD_PIC_REG(PIC_REG) \
+do { Elf64_Addr tmp; \
+ __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+ "rd %%pc, %0\n\t" \
+ "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \
+ "add %0, %1, %0" \
+ : "=r" (PIC_REG), "=r" (tmp)); \
+} while (0)
+
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
first element of the GOT. This must be inlined in a function which
uses global data. */
@@ -47,6 +59,8 @@ elf_machine_dynamic (void)
{
register Elf64_Addr *elf_pic_register __asm__("%l7");
+ LOAD_PIC_REG (elf_pic_register);
+
return *elf_pic_register;
}
@@ -56,6 +70,8 @@ elf_machine_load_address (void)
{
register Elf64_Addr *elf_pic_register __asm__("%l7");
+ LOAD_PIC_REG (elf_pic_register);
+
/* We used to utilize the fact that a local .got entry will
be partially initialized at startup awaiting its RELATIVE
fixup:
diff --git a/sysdeps/sparc/sparc64/strncmp.S b/sysdeps/sparc/sparc64/strncmp.S
index 3bc21d6664..31fcfeee08 100644
--- a/sysdeps/sparc/sparc64/strncmp.S
+++ b/sysdeps/sparc/sparc64/strncmp.S
@@ -290,14 +290,15 @@ ENTRY(strncmp)
ldxa [%o0] ASI_PNF, %g4 /* Load */
11: sllx %g3, 3, %g5 /* IEU0 Group */
mov 64, %g7 /* IEU1 */
- sub %o1, %g3, %o1 /* IEU0 Group */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ sub %o1, %g3, %o1 /* IEU1 */
- sub %g7, %g5, %g7 /* IEU1 */
+ sub %g7, %g5, %g7 /* IEU0 Group */
ldxa [%o1] ASI_PNF, %o4 /* Load */
- sllx %g1, 7, %g2 /* IEU0 Group */
- add %o1, 8, %o1 /* IEU1 */
+ sllx %g1, 7, %g2 /* IEU1 */
+ add %o1, 8, %o1 /* IEU0 Group */
/* %g1 = 0101010101010101
- %g2 = 8080808080800880
+ %g2 = 8080808080808080
%g3 = %o1 alignment
%g5 = number of bits to shift left
%g7 = number of bits to shift right */
diff --git a/sysdeps/unix/sysv/linux/sparc/fork.S b/sysdeps/unix/sysv/linux/sparc/fork.S
index 870d9608c1..ad9f3bb475 100644
--- a/sysdeps/unix/sysv/linux/sparc/fork.S
+++ b/sysdeps/unix/sysv/linux/sparc/fork.S
@@ -25,5 +25,6 @@ PSEUDO (__libc_fork, fork, 0)
and %o0, %o1, %o0
PSEUDO_END (__libc_fork)
+strong_alias (__libc_fork, __fork_internal)
weak_alias (__libc_fork, __fork)
weak_alias (__libc_fork, fork)
diff --git a/sysdeps/unix/sysv/linux/sparc/sys/procfs.h b/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
index e5d35f524a..2827b1ec33 100644
--- a/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
+++ b/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
@@ -35,7 +35,7 @@ __BEGIN_DECLS
#if __WORDSIZE == 64
-#define ELF_NGREG 20
+#define ELF_NGREG 36
typedef struct
{
@@ -139,6 +139,73 @@ typedef __pid_t lwpid_t;
typedef struct elf_prstatus prstatus_t;
typedef struct elf_prpsinfo prpsinfo_t;
+#if __WORDSIZE == 64
+
+/* Provide 32-bit variants so that BFD can read 32-bit
+ core files. */
+#define ELF_NGREG32 38
+typedef struct
+ {
+ union
+ {
+ unsigned int pr_regs[32];
+ double pr_dregs[16];
+ } pr_fr;
+ unsigned int __unused;
+ unsigned int pr_fsr;
+ unsigned char pr_qcnt;
+ unsigned char pr_q_entrysize;
+ unsigned char pr_en;
+ unsigned int pr_q[64];
+ } elf_fpregset_t32;
+
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG32];
+
+struct elf_prstatus32
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned int pr_sigpend; /* Set of pending signals. */
+ unsigned int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct
+ {
+ int tv_sec, tv_usec;
+ } pr_utime, /* User time. */
+ pr_stime, /* System time. */
+ pr_cutime, /* Cumulative user time. */
+ pr_cstime; /* Cumulative system time. */
+ elf_gregset_t32 pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+typedef elf_gregset_t32 prgregset32_t;
+typedef elf_fpregset_t32 prfpregset32_t;
+
+typedef struct elf_prstatus32 prstatus32_t;
+typedef struct elf_prpsinfo32 prpsinfo32_t;
+
+#endif /* sparc64 */
+
__END_DECLS
#endif /* sys/procfs.h */