OSDN Git Service

Cope with gcc 3.4's more aggressive persuit of attribute unused
[uclinux-h8/uClibc.git] / ldso / ldso / powerpc / dl-startup.h
1 /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
2  * will work as expected and cope with whatever platform specific wierdness is
3  * needed for this architecture.  */
4
5 /* Overrive the default _dl_boot function, and replace it with a bit of asm.
6  * Then call the real _dl_boot function, which is now named _dl_boot2. */
7
8 asm("" \
9 "       .text\n"                        \
10 "       .globl  _dl_boot\n"             \
11 "_dl_boot:\n"                           \
12 "       mr      3,1\n"          \
13 "       li      4,0\n"                  \
14 "       addi    1,1,-16\n"              \
15 "       stw     4,0(1)\n"               \
16 "       bl      _dl_boot2\n"            \
17 ".previous\n"                           \
18 );
19
20 #define DL_BOOT(X) static void __attribute_used__ _dl_boot2(X)
21
22 /*
23  * Get a pointer to the argv array.  On many platforms this can be just
24  * the address if the first argument, on other platforms we need to
25  * do something a little more subtle here.
26  */
27 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
28
29 /*
30  * Here is a macro to perform a relocation.  This is only used when
31  * bootstrapping the dynamic loader.  RELP is the relocation that we
32  * are performing, REL is the pointer to the address we are relocating.
33  * SYMBOL is the symbol involved in the relocation, and LOAD is the
34  * load address.
35  */
36 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
37         {int type=ELF32_R_TYPE((RELP)->r_info);         \
38          Elf32_Addr finaladdr=(SYMBOL)+(RELP)->r_addend;\
39         if (type==R_PPC_RELATIVE) {                     \
40                 *REL=(Elf32_Word)(LOAD)+(RELP)->r_addend;\
41         } else if (type==R_PPC_JMP_SLOT) {              \
42                 Elf32_Sword delta=finaladdr-(Elf32_Word)(REL);\
43                 *REL=OPCODE_B(delta);                   \
44         } else if (type==R_PPC_ADDR32) {                \
45                 *REL=finaladdr;                         \
46         } else {                                        \
47           _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));   \
48         }                                               \
49         PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL);        \
50         }
51 /*
52  * Transfer control to the user's application, once the dynamic loader
53  * is done.  This routine has to exit the current function, then
54  * call the _dl_elf_main function.
55  */
56
57 /*
58  * Use "b"(Address base register) operand for %1 since "b" excludes
59  * r0 which is important for the addi instruction in this case. 
60  */
61 #define START()         \
62         __asm__ volatile ( \
63                     "addi 1,%1,0\n\t" \
64                     "mtlr %0\n\t" \
65                     "blrl\n\t"  \
66                     : : "r" (_dl_elf_main), "b" (args))
67
68
69