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