Re: [PATCH 2/2] Add LoongArch64 basic support
Jinyang He <[email protected]> Mon, 15 Jul 2024 10:43:09 +0800
| Newsgroups | gmane.lisp.gcl.devel |
|---|---|
| Message-ID | <[email protected]> |
On 2024-07-15 03:51, Camm Maguire wrote: > Greetings, and thanks so much again! > > This is going in now both to master and Version_2_6_15pre. Debian > package release to test on autobuilders vis a vis all supported packages > uploaded now. Thanks! I tested Version_2_6_15pre locally and it works well. (Some tests failed same as Debian builders. See [1]) > Do you need all the defines at the top of > elf64_loongarch64_reloc_special.h? Are they not in elf.h on your > platform? Not all of them. These relocation types (>=64) are LoongArch psABI 2.0+. The elf.h is comes from glibc, which may not mattched binutils. The first version of glibc is not support these relocation types. So I add define in the file. The Debian's glibc usually is the newest for LoongArch and it is OK to not define them, but I cannot promise other OS release. Or is it better to "#ifndef xxx, #define xxx yy #endif"? > In master, I've separately committed a hardlinking of libboot.so into > the pre_ images to fix the address. Could you please try this out and > let me know if it fixes the issue addressed in your other patch? Could you please show this patch in email? I cannot see the commit in the master branch. > Would also like to move the execve to set the personality to the top of > gcl_init_alloc to close the window for possible mmap layout changes. > Not committed yet. That looks better! But we had to know the "argc,argv,envp,auxv" first. I think maybe init_array can get it early, or others? [1] https://buildd.debian.org/status/logs.php?pkg=gcl&ver=2.6.14-10&arch=loong64 Thanks, Jinyang > > Take care, > > Jinyang He <[email protected]> writes: > >> The result of test, >> $ cd gcl/ >> $ autoconf -i -f >> $ ./configure >> $ make >> $ cd ansi-tests/ >> $ LISP=../unixport/saved_ansi_gcl make test >> 2 out of 21727 total tests failed: DECODE-UNIVERSAL-TIME.1, DECODE-UNIVERSAL-TIME.2. >> real time : 148.230 secs >> run-gbc time : 58.380 secs >> child run time : 80.520 secs >> gbc time : 2.820 secs >> allocation : 16046 Mbytes >> NIL >> --- >> gcl/configure.in | 4 ++ >> gcl/h/elf64_loongarch64_reloc.h | 93 +++++++++++++++++++++++++ >> gcl/h/elf64_loongarch64_reloc_special.h | 70 +++++++++++++++++++ >> gcl/h/loongarch64-linux.h | 27 +++++++ >> 4 files changed, 194 insertions(+) >> create mode 100644 gcl/h/elf64_loongarch64_reloc.h >> create mode 100644 gcl/h/elf64_loongarch64_reloc_special.h >> create mode 100644 gcl/h/loongarch64-linux.h >> >> diff --git a/gcl/configure.in b/gcl/configure.in >> index c983ef0c3..358e02889 100644 >> --- a/gcl/configure.in >> +++ b/gcl/configure.in >> @@ -47,6 +47,7 @@ case $canonical in >> s390*linux*) use=s390-linux;; >> ia64*linux*) use=ia64-linux;; >> hppa*linux*) use=hppa-linux;; >> + loongarch64*linux*) use=loongarch64-linux;; >> powerpc*linux*) use=powerpc-linux;; >> powerpc-*-darwin*) use=powerpc-macosx;; >> *86*darwin*) use=386-macosx;; >> @@ -343,6 +344,9 @@ case $use in >> if ! add_arg_to_cflags -msse2 || ! add_arg_to_cflags -mfpmath=sse ; then >> add_arg_to_cflags -ffloat-store; >> fi;; >> + loongarch64-linux) >> + add_arg_to_cflags -mno-relax >> + add_arg_to_cflags -Wa,-mno-relax;; >> 386-macosx) >> # assert_arg_to_cflags -Wno-error=implicit-function-declaration >> add_arg_to_cflags -Wno-incomplete-setjmp-declaration >> diff --git a/gcl/h/elf64_loongarch64_reloc.h b/gcl/h/elf64_loongarch64_reloc.h >> new file mode 100644 >> index 000000000..97260111a >> --- /dev/null >> +++ b/gcl/h/elf64_loongarch64_reloc.h >> @@ -0,0 +1,93 @@ >> +#define get_insn_page(x) ((x) & ~0xffful) >> +#define get_page_delta(dest, pc) ({ \ >> + ul res = get_insn_page(dest) - get_insn_page(pc); \ >> + if ((dest) & 0x800) \ >> + res += 0x1000ul - 0x100000000ul; \ >> + if (res & 0x80000000) \ >> + res += 0x100000000ul; \ >> + res; \ >> +}) >> +#define get_page_low(dest) ((dest) & 0xfff) >> +#define bdest (((long)((s+a)-p))>>2) >> +#define bgdest (((long)(((ul)got)-p))>>2) >> + >> + case R_LARCH_RELAX: >> + case R_LARCH_ALIGN: >> + massert(!emsg("Unsupport relaxation, please compile with '-mno-relax -Wa,-mno-relax'\n")); >> + break; >> + case R_LARCH_64: >> + store_val(where,~0L,(s+a)); >> + break; >> + case R_LARCH_32: >> + store_val(where,MASK(32),(s+a)); >> + break; >> + case R_LARCH_32_PCREL: >> + store_val(where,MASK(32),(s+a)-p); >> + break; >> + case R_LARCH_ADD6: >> + add_val(where,MASK(6),(s+a)); >> + break; >> + case R_LARCH_ADD8: >> + add_val(where,MASK(8),(s+a)); >> + break; >> + case R_LARCH_ADD16: >> + add_val(where,MASK(16),(s+a)); >> + break; >> + case R_LARCH_ADD32: >> + add_val(where,MASK(32),(s+a)); >> + break; >> + case R_LARCH_ADD64: >> + add_val(where,~0L,(s+a)); >> + break; >> + case R_LARCH_SUB6: >> + add_val(where,MASK(6),-(s+a)); >> + break; >> + case R_LARCH_SUB8: >> + add_val(where,MASK(8),-(s+a)); >> + break; >> + case R_LARCH_SUB16: >> + add_val(where,MASK(16),-(s+a)); >> + break; >> + case R_LARCH_SUB32: >> + add_val(where,MASK(32),-(s+a)); >> + break; >> + case R_LARCH_SUB64: >> + add_val(where,~0L,-(s+a)); >> + break; >> + case R_LARCH_B16: >> + store_val(where,MASK(16)<<10,bdest<<10); >> + break; >> + case R_LARCH_B21: >> + store_val(where,(MASK(16)<<10)|MASK(5),bdest<<10|((bdest>>16)&0x1f)); >> + break; >> + case R_LARCH_B26: >> + { >> + if ((bdest&(~MASK(25)))==0||((~bdest)&(~MASK(25)))==0) { >> + store_val(where,MASK(26),bdest<<10|((bdest>>16)&0x3ff)); >> + break; >> + } >> + if (!(sym->st_size&0x2)) >> + massert(!emsg("Unresolved R_LARCH_B26 symbol\n")); >> + got+=(sym->st_size>>2)+(sym->st_size&0x1?1:0); >> + store_val(where,MASK(26),bgdest<<10|((bgdest>>16)&0x3ff)); >> + memcpy(got,tramp,sizeof(tramp)); >> + store_val(got,MASK(20)<<5,(get_insn_page(s+a)-get_insn_page((ul)got))>>12<<5); >> + store_val((ul*)((ul)got+4),MASK(16)<<10,(((s+a)>>2)&0x3ff)<<10); >> + } >> + break; >> + case R_LARCH_PCALA_HI20: >> + store_val(where,MASK(20)<<5,get_page_delta(s+a,p)>>12<<5); >> + break; >> + case R_LARCH_PCALA_LO12: >> + store_val(where,MASK(12)<<10,get_page_low(s+a)<<10); >> + break; >> + case R_LARCH_GOT_PC_HI20: >> + got+=sym->st_size>>2; >> + *got=s+a; >> + store_val(where,MASK(20)<<5,get_page_delta((ul)got,p)>>12<<5); >> + break; >> + case R_LARCH_GOT_PC_LO12: >> + got+=sym->st_size>>2; >> + // *got=s+a; >> + store_val(where,MASK(12)<<10,get_page_low((ul)got)<<10); >> + break; >> diff --git a/gcl/h/elf64_loongarch64_reloc_special.h b/gcl/h/elf64_loongarch64_reloc_special.h >> new file mode 100644 >> index 000000000..50f4811e8 >> --- /dev/null >> +++ b/gcl/h/elf64_loongarch64_reloc_special.h >> @@ -0,0 +1,70 @@ >> +#define R_LARCH_B16 64 >> +#define R_LARCH_B21 65 >> +#define R_LARCH_B26 66 >> +#define R_LARCH_PCALA_HI20 71 >> +#define R_LARCH_PCALA_LO12 72 >> +#define R_LARCH_GOT_PC_HI20 75 >> +#define R_LARCH_GOT_PC_LO12 76 >> +#define R_LARCH_32_PCREL 99 >> +#define R_LARCH_RELAX 100 >> +#define R_LARCH_ALIGN 102 >> +#define R_LARCH_ADD6 105 >> +#define R_LARCH_SUB6 106 >> + >> +static unsigned int tramp[] = { >> + 0x1a00000c, /* pcalau12i $t0, %hi(sym) */ >> + 0x4c000180 /* jirl $zero, $t0, %lo(sym) */}; >> + >> +static int >> +find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn, >> + const char *st1,Sym *ds1,Sym *dse,Sym *sym,Sym *syme) { >> + return 0; >> + >> +} >> + >> +static int >> +label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const char *st1,const char *sn,ul *gs) { >> + Rela *r; >> + Sym *sym; >> + Shdr *sec; >> + void *v,*ve; >> + int idx; >> + const int gz = sizeof(ul)/sizeof(ul), tz = sizeof(tramp)/sizeof(ul); >> + massert(gz==1); >> + massert(tz==1); >> + >> + for (sym=sym1;sym<syme;sym++) >> + sym->st_size=0; >> + >> + /* Count the symbols need to be fixed first. */ >> + for (sec=sec1;sec<sece;sec++) >> + if (sec->sh_type==SHT_RELA) >> + for (v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v) >> + if ( >> + ELF_R_TYPE(r->r_info)==R_LARCH_GOT_PC_HI20 || >> + ELF_R_TYPE(r->r_info)==R_LARCH_B26 >> + ) { >> + sym=sym1+ELF_R_SYM(r->r_info); >> + if (ELF_R_TYPE(r->r_info)==R_LARCH_B26 && LOCAL_SYM(sym)) >> + continue; >> + >> + if (ELF_R_TYPE(r->r_info)==R_LARCH_GOT_PC_HI20) >> + sym->st_size|=0x1; >> + if (ELF_R_TYPE(r->r_info)==R_LARCH_B26) >> + sym->st_size|=0x2; >> + } >> + >> + for (idx=0,sym=sym1;sym<syme;sym++) { >> + if (sym->st_size==0) >> + continue; >> + massert(!(sym->st_size>>2)); >> + sym->st_size|=idx<<2; >> + if (sym->st_size&0x1) >> + idx+=gz; >> + if (sym->st_size&0x2) >> + idx+=tz; >> + } >> + >> + *gs=idx; >> + return 0; >> +} >> diff --git a/gcl/h/loongarch64-linux.h b/gcl/h/loongarch64-linux.h >> new file mode 100644 >> index 000000000..d50065ae1 >> --- /dev/null >> +++ b/gcl/h/loongarch64-linux.h >> @@ -0,0 +1,27 @@ >> +#include "linux.h" >> + >> +#ifdef IN_GBC >> +#undef MPROTECT_ACTION_FLAGS >> +#define MPROTECT_ACTION_FLAGS SA_RESTART|SA_SIGINFO >> +#define GET_FAULT_ADDR(sig,code,sv,a) \ >> + ((siginfo_t *)code)->si_addr >> +#endif >> + >> +/*#define NULL_OR_ON_C_STACK(x) ((x)==0 || ((unsigned int)x) > (unsigned int)(pagetochar(MAXPAGE+1)))*/ >> + >> +/* #define ADDITIONAL_FEATURES \ */ >> +/* ADD_FEATURE("BSD386"); \ */ >> +/* ADD_FEATURE("MC68020") */ >> + >> + >> +/* #define I386 */ >> +#define SGC >> + >> +/* Apparently stack pointers can be 4 byte aligned, at least &argc -- CM */ >> +#define C_GC_OFFSET 4 >> + >> +#define RELOC_H "elf64_loongarch64_reloc.h" >> +#define SPECIAL_RELOC_H "elf64_loongarch64_reloc_special.h" >> +/* #define MAX_CODE_ADDRESS (1L<<31)/\*large memory model broken gcc 4.8*\/ */ >> + >> +#define NEED_STACK_CHK_GUARD