summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Fan <van.freenix@gmail.com>2013-07-18 11:38:12 +0800
committerPeng Fan <van.freenix@gmail.com>2013-07-22 10:51:46 +0800
commit20cac2e624ce8f2bc55af38b2b030c92a4aac6d1 (patch)
tree4454a1aa4c5e6508a3020cd83a06063d0f1cf572
parent19b3b6033adfe740038a5cd483f05b7c9273a148 (diff)
powerpc support
Signed-off-by: Peng Fan <van.freenix@gmail.com>
-rw-r--r--libbsd/include/arch/powerpc/machine/ansi.h67
-rw-r--r--libbsd/include/arch/powerpc/machine/asm.h397
-rw-r--r--libbsd/include/arch/powerpc/machine/cdefs.h8
-rw-r--r--libbsd/include/arch/powerpc/machine/elf_machdep.h105
-rw-r--r--libbsd/include/arch/powerpc/machine/int_types.h79
-rw-r--r--rtl-mdreloc-powerpc.c205
-rw-r--r--testcase/1.c38
-rw-r--r--testcase/Readme8
-rw-r--r--testcase/wscript11
-rw-r--r--wscript2
10 files changed, 833 insertions, 87 deletions
diff --git a/libbsd/include/arch/powerpc/machine/ansi.h b/libbsd/include/arch/powerpc/machine/ansi.h
new file mode 100644
index 0000000..5f792b1
--- /dev/null
+++ b/libbsd/include/arch/powerpc/machine/ansi.h
@@ -0,0 +1,67 @@
+/* $NetBSD: ansi.h,v 1.29 2011/07/17 20:54:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+#include <sys/cdefs.h>
+#include <machine/int_types.h>
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#ifdef _LP64
+#define _BSD_PTRDIFF_T_ long /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ unsigned long /* sizeof() */
+#define _BSD_SSIZE_T_ long /* byte count or error */
+#else
+#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ unsigned int /* sizeof() */
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#endif
+#define _BSD_TIME_T_ __int64_t /* time() */
+#define _BSD_CLOCKID_T_ int /* clockid_t */
+#define _BSD_TIMER_T_ int /* timer_t */
+#define _BSD_SUSECONDS_T_ int /* suseconds_t */
+#define _BSD_USECONDS_T_ unsigned int /* useconds_t */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+
+#endif /* _ANSI_H_ */
diff --git a/libbsd/include/arch/powerpc/machine/asm.h b/libbsd/include/arch/powerpc/machine/asm.h
new file mode 100644
index 0000000..66379cd
--- /dev/null
+++ b/libbsd/include/arch/powerpc/machine/asm.h
@@ -0,0 +1,397 @@
+/* $NetBSD: asm.h,v 1.39 2011/10/26 01:46:11 christos Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PPC_ASM_H_
+#define _PPC_ASM_H_
+
+#ifdef _LP64
+
+/* ppc64 is always PIC, r2 is always the TOC */
+
+# define PIC_PLT(x) .x
+
+#else
+
+# ifdef PIC
+# define PIC_PROLOGUE XXX
+# define PIC_EPILOGUE XXX
+# define PIC_PLT(x) x+32768@plt
+# ifdef __STDC__
+# define PIC_TOCNAME(name) .LCTOC_##name
+# else
+# define PIC_TOCNAME(name) .LCTOC_/**/name
+# endif /* __STDC __*/
+# define PIC_TOCSETUP(name, reg) \
+ .pushsection ".got2","aw" ;\
+ PIC_TOCNAME(name) = . + 32768 ;\
+ .popsection ;\
+ bcl 20,31,1001f ;\
+ 1001: mflr reg ;\
+ addis reg,reg,PIC_TOCNAME(name)-1001b@ha ;\
+ addi reg,reg,PIC_TOCNAME(name)-1001b@l
+# define PIC_GOTSETUP(reg) \
+ bcl 20,31,2002f ;\
+ 2002: mflr reg ;\
+ addis reg,reg,_GLOBAL_OFFSET_TABLE_-2002b@ha ;\
+ addi reg,reg,_GLOBAL_OFFSET_TABLE_-2002b@l
+# ifdef __STDC__
+# define PIC_GOT(x) XXX
+# define PIC_GOTOFF(x) XXX
+# else /* not __STDC__ */
+# define PIC_GOT(x) XXX
+# define PIC_GOTOFF(x) XXX
+# endif /* __STDC__ */
+# else /* !PIC */
+# define PIC_PROLOGUE
+# define PIC_EPILOGUE
+# define PIC_PLT(x) x
+# define PIC_GOT(x) x
+# define PIC_GOTOFF(x) x
+# define PIC_GOTSETUP(r)
+# define PIC_TOCSETUP(n, r)
+# endif /* PIC */
+
+#endif /* __LP64__ */
+
+#define _C_LABEL(x) x
+#define _ASM_LABEL(x) x
+
+#define _GLOBAL(x) \
+ .data; .align 2; .globl x; x:
+
+#ifdef GPROF
+# define _PROF_PROLOGUE mflr 0; stw 0,4(1); bl _mcount
+#else
+# define _PROF_PROLOGUE
+#endif
+
+#ifdef _LP64
+
+# define SF_HEADER_SZ 48
+# define SF_PARAM_SZ 64
+# define SF_SZ (SF_HEADER_SZ + SF_PARAM_SZ)
+
+# define SF_SP 0
+# define SF_CR 8
+# define SF_LR 16
+# define SF_PARAM SF_HEADER_SZ
+
+# define ENTRY(y) \
+ .globl y; \
+ .section ".opd","aw"; \
+ .align 3; \
+y: .quad .y,.TOC.@tocbase,0; \
+ .previous; \
+ .size y,24; \
+ .type .y,@function; \
+ .globl .y; \
+ .align 3; \
+.y:
+
+# define END(y)
+
+# define CALL(y) \
+ bl .y; \
+ nop
+
+# define ENTRY_NOPROFILE(y) ENTRY(y)
+# define ASENTRY(y) ENTRY(y)
+#else /* !_LP64 */
+
+# define _ENTRY(x) \
+ .text; .align 2; .globl x; .type x,@function; x:
+
+# define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+
+# define END(y) .size _C_LABEL(y),.-_C_LABEL(y)
+
+# define CALL(y) \
+ bl y
+
+# define ENTRY_NOPROFILE(y) _ENTRY(_C_LABEL(y))
+# define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#endif /* __LP64__ */
+
+#define GLOBAL(y) _GLOBAL(_C_LABEL(y))
+
+#define ASMSTR .asciz
+
+#undef __RCSID
+#define RCSID(x) __RCSID(x)
+#define __RCSID(x) .pushsection .ident; .asciz x; .popsection
+
+#ifdef __ELF__
+# define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif /* __ELF__ */
+/*
+ * STRONG_ALIAS: create a strong alias.
+ */
+#define STRONG_ALIAS(alias,sym) \
+ .globl alias; \
+ alias = sym
+
+#ifdef __STDC__
+# define WARN_REFERENCES(sym,msg) \
+ .pushsection .gnu.warning. ## sym; \
+ .ascii msg; \
+ .popsection
+#else
+# define WARN_REFERENCES(sym,msg) \
+ .pushsection .gnu.warning./**/sym; \
+ .ascii msg; \
+ .popsection
+#endif /* __STDC__ */
+
+#ifdef _KERNEL
+/*
+ * Get cpu_info pointer for current processor. Always in SPRG0. *ALWAYS*
+ */
+# define GET_CPUINFO(r) mfsprg r,0
+/*
+ * IN:
+ * R4[er] = first free byte beyond end/esym.
+ *
+ * OUT:
+ * R1[sp] = new kernel stack
+ * R4[er] = kernelend
+ */
+
+# ifdef CI_INTSTK
+# define INIT_CPUINFO_INTSTK(er,tmp1) \
+ addi er,er,INTSTK; \
+ stptr er,CI_INTSTK(tmp1)
+# else
+# define INIT_CPUINFO_INTSTK(er,tmp1) /* nothing */
+# endif /* CI_INTSTK */
+
+/*
+ * We use lis/ori instead of lis/addi in case tmp2 is r0.
+ */
+# define INIT_CPUINFO(er,sp,tmp1,tmp2) \
+ li tmp1,PAGE_MASK; \
+ add er,er,tmp1; \
+ andc er,er,tmp1; /* page align */ \
+ lis tmp1,_C_LABEL(cpu_info)@ha; \
+ addi tmp1,tmp1,_C_LABEL(cpu_info)@l; \
+ mtsprg0 tmp1; /* save for later use */ \
+ INIT_CPUINFO_INTSTK(er,tmp1); \
+ lis tmp2,_C_LABEL(emptyidlespin)@h; \
+ ori tmp2,tmp2,_C_LABEL(emptyidlespin)@l; \
+ stptr tmp2,CI_IDLESPIN(tmp1); \
+ li tmp2,-1; \
+ stint tmp2,CI_IDEPTH(tmp1); \
+ li tmp2,0; \
+ lis %r13,_C_LABEL(lwp0)@h; \
+ ori %r13,%r13,_C_LABEL(lwp0)@l; \
+ stptr er,L_PCB(%r13); /* XXXuvm_lwp_getuarea */ \
+ stptr tmp1,L_CPU(%r13); \
+ addi er,er,USPACE; /* stackpointer for lwp0 */ \
+ addi sp,er,-FRAMELEN-CALLFRAMELEN; /* stackpointer for lwp0 */ \
+ stptr sp,L_MD_UTF(%r13); /* save in lwp0.l_md.md_utf */ \
+ /* er = end of mem reserved for kernel */ \
+ li tmp2,0; \
+ stptr tmp2,-CALLFRAMELEN(er); /* end of stack chain */ \
+ stptru tmp2,-CALLFRAMELEN(sp) /* end of stack chain */
+
+#endif /* _KERNEL */
+
+
+#if defined(_REGNAMES) && (defined(_KERNEL) || defined(_STANDALONE))
+ /* Condition Register Bit Fields */
+# define cr0 0
+# define cr1 1
+# define cr2 2
+# define cr3 3
+# define cr4 4
+# define cr5 5
+# define cr6 6
+# define cr7 7
+ /* General Purpose Registers (GPRs) */
+# define r0 0
+# define r1 1
+# define r2 2
+# define r3 3
+# define r4 4
+# define r5 5
+# define r6 6
+# define r7 7
+# define r8 8
+# define r9 9
+# define r10 10
+# define r11 11
+# define r12 12
+# define r13 13
+# define r14 14
+# define r15 15
+# define r16 16
+# define r17 17
+# define r18 18
+# define r19 19
+# define r20 20
+# define r21 21
+# define r22 22
+# define r23 23
+# define r24 24
+# define r25 25
+# define r26 26
+# define r27 27
+# define r28 28
+# define r29 29
+# define r30 30
+# define r31 31
+ /* Floating Point Registers (FPRs) */
+# define fr0 0
+# define fr1 1
+# define fr2 2
+# define fr3 3
+# define fr4 4
+# define fr5 5
+# define fr6 6
+# define fr7 7
+# define fr8 8
+# define fr9 9
+# define fr10 10
+# define fr11 11
+# define fr12 12
+# define fr13 13
+# define fr14 14
+# define fr15 15
+# define fr16 16
+# define fr17 17
+# define fr18 18
+# define fr19 19
+# define fr20 20
+# define fr21 21
+# define fr22 22
+# define fr23 23
+# define fr24 24
+# define fr25 25
+# define fr26 26
+# define fr27 27
+# define fr28 28
+# define fr29 29
+# define fr30 30
+# define fr31 31
+#endif /* _REGNAMES && (_KERNEL || _STANDALONE) */
+
+/*
+ * Add some psuedo instructions to made sharing of assembly versions of
+ * ILP32 and LP64 code possible.
+ */
+#define ldint lwz /* not needed but for completeness */
+#define ldintu lwzu /* not needed but for completeness */
+#define stint stw /* not needed but for completeness */
+#define stintu stwu /* not needed but for completeness */
+
+#ifndef _LP64
+
+# define ldlong lwz /* load "C" long */
+# define ldlongu lwzu /* load "C" long with udpate */
+# define stlong stw /* load "C" long */
+# define stlongu stwu /* load "C" long with udpate */
+# define ldptr lwz /* load "C" pointer */
+# define ldptru lwzu /* load "C" pointer with udpate */
+# define stptr stw /* load "C" pointer */
+# define stptru stwu /* load "C" pointer with udpate */
+# define ldreg lwz /* load PPC general register */
+# define ldregu lwzu /* load PPC general register with udpate */
+# define streg stw /* load PPC general register */
+# define stregu stwu /* load PPC general register with udpate */
+# define SZREG 4 /* 4 byte registers */
+
+# define lptrarx lwarx /* load "C" pointer with reservation */
+# define llongarx lwarx /* load "C" long with reservation */
+# define lregarx lwarx /* load PPC general register with reservation */
+
+# define stptrcx stwcx /* store "C" pointer conditional */
+# define stlongcx stwcx /* store "C" long conditional */
+# define stregcx stwcx /* store PPC general register conditional */
+
+# define clrrptri clrrwi /* clear right "C" pointer immediate */
+# define clrrlongi clrrwi /* clear right "C" long immediate */
+# define clrrregi clrrwi /* clear right PPC general register immediate */
+
+#else /* __LP64__ */
+
+# define ldlong ld /* load "C" long */
+# define ldlongu ldu /* load "C" long with update */
+# define stlong std /* store "C" long */
+# define stlongu stdu /* store "C" long with update */
+# define ldptr ld /* load "C" pointer */
+# define ldptru ldu /* load "C" pointer with update */
+# define stptr std /* store "C" pointer */
+# define stptru stdu /* store "C" pointer with update */
+# define ldreg ld /* load PPC general register */
+# define ldregu ldu /* load PPC general register with update */
+# define streg std /* store PPC general register */
+# define stregu stdu /* store PPC general register with update */
+/* redefined this to force an error on PPC64 to catch their use. */
+# define lmw lmd /* load multiple PPC general registers */
+# define stmw stmd /* store multiple PPC general registers */
+# define SZREG 8 /* 8 byte registers */
+
+# define lptrarx ldarx /* load "C" pointer with reservation */
+# define llongarx ldarx /* load "C" long with reservation */
+# define lregarx ldarx /* load PPC general register with reservation */
+
+# define stptrcx stdcx /* store "C" pointer conditional */
+# define stlongcx stdcx /* store "C" long conditional */
+# define stregax stdcx /* store PPC general register conditional */
+
+# define clrrptri clrrdi /* clear right "C" pointer immediate */
+# define clrrlongi clrrdi /* clear right "C" long immediate */
+# define clrrregi clrrdi /* clear right PPC general register immediate */
+
+#endif /* __LP64__ */
+
+#ifdef _LOCORE
+.macro stmd r,dst
+ i = 0
+ .rept 32-\r
+ std i+\r, i*8+\dst
+ i = i + 1
+ .endr
+.endm
+
+.macro lmd r,dst
+ i = 0
+ .rept 32-\r
+ ld i+\r, i*8+\dst
+ i = i + 1
+ .endr
+.endm
+#endif /* _LOCORE */
+
+#endif /* !_PPC_ASM_H_ */
diff --git a/libbsd/include/arch/powerpc/machine/cdefs.h b/libbsd/include/arch/powerpc/machine/cdefs.h
new file mode 100644
index 0000000..33c9489
--- /dev/null
+++ b/libbsd/include/arch/powerpc/machine/cdefs.h
@@ -0,0 +1,8 @@
+/* $NetBSD: cdefs.h,v 1.7 2012/01/20 14:08:06 joerg Exp $ */
+
+#ifndef _POWERPC_CDEFS_H_
+#define _POWERPC_CDEFS_H_
+
+#define __ALIGNBYTES (sizeof(double) - 1)
+
+#endif /* !_POWERPC_CDEFS_H_ */
diff --git a/libbsd/include/arch/powerpc/machine/elf_machdep.h b/libbsd/include/arch/powerpc/machine/elf_machdep.h
new file mode 100644
index 0000000..f0fdb3f
--- /dev/null
+++ b/libbsd/include/arch/powerpc/machine/elf_machdep.h
@@ -0,0 +1,105 @@
+/* $NetBSD: elf_machdep.h,v 1.9 2011/01/15 10:00:07 matt Exp $ */
+
+#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
+#define ELF32_MACHDEP_ID_CASES \
+ case EM_PPC: \
+ break;
+
+#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
+#define ELF64_MACHDEP_ID_CASES \
+ case EM_PPC64: \
+ break;
+
+#define ELF32_MACHDEP_ID EM_PPC
+#define ELF64_MACHDEP_ID EM_PPC64
+
+#ifdef _LP64
+#define ARCH_ELFSIZE 64 /* MD native binary size */
+#else
+#define ARCH_ELFSIZE 32 /* MD native binary size */
+#endif
+
+/* Specify the value of _GLOBAL_OFFSET_TABLE_ */
+#define DT_PPC_GOT DT_LOPROC
+
+#define R_PPC_NONE 0
+#define R_PPC_32 1
+#define R_PPC_24 2
+#define R_PPC_16 3
+#define R_PPC_16_LO 4
+#define R_PPC_16_HI 5 /* R_PPC_ADDIS */
+#define R_PPC_16_HA 6
+#define R_PPC_14 7
+#define R_PPC_14_TAKEN 8
+#define R_PPC_14_NTAKEN 9
+#define R_PPC_REL24 10 /* R_PPC_BRANCH */
+#define R_PPC_REL14 11
+#define R_PPC_REL14_TAKEN 12
+#define R_PPC_REL14_NTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLT24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_U32 24
+#define R_PPC_U16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+#define R_PPC_ADDR30 37
+
+/* TLS relocations */
+#define R_PPC_TLS 67
+
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+#define R_PPC_GOT_DTPREL16 91
+#define R_PPC_GOT_DTPREL16_LO 92
+#define R_PPC_GOT_DTPREL16_HI 93
+#define R_PPC_GOT_DTPREL16_HA 94
+#define R_PPC_TLSGD 95
+#define R_PPC_TLSLD 96
+
+/* Used for the secure-plt PIC code sequences */
+#define R_PPC_REL16 249
+#define R_PPC_REL16_LO 250
+#define R_PPC_REL16_HI 251
+#define R_PPC_REL16_HA 252
+
+#define R_TYPE(name) __CONCAT(R_PPC_,name)
diff --git a/libbsd/include/arch/powerpc/machine/int_types.h b/libbsd/include/arch/powerpc/machine/int_types.h
new file mode 100644
index 0000000..69de236
--- /dev/null
+++ b/libbsd/include/arch/powerpc/machine/int_types.h
@@ -0,0 +1,79 @@
+/* $NetBSD: int_types.h,v 1.10 2005/12/24 20:07:28 perry Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)types.h 8.3 (Berkeley) 1/5/94
+ */
+
+#ifndef _POWERPC_INT_TYPES_H_
+#define _POWERPC_INT_TYPES_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * 7.18.1 Integer types
+ */
+
+/* 7.18.1.1 Exact-width integer types */
+
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef short int __int16_t;
+typedef unsigned short int __uint16_t;
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#ifdef __COMPILER_INT64__
+typedef __COMPILER_INT64__ __int64_t;
+typedef __COMPILER_UINT64__ __uint64_t;
+#elif defined(_LP64)
+typedef long int __int64_t;
+typedef unsigned long int __uint64_t;
+#else
+/* LONGLONG */
+typedef long long int __int64_t;
+/* LONGLONG */
+typedef unsigned long long int __uint64_t;
+#endif
+
+#define __BIT_TYPES_DEFINED__
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+
+#ifdef _LP64
+typedef long int __intptr_t;
+typedef unsigned long int __uintptr_t;
+#else
+typedef int __intptr_t;
+typedef unsigned int __uintptr_t;
+#endif
+
+#endif /* !_POWERPC_INT_TYPES_H_ */
diff --git a/rtl-mdreloc-powerpc.c b/rtl-mdreloc-powerpc.c
index 719570e..4f009c9 100644
--- a/rtl-mdreloc-powerpc.c
+++ b/rtl-mdreloc-powerpc.c
@@ -4,34 +4,6 @@
/* $NetBSD: ppc_reloc.c,v 1.44 2010/01/13 20:17:22 christos Exp $ */
-/*-
- * Copyright (C) 1998 Tsubai Masanari
- * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
#include <sys/cdefs.h>
#include <errno.h>
@@ -48,105 +20,166 @@
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
#define l(x) ((u_int32_t)(x) & 0xffff)
-/*
- * The PPC PLT format consists of three sections:
- * (1) The "pltcall" and "pltresolve" glue code. This is always 18 words.
- * (2) The code part of the PLT entries. There are 2 words per entry for
- * up to 8192 entries, then 4 words per entry for any additional entries.
- * (3) The data part of the PLT entries, comprising a jump table.
- * This section is half the size of the second section (ie. 1 or 2 words
- * per entry).
- */
-/*
- * Setup the plt glue routines.
- */
-#define PLTCALL_SIZE 20
-#define PLTRESOLVE_SIZE 24
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
+{
+ return true;
+}
bool
-rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj,
- const Elf_Rela* rela,
- rtems_rtl_obj_sect_t* sect,
- const Elf_Sym* sym,
- const char* symname)
+rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect_t* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
{
Elf_Addr target = 0;
Elf_Addr* where;
- Elf_Word symvalue;
+ Elf_Word tmp;
+ uint32_t mask = 0;
+ uint32_t bits = 0;
where = (Elf_Addr *)(sect->base + rela->r_offset);
-
switch (ELF_R_TYPE(rela->r_info)) {
- case R_TYPE(JMP_SLOT):
case R_TYPE(NONE):
break;
- case R_TYPE(PC32):
- if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
- return false;
-
- target = (Elf_Addr) symvalue + rela->r_addend;
- *where += target - (Elf_Addr)where;
-
+ case R_TYPE(32):
+ /*
+ * value:1; Field: word32; Expression: S + A
+ */
+ *where = symvalue + rela->r_addend;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: reloc PC32 %s in %s --> %p (%p) in %s\n",
- symname, sect->name, (void*) (symvalue + rela->r_addend),
- (void *)*where, obj->oname);
+ printf ("rtl: ADDR32 %p @ %p in %s\n",
+ (void *)*(where), where, rtems_rtl_obj_oname (obj));
break;
- case R_TYPE(32): /* word32 S + A */
- case R_TYPE(GLOB_DAT): /* word32 S + A */
- if (!rtems_rtl_elf_find_symbol (obj, sym, symname, &symvalue))
+ case R_TYPE(14):
+ /*
+ * value:7; Field: low14*; Expression: (S + A) >> 2
+ */
+ case R_TYPE(24):
+ /*
+ * value:2; Field: low24*; Expression: (S + A) >> 2
+ */
+ if (ELF_R_TYPE(rela->r_info) == R_TYPE(14)) {
+ bits = 14;
+ mask = 0xfffc;
+ } else {
+ bits = 24;
+ mask = 0x3fffffc;
+ }
+ tmp = (symvalue + rela->r_addend) >> 2;
+ if (tmp > (1<<bits -1 )) {
+ printf("Overflow ADDR14/ADDR24\n");
return false;
+ }
+ tmp = *where;
+ tmp &= ~mask;
+ tmp |= (symvalue + rela->r_addend) & mask;
+ *where = tmp;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: ADDR14/ADDR24 %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ break;
- target = (Elf_Addr) symvalue + rela->r_addend;
+ case R_TYPE(16_HA):
+ /*
+ * value:6; Field:half16; Expression: #ha(S+A)
+ */
- if (*where != target)
- *where = target;
+ tmp = symvalue + rela->r_addend;
+ *(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & 0xffff);
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: 16_HA %p @ %p in %s\n",
+ (void *)*(where), where, rtems_rtl_obj_oname (obj));
+ break;
+ case R_TYPE(16_HI):
+ /*
+ * value:5; Field:half16; Expression: #hi(S+A)
+ */
+ *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: 16_HI %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ break;
+ case R_TYPE(16_LO):
+ /*
+ * value:4; Field:half16; Expression: #lo(S+A)
+ */
+ *(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: reloc 32/GLOB_DAT %s in %s --> %p in %s\n",
- symname, sect->name, (void *)*where, obj->oname);
+ printf ("rtl: 16_LO %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
break;
- case R_TYPE(RELATIVE): /* word32 B + A */
- *where += (Elf_Addr) sect->base + rela->r_addend;
+ case R_TYPE(REL14):
+ /*
+ * value:11; Field:low14*; Expression:(S+A-P)>>2
+ */
+ case R_TYPE(REL24):
+ /*
+ * value:10; Field:low24*; Expression:(S+A-P)>>2
+ */
+ if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL24)) {
+ mask = 0x3fffffc;
+ bits = 24;
+ }
+ else if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL14)) {
+ mask = 0xfffc;
+ bits = 14;
+ }
+
+ tmp =((int) (symvalue + rela->r_addend - (Elf_Addr)where)) >> 2;
+ if (((Elf_Sword)tmp > ((1<<(bits-1)) - 1)) ||
+ ((Elf_Sword)tmp < -(1<<(bits-1)))) {
+ printf("Overflow REL14/REL24\n");
+ return false;
+ }
+
+ tmp = *where;
+ tmp &= ~mask;
+ tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
+ *where = tmp;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: reloc RELATIVE in %s --> %p\n", obj->oname, (void *)*where);
+ printf ("rtl: REL24/REL14 %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
break;
- case R_TYPE(COPY):
+ case R_TYPE(REL32):
/*
- * These are deferred until all other relocations have
- * been done. All we do here is make sure that the
- * COPY relocation is not in a shared library. They
- * are allowed only in executable files.
+ * value:26; Field:word32*; Expression:S+A-P
*/
- printf ("rtl: reloc COPY (please report)\n");
+ *where = symvalue + rela->r_addend - (Elf_Addr)where;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: REL32 %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
break;
default:
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
- "contents = %p, symbol = %s\n",
+ "contents = %p\n",
ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
- (void *)rela->r_offset, (void *)*where, symname);
+ (void *)rela->r_offset, (void *)*where);
rtems_rtl_set_error (EINVAL,
"%s: Unsupported relocation type %ld "
"in non-PLT relocations",
sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
return false;
}
-
- return false;
+ return true;
}
bool
-rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj,
- const Elf_Rel* rel,
- rtems_rtl_obj_sect_t* sect,
- const Elf_Sym* sym,
- const char* symname)
+rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect_t* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
{
printf ("rtl: rel type record not supported; please report\n");
return false;
diff --git a/testcase/1.c b/testcase/1.c
index e8a1241..98d4453 100644
--- a/testcase/1.c
+++ b/testcase/1.c
@@ -10,7 +10,19 @@ void hello(int arg)
case 2:
printf("Inter-module call hello()\n");
break;
+#if defined PPC
+ case 24:
+ printf("PPC ADDR24 'bla hello' call\n");
+ break;
+ case 14:
+ printf("PPC REL14 'beq cr7, hello' jump\n");
+ break;
+ case 15:
+ printf("PPC ADDR14 'beqa cr7, hello' jump\n");
+ break;
+#endif
default:
+ printf("no arg in hello\n");
return;
}
}
@@ -99,6 +111,32 @@ int rtems(int argc, char **argv)
);
#endif
+#elif defined PPC
+ __asm__ volatile (
+ "stwu 3, -8(1)\r\n"
+ "li 3, 24\r\n"
+ "bla hello\r\n" /*ADDR24*/
+ "nop\r\n"
+ "nop\r\n"
+ "lwz 3, 8(1)\r\n"
+ "addi 1, 1, 8\r\n"
+ );
+
+ __asm__ volatile (
+ "stwu 3, -4(1)\r\n"
+ "li 3, 14\r\n"
+ "cmpwi cr7, 3, 14\r\n"
+ "bl 1f\r\n"
+ "1: mflr 6\r\n"
+ "addi 6, 6, 20\r\n"
+ "mtlr 6\r\n"
+ "beq cr7, hello\r\n" /*REL14*/
+ "nop\r\n"
+ "nop\r\n"
+ "nop\r\n"
+ "lwz 3, 4(1)\r\n"
+ "addi 1, 1, 4\r\n"
+ );
#else
/* other archs */
#endif
diff --git a/testcase/Readme b/testcase/Readme
index 1312f60..81a7559 100644
--- a/testcase/Readme
+++ b/testcase/Readme
@@ -9,3 +9,11 @@ arm:
waf configure --rtems=/opt/rtems-4.11 --rtems-tools=/opt/rtems-4.11 --rtems-archs=arm --rtems-bsps=arm/realview_pbx_a9_qemu
In the wscript, you can use different cflags to test.
+
+powerpc:
+ Simulator:
+ psim -i build/powerpc-rtems4.11-psim/rtld
+
+ Configuration:
+ waf configure --rtems=/opt/rtems-4.11 --rtems-tools=/opt/rtems-4.11 --rtems-archs=powerpc --rtems-bsps=powerpc/psim
+ "-fno-common" are add to cflags to avoid common section problem.
diff --git a/testcase/wscript b/testcase/wscript
index a518cb6..0eacc2f 100644
--- a/testcase/wscript
+++ b/testcase/wscript
@@ -27,6 +27,17 @@ def build(bld):
'--entry', 'my_main'],
source = ['1.c', '2.c'])
+ elif arch == 'powerpc':
+ bld(target = 'test.rap',
+ features = 'c rap',
+ xxxx = 'hello',
+
+ cflags = '-fno-common -DPPC_TEST',
+
+ rtems_linkflags = ['--base', 'rtld.prelink',
+ '--entry', 'my_main'],
+ source = ['1.c', '2.c'])
+
bld(target = '../test.rap',
source = ['test.rap'],
rule = 'cp ${SRC} ${TGT}')
diff --git a/wscript b/wscript
index 3d3a1b4..41a4bbd 100644
--- a/wscript
+++ b/wscript
@@ -60,7 +60,7 @@ def build(bld):
#
# The ARM as special BSP initialise code.
#
- if arch == 'arm':
+ if arch == 'arm' or arch == 'powerpc':
bld(target = 'bspinit',
features = 'c',
includes = bld.includes,