int
arch_elf_relocate_rela(struct elf_image_info *image,
	struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len)
#endif
{
	int i;
	struct Elf32_Sym *sym;
	int vlErr;
	addr_t S = 0;   // symbol address
	addr_t R = 0;   // section relative symbol address

	addr_t G = 0;   // GOT address
	addr_t L = 0;   // PLT address

	#define P ((addr_t)(image->text_region.delta + rel[i].r_offset))
	#define A ((addr_t)rel[i].r_addend)
	#define B (image->text_region.delta)
	#warning ARM:define T correctly for thumb!!!
	#define	T 0

	// TODO: Get the GOT address!
	#define REQUIRE_GOT     \
		if (G == 0) {   \
			dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \
			return B_ERROR; \
		}

	// TODO: Get the PLT address!
	#define REQUIRE_PLT     \
	if (L == 0) {   \
		dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \
		return B_ERROR; \
	}

	for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) {
		#if CHATTY
		dprintf("looking at rel type %d, offset 0x%lx, "
		"sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info),
		rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend);
		#endif
		switch (ELF32_R_TYPE(rel[i].r_info)) {
		#warning ARM:ADDOTHERREL
			case R_ARM_GLOB_DAT:
				sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

				#ifdef _BOOT_MODE
				vlErr = boot_elf_resolve_symbol(image, sym, &S);
				#else
				vlErr = elf_resolve_symbol(image, sym, resolve_image, &S);
				#endif
				if (vlErr < 0) {
					dprintf("%s(): Failed to relocate "
						"entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, "
						"addend 0x%lx\n", __FUNCTION__, i,
						ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset,
						ELF32_R_SYM(rel[i].r_info), rel[i].r_addend);
					return vlErr;
				}
				break;
		}

		#warning ARM:ADDOTHERREL
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_ARM_GLOB_DAT:
				write_32(P, (S + A) | T);
				break;

			case R_ARM_NONE:
				break;

			default:
				dprintf("arch_elf_relocate_rela(): unhandled "
					"relocation type %d!\n", ELF32_R_TYPE(rel[i].r_info));
				return B_ERROR;
		}
	}

	#warning ARM: FIXME!!!!!!!
	return B_NO_ERROR;
}
int
arch_elf_relocate_rel(struct elf_image_info *image,
	struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength)
#endif
{
	addr_t S;
	addr_t A;
	addr_t P;
	addr_t finalAddress;
	addr_t *resolveAddress;
	int i;

	S = A = P = 0;

	for (i = 0; i * (int)sizeof(struct Elf32_Rel) < relLength; i++) {
		TRACE(("looking at rel type %s, offset 0x%lx\n",
			kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset));

		// calc S
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_ARM_JMP_SLOT:
			case R_ARM_GLOB_DAT:
			case R_ARM_ABS32:
			{
				struct Elf32_Sym *symbol;
				status_t status;

				symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

#ifdef _BOOT_MODE
				status = boot_elf_resolve_symbol(image, symbol, &S);
#else
				status = elf_resolve_symbol(image, symbol, resolveImage, &S);
#endif
				if (status < B_OK) {
#ifndef _BOOT_MODE
					TRACE(("failed relocating %s\n", SYMNAME(image, symbol)));
#endif
//IRA					return status;
					return B_OK;
				}
#ifndef _BOOT_MODE
				TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, symbol)));
#endif
			}
		}

		// calc A
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_ARM_ABS32:
			case R_ARM_RELATIVE:
				A = *(addr_t *)(image->text_region.delta + rel[i].r_offset);
				TRACE(("A %p\n", (void *)A));
				break;
		}

		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_ARM_NONE:
				continue;
			case R_ARM_RELATIVE:
				// B + A;
				finalAddress = image->text_region.delta + A;
				break;
			case R_ARM_JMP_SLOT:
			case R_ARM_GLOB_DAT:
				finalAddress = S;
				break;
			case R_ARM_ABS32:
				finalAddress = S + A;
				break;
			default:
				dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n",
					ELF32_R_TYPE(rel[i].r_info));
				return B_BAD_DATA;
		}

		resolveAddress = (addr_t *)(image->text_region.delta + rel[i].r_offset);
