diff options
author | Peng Fan <van.freenix@gmail.com> | 2013-07-18 11:38:12 +0800 |
---|---|---|
committer | Peng Fan <van.freenix@gmail.com> | 2013-07-22 10:51:46 +0800 |
commit | 20cac2e624ce8f2bc55af38b2b030c92a4aac6d1 (patch) | |
tree | 4454a1aa4c5e6508a3020cd83a06063d0f1cf572 | |
parent | 19b3b6033adfe740038a5cd483f05b7c9273a148 (diff) |
powerpc support
Signed-off-by: Peng Fan <van.freenix@gmail.com>
-rw-r--r-- | libbsd/include/arch/powerpc/machine/ansi.h | 67 | ||||
-rw-r--r-- | libbsd/include/arch/powerpc/machine/asm.h | 397 | ||||
-rw-r--r-- | libbsd/include/arch/powerpc/machine/cdefs.h | 8 | ||||
-rw-r--r-- | libbsd/include/arch/powerpc/machine/elf_machdep.h | 105 | ||||
-rw-r--r-- | libbsd/include/arch/powerpc/machine/int_types.h | 79 | ||||
-rw-r--r-- | rtl-mdreloc-powerpc.c | 205 | ||||
-rw-r--r-- | testcase/1.c | 38 | ||||
-rw-r--r-- | testcase/Readme | 8 | ||||
-rw-r--r-- | testcase/wscript | 11 | ||||
-rw-r--r-- | wscript | 2 |
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}') @@ -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, |