123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- /*
- * Copyright (C) 2013 Imagination Technologies Ltd.
- *
- * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
- */
- /*
- * This code fixes the stack pointer so that the dynamic linker
- * can find argc, argv and auxvt (Auxillary Vector Table).
- */
- __asm__ (
- " .text\n"
- " .global __start\n"
- " .type __start,@function\n"
- " .hidden __start\n"
- "_start:\n"
- "__start:\n"
- " MSETL [A0StP++],D0Ar4,D0Ar2\n"
- " MOV D1Ar1,D0Ar2\n"
- " CALLR D1RtP,__dl_start\n"
- " GETL D0Ar2,D1Ar1,[A0StP+#-(1*8)]\n"
- " GETL D0Ar4,D1Ar3,[A0StP+#-(2*8)]\n"
- " SUB A0StP,A0StP,#(2*8)\n"
- " MOV PC,D0Re0\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))
- /* Handle relocation of the symbols in the dynamic loader. */
- static inline
- void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
- unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab)
- {
- switch (ELF32_R_TYPE(rpnt->r_info)) {
- case R_METAG_GLOB_DAT:
- case R_METAG_JMP_SLOT:
- case R_METAG_ADDR32:
- *reloc_addr = symbol_addr;
- break;
- case R_METAG_RELATIVE:
- *reloc_addr = load_addr + rpnt->r_addend;
- break;
- case R_METAG_RELBRANCH:
- *reloc_addr = symbol_addr + rpnt->r_addend - *reloc_addr - 4;
- break;
- case R_METAG_NONE:
- break;
- default:
- _dl_exit(1);
- break;
- }
- }
|