summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/powerpc/dl-startup.h7
-rw-r--r--ldso/ldso/powerpc/dl-sysdep.h52
-rw-r--r--ldso/ldso/powerpc/elfinterp.c113
-rw-r--r--libc/sysdeps/linux/bfin/crt1.S27
-rw-r--r--libc/sysdeps/linux/bfin/sys/ucontext.h188
-rw-r--r--libc/sysdeps/linux/nios2/bits/mman.h9
-rw-r--r--libc/sysdeps/linux/nios2/bits/syscalls.h290
-rw-r--r--libc/sysdeps/linux/nios2/crt1.S6
-rw-r--r--libc/sysdeps/linux/nios2/crti.S25
-rw-r--r--libc/sysdeps/linux/nios2/crtn.S24
-rw-r--r--libc/sysdeps/linux/nios2/vfork.S2
-rw-r--r--libc/sysdeps/linux/powerpc/brk.S7
-rw-r--r--libc/sysdeps/linux/powerpc/bsd-_setjmp.S8
-rw-r--r--libc/sysdeps/linux/powerpc/bsd-setjmp.S8
-rw-r--r--libc/sysdeps/linux/powerpc/crt1.S7
-rw-r--r--libc/sysdeps/linux/powerpc/setjmp.S8
16 files changed, 553 insertions, 228 deletions
diff --git a/ldso/ldso/powerpc/dl-startup.h b/ldso/ldso/powerpc/dl-startup.h
index becfa191e..a5a8a83f2 100644
--- a/ldso/ldso/powerpc/dl-startup.h
+++ b/ldso/ldso/powerpc/dl-startup.h
@@ -16,8 +16,15 @@ asm(
" bl _dl_start@local\n" /* Perform relocation */
/* Save the address of the apps entry point in CTR register */
" mtctr 3\n" /* application entry point */
+#ifdef HAVE_ASM_PPC_REL16
+ " bcl 20,31,1f\n"
+ "1: mflr 31\n"
+ " addis 31,31,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+ " addi 31,31,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+#else
" bl _GLOBAL_OFFSET_TABLE_-4@local\n" /* Put our GOT pointer in r31, */
" mflr 31\n"
+#endif
" addi 1,1,16\n" /* Restore SP */
" lwz 7,_dl_skip_args@got(31)\n" /* load EA of _dl_skip_args */
" lwz 7,0(7)\n" /* Load word from _dl_skip_args */
diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h
index a06aa8aff..44f9c955c 100644
--- a/ldso/ldso/powerpc/dl-sysdep.h
+++ b/ldso/ldso/powerpc/dl-sysdep.h
@@ -89,23 +89,38 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
DT_RELA table. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
+/* Return the value of the GOT pointer. */
+static inline Elf32_Addr * __attribute__ ((const))
+ppc_got (void)
+{
+ Elf32_Addr *got;
+#ifdef HAVE_ASM_PPC_REL16
+ asm (" bcl 20,31,1f\n"
+ "1:mflr %0\n"
+ " addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+ " addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+ : "=b" (got) : : "lr");
+#else
+ asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
+ : "=l" (got));
+#endif
+ return got;
+}
+
/* Return the link-time address of _DYNAMIC, stored as
the first value in the GOT. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
elf_machine_dynamic (void)
{
- Elf32_Addr *got;
- asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
- : "=l"(got));
- return *got;
+ return *ppc_got();
}
/* Return the run-time load address of the shared object. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
elf_machine_load_address (void)
{
- unsigned int *got;
- unsigned int *branchaddr;
+ Elf32_Addr *branchaddr;
+ Elf32_Addr runtime_dynamic;
/* This is much harder than you'd expect. Possibly I'm missing something.
The 'obvious' way:
@@ -136,19 +151,17 @@ elf_machine_load_address (void)
the address ourselves. That gives us the following code: */
/* Get address of the 'b _DYNAMIC@local'... */
- asm ("bl 0f ;"
+ asm ("bcl 20,31,0f;"
"b _DYNAMIC@local;"
"0:"
: "=l"(branchaddr));
- /* ... and the address of the GOT. */
- asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
- : "=l"(got));
-
/* So now work out the difference between where the branch actually points,
and the offset of that location in memory from the start of the file. */
- return ((Elf32_Addr)branchaddr - *got
- + ((int)(*branchaddr << 6 & 0xffffff00) >> 6));
+ runtime_dynamic = ((Elf32_Addr) branchaddr
+ + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
+
+ return runtime_dynamic - elf_machine_dynamic ();
}
static inline void
@@ -163,3 +176,12 @@ elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
*reloc_addr = load_off + rpnt->r_addend;
} while (--relative_count);
}
+
+#define ARCH_NUM 1
+#define DT_PPC_GOT_IDX (DT_NUM + OS_NUM)
+
+#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
+do { \
+if (dpnt->d_tag == DT_PPC_GOT) \
+ dynamic[DT_PPC_GOT_IDX] = dpnt->d_un.d_ptr; \
+} while (0)
diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c
index d2a164287..b48625a37 100644
--- a/ldso/ldso/powerpc/elfinterp.c
+++ b/ldso/ldso/powerpc/elfinterp.c
@@ -41,6 +41,12 @@ void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
Elf32_Word rel_offset_words;
Elf32_Word dlrr = (Elf32_Word) _dl_linux_resolve;
+ if (tpnt->dynamic_info[DT_JMPREL] == 0)
+ return;
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ tpnt->dynamic_info[DT_PPC_GOT_IDX] += tpnt->loadaddr;
+ return;
+ }
num_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
data_words = (Elf32_Word) (plt + rel_offset_words);
@@ -148,32 +154,35 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
if (_dl_debug_reloc && _dl_debug_detail)
_dl_dprintf(_dl_debug_file, "%x\n", finaladdr);
#endif
- delta = finaladdr - (Elf32_Word)reloc_addr;
- if (delta<<6>>6 == delta) {
- *reloc_addr = OPCODE_B(delta);
- } else if (finaladdr <= 0x01fffffc) {
- *reloc_addr = OPCODE_BA (finaladdr);
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ *reloc_addr = finaladdr;
} else {
- /* Warning: we don't handle double-sized PLT entries */
- Elf32_Word *plt, *data_words, index, offset;
+ delta = finaladdr - (Elf32_Word)reloc_addr;
+ if (delta<<6>>6 == delta) {
+ *reloc_addr = OPCODE_B(delta);
+ } else if (finaladdr <= 0x01fffffc) {
+ *reloc_addr = OPCODE_BA (finaladdr);
+ } else {
+ /* Warning: we don't handle double-sized PLT entries */
+ Elf32_Word *plt, *data_words, index, offset;
+
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ offset = reloc_addr - plt;
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ data_words = (Elf32_Word *)tpnt->data_words;
+ reloc_addr += 1;
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
- offset = reloc_addr - plt;
- index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
- data_words = (Elf32_Word *)tpnt->data_words;
- reloc_addr += 1;
+ data_words[index] = finaladdr;
+ PPC_SYNC;
+ *reloc_addr = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+ }
- data_words[index] = finaladdr;
+ /* instructions were modified */
+ PPC_DCBST(reloc_addr);
PPC_SYNC;
- *reloc_addr = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+ PPC_ICBI(reloc_addr);
+ PPC_ISYNC;
}
-
- /* instructions were modified */
- PPC_DCBST(reloc_addr);
- PPC_SYNC;
- PPC_ICBI(reloc_addr);
- PPC_ISYNC;
-
return finaladdr;
}
@@ -219,28 +228,33 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
goto out_nocode; /* No code code modified */
case R_PPC_JMP_SLOT:
{
- Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
- if (delta<<6>>6 == delta) {
- *reloc_addr = OPCODE_B(delta);
- } else if (finaladdr <= 0x01fffffc) {
- *reloc_addr = OPCODE_BA (finaladdr);
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ *reloc_addr = finaladdr;
+ goto out_nocode; /* No code code modified */
} else {
- /* Warning: we don't handle double-sized PLT entries */
- Elf32_Word *plt, *data_words, index, offset;
-
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
- offset = reloc_addr - plt;
- index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
- data_words = (Elf32_Word *)tpnt->data_words;
-
- data_words[index] = finaladdr;
- reloc_addr[0] = OPCODE_LI(11,index*4);
- reloc_addr[1] = OPCODE_B((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
-
- /* instructions were modified */
- PPC_DCBST(reloc_addr+1);
- PPC_SYNC;
- PPC_ICBI(reloc_addr+1);
+ Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
+ if (delta<<6>>6 == delta) {
+ *reloc_addr = OPCODE_B(delta);
+ } else if (finaladdr <= 0x01fffffc) {
+ *reloc_addr = OPCODE_BA (finaladdr);
+ } else {
+ /* Warning: we don't handle double-sized PLT entries */
+ Elf32_Word *plt, *data_words, index, offset;
+
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ offset = reloc_addr - plt;
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ data_words = (Elf32_Word *)tpnt->data_words;
+
+ data_words[index] = finaladdr;
+ reloc_addr[0] = OPCODE_LI(11,index*4);
+ reloc_addr[1] = OPCODE_B((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+
+ /* instructions were modified */
+ PPC_DCBST(reloc_addr+1);
+ PPC_SYNC;
+ PPC_ICBI(reloc_addr+1);
+ }
}
break;
}
@@ -309,9 +323,22 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
Elf32_Word *plt, offset, i, num_plt_entries, rel_offset_words;
num_plt_entries = rel_size / sizeof(ELF_RELOC);
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ /* Secure PLT */
+ Elf32_Addr *got = (Elf32_Addr *)tpnt->dynamic_info[DT_PPC_GOT_IDX];
+ Elf32_Word dlrr = (Elf32_Word) _dl_linux_resolve;
+
+ got[1] = (Elf32_Addr) dlrr;
+ got[2] = (Elf32_Addr) tpnt;
+
+ /* Relocate everything in .plt by the load address offset. */
+ while (num_plt_entries-- != 0)
+ *plt++ += tpnt->loadaddr;
+ return;
+ }
rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
/* Set up the lazy PLT entries. */
offset = PLT_INITIAL_ENTRY_WORDS;
diff --git a/libc/sysdeps/linux/bfin/crt1.S b/libc/sysdeps/linux/bfin/crt1.S
index ffbd6e9af..156654437 100644
--- a/libc/sysdeps/linux/bfin/crt1.S
+++ b/libc/sysdeps/linux/bfin/crt1.S
@@ -83,6 +83,7 @@ __start:
L3 = 0;
#ifdef __ID_SHARED_LIB__
+ /* We know we have a local copy, so we can avoid the GOT. */
CALL ___shared_flat_add_library;
#endif
/* Load register R1 (argc) from the stack to its final resting place */
@@ -92,24 +93,15 @@ __start:
/* Copy argv pointer into R2 -- which its final resting place */
R2 = P0;
-/* Skip to the end of argv and put a pointer to the environment in
- [SP + 12] */
- R3 = R1;
- R3 <<= 2;
- R3 += 4;
- R3 = R2 + R3;
-
- P2 = SP;
- SP += -32;
- [SP + 12] = R3;
+ SP += -28;
#ifndef __BFIN_FDPIC__
R7 = 0;
#endif
/* Pass highest stack pointer to the app. */
- [SP + 28] = P2;
+ [SP + 24] = P2;
/* Store the pointer to ld.so's fini that we got in P1. */
- [SP + 24] = R7;
+ [SP + 20] = R7;
/* Ok, now run uClibc's main() -- shouldn't return */
#if defined L_crt1 && defined __UCLIBC_CTOR_DTOR__
@@ -123,7 +115,8 @@ __start:
R3.H = __init;
R3.L = __init;
#endif
- [SP+16] = R3;
+ [SP+12] = R3;
+
#ifdef __BFIN_FDPIC__
R3 = [P3 + __fini@FUNCDESC_GOT17M4];
@@ -133,11 +126,11 @@ __start:
R3.H = __fini;
R3.L = __fini;
#endif
- [SP+20] = R3;
+ [SP+16] = R3;
#else /* no ctor/dtor handling */
R3 = 0;
+ [SP + 12] = R3;
[SP + 16] = R3;
- [SP + 20] = R3;
#endif
#ifdef __BFIN_FDPIC__
@@ -162,8 +155,8 @@ __start:
.type lib_main,@function
lib_main:
RETS = [SP++];
- P0 = [P5 + ___shared_flat_add_library@GOT];
- JUMP (P0);
+ /* We know we have a local copy, so we can avoid the GOT. */
+ JUMP.L ___shared_flat_add_library;
.hidden _current_shared_library_p5_offset_
#endif
diff --git a/libc/sysdeps/linux/bfin/sys/ucontext.h b/libc/sysdeps/linux/bfin/sys/ucontext.h
index ac469daac..0e16788c5 100644
--- a/libc/sysdeps/linux/bfin/sys/ucontext.h
+++ b/libc/sysdeps/linux/bfin/sys/ucontext.h
@@ -36,100 +36,100 @@ typedef greg_t gregset_t[NGREG];
/* Number of each register is the `gregset_t' array. */
enum
{
- R0 = 0,
-#define R0 R0
- R1 = 1,
-#define R1 R1
- R2 = 2,
-#define R2 R2
- R3 = 3,
-#define R3 R3
- R4 = 4,
-#define R4 R4
- R5 = 5,
-#define R5 R5
- R6 = 6,
-#define R6 R6
- R7 = 7,
-#define R7 R7
- P0 = 8,
-#define P0 P0
- P1 = 9,
-#define P1 P1
- P2 = 10,
-#define P2 P2
- P3 = 11,
-#define P3 P3
- P4 = 12,
-#define P4 P4
- P5 = 13,
-#define P5 P5
- USP = 14,
-#define USP USP
- A0W = 15,
-#define A0W A0W
- A1W = 16,
-#define A1W A1W
- A0X = 17,
-#define A0X A0X
- A1X = 18,
-#define A1X A1X
- ASTAT = 19,
-#define ASTAT ASTAT
- RETS = 20,
-#define RETS RETS
- PC= 21,
-#define PC PC
- RETX = 22,
-#define RETX RETX
- FP = 23,
-#define FP FP
- I0 = 24,
-#define I0 I0
- I1 = 25,
-#define I1 I1
- I2 = 26,
-#define I2 I2
- I3 = 27,
-#define I3 I3
- M0 = 28,
-#define M0 M0
- M1 = 29,
-#define M1 M1
- M2 = 30,
-#define M2 M2
- M3 = 31,
-#define M3 M3
- L0 = 32,
-#define L0 L0
- L1 = 33,
-#define L1 L1
- L2 = 34,
-#define L2 L2
- L3 = 35,
-#define L3 L3
- B_0 = 36,
-#define B_0 B_0
- B1 = 37,
-#define B1 B1
- B2 = 38,
-#define B2 B2
- B3 = 39,
-#define B3 B3
- LC0 = 40,
-#define LC0 LC0
- LC1 = 41,
-#define LC1 LC1
- LT0 = 42,
-#define LT0 LT0
- LT1 = 43,
-#define LT1 LT1
- LB0 = 44,
-#define LB0 LB0
- LB1 = 45,
-#define LB1 LB1
- SEQSTAT = 46
-#define SEQSTAT SEQSTAT
+ REG_R0 = 0,
+#define REG_R0 REG_R0
+ REG_R1 = 1,
+#define REG_R1 REG_R1
+ REG_R2 = 2,
+#define REG_R2 REG_R2
+ REG_R3 = 3,
+#define REG_R3 REG_R3
+ REG_R4 = 4,
+#define REG_R4 REG_R4
+ REG_R5 = 5,
+#define REG_R5 REG_R5
+ REG_R6 = 6,
+#define REG_R6 REG_R6
+ REG_R7 = 7,
+#define REG_R7 REG_R7
+ REG_P0 = 8,
+#define REG_P0 REG_P0
+ REG_P1 = 9,
+#define REG_P1 REG_P1
+ REG_P2 = 10,
+#define REG_P2 REG_P2
+ REG_P3 = 11,
+#define REG_P3 REG_P3
+ REG_P4 = 12,
+#define REG_P4 REG_P4
+ REG_P5 = 13,
+#define REG_P5 REG_P5
+ REG_USP = 14,
+#define REG_USP REG_USP
+ REG_A0W = 15,
+#define REG_A0W REG_A0W
+ REG_A1W = 16,
+#define REG_A1W REG_A1W
+ REG_A0X = 17,
+#define REG_A0X REG_A0X
+ REG_A1X = 18,
+#define REG_A1X REG_A1X
+ REG_ASTAT = 19,
+#define REG_ASTAT REG_ASTAT
+ REG_RETS = 20,
+#define REG_RETS REG_RETS
+ REG_PC= 21,
+#define REG_PC REG_PC
+ REG_RETX = 22,
+#define REG_RETX REG_RETX
+ REG_FP = 23,
+#define REG_FP REG_FP
+ REG_I0 = 24,
+#define REG_I0 REG_I0
+ REG_I1 = 25,
+#define REG_I1 REG_I1
+ REG_I2 = 26,
+#define REG_I2 REG_I2
+ REG_I3 = 27,
+#define REG_I3 REG_I3
+ REG_M0 = 28,
+#define REG_M0 REG_M0
+ REG_M1 = 29,
+#define REG_M1 REG_M1
+ REG_M2 = 30,
+#define REG_M2 REG_M2
+ REG_M3 = 31,
+#define REG_M3 REG_M3
+ REG_L0 = 32,
+#define REG_L0 REG_L0
+ REG_L1 = 33,
+#define REG_L1 REG_L1
+ REG_L2 = 34,
+#define REG_L2 REG_L2
+ REG_L3 = 35,
+#define REG_L3 REG_L3
+ REG_B_0 = 36,
+#define REG_B_0 REG_B_0
+ REG_B1 = 37,
+#define REG_B1 REG_B1
+ REG_B2 = 38,
+#define REG_B2 REG_B2
+ REG_B3 = 39,
+#define REG_B3 REG_B3
+ REG_LC0 = 40,
+#define REG_LC0 REG_LC0
+ REG_LC1 = 41,
+#define REG_LC1 REG_LC1
+ REG_LT0 = 42,
+#define REG_LT0 REG_LT0
+ REG_LT1 = 43,
+#define REG_LT1 REG_LT1
+ REG_LB0 = 44,
+#define REG_LB0 REG_LB0
+ REG_LB1 = 45,
+#define REG_LB1 REG_LB1
+ REG_SEQSTAT = 46
+#define REG_SEQSTAT REG_SEQSTAT
};
/* Context to describe whole processor state. */
diff --git a/libc/sysdeps/linux/nios2/bits/mman.h b/libc/sysdeps/linux/nios2/bits/mman.h
index 7f644b99b..2fa35e663 100644
--- a/libc/sysdeps/linux/nios2/bits/mman.h
+++ b/libc/sysdeps/linux/nios2/bits/mman.h
@@ -59,6 +59,15 @@
# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */
#endif
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
+
/* Flags to `msync'. */
#define MS_ASYNC 1 /* Sync memory asynchronously. */
#define MS_SYNC 4 /* Synchronous memory sync. */
diff --git a/libc/sysdeps/linux/nios2/bits/syscalls.h b/libc/sysdeps/linux/nios2/bits/syscalls.h
index b21851333..ec5370712 100644
--- a/libc/sysdeps/linux/nios2/bits/syscalls.h
+++ b/libc/sysdeps/linux/nios2/bits/syscalls.h
@@ -4,12 +4,292 @@
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
-#include <features.h>
+#ifndef __ASSEMBLER__
-/* Do something very evil for now. Until we create our own syscall
- * macros, short circuit bits/sysnum.h and use asm/unistd.h instead */
-#warning "fixme -- add arch specific syscall macros.h"
-#include <asm/unistd.h>
+#include <errno.h>
+#include <asm/traps.h>
+#define __syscall_return(type, res) \
+do { \
+ if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+ \
+ /* avoid using res which is declared to be in \
+ register r2; errno might expand to a function \
+ call and clobber it. */ \
+ \
+ int __err = -(res); \
+ errno = __err; \
+ res = -1; \
+ } \
+ return (type) (res); \
+} while (0)
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,atype,a) \
+type name(atype a) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,atype,a,btype,b) \
+type name(atype a,btype b) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ " mov r5, %4\n\t" /* (long) b */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ , "r" ((long) b) /* %4 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ , "r5" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a,btype b,ctype c) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ " mov r5, %4\n\t" /* (long) b */ \
+ " mov r6, %5\n\t" /* (long) c */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ , "r" ((long) b) /* %4 */ \
+ , "r" ((long) c) /* %5 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ , "r5" /* Clobbered */ \
+ , "r6" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name (atype a, btype b, ctype c, dtype d) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ " mov r5, %4\n\t" /* (long) b */ \
+ " mov r6, %5\n\t" /* (long) c */ \
+ " mov r7, %6\n\t" /* (long) d */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ , "r" ((long) b) /* %4 */ \
+ , "r" ((long) c) /* %5 */ \
+ , "r" ((long) d) /* %6 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ , "r5" /* Clobbered */ \
+ , "r6" /* Clobbered */ \
+ , "r7" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name (atype a,btype b,ctype c,dtype d,etype e) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ " mov r5, %4\n\t" /* (long) b */ \
+ " mov r6, %5\n\t" /* (long) c */ \
+ " mov r7, %6\n\t" /* (long) c */ \
+ " mov r8, %7\n\t" /* (long) e */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ , "r" ((long) b) /* %4 */ \
+ , "r" ((long) c) /* %5 */ \
+ , "r" ((long) d) /* %6 */ \
+ , "r" ((long) e) /* %7 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ , "r5" /* Clobbered */ \
+ , "r6" /* Clobbered */ \
+ , "r7" /* Clobbered */ \
+ , "r8" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+{ \
+ long __res; \
+ \
+ __asm__ __volatile__ ( \
+ \
+ " \n\t" \
+ \
+ " movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
+ " movi r3, %1\n\t" /* __NR_##name */ \
+ " mov r4, %3\n\t" /* (long) a */ \
+ " mov r5, %4\n\t" /* (long) b */ \
+ " mov r6, %5\n\t" /* (long) c */ \
+ " mov r7, %6\n\t" /* (long) c */ \
+ " mov r8, %7\n\t" /* (long) e */ \
+ " mov r9, %8\n\t" /* (long) f */ \
+ \
+ " trap\n\t" \
+ " mov %0, r2\n\t" /* syscall rtn */ \
+ \
+ " \n\t" \
+ \
+ : "=r" (__res) /* %0 */ \
+ \
+ : "i" (__NR_##name) /* %1 */ \
+ , "i" (TRAP_ID_SYSCALL) /* %2 */ \
+ , "r" ((long) a) /* %3 */ \
+ , "r" ((long) b) /* %4 */ \
+ , "r" ((long) c) /* %5 */ \
+ , "r" ((long) d) /* %6 */ \
+ , "r" ((long) e) /* %7 */ \
+ , "r" ((long) f) /* %8 */ \
+ \
+ : "r2" /* Clobbered */ \
+ , "r3" /* Clobbered */ \
+ , "r4" /* Clobbered */ \
+ , "r5" /* Clobbered */ \
+ , "r6" /* Clobbered */ \
+ , "r7" /* Clobbered */ \
+ , "r8" /* Clobbered */ \
+ , "r9" /* Clobbered */ \
+ ); \
+ \
+__syscall_return(type,__res); \
+}
+
+#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/nios2/crt1.S b/libc/sysdeps/linux/nios2/crt1.S
index d5e1bd7c2..0ba8d59e6 100644
--- a/libc/sysdeps/linux/nios2/crt1.S
+++ b/libc/sysdeps/linux/nios2/crt1.S
@@ -16,9 +16,13 @@
#include <asm/unistd.h>
.global _start
- .type __start,@function
+ .type _start,@function
+ .type _init,%function
+ .type _fini,%function
+#ifndef __UCLIBC_CTOR_DTOR__
.weak _init
.weak _fini
+#endif
.type main,@function
.type __uClibc_main,@function
.type __h_errno_location, @function
diff --git a/libc/sysdeps/linux/nios2/crti.S b/libc/sysdeps/linux/nios2/crti.S
index 7867c21c0..26c55c970 100644
--- a/libc/sysdeps/linux/nios2/crti.S
+++ b/libc/sysdeps/linux/nios2/crti.S
@@ -1,31 +1,22 @@
- .file "initfini.c"
-#APP
-
+
.section .init
-#NO_APP
.balign 4
- .global __init
- .type __init, @function
-__init:
+ .global _init
+ .type _init, @function
+_init:
addi sp, sp, -8
stw ra, 0(sp)
stw fp, 4(sp)
-#APP
-
+
.balign 4
.section .fini
-#NO_APP
.balign 4
- .global __fini
- .type __fini, @function
-__fini:
+ .global _fini
+ .type _fini, @function
+_fini:
addi sp, sp, -8
stw ra, 0(sp)
stw fp, 4(sp)
-#APP
.balign 4
-
-
- .ident "GCC: (GNU) 3.3.2"
diff --git a/libc/sysdeps/linux/nios2/crtn.S b/libc/sysdeps/linux/nios2/crtn.S
index dfac2ab22..de00fd132 100644
--- a/libc/sysdeps/linux/nios2/crtn.S
+++ b/libc/sysdeps/linux/nios2/crtn.S
@@ -1,30 +1,14 @@
- .file "initfini.c"
-#APP
-
+
.section .init
-#NO_APP
- .balign 4
- .globl _init
- .type _init, @function
-#NO_APP
+
ldw ra, 0(sp)
ldw fp, 4(sp)
addi sp, sp, 8
ret
- .size _init, .-_init
-#APP
-
+
.section .fini
-#NO_APP
- .balign 4
- .globl _fini
- .type _fini, @function
-#NO_APP
+
ldw ra, 0(sp)
ldw fp, 4(sp)
addi sp, sp, 8
ret
- .size _fini, .-_fini
-#APP
-
- .ident "GCC: (GNU) 3.3.2"
diff --git a/libc/sysdeps/linux/nios2/vfork.S b/libc/sysdeps/linux/nios2/vfork.S
index ca8811a4f..5d275ffdd 100644
--- a/libc/sysdeps/linux/nios2/vfork.S
+++ b/libc/sysdeps/linux/nios2/vfork.S
@@ -14,7 +14,7 @@
#define _ERRNO_H
#include <bits/errno.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
#ifndef __NR_vfork
#define __NR_vfork __NR_fork /* uClinux-2.0 only has fork which is vfork */
diff --git a/libc/sysdeps/linux/powerpc/brk.S b/libc/sysdeps/linux/powerpc/brk.S
index 25155ad46..5fe8d4086 100644
--- a/libc/sysdeps/linux/powerpc/brk.S
+++ b/libc/sysdeps/linux/powerpc/brk.S
@@ -50,8 +50,15 @@ brk:
lwz r6,8(r1)
#ifdef __PIC__
mflr r4
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
bl _GLOBAL_OFFSET_TABLE_@local-4
mflr r5
+# endif
lwz r5,__curbrk@got(r5)
mtlr r4
stw r3,0(r5)
diff --git a/libc/sysdeps/linux/powerpc/bsd-_setjmp.S b/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
index d58e45b13..585878acf 100644
--- a/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
@@ -29,9 +29,7 @@
_setjmp:
li r4,0 /* Set second argument to 0. */
-#ifdef __PIC__
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+
+ b __sigsetjmp@local
+
.size _setjmp,.-_setjmp
diff --git a/libc/sysdeps/linux/powerpc/bsd-setjmp.S b/libc/sysdeps/linux/powerpc/bsd-setjmp.S
index 6128d9fa2..f95d08217 100644
--- a/libc/sysdeps/linux/powerpc/bsd-setjmp.S
+++ b/libc/sysdeps/linux/powerpc/bsd-setjmp.S
@@ -29,11 +29,9 @@
__setjmp:
li r4,1 /* Set second argument to 1. */
-#ifdef __PIC__
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+
+ b __sigsetjmp@local
+
.size __setjmp,.-__setjmp
.globl setjmp;
diff --git a/libc/sysdeps/linux/powerpc/crt1.S b/libc/sysdeps/linux/powerpc/crt1.S
index 47419bb52..7928a7ed3 100644
--- a/libc/sysdeps/linux/powerpc/crt1.S
+++ b/libc/sysdeps/linux/powerpc/crt1.S
@@ -48,8 +48,15 @@ _start:
mr r9,r1 /* Save the stack pointer and pass it to __uClibc_main */
clrrwi r1,r1,4 /* Align stack ptr to 16 bytes */
#ifdef __PIC__
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r31
+ addis r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
bl _GLOBAL_OFFSET_TABLE_-4@local
mflr r31
+# endif
#endif
/* Set up an initial stack frame, and clear the LR. */
li r0,0
diff --git a/libc/sysdeps/linux/powerpc/setjmp.S b/libc/sysdeps/linux/powerpc/setjmp.S
index b1625b615..3bdf6cbfe 100644
--- a/libc/sysdeps/linux/powerpc/setjmp.S
+++ b/libc/sysdeps/linux/powerpc/setjmp.S
@@ -76,9 +76,7 @@ FP( stfd fp29,((JB_FPRS+15*2)*4)(3))
FP( stfd fp30,((JB_FPRS+16*2)*4)(3))
stw r31,((JB_GPRS+17)*4)(3)
FP( stfd fp31,((JB_FPRS+17*2)*4)(3))
-#ifdef __PIC__
- b __sigjmp_save@plt
-#else
- b __sigjmp_save
-#endif
+
+ b __sigjmp_save@local
+
.size __sigsetjmp,.-__sigsetjmp