summaryrefslogtreecommitdiff
path: root/ldso/ldso/csky/dl-startup.h
blob: 0a74ab69fe5e5d2978be3cea5fd25341496bfb1a (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
#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);
    }
}