#ifndef _BOOT_MODE
		if (!is_in_image(image, (addr_t)resolveAddress)) {
			dprintf("arch_elf_relocate_rel: invalid offset %#lx\n",
				rel[i].r_offset);
			return B_BAD_ADDRESS;
		}
#endif
		*resolveAddress = finalAddress;
		TRACE(("-> offset %#lx = %#lx\n",
			(image->text_region.delta + rel[i].r_offset), finalAddress));
	}

	return B_NO_ERROR;
}
Exemple #3
0
int
arch_elf_relocate_rel(struct elf_image_info *image,
	struct elf_image_info *resolveImage, Elf32_Rel *rel, int relLength)
#endif
{
	elf_addr S;
	uint32 A;
	uint32 P;
	uint32 finalAddress;
	uint32 *resolveAddress;
	int i;

	S = A = P = 0;

	for (i = 0; i * (int)sizeof(Elf32_Rel) < relLength; i++) {
		TRACE(("looking at rel type %s, offset 0x%lx\n",
			kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset));

		// calc S
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_32:
			case R_386_PC32:
			case R_386_GLOB_DAT:
			case R_386_JMP_SLOT:
			case R_386_GOTOFF:
			{
				Elf32_Sym *symbol;
				status_t status;

				symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

#ifdef _BOOT_MODE
				status = boot_elf_resolve_symbol(image, symbol, &S);
#else
				status = elf_resolve_symbol(image, symbol, resolveImage, &S);
#endif
				if (status < B_OK)
					return status;
				TRACE(("S %p (%s)\n", (void *)S, SYMNAME(image, symbol)));
			}
		}
		// calc A
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_32:
			case R_386_PC32:
			case R_386_GOT32:
			case R_386_PLT32:
			case R_386_RELATIVE:
			case R_386_GOTOFF:
			case R_386_GOTPC:
				A = *(uint32 *)(image->text_region.delta + rel[i].r_offset);
				TRACE(("A %p\n", (void *)A));
				break;
		}
		// calc P
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_PC32:
			case R_386_GOT32:
			case R_386_PLT32:
			case R_386_GOTPC:
				P = image->text_region.delta + rel[i].r_offset;
				TRACE(("P %p\n", (void *)P));
				break;
		}

		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_NONE:
				continue;
			case R_386_32:
				finalAddress = S + A;
				break;
			case R_386_PC32:
				finalAddress = S + A - P;
				break;
			case R_386_RELATIVE:
				// B + A;
				finalAddress = image->text_region.delta + A;
				break;
			case R_386_JMP_SLOT:
			case R_386_GLOB_DAT:
				finalAddress = S;
				break;

			default:
				dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n",
					ELF32_R_TYPE(rel[i].r_info));
				return B_BAD_DATA;
		}

		resolveAddress = (uint32 *)(image->text_region.delta + rel[i].r_offset);
#ifndef _BOOT_MODE
		if (!is_in_image(image, (addr_t)resolveAddress)) {
			dprintf("arch_elf_relocate_rel: invalid offset %#lx\n",
				rel[i].r_offset);
			return B_BAD_ADDRESS;
		}
#endif
		*resolveAddress = finalAddress;
		TRACE(("-> offset %#lx (%#lx) = %#lx\n",
			(image->text_region.delta + rel[i].r_offset), rel[i].r_offset, finalAddress));
	}

	return B_NO_ERROR;
}
Exemple #4
0
int
arch_elf_relocate_rela(struct elf_image_info *image,
	struct elf_image_info *resolveImage, Elf64_Rela *rel, int relLength)
#endif
{
	for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) {
		int type = ELF64_R_TYPE(rel[i].r_info);
		int symIndex = ELF64_R_SYM(rel[i].r_info);
		Elf64_Addr symAddr = 0;

		// Resolve the symbol, if any.
		if (symIndex != 0) {
			Elf64_Sym* symbol = SYMBOL(image, symIndex);

			status_t status;
#ifdef _BOOT_MODE
			status = boot_elf_resolve_symbol(image, symbol, &symAddr);
#else
			status = elf_resolve_symbol(image, symbol, resolveImage, &symAddr);
#endif
			if (status < B_OK)
				return status;
		}

		// Address of the relocation.
		Elf64_Addr relocAddr = image->text_region.delta + rel[i].r_offset;

		// Calculate the relocation value.
		Elf64_Addr relocValue;
		switch (type) {
			case R_X86_64_NONE:
				continue;
			case R_X86_64_64:
				relocValue = symAddr + rel[i].r_addend;
				break;
			case R_X86_64_PC32:
				relocValue = symAddr + rel[i].r_addend - rel[i].r_offset;
				break;
			case R_X86_64_GLOB_DAT:
			case R_X86_64_JUMP_SLOT:
				relocValue = symAddr + rel[i].r_addend;
				break;
			case R_X86_64_RELATIVE:
				relocValue = image->text_region.delta + rel[i].r_addend;
				break;
			default:
				dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n",
					type);
				return B_BAD_DATA;
		}
