Esempio n. 1
0
static void load_adjustCopyGotEntry(const char *name,uintptr_t copyAddr) {
	uintptr_t address;
	/* go through all libraries and copy the address of the object (copy-relocated) to
	 * the corresponding GOT-entry. this ensures that all DSO's use the same object */
	for(sSharedLib *l = libs; l != NULL; l = l->next) {
		/* don't do that in the executable */
		if(!l->isDSO)
			continue;

		if(lookup_byNameIn(l,name,&address)) {
			/* TODO we should store DT_REL and DT_RELSZ */
			sElfRel *rel = (sElfRel*)load_getDyn(l->dyn,DT_REL);
			if(rel) {
				size_t x,relCount = load_getDyn(l->dyn,DT_RELSZ);
				relCount /= sizeof(sElfRel);
				rel = (sElfRel*)((uintptr_t)rel + l->loadAddr);
				for(x = 0; x < relCount; x++) {
					if(ELF_R_TYPE(rel[x].r_info) == R_GLOB_DAT) {
						uint symIndex = ELF_R_SYM(rel[x].r_info);
						if(l->dynsyms[symIndex].st_value + l->loadAddr == address) {
							uintptr_t *ptr = (uintptr_t*)(rel[x].r_offset + l->loadAddr);
							*ptr = copyAddr;
							break;
						}
					}
				}
			}

			sElfRela *rela = (sElfRela*)load_getDyn(l->dyn,DT_RELA);
			if(rela) {
				size_t x,relCount = load_getDyn(l->dyn,DT_RELASZ);
				relCount /= sizeof(sElfRela);
				rela = (sElfRela*)((uintptr_t)rela + l->loadAddr);
				for(x = 0; x < relCount; x++) {
					if(ELF_R_TYPE(rela[x].r_info) == R_GLOB_DAT) {
						uint symIndex = ELF_R_SYM(rela[x].r_info);
						if(l->dynsyms[symIndex].st_value + l->loadAddr == address) {
							uintptr_t *ptr = (uintptr_t*)(rela[x].r_offset + l->loadAddr);
							*ptr = copyAddr;
							break;
						}
					}
				}
			}
		}
	}
}
Esempio n. 2
0
File: init.c Progetto: jarn0x/Escape
static void load_initLib(sSharedLib *l) {
    /* already initialized? */
    if(l->initialized)
        return;

    /* first go through the dependencies */
    for(sDep *dl = l->deps; dl != NULL; dl = dl->next)
        load_initLib(dl->lib);

    /* if its not the executable, call the init-function */
    if(l->isDSO) {
        uintptr_t initAddr = (uintptr_t)load_getDyn(l->dyn,DT_INIT);
        if(initAddr) {
            DBGDL("Calling _init of %s...\n",l->name);
            void (*initFunc)(void) = (void (*)(void))(initAddr + l->loadAddr);
            initFunc();
        }
    }

    l->initialized = true;
}
Esempio n. 3
0
static void load_relocLib(sSharedLib *l) {
	ElfAddr *got;
	sElfRel *rel;

	/* already relocated? */
	if(l->relocated)
		return;

	/* first go through the dependencies; this may be required for the R_386_COPY-relocation */
	for(sDep *dl = l->deps; dl != NULL; dl = dl->next)
		load_relocLib(dl->lib);

	if(load_hasDyn(l->dyn,DT_TEXTREL))
		load_error("Unable to reloc library %s: requires a writable text segment\n",l->name);

	DBGDL("Relocating %s (loaded @ %p)\n",l->name,l->loadAddr ? l->loadAddr : l->textAddr);

	rel = (sElfRel*)load_getDyn(l->dyn,DT_REL);
	if(rel)
		load_relocDyn(l,rel,load_getDyn(l->dyn,DT_RELSZ),DT_REL);
	rel = (sElfRel*)load_getDyn(l->dyn,DT_RELA);
	if(rel)
		load_relocDyn(l,rel,load_getDyn(l->dyn,DT_RELASZ),DT_RELA);

	/* adjust addresses in PLT-jumps */
	if(l->jmprel) {
		load_relocDyn(l,(void*)((uintptr_t)l->jmprel - l->loadAddr),
			load_getDyn(l->dyn,DT_PLTRELSZ),l->jmprelType);
	}

	/* store pointer to library and lookup-function into GOT */
	got = (ElfAddr*)load_getDyn(l->dyn,DT_PLTGOT);
	DBGDL("GOT-Address of %s: %p\n",l->name,got);
	if(got) {
		got = (ElfAddr*)((uintptr_t)got + l->loadAddr);
		got[1] = (ElfAddr)l;
		got[2] = (ElfAddr)&lookup_resolveStart;
	}

	l->relocated = true;
	/* no longer needed */
	close(l->fd);
}