]> git.ipfire.org Git - thirdparty/glibc.git/blame - ports/sysdeps/tile/dl-start.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / ports / sysdeps / tile / dl-start.S
CommitLineData
d4697bc9 1/* Copyright (C) 2011-2014 Free Software Foundation, Inc.
63d143a2
CM
2 This file is part of the GNU C Library.
3 Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
ab84e3ff
PE
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
63d143a2
CM
18
19#include <sysdep.h>
20
21 /* Get address of "sym" in "reg" assuming r51 holds ".Llink". */
22 .macro pic_addr reg, sym
23#ifdef __tilegx__
24 moveli \reg, hw1_last(\sym - .Llink)
25 shl16insli \reg, \reg, hw0(\sym - .Llink)
26 ADD_PTR \reg, r51, \reg
27#else
28 ADDLI_PTR \reg, r51, lo16(\sym - .Llink)
29 auli \reg, \reg, ha16(\sym - .Llink)
30#endif
31 .endm
32
33 .text
34ENTRY (_start)
35 /* Linux starts us with sp pointing at the conventional Elf layout,
36 but we need to allow two 'caller' words for our ABI convention. */
37 {
38 move r52, sp
39 andi sp, sp, -8
40 }
41 cfi_def_cfa_register (r52)
42 {
43 /* Point sp at base of ABI area; point r4 to the caller-sp word. */
44 ADDI_PTR sp, sp, -(2 * REGSIZE)
45 ADDI_PTR r4, sp, -REGSIZE
46 }
47 {
48 /* Save zero for caller sp in our 'caller' save area, and make
49 sure lr has a zero value, to limit backtraces. */
50 move lr, zero
51 ST r4, zero
52 }
53 {
54 move r0, r52
55 jal _dl_start
56 }
57 /* Save returned start of user program address for later. */
58 move r50, r0
59
60 /* See if we were invoked explicitly with the dynamic loader,
61 in which case we have to adjust the argument vector. */
62 lnk r51; .Llink:
63 pic_addr r4, _dl_skip_args
64 LD4U r4, r4
65 BEQZT r4, .Lno_skip
66
67 /* Load the argc word at the initial sp and adjust it.
68 We basically jump "sp" up over the first few argv entries
69 and write "argc" a little higher up in memory, to be the
70 base of the new kernel-initialized stack area. */
71 LD_PTR r0, r52
72 {
73 sub r0, r0, r4
74 SHL_PTR_ADD r52, r4, r52
75 }
76 {
77 ST_PTR r52, r0
78 SHL_PTR_ADD sp, r4, sp
79 }
bcfe09d2 80 andi sp, sp, -8
63d143a2
CM
81
82.Lno_skip:
83 /* Call_dl_init (_dl_loaded, argc, argv, envp). See elf/start.s
84 for the layout of memory here; r52 is pointing to "+0". */
85 pic_addr r0, _rtld_local
86 {
87 LD_PTR r1, r52 /* load argc in r1 */
88 ADDLI_PTR r2, r52, __SIZEOF_POINTER__ /* point r2 at argv */
89 }
90 {
91 LD_PTR r0, r0 /* yields _rtld_global._ns_loaded */
92 addi r3, r1, 1
93 move lr, zero
94 }
95 {
96 SHL_PTR_ADD r3, r3, r2 /* point r3 at envp */
97 jal _dl_init_internal
98 }
99
100 /* Call user program whose address we saved in r50.
101 We invoke it just like a static binary, but with _dl_fini
102 in r0 so we can distinguish. */
103
104 pic_addr r0, _dl_fini
105 move lr, zero
106 {
107 move sp, r52
108 jr r50
109 }
110
111 /* Tell backtracer to give up (_start has no caller). */
112 info 2 /* INFO_OP_CANNOT_BACKTRACE */
113
114END (_start)