diff options
author | Guo Ren <ren_guo@c-sky.com> | 2017-10-15 20:59:34 +0800 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2017-11-19 09:20:11 +0100 |
commit | 2fcffe26e815b7125a357c83b59617ab93c16b41 (patch) | |
tree | fe5a973dc4bbf38bce8468a4497f5f656f082a9f | |
parent | 9e38e0aa45cca21d5023d0af94377f0e1e41d2f4 (diff) |
csky: port to uclibc-ng
Follow the steps to build c-sky uclibc linux system:
1. git clone https://github.com/c-sky/buildroot.git
2. cd buildroot
3. make qemu_csky_ck810_uclibc_defconfig
4. make
Follow the buildroot/board/qemu/csky/readme.txt to run.
This buildroot toolchain is pre-build, But you can rebuild
the c-sky uclibc-ng alone and install it to the buildroot
sysroot manually.
We'll try our best to improve the uclibc-ng continuously.
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
76 files changed, 4631 insertions, 2 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 642f9034a..d5aa02441 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7,6 +7,9 @@ ARC: Alexey Brodkin <Alexey.Brodkin@synopsys.com> Vineet Gupta <Vineet.Gupta1@synopsys.com> +CSKY: +Guo Ren <ren_guo@c-sky.com> + MIPS: Matthew Fortune <Matthew.Fortune@imgtec.com> @@ -453,6 +453,21 @@ ifeq ($(TARGET_ARCH),cris) PIEFLAG_NAME:=-fpie endif +ifeq ($(TARGET_ARCH),csky) + # In csky gas implement, we use $t and $d to detect .text or literal pool. + # So we couldn't strip them for objdump. + STRIP_FLAGS += -K "$$"t -K "$$"d + + CPU_CFLAGS-$(CK610) += -mcpu=ck610f + CPU_CFLAGS-$(CK810) += -mcpu=ck810f + CPU_CFLAGS-$(CK807) += -mcpu=ck807f + + CPU_CFLAGS-$(UCLIBC_HAS_FPU) += -mhard-float + + CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN) += -mlittle-endian + CPU_CFLAGS-$(ARCH_BIG_ENDIAN) += -mbig-endian +endif + ifeq ($(TARGET_ARCH),m68k) # -fPIC is only supported for 68020 and above. It is not supported # for 68000, 68010, or Coldfire. diff --git a/extra/Configs/Config.csky b/extra/Configs/Config.csky new file mode 100644 index 000000000..704f7be1b --- /dev/null +++ b/extra/Configs/Config.csky @@ -0,0 +1,25 @@ +config TARGET_ARCH + string + default "csky" + +config FORCE_OPTIONS_FOR_ARCH + bool + default y + select ARCH_ANY_ENDIAN + select ARCH_HAS_DEPRECATED_SYSCALLS + select ARCH_USE_MMU + select ARCH_HAS_MMU + +choice + prompt "Target Processor Type" + default CK610 + +config CK610 + bool "ck610" +config CK810 + bool "ck810" +config CK807 + bool "ck807" + +endchoice + diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index ce832b55b..b5ee294db 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -22,6 +22,7 @@ choice default TARGET_avr32 if DESIRED_TARGET_ARCH = "avr32" default TARGET_bfin if DESIRED_TARGET_ARCH = "bfin" default TARGET_cris if DESIRED_TARGET_ARCH = "cris" + default TARGET_csky if DESIRED_TARGET_ARCH = "csky" default TARGET_frv if DESIRED_TARGET_ARCH = "frv" default TARGET_h8300 if DESIRED_TARGET_ARCH = "h8300" default TARGET_hppa if DESIRED_TARGET_ARCH = "hppa" @@ -70,6 +71,9 @@ config TARGET_c6x config TARGET_cris bool "cris" +config TARGET_csky + bool "csky" + config TARGET_frv bool "frv" @@ -156,6 +160,10 @@ if TARGET_cris source "extra/Configs/Config.cris" endif +if TARGET_csky +source "extra/Configs/Config.csky" +endif + if TARGET_frv source "extra/Configs/Config.frv" endif diff --git a/extra/Configs/defconfigs/csky/defconfig b/extra/Configs/defconfigs/csky/defconfig new file mode 100644 index 000000000..da837fc29 --- /dev/null +++ b/extra/Configs/defconfigs/csky/defconfig @@ -0,0 +1 @@ +TARGET_csky=y diff --git a/include/elf.h b/include/elf.h index c8488bb3d..fcb546a0f 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1200,6 +1200,67 @@ typedef struct #define ELF64_M_SIZE(info) ELF32_M_SIZE (info) #define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) +/* C-SKY relocs. */ + +#define R_CKCORE_NONE 0 +#define R_CKCORE_ADDR32 1 +#define R_CKCORE_PCRELIMM8BY4 2 +#define R_CKCORE_PCRELIMM11BY2 3 +#define R_CKCORE_PCRELIMM4BY2 4 +#define R_CKCORE_PCREL32 5 +#define R_CKCORE_PCRELJSR_IMM11BY2 6 +#define R_CKCORE_GNU_VTINHERIT 7 +#define R_CKCORE_GNU_VTENTRY 8 +#define R_CKCORE_RELATIVE 9 +#define R_CKCORE_COPY 10 +#define R_CKCORE_GLOB_DAT 11 +#define R_CKCORE_JUMP_SLOT 12 +#define R_CKCORE_GOTOFF 13 +#define R_CKCORE_GOTPC 14 +#define R_CKCORE_GOT32 15 +#define R_CKCORE_PLT32 16 +#define R_CKCORE_ADDRGOT 17 +#define R_CKCORE_ADDRPLT 18 +#define R_CKCORE_PCREL_IMM26BY2 19 +#define R_CKCORE_PCREL_IMM16BY2 20 +#define R_CKCORE_PCREL_IMM16BY4 21 +#define R_CKCORE_PCREL_IMM10BY2 22 +#define R_CKCORE_PCREL_IMM10BY4 23 +#define R_CKCORE_ADDR_HI16 24 +#define R_CKCORE_ADDR_LO16 25 +#define R_CKCORE_GOTPC_HI16 26 +#define R_CKCORE_GOTPC_LO16 27 +#define R_CKCORE_GOTOFF_HI16 28 +#define R_CKCORE_GOTOFF_LO16 29 +#define R_CKCORE_GOT12 30 +#define R_CKCORE_GOT_HI16 31 +#define R_CKCORE_GOT_LO16 32 +#define R_CKCORE_PLT12 33 +#define R_CKCORE_PLT_HI16 34 +#define R_CKCORE_PLT_LO16 35 +#define R_CKCORE_ADDRGOT_HI16 36 +#define R_CKCORE_ADDRGOT_LO16 37 +#define R_CKCORE_ADDRPLT_HI16 38 +#define R_CKCORE_ADDRPLT_LO16 39 +#define R_CKCORE_PCREL_JSR_IMM26BY2 40 +#define R_CKCORE_TOFFSET_LO16 41 +#define R_CKCORE_DOFFSET_LO16 42 +#define R_CKCORE_PCREL_IMM18BY2 43 +#define R_CKCORE_DOFFSET_IMM18 44 +#define R_CKCORE_DOFFSET_IMM18BY2 45 +#define R_CKCORE_DOFFSET_IMM18BY4 46 +#define R_CKCORE_GOTOFF_IMM18 47 +#define R_CKCORE_GOT_IMM18BY4 48 +#define R_CKCORE_PLT_IMM18BY4 49 +#define R_CKCORE_PCREL_IMM7BY4 50 +#define R_CKCORE_TLS_LE32 51 +#define R_CKCORE_TLS_IE32 52 +#define R_CKCORE_TLS_GD32 53 +#define R_CKCORE_TLS_LDM32 54 +#define R_CKCORE_TLS_LDO32 55 +#define R_CKCORE_TLS_DTPMOD32 56 +#define R_CKCORE_TLS_DTPOFF32 57 +#define R_CKCORE_TLS_TPOFF32 58 /* Motorola 68k specific definitions. */ diff --git a/ldso/ldso/csky/dl-startup.h b/ldso/ldso/csky/dl-startup.h new file mode 100644 index 000000000..0a74ab69f --- /dev/null +++ b/ldso/ldso/csky/dl-startup.h @@ -0,0 +1,115 @@ +#ifdef __CSKYABIV2__ + +__asm__ ( + " .text\n\t" + " .globl _start\n\t" + "_start:\n\t" + " mov a0, sp\n\t" + " bsr _dl_start\n\t" + " # Return from _dl_start, user entry point address in a0 \n\t" + " # the code is PIC, so get global offset table\n\t" + " grs gb,.Lgetpc1\n\t" + ".Lgetpc1:\n\t " + " lrw t0, .Lgetpc1@GOTPC\n\t" + " add gb, gb,t0\n\t" + " lrw r5, _dl_skip_args@GOT\n\t" + " ldr.w r5, (gb, r5 << 0)\n\t" + " # get the value of variable _dl_skip_args in r6\n\t" + " ldw r6, (r5, 0)\n\t" + " # get the argc in r7 \n\t" + " ldw r7, (sp, 0)\n\t" + " # adjust the argc, this may be a bug when _dl_skip_args > argc\n\t" + " rsub r6, r7\n\t" + " # adjust the stack\n\t" + " mov r7, r6\n\t" + " lsli r6, 2\n\t" + " # adjust the stack pointer,this may be a bug, " + " # because it must be 8 bytes align" + " addu sp, r6\n\t" + " stw r7, (sp, 0)\n\t" + " lrw r7, _dl_fini@GOTOFF\n\t" + " addu r7, gb\n\t" + " jmp a0" +); +#else +__asm__ ( + " .text\n\t" + " .globl _start\n\t" + "_start:\n\t" + " mov r2, r0\n\t" +# if defined(__ck810__) + " bsr _dl_start\n\t" +#else + " # the code is PIC, so get global offset table\n\t" + " bsr .Lgetpc0\n\t" + ".Lgetpc0:\n\t " + " lrw r14, .Lgetpc0@GOTPC\n\t" + " add r14, r15\n\t" + " lrw r4, _dl_start@GOTOFF\n\t" + " add r4, r14\n\t" + " jsr r4\n\t" +#endif + " # Return from _dl_start, user entry point address in r2 \n\t" + " # the code is PIC, so get global offset table\n\t" + " bsr .Lgetpc1\n\t" + ".Lgetpc1:\n\t " + " lrw r3, .Lgetpc1@GOTPC\n\t" + " add r3, r15\n\t" +# if defined(__ck810__) + " ldw r5, (r3, _dl_skip_args@GOT)\n\t" +#else + " lrw r4, _dl_skip_args@GOT\n\t" + " add r4, r3\n\t" + " ldw r5, (r4, 0)\n\t" +#endif + " # get the value of variable _dl_skip_args in r6\n\t" + " ldw r6, (r5, 0)\n\t" + " # get the argc in r7 \n\t" + " ldw r7, (r0, 0)\n\t" + " # adjust the argc, this may be a bug when _dl_skip_args > argc\n\t" + " rsub r6, r7\n\t" + " # adjust the stack\n\t" + " mov r7, r6\n\t" + " lsli r6, 2\n\t" + " # adjust the stack pointer,this may be a bug, " + " # because it must be 8 bytes align" + " addu r0, r6\n\t" + " stw r7, (r0, 0)\n\t" + " lrw r7, _dl_fini@GOTOFF\n\t" + " addu r7, r3\n\t" + " jmp r2" +); + +#endif + +/* Get a pointer to the argv array. */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1) + +/* Function calls are not safe until the GOT relocations have been done. */ +#define NO_FUNCS_BEFORE_BOOTSTRAP +/* Handle relocation of the symbols in the dynamic loader. */ +static __always_inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab) +{ + switch (ELF32_R_TYPE(rpnt->r_info)) + { + case R_CKCORE_RELATIVE: + *reloc_addr = load_addr + rpnt->r_addend; + break; + case R_CKCORE_GLOB_DAT: + case R_CKCORE_JUMP_SLOT: + *reloc_addr = symbol_addr; + break; + case R_CKCORE_ADDR32: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; + case R_CKCORE_NONE: + break; + + default: + _dl_exit(1); + } +} + + diff --git a/ldso/ldso/csky/dl-syscalls.h b/ldso/ldso/csky/dl-syscalls.h new file mode 100644 index 000000000..f40c4fd31 --- /dev/null +++ b/ldso/ldso/csky/dl-syscalls.h @@ -0,0 +1 @@ +/* stub for arch-specific syscall issues */ diff --git a/ldso/ldso/csky/dl-sysdep.h b/ldso/ldso/csky/dl-sysdep.h new file mode 100644 index 000000000..c78dd81bc --- /dev/null +++ b/ldso/ldso/csky/dl-sysdep.h @@ -0,0 +1,89 @@ +/* Define this if the system uses RELOCA. */ +#define ELF_USES_RELOCA + +#include <elf.h> +/* Initialization sequence for the GOT. */ +#define INIT_GOT(GOT_BASE,MODULE) \ +do { \ + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ + GOT_BASE[1] = (unsigned long) MODULE; \ +} while(0) + +/* Here we define the magic numbers that this dynamic loader should accept */ +#define MAGIC1 EM_MCORE +#undef MAGIC2 + +/* Used for error messages */ +#define ELF_TARGET "csky" + +struct elf_resolve; +extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + +/* 65536 bytes alignment */ +#define PAGE_ALIGN 0xfffff000 /* need modify */ +#define ADDR_ALIGN 0xfff +#define OFFS_ALIGN 0x7ffff000 + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. + ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_CKCORE_JUMP_SLOT || (type) == R_CKCORE_TLS_DTPMOD32 \ + || (type) == R_CKCORE_TLS_DTPOFF32 || (type) == R_CKCORE_TLS_TPOFF32) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_CKCORE_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* 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. */ +static __inline__ Elf32_Addr elf_machine_dynamic (void) attribute_unused; +static __inline__ Elf32_Addr +elf_machine_dynamic (void) +{ + register Elf32_Addr *got __asm__ ("gb"); /* need modify */ + return *got; +} + +/* this funtion will be called only when the auxvt[AT_BASE].a_un.a_val == 0 + so it normal not be called, we should define a default address of the interprrter load */ +static __inline__ Elf32_Addr elf_machine_load_address (void) attribute_unused; +static __inline__ Elf32_Addr +elf_machine_load_address (void) +{ +#ifdef __CSKYABIV2__ + extern Elf32_Addr internal_function __dl_start (void *) __asm__ ("_dl_start"); + Elf32_Addr got_addr = (Elf32_Addr) &__dl_start; + Elf32_Addr pcrel_addr; + __asm__ ("grs %0,_dl_start\n" : "=r" (pcrel_addr)); +#else + extern Elf32_Addr internal_function __start_flag (void *) __asm__ ("start_flag"); + Elf32_Addr got_addr = (Elf32_Addr) &__start_flag; + Elf32_Addr pcrel_addr; + __asm__ ("subi sp,8\n" \ + "stw lr,(sp,0)\n" \ + "bsr start_flag\n" \ + "start_flag:" \ + "mov %0, lr\n" \ + "ldw lr,(sp,0)\n" \ + "addi sp,8\n" \ + : "=r" (pcrel_addr)); +#endif + return pcrel_addr - got_addr; + +} + +/* some relocation information are machine special */ +static __inline__ void +elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) +{ + Elf32_Rela *rpnt = (void *) rel_addr; + --rpnt; + do { + Elf32_Addr *reloc_addr = (void *) (load_off + (++rpnt)->r_offset); + *reloc_addr = load_off + rpnt->r_addend; + } while (--relative_count); /* maybe need modify */ +} + diff --git a/ldso/ldso/csky/elfinterp.c b/ldso/ldso/csky/elfinterp.c new file mode 100644 index 000000000..1469c28f1 --- /dev/null +++ b/ldso/ldso/csky/elfinterp.c @@ -0,0 +1,297 @@ +#include "ldso.h" + +unsigned long +_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) +{ + ELF_RELOC *this_reloc; + int symtab_index; + //char *rel_tab; + Elf32_Sym *sym_tab; + char *str_tab; + char *sym_name; + char *sym_addr; + char **reloc_addr; + + this_reloc = (ELF_RELOC *)tpnt->dynamic_info[DT_JMPREL]; + this_reloc += reloc_entry; + //this_reloc = (ELF_RELOC *)(intptr_t)(rel_tab + reloc_entry); + symtab_index = ELF32_R_SYM(this_reloc->r_info |