diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/sparc/sparc32/dl-machine.h | 16 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/dl-machine.h | 16 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/strncmp.S | 11 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/fork.S | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sys/procfs.h | 69 |
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 */ |