#ifdef _BOOT_MODE
		boot_elf64_set_relocation(relocAddr, relocValue);
#else
		if (!is_in_image(image, relocAddr)) {
			dprintf("arch_elf_relocate_rela: invalid offset %#lx\n",
				rel[i].r_offset);
			return B_BAD_ADDRESS;
		}

		if (type == R_X86_64_PC32)
			*(Elf32_Addr *)relocAddr = relocValue;
		else
			*(Elf64_Addr *)relocAddr = relocValue;
#endif
	}

	return B_OK;
}
Exemple #5
0
int
arch_elf_relocate_rela(struct elf_image_info *image,
	struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len)
#endif
{
	int i;
	struct Elf32_Sym *sym;
	int vlErr;
	addr_t S = 0;	// symbol address
	addr_t R = 0;	// section relative symbol address

	addr_t G = 0;	// GOT address
	addr_t L = 0;	// PLT address

	#define P	((addr_t)(image->text_region.delta + rel[i].r_offset))
	#define A	((addr_t)rel[i].r_addend)
	#define B	(image->text_region.delta)

	// TODO: Get the GOT address!
	#define REQUIRE_GOT	\
		if (G == 0) {	\
			dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \
			return B_ERROR;	\
		}

	// TODO: Get the PLT address!
	#define REQUIRE_PLT	\
		if (L == 0) {	\
			dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \
			return B_ERROR;	\
		}

	for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) {
#if CHATTY
		dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n",
			ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend);
#endif
		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_68K_32:
			case R_68K_16:
			case R_68K_8:
			case R_68K_PC32:
			case R_68K_PC16:
			case R_68K_PC8:
			case R_68K_GLOB_DAT:
			case R_68K_JMP_SLOT:
				sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

#ifdef _BOOT_MODE
				vlErr = boot_elf_resolve_symbol(image, sym, &S);
#else
				vlErr = elf_resolve_symbol(image, sym, resolve_image, &S);
