summaryrefslogtreecommitdiff
path: root/ldso/ldso/sparc/sysdep.h
blob: 1d4c0354f25769ca2d8a2b50c8d7eb4f13ec9a2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

/*
 * Various assmbly language/system dependent  hacks that are required
 * so that we can minimize the amount of platform specific code.
 */
#define LINUXBIN

/*
 * Define this if the system uses RELOCA.
 */
#define ELF_USES_RELOCA

/*
 * Get the address of the Global offset table.  This must be absolute, not
 * relative.
 */
#define GET_GOT(X)     __asm__("\tmov %%l7,%0\n\t" : "=r" (X))

/*
 * Get a pointer to the argv array.  On many platforms this can be just
 * the address if the first argument, on other platforms we need to
 * do something a little more subtle here.  We assume that argc is stored
 * at the word just below the argvp that we return here.
 */
#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP));

/*
 * Initialization sequence for a GOT.  For the Sparc, this points to the
 * PLT, and we need to initialize a couple of the slots.  The PLT should
 * look like:
 *
 *		save %sp, -64, %sp
 *		call _dl_linux_resolve
 *		nop
 *		.word implementation_dependent
 */
#define INIT_GOT(GOT_BASE,MODULE) \
{				\
   GOT_BASE[0] = 0x9de3bfc0;  /* save %sp, -64, %sp */	\
   GOT_BASE[1] = 0x40000000 | (((unsigned int) _dl_linux_resolve - (unsigned int) GOT_BASE - 4) >> 2);	\
   GOT_BASE[2] = 0x01000000; /* nop */ 			\
   GOT_BASE[3] = (int) MODULE;					\
}

/*
 * Here is a macro to perform a relocation.  This is only used when
 * bootstrapping the dynamic loader.
 */
#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
	switch(ELF32_R_TYPE((RELP)->r_info)) {		\
	case R_SPARC_32:				\
	  *REL = SYMBOL + (RELP)->r_addend;		\
	  break;					\
	case R_SPARC_GLOB_DAT:				\
	  *REL = SYMBOL + (RELP)->r_addend;		\
	  break;					\
	case R_SPARC_JMP_SLOT:				\
	  REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff);	\
	  REL[2] = 0x81c06000 | (SYMBOL & 0x3ff);	\
	  break;					\
	case R_SPARC_NONE:				\
	  break;					\
        case R_SPARC_WDISP30:				\
          break;                                        \
	case R_SPARC_RELATIVE:				\
	  *REL += (unsigned int) LOAD + (RELP)->r_addend; \
	  break;					\
	default:					\
	  _dl_exit(1);					\
	}


/*
 * Transfer control to the user's application, once the dynamic loader
 * is done.  The crt calls atexit with $g1 if not null, so we need to
 * ensure that it contains NULL.
 */

#define START()		\
	__asm__ volatile ( \
	                   "add %%g0,%%g0,%%g1\n\t" \
			   "jmpl %0, %%o7\n\t"	\
			   "restore %%g0,%%g0,%%g0\n\t" \
		    	: /*"=r" (status) */ :	\
		    	  "r" (_dl_elf_main): "g1", "o0", "o1")



/* Here we define the magic numbers that this dynamic loader should accept */

#define MAGIC1 EM_SPARC
#undef  MAGIC2
/* Used for error messages */
#define ELF_TARGET "Sparc"

#ifndef COMPILE_ASM
extern unsigned int _dl_linux_resolver(unsigned int reloc_entry,
					unsigned int * i);
#endif

/*
 * Define this if you want a dynamic loader that works on Solaris.
 */
#define SOLARIS_COMPATIBLE

/*
 * Define this because we do not want to call .udiv in the library.
 * Change on the plans -miguel:
 * We just statically link against .udiv.  This is required
 * if we want to be able to run on Sun4c machines.
 */

/* We now link .urem against this one */
#ifdef USE_V8
#define do_rem(result,n,base) ({ \
volatile int __res; \
__asm__("mov %%g0,%%Y\n\t" \
	"sdiv %2,%3,%%l6\n\t" \
	 "smul %%l6,%3,%%l6\n\t" \
	 "sub  %2,%%l6,%0\n\t" \
	 :"=r" (result),"=r" (__res):"r" (n),"r"(base) : "l6" ); __res; })
#else
#define do_rem(a,b,c) a = _dl_urem (b,c);
#endif
/*
 * dbx wants the binder to have a specific name.  Mustn't disappoint it.
 */
#ifdef SOLARIS_COMPATIBLE
#define _dl_linux_resolve _elf_rtbndr
#endif