2 * Architecture specific code used by dl-startup.c
4 * Copyright (C) 2005-2007 Atmel Corporation
6 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
9 /* This is the library loader's main entry point. Let _dl_boot2 do its
10 * initializations and jump to the application's entry point
14 " .type _start,@function\n"
17 /* All arguments are on the stack initially */
20 /* Returns user entry point in r12. Save it. */
22 /* We're PIC, so get the Global Offset Table */
26 /* Adjust argc and argv according to _dl_skip_args */
27 " ld.w r1, r6[_dl_skip_args@got]\n"
31 " add sp, sp, r1 << 2\n"
33 /* Load the finalizer function */
34 " ld.w r12, r6[_dl_fini@got]\n"
35 /* Jump to the user's entry point */
40 " .long .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
41 " .size _start, . - _start\n"
44 /* Get a pointer to the argv array. On many platforms this can be just
45 * the address of the first argument, on other platforms we need to
46 * do something a little more subtle here. */
47 #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
50 /* We can't call functions before the GOT has been initialized */
51 #define NO_FUNCS_BEFORE_BOOTSTRAP
54 * Relocate the GOT during dynamic loader bootstrap. This will add
55 * the load address to all entries in the GOT, which is necessary
56 * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
59 static __always_inline
60 void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
63 register Elf32_Addr *__r6 __asm__("r6");
64 Elf32_Addr *got = __r6;
66 nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
67 for (i = 2; i < nr_got; i++)
68 got[i] += tpnt->loadaddr;
71 #define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
73 /* Handle relocation of the symbols in the dynamic loader. */
74 static __always_inline
75 void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
76 unsigned long symbol_addr,
77 unsigned long load_addr, Elf32_Sym *symtab)
79 switch(ELF_R_TYPE(rpnt->r_info)) {
82 case R_AVR32_GLOB_DAT:
83 case R_AVR32_JMP_SLOT:
84 *reloc_addr = symbol_addr;
86 case R_AVR32_RELATIVE:
87 SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
88 SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
89 SEND_STDERR_DEBUG(" + ");
90 SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
91 *reloc_addr = load_addr + rpnt->r_addend;
94 SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
95 SEND_NUMBER_STDERR(ELF_R_TYPE(rpnt->r_info), 1);
96 SEND_STDERR("REL, SYMBOL, LOAD: ");
97 SEND_ADDRESS_STDERR(reloc_addr, 0);
99 SEND_ADDRESS_STDERR(symbol_addr, 0);
101 SEND_ADDRESS_STDERR(load_addr, 1);