#endif
				if (vlErr < 0) {
					dprintf("%s(): Failed to relocate "
						"entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, "
						"addend 0x%lx\n", __FUNCTION__, i, ELF32_R_TYPE(rel[i].r_info),
						rel[i].r_offset, ELF32_R_SYM(rel[i].r_info),
						rel[i].r_addend);
					return vlErr;
				}
				break;
		}

		switch (ELF32_R_TYPE(rel[i].r_info)) {
			case R_68K_NONE:
				break;

			case R_68K_COPY:
				// TODO: Implement!
				dprintf("arch_elf_relocate_rela(): R_68K_COPY not yet "
					"supported!\n");
				return B_ERROR;

			case R_68K_32:
			case R_68K_GLOB_DAT:
				write_32(P, S + A);
				break;

			case R_68K_16:
				if (write_16_check(P, S + A))
					break;
dprintf("R_68K_16 overflow\n");
				return B_BAD_DATA;

			case R_68K_8:
				if (write_8_check(P, S + A))
					break;
dprintf("R_68K_8 overflow\n");
				return B_BAD_DATA;

			case R_68K_PC32:
				write_32(P, (S + A - P));
				break;

			case R_68K_PC16:
				if (write_16_check(P, (S + A - P)))
					break;
dprintf("R_68K_PC16 overflow\n");
				return B_BAD_DATA;

			case R_68K_PC8:
				if (write_8(P, (S + A - P)))
					break;
dprintf("R_68K_PC8 overflow\n");
				return B_BAD_DATA;

			case R_68K_GOT32:
				REQUIRE_GOT;
				write_32(P, (G + A - P));
				break;

			case R_68K_GOT16:
				REQUIRE_GOT;
				if (write_16_check(P, (G + A - P)))
					break;
dprintf("R_68K_GOT16 overflow\n");
				return B_BAD_DATA;

			case R_68K_GOT8:
				REQUIRE_GOT;
				if (write_8_check(P, (G + A - P)))
					break;
dprintf("R_68K_GOT8 overflow\n");
				return B_BAD_DATA;

			case R_68K_GOT32O:
				REQUIRE_GOT;
				write_32(P, (G + A));
				break;

			case R_68K_GOT16O:
				REQUIRE_GOT;
				if (write_16_check(P, (G + A)))
					break;
dprintf("R_68K_GOT16 overflow\n");
				return B_BAD_DATA;

			case R_68K_GOT8O:
				REQUIRE_GOT;
				if (write_8_check(P, (G + A)))
					break;
dprintf("R_68K_GOT8 overflow\n");
				return B_BAD_DATA;

			case R_68K_JMP_SLOT:
				write_32(P, (G + A));
				break;

			case R_68K_RELATIVE:
				write_32(P, B + A);
				break;

			case R_68K_PLT32:
				REQUIRE_PLT;
				write_32(P, (L + A - P));
				break;

			case R_68K_PLT16:
				REQUIRE_PLT;
				if (write_16_check(P, (L + A - P)))
					break;
dprintf("R_68K_PLT16 overflow\n");
				return B_BAD_DATA;

			case R_68K_PLT8:
				REQUIRE_PLT;
				if (write_8_check(P, (L + A - P)))
					break;
dprintf("R_68K_PLT8 overflow\n");
				return B_BAD_DATA;

			case R_68K_PLT32O:
				REQUIRE_PLT;
				write_32(P, (L + A));
				break;

			case R_68K_PLT16O:
				REQUIRE_PLT;
				if (write_16_check(P, (L + A)))
					break;
dprintf("R_68K_PLT16O overflow\n");
				return B_BAD_DATA;

			case R_68K_PLT8O:
				REQUIRE_PLT;
				if (write_8_check(P, (L + A)))
					break;
dprintf("R_68K_PLT8O overflow\n");
				return B_BAD_DATA;

			default:
				dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info));
				return B_ERROR;
		}
	}

	return B_NO_ERROR;
}
Exemple #6
0
int arch_elf_relocate_rel(struct elf_image_info *image, const char *sym_prepend,
	struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len)
{
	int i;
	struct Elf32_Sym *sym;
	int vlErr;
	addr_t S;
	addr_t A;
	addr_t P;
	addr_t final_val;

	S = A = P = 0;

	for(i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) {
		//dprintf("looking at rel type %d, offset 0x%x\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset);

		// calc S
		switch(ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_32:
			case R_386_PC32:
			case R_386_GLOB_DAT:
			case R_386_JMP_SLOT:
			case R_386_GOTOFF:
				sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

				vlErr = elf_resolve_symbol(image, sym, resolve_image, sym_prepend, &S);
                                if(vlErr<0) return vlErr;
				//dprintf("S 0x%x\n", S);
		}
		// calc A
		switch(ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_32:
			case R_386_PC32:
			case R_386_GOT32:
			case R_386_PLT32:
			case R_386_RELATIVE:
			case R_386_GOTOFF:
			case R_386_GOTPC:
				A = *(addr_t *)(image->regions[0].delta + rel[i].r_offset);
//					dprintf("A 0x%x\n", A);
				break;
		}
		// calc P
		switch(ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_PC32:
			case R_386_GOT32:
			case R_386_PLT32:
			case R_386_GOTPC:
				P = image->regions[0].delta + rel[i].r_offset;
//					dprintf("P 0x%x\n", P);
				break;
		}

		switch(ELF32_R_TYPE(rel[i].r_info)) {
			case R_386_NONE:
				continue;
			case R_386_32:
				final_val = S + A;
				break;
			case R_386_PC32:
				final_val = S + A - P;
				break;
			case R_386_RELATIVE:
				// B + A;
				final_val = image->regions[0].delta + A;
				break;
			case R_386_JMP_SLOT:
				final_val = S;
				//dprintf( "final = %lx\n", final_val );
				break;
			default:
				dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info));
				return ERR_NOT_ALLOWED;
		}
		*(addr_t *)(image->regions[0].delta + rel[i].r_offset) = final_val;
	}

	return NO_ERROR;
}