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
|
/*
* Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
*/
/*
* vineetg: Refactoring/cleanup of loader entry point
* Removed 6 useless insns
* Joern Improved it even further:
* -better insn scheduling
* -no need for conditional code for _dl_skip_args
* -use of assembler .&2 expressions vs. @gotpc refs (avoids need for GP)
*
* What this code does:
* -ldso starts execution here when kernel returns from execve()
* -calls into generic ldso entry point _dl_start( )
* -optionally adjusts argc for executable if exec passed as cmd
* -calls into app main with address of finaliser
*/
__asm__(
".section .text \n"
".align 4 \n"
".global _start \n"
".hidden _start \n"
".type _start,@function \n"
"_start: \n"
" ; ldso entry point, returns app entry point \n"
" bl.d _dl_start \n"
" mov_s r0, sp ; pass ptr to aux vector tbl \n"
" ; If ldso ran as cmd with executable file nm as arg \n"
" ; skip the extra args calc by dl_start() \n"
" ld_s r1, [sp] ; orig argc from aux-vec Tbl \n"
#ifdef __UCLIBC_HAS_THREADS_NATIVE__
" ld r12, [pcl, _dl_skip_args@pcl] \n"
" add r2, pcl, _dl_fini@pcl ; finalizer \n"
#else
" add r12, pcl, _dl_skip_args-.+(.&2) \n"
" ld r12, [r12] \n"
" add r2, pcl, _dl_fini-.+(.&2) ; finalizer \n"
#endif
" add2 sp, sp, r12 ; discard argv entries from stack\n"
" sub_s r1, r1, r12 ; adjusted argc, on stack \n"
" st_s r1, [sp] \n"
" j_s.d [r0] ; app entry point \n"
" mov_s r0, r2 ; ptr to finalizer _dl_fini \n"
".size _start,.-_start \n"
".previous \n"
);
/*
* 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.
*/
#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS + 1)
/*
* Dynamic loader bootstrapping:
* Since we don't modify text at runtime, these can only be data relos
* (so safe to assume that they are word aligned).
* And also they HAVE to be RELATIVE relos only
* @RELP is the relo entry being processed
* @REL is the pointer to the address we are relocating.
* @SYMBOL is the symbol involved in the relocation
* @LOAD is the load address.
*/
#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
do { \
int type = ELF32_R_TYPE((RELP)->r_info); \
if (likely(type == R_ARC_RELATIVE)) \
*REL += (unsigned long) LOAD; \
else \
_dl_exit(1); \
}while(0)
/*
* This will go away once we have DT_RELACOUNT
*/
#define ARCH_NEEDS_BOOTSTRAP_RELOCS
/* we dont need to spit out argc, argv etc for debugging */
#define NO_EARLY_SEND_STDERR 1
|