diff options
| -rw-r--r-- | ldso/ldso/cris/boot1_arch.h | 22 | ||||
| -rw-r--r-- | ldso/ldso/cris/dl-startup.h | 22 | ||||
| -rw-r--r-- | ldso/ldso/cris/dl-sysdep.h | 121 | ||||
| -rw-r--r-- | ldso/ldso/cris/elfinterp.c | 64 | ||||
| -rw-r--r-- | ldso/ldso/cris/ld_sysdep.h | 121 | 
5 files changed, 181 insertions, 169 deletions
| diff --git a/ldso/ldso/cris/boot1_arch.h b/ldso/ldso/cris/boot1_arch.h index 5fe5cae43..6824076fb 100644 --- a/ldso/ldso/cris/boot1_arch.h +++ b/ldso/ldso/cris/boot1_arch.h @@ -1,17 +1,17 @@  /* - * This code fix the stack pointer so that the dunamic linker + * This code fix the stack pointer so that the dynamic linker   * can find argc, argv and auxvt (Auxillary Vector Table).   */ -asm("\ -	.text -	.globl _dl_boot -	.type _dl_boot,@function -_dl_boot: -	move.d $sp,$r10 -	move.d $pc,$r9 -	add.d _dl_boot2 - ., $r9 -	jsr $r9 -"); +asm(""					\ +"	.text\n"			\ +"	.globl _dl_boot\n"		\ +"	.type _dl_boot,@function\n"	\ +"_dl_boot:\n"				\ +"	move.d $sp,$r10\n"		\ +"	move.d $pc,$r9\n"		\ +"	add.d _dl_boot2 - ., $r9\n"	\ +"	jsr $r9\n"			\ +);  #define _dl_boot _dl_boot2  #define LD_BOOT(X) static void __attribute__ ((unused)) _dl_boot(X) diff --git a/ldso/ldso/cris/dl-startup.h b/ldso/ldso/cris/dl-startup.h index 5fe5cae43..6824076fb 100644 --- a/ldso/ldso/cris/dl-startup.h +++ b/ldso/ldso/cris/dl-startup.h @@ -1,17 +1,17 @@  /* - * This code fix the stack pointer so that the dunamic linker + * This code fix the stack pointer so that the dynamic linker   * can find argc, argv and auxvt (Auxillary Vector Table).   */ -asm("\ -	.text -	.globl _dl_boot -	.type _dl_boot,@function -_dl_boot: -	move.d $sp,$r10 -	move.d $pc,$r9 -	add.d _dl_boot2 - ., $r9 -	jsr $r9 -"); +asm(""					\ +"	.text\n"			\ +"	.globl _dl_boot\n"		\ +"	.type _dl_boot,@function\n"	\ +"_dl_boot:\n"				\ +"	move.d $sp,$r10\n"		\ +"	move.d $pc,$r9\n"		\ +"	add.d _dl_boot2 - ., $r9\n"	\ +"	jsr $r9\n"			\ +);  #define _dl_boot _dl_boot2  #define LD_BOOT(X) static void __attribute__ ((unused)) _dl_boot(X) diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index e915bf600..cf36752fb 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -11,11 +11,11 @@  /*   * Initialization sequence for a GOT.   */ -#define INIT_GOT(GOT_BASE,MODULE) 				\ -{                               				\ -	 GOT_BASE[1] = (unsigned long) MODULE; 			\ -	 GOT_BASE[2] = (unsigned long) _dl_linux_resolve; 	\ -}  +#define INIT_GOT(GOT_BASE,MODULE)				\ +{								\ +	GOT_BASE[1] = (unsigned long) MODULE; 			\ +	GOT_BASE[2] = (unsigned long) _dl_linux_resolve; 	\ +}  /*   * Here is a macro to perform a relocation.  This is only used when @@ -24,38 +24,39 @@   * SYMBOL is the symbol involved in the relocation, and LOAD is the   * load address.   */ -#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD)			\ -	switch (ELF32_R_TYPE((RELP)->r_info)) {           			\ -		case R_CRIS_GLOB_DAT:						\ -		case R_CRIS_JUMP_SLOT:						\ -		case R_CRIS_32:							\ -			*REL = SYMBOL;						\ -			break;							\ -		case R_CRIS_16_PCREL:						\ +#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD)		\ +	switch (ELF32_R_TYPE((RELP)->r_info)) {				\ +		case R_CRIS_GLOB_DAT:					\ +		case R_CRIS_JUMP_SLOT:					\ +		case R_CRIS_32:						\ +			*REL = SYMBOL;					\ +			break;						\ +		case R_CRIS_16_PCREL:					\  			*(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2;	\ -			break;							\ -		case R_CRIS_32_PCREL:						\ -			*REL = SYMBOL + (RELP)->r_addend - *REL - 4;		\ -			break;							\ -		case R_CRIS_NONE:						\ -			break;							\ -		case R_CRIS_RELATIVE:						\ -			*REL = (unsigned long) LOAD + (RELP)->r_addend;		\ -			break;							\ -		default:							\ -			_dl_exit(1);						\ -			break;							\ -	}  +			break;						\ +		case R_CRIS_32_PCREL:					\ +			*REL = SYMBOL + (RELP)->r_addend - *REL - 4;	\ +			break;						\ +		case R_CRIS_NONE:					\ +			break;						\ +		case R_CRIS_RELATIVE:					\ +			*REL = (unsigned long) LOAD + (RELP)->r_addend;	\ +			break;						\ +		default:						\ +			_dl_exit(1);					\ +			break;						\ +	}  /*   * Transfer control to the user's application once the dynamic loader   * is done. This routine has to exit the current function, then call   * _dl_elf_main.   */ -#define START() __asm__ volatile ("moveq 0,$r8\n\t -								   move $r8,$srp\n\t -								   move.d %1,$sp\n\t -								   jump %0\n\t" : : "r" (_dl_elf_main), "r" (args)) +#define START() __asm__ volatile ("moveq 0,$r8\n\t" \ +				  "move $r8,$srp\n\t" \ +				  "move.d %1,$sp\n\t" \ +				  "jump %0\n\t" \ +				  : : "r" (_dl_elf_main), "r" (args))  /* Defined some magic numbers that this ld.so should accept. */  #define MAGIC1 EM_CRIS @@ -66,41 +67,41 @@ struct elf_resolve;  extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);  /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ -static inline unsigned long  -cris_mod(unsigned long m, unsigned long p)  +static inline unsigned long +cris_mod(unsigned long m, unsigned long p)  {  	unsigned long i, t, inc; -         -	i = p;  + +	i = p;  	t = 0; -        while (!(i & (1 << 31))) { -                i <<= 1; -                t++; -        } -	 -        t--; -         +	while (!(i & (1 << 31))) { +		i <<= 1; +		t++; +	} + +	t--; +  	for (inc = t; inc > 2; inc--) { -                i = p << inc; -		 -                if (i & (1 << 31)) -                        break; -			 -                while (m >= i) { -                        m -= i; -                        i <<= 1; -                        if (i & (1 << 31)) -                                break; -                        if (i < p) -                                break; -                } -        } -	 -        while (m >= p) -                m -= p; - -        return m; +		i = p << inc; + +		if (i & (1 << 31)) +			break; + +		while (m >= i) { +			m -= i; +			i <<= 1; +			if (i & (1 << 31)) +				break; +			if (i < p) +				break; +		} +	} + +	while (m >= p) +		m -= p; + +	return m;  }  #define do_rem(result, n, base) result = cris_mod(n, base); diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c index 72e85530e..0e395a6e0 100644 --- a/ldso/ldso/cris/elfinterp.c +++ b/ldso/ldso/cris/elfinterp.c @@ -69,7 +69,7 @@ debug_sym(Elf32_Sym *symtab, char *strtab, int symtab_index)  				symtab[symtab_index].st_info,  				symtab[symtab_index].st_other,  				symtab[symtab_index].st_shndx); -    	} +		}    	}  }  @@ -82,13 +82,18 @@ debug_reloc(Elf32_Sym *symtab, char *strtab, ELF_RELOC *rpnt)  		symtab_index = ELF32_R_SYM(rpnt->r_info);  		sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0"; + +		if (_dl_debug_symbols) +			_dl_printf(_dl_debug_file, "\n\t"); +		else +			_dl_printf(_dl_debug_file, "\n%s\n\t", sym);  #ifdef ELF_USES_RELOCA -		_dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x %s", -			_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), rpnt->r_offset, rpnt->r_addend, sym); +		_dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x", +			_dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), rpnt->r_offset, rpnt->r_addend);  #else -		_dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s", _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), -			rpnt->r_offset, sym); +		_dl_dprintf(_dl_debug_file, "\n%s\toffset=%x", _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), +			rpnt->r_offset);  #endif  	}  } @@ -104,6 +109,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_offset)  	int reloc_type;  	int symtab_index;  	char *strtab; +	char *symname;  	char *new_addr;  	char **got_addr;  	ELF_RELOC *reloc; @@ -117,9 +123,10 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_offset)  	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);  	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); +	symname = strtab + symtab[symtab_index].st_name;  	if (reloc_type != R_CRIS_JUMP_SLOT) { -		_dl_dprintf(_dl_debug_file, "%s: Incorrect relocation type for jump relocations.\n", _dl_progname); +		_dl_dprintf(2, "%s: Incorrect relocation type for jump relocations.\n", _dl_progname);  		_dl_exit(1);  	} @@ -128,20 +135,23 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_offset)  	got_addr = (char **) instr_addr;  #ifdef DL_DEBUG_SYMBOLS -	_dl_dprintf(_dl_debug_file, "Resolving symbol: %s\n", strtab + symtab[symtab_index].st_name); +	_dl_dprintf(_dl_debug_file, "Resolving symbol: %s\n", symname);  #endif  	/* Fetch the address of the GOT entry. */ -	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, tpnt->symbol_scope, tpnt, 0); +	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);  	if (!new_addr) { -		_dl_dprintf(_dl_debug_file, "%s: Can't resolv symbol '%s'\n", _dl_progname, strtab + symtab[symtab_index].st_name); +		if ((new_addr = _dl_find_hash(symname, NULL, NULL, resolver))) +			return (unsigned long) new_addr; + +		_dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);  		_dl_exit(1);  	}  #if defined (__SUPPORT_LD_DEBUG__)  	if (_dl_debug_bindings) { -		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", strtab + symtab[symtab_index].st_name); +		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);  		if (_dl_debug_detail)  			_dl_dprintf(_dl_debug_file, "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr); @@ -168,6 +178,7 @@ _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long re  	rel_size = rel_size / sizeof(ELF_RELOC);  	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);  	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); +	symname = strtab + symtab[symtab_index].st_name;  	for (i = 0; i < rel_size; i++, rpnt++) {  		reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + (Elf32_Addr) rpnt->r_offset); @@ -181,7 +192,7 @@ _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long re  		if (!symtab_index && tpnt->libtype == program_interpreter)  		 	continue;  		if (symtab_index && tpnt->libtype == program_interpreter && -			_dl_symbol(strtab + symtab[symtab_index].st_name)) +			_dl_symbol(symname))  			continue;  #if defined (__SUPPORT_LD_DEBUG__) @@ -189,7 +200,6 @@ _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long re  		unsigned long old_val = *reloc_addr;  #endif -  		switch (reloc_type) {  			case R_CRIS_NONE:  				break; @@ -197,13 +207,13 @@ _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long re  				*reloc_addr += (Elf32_Addr) tpnt->loadaddr;  				break;  			default: -				_dl_dprintf(_dl_debug_file, "%s: Can't handle relocation type (lazy).\n", +				_dl_dprintf(2, "%s: Can't handle relocation type (lazy).\n",  					_dl_progname);  #ifdef __SUPPORT_LD_DEBUG__  					_dl_dprintf(_dl_debug_file, "%s ", _dl_reltypes(reloc_type));  #endif  				if (symtab_index) -					_dl_dprintf(_dl_debug_file, "'%s'\n", strtab + symtab[symtab_index].st_name); +					_dl_dprintf(2, "'%s'\n", symname);  				_dl_exit(1);  		} @@ -223,6 +233,7 @@ _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_add  	int reloc_type;  	int symtab_index;  	char *strtab; +	char *symname;  	Elf32_Sym *symtab;  	ELF_RELOC *rpnt;  	Elf32_Addr *reloc_addr; @@ -234,7 +245,8 @@ _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_add  	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);  	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); - +	symname = strtab + symtab[symtab_index].st_name; +	  	for (i = 0; i < rel_size; i++, rpnt++) {  		reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + (Elf32_Addr) rpnt->r_offset);  		reloc_type = ELF32_R_TYPE(rpnt->r_info); @@ -252,8 +264,8 @@ _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_add  			if (symtab[symtab_index].st_shndx != SHN_UNDEF && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_LOCAL)  				symbol_addr = (Elf32_Addr) tpnt->loadaddr;  			else -				symbol_addr = (Elf32_Addr) _dl_find_hash(strtab + symtab[symtab_index].st_name, -					tpnt->symbol_scope, (reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), 0); +				symbol_addr = (Elf32_Addr) _dl_find_hash(symname, tpnt->symbol_scope, +					(reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), 0);  			/*  			 * We want to allow undefined references to weak symbols - this @@ -261,8 +273,7 @@ _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_add  			 * symbols here, so all bases should be covered.  			 */  			if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) { -				_dl_dprintf(_dl_debug_file, "%s: Can't resolve '%s'\n", -					_dl_progname, strtab + symtab[symtab_index].st_name); +				_dl_dprintf(2, "%s: Can't resolve '%s'\n", _dl_progname, symname);  				goof++;  			} @@ -306,12 +317,12 @@ _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long rel_add  			case R_CRIS_NONE:  				break;  			default: -				_dl_dprintf(_dl_debug_file, "%s: Can't handle relocation type ", _dl_progname); +				_dl_dprintf(2, "%s: Can't handle relocation type ", _dl_progname);  #ifdef __SUPPORT_LD_DEBUG__  				_dl_dprintf(_dl_debug_file, "%s\n", _dl_reltypes(reloc_type));  #endif  				if (symtab_index) { -					_dl_dprintf(_dl_debug_file, "'%s'\n", strtab + symtab[symtab_index].st_name); +					_dl_dprintf(2, "'%s'\n", symname);  					return -1;  				}  		} @@ -337,6 +348,7 @@ _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, unsigne  	int goof;  	int symtab_index;  	char *strtab; +	char *symname;  	struct elf_resolve *tpnt;  	Elf32_Sym *symtab;  	ELF_RELOC *rpnt; @@ -351,6 +363,7 @@ _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, unsigne  	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);  	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); +	symname = strtab + symtab[symtab_index].st_name;  	for (i = 0; i < rel_size; i++, rpnt++) {  		reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + (Elf32_Addr) rpnt->r_offset); @@ -366,16 +379,13 @@ _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, unsigne  			continue;  		if (symtab_index) { -			if (tpnt->libtype == program_interpreter &&  -				_dl_symbol(strtab + symtab[symtab_index].st_name)) +			if (tpnt->libtype == program_interpreter && _dl_symbol(symname))  				continue; -			symbol_addr = (Elf32_Addr) _dl_find_hash(strtab +  -				symtab[symtab_index].st_name, xpnt->next, NULL, 1); +			symbol_addr = (Elf32_Addr) _dl_find_hash(symname, xpnt->next, NULL, 1);  			if (!symbol_addr) { -				_dl_dprintf(_dl_debug_file, "%s: Can't resolv symbol '%s'\n", -					_dl_progname, strtab + symtab[symtab_index].st_name); +				_dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);  				goof++;  			}  		} diff --git a/ldso/ldso/cris/ld_sysdep.h b/ldso/ldso/cris/ld_sysdep.h index e915bf600..cf36752fb 100644 --- a/ldso/ldso/cris/ld_sysdep.h +++ b/ldso/ldso/cris/ld_sysdep.h @@ -11,11 +11,11 @@  /*   * Initialization sequence for a GOT.   */ -#define INIT_GOT(GOT_BASE,MODULE) 				\ -{                               				\ -	 GOT_BASE[1] = (unsigned long) MODULE; 			\ -	 GOT_BASE[2] = (unsigned long) _dl_linux_resolve; 	\ -}  +#define INIT_GOT(GOT_BASE,MODULE)				\ +{								\ +	GOT_BASE[1] = (unsigned long) MODULE; 			\ +	GOT_BASE[2] = (unsigned long) _dl_linux_resolve; 	\ +}  /*   * Here is a macro to perform a relocation.  This is only used when @@ -24,38 +24,39 @@   * SYMBOL is the symbol involved in the relocation, and LOAD is the   * load address.   */ -#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD)			\ -	switch (ELF32_R_TYPE((RELP)->r_info)) {           			\ -		case R_CRIS_GLOB_DAT:						\ -		case R_CRIS_JUMP_SLOT:						\ -		case R_CRIS_32:							\ -			*REL = SYMBOL;						\ -			break;							\ -		case R_CRIS_16_PCREL:						\ +#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD)		\ +	switch (ELF32_R_TYPE((RELP)->r_info)) {				\ +		case R_CRIS_GLOB_DAT:					\ +		case R_CRIS_JUMP_SLOT:					\ +		case R_CRIS_32:						\ +			*REL = SYMBOL;					\ +			break;						\ +		case R_CRIS_16_PCREL:					\  			*(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2;	\ -			break;							\ -		case R_CRIS_32_PCREL:						\ -			*REL = SYMBOL + (RELP)->r_addend - *REL - 4;		\ -			break;							\ -		case R_CRIS_NONE:						\ -			break;							\ -		case R_CRIS_RELATIVE:						\ -			*REL = (unsigned long) LOAD + (RELP)->r_addend;		\ -			break;							\ -		default:							\ -			_dl_exit(1);						\ -			break;							\ -	}  +			break;						\ +		case R_CRIS_32_PCREL:					\ +			*REL = SYMBOL + (RELP)->r_addend - *REL - 4;	\ +			break;						\ +		case R_CRIS_NONE:					\ +			break;						\ +		case R_CRIS_RELATIVE:					\ +			*REL = (unsigned long) LOAD + (RELP)->r_addend;	\ +			break;						\ +		default:						\ +			_dl_exit(1);					\ +			break;						\ +	}  /*   * Transfer control to the user's application once the dynamic loader   * is done. This routine has to exit the current function, then call   * _dl_elf_main.   */ -#define START() __asm__ volatile ("moveq 0,$r8\n\t -								   move $r8,$srp\n\t -								   move.d %1,$sp\n\t -								   jump %0\n\t" : : "r" (_dl_elf_main), "r" (args)) +#define START() __asm__ volatile ("moveq 0,$r8\n\t" \ +				  "move $r8,$srp\n\t" \ +				  "move.d %1,$sp\n\t" \ +				  "jump %0\n\t" \ +				  : : "r" (_dl_elf_main), "r" (args))  /* Defined some magic numbers that this ld.so should accept. */  #define MAGIC1 EM_CRIS @@ -66,41 +67,41 @@ struct elf_resolve;  extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);  /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ -static inline unsigned long  -cris_mod(unsigned long m, unsigned long p)  +static inline unsigned long +cris_mod(unsigned long m, unsigned long p)  {  	unsigned long i, t, inc; -         -	i = p;  + +	i = p;  	t = 0; -        while (!(i & (1 << 31))) { -                i <<= 1; -                t++; -        } -	 -        t--; -         +	while (!(i & (1 << 31))) { +		i <<= 1; +		t++; +	} + +	t--; +  	for (inc = t; inc > 2; inc--) { -                i = p << inc; -		 -                if (i & (1 << 31)) -                        break; -			 -                while (m >= i) { -                        m -= i; -                        i <<= 1; -                        if (i & (1 << 31)) -                                break; -                        if (i < p) -                                break; -                } -        } -	 -        while (m >= p) -                m -= p; - -        return m; +		i = p << inc; + +		if (i & (1 << 31)) +			break; + +		while (m >= i) { +			m -= i; +			i <<= 1; +			if (i & (1 << 31)) +				break; +			if (i < p) +				break; +		} +	} + +	while (m >= p) +		m -= p; + +	return m;  }  #define do_rem(result, n, base) result = cris_mod(n, base); | 
