1 /* Copyright (C) 2010 Texas Instruments Incorporated
2 * Contributed by Mark Salter <msalter@redhat.com>
4 * Borrowed heavily from frv arch:
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
13 _dl_start (unsigned placeholder, \
14 struct elf32_dsbt_loadmap *dl_boot_progmap, \
15 struct elf32_dsbt_loadmap *dl_boot_ldsomap, \
16 Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
20 * On entry, the kernel has set up the stack thusly:
27 * (4*(argc+3))(sp) NULL
28 * (4*(argc+4))(sp) envp[0]
32 * Register values are unspecified, except:
34 * B4 --> executable loadmap address
35 * A6 --> interpreter loadmap address
36 * B6 --> dynamic section address
37 * B14 --> our DP setup by kernel
39 * NB: DSBT index is always 0 for the executable
40 * and 1 for the interpreter
47 " STW .D2T2 B14, *+B14[1]\n"
48 " ADD .D1X B15,8,A8\n"
49 " ADDKPC .S2 ret_from_dl,B3,2\n"
52 " || LDW .D2T2 *+B14[0],B14\n"
53 " ADDKPC .S2 __dl_fini,B0,0\n"
59 " LDW .D2T2 *+B14[1],B14\n"
61 " LDW .D2T1 *+B14($GOT(_dl_fini)), A0\n"
63 " BNOP .S2X A0, 5\n");
79 * Get a pointer to the argv array. On many platforms this can be just
80 * the address of the first argument, on other platforms we need to
81 * do something a little more subtle here.
83 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS) + 1)
85 struct elf32_dsbt_loadmap;
88 * Here is a macro to perform a relocation. This is only used when
89 * bootstrapping the dynamic loader. RELP is the relocation that we
90 * are performing, REL is the pointer to the address we are relocating.
91 * SYMBOL is the symbol involved in the relocation, and LOAD is the
94 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
95 switch(ELF32_R_TYPE((RELP)->r_info)){ \
96 case R_C6000_ABS_L16: \
98 unsigned int opcode = *(REL); \
99 unsigned int v = (SYMBOL) + (RELP)->r_addend; \
100 opcode &= ~0x7fff80; \
101 opcode |= ((v & 0xffff) << 7); \
105 case R_C6000_ABS_H16: \
107 unsigned int opcode = *(REL); \
108 unsigned int v = (SYMBOL) + (RELP)->r_addend; \
109 opcode &= ~0x7fff80; \
110 opcode |= ((v >> 9) & 0x7fff80); \
114 case R_C6000_ABS32: \
115 *(REL) = (SYMBOL) + (RELP)->r_addend; \
121 extern void __c6x_cache_sync(unsigned long start, unsigned long end)