#include #include "dynlink.h" #ifdef SHARED #ifndef START #define START "_dlstart" #endif #include "crt_arch.h" __attribute__((__visibility__("hidden"))) void _dlstart_c(size_t *sp, size_t *dynv) { size_t i, aux[AUX_CNT], dyn[DYN_CNT]; int argc = *sp; char **argv = (void *)(sp+1); for (i=argc+1; argv[i]; i++); size_t *auxv = (void *)(argv+i+1); for (i=0; ip_type == PT_DYNAMIC) { base = (void *)((size_t)dynv - ph->p_vaddr); break; } } } /* MIPS uses an ugly packed form for GOT relocations. Since we * can't make function calls yet and the code is tiny anyway, * it's simply inlined here. */ if (NEED_MIPS_GOT_RELOCS) { size_t local_cnt = 0; size_t *got = (void *)(base + dyn[DT_PLTGOT]); for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO) local_cnt = dynv[i+1]; for (i=0; i 4096; size_t naddends = too_many_addends ? 1 : symbolic_rel_cnt; size_t addends[naddends]; size_t *paddends = too_many_addends ? 0 : addends; const char *strings = (void *)(base + dyn[DT_STRTAB]); const Sym *syms = (void *)(base + dyn[DT_SYMTAB]); /* Call dynamic linker stage-2, __dls2 */ for (i=0; ;i++) { const char *s = strings + syms[i].st_name; if (s[0]=='_' && s[1]=='_' && s[2]=='d' && s[3]=='l' && s[4]=='s' && s[5]=='2' && !s[6]) break; } ((stage2_func)(base + syms[i].st_value))(base, paddends); /* Call dynamic linker stage-3, __dls3 */ for (i=0; ;i++) { const char *s = strings + syms[i].st_name; if (s[0]=='_' && s[1]=='_' && s[2]=='d' && s[3]=='l' && s[4]=='s' && s[5]=='3' && !s[6]) break; } ((stage3_func)(base + syms[i].st_value))(sp); } #endif