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
|
#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);
}
}
|