コード例 #1
0
static int
relocate_rela(image_t *rootImage, image_t *image, Elf32_Rela *rel, int rel_len,
	SymbolLookupCache* cache)
{
	int i;
	addr_t S;
	addr_t final_val;

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

	for (i = 0; i * (int)sizeof(Elf32_Rel) < rel_len; i++) {
		unsigned type = ELF32_R_TYPE(rel[i].r_info);

		switch (type) {
			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:
			{
				Elf32_Sym *sym;
				status_t status;
				sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));

				status = resolve_symbol(rootImage, image, sym, cache, &S);
				if (status < B_OK) {
					TRACE(("resolve symbol \"%s\" returned: %ld\n",
						SYMNAME(image, sym), status));
					printf("resolve symbol \"%s\" returned: %ld\n",
						SYMNAME(image, sym), status);
					return status;
				}
			}
		}
		switch (type) {
			case R_68K_NONE:
				continue;
			case R_68K_32:
				write_32(P, S + A);
				break;
			case R_68K_16:
				if (write_16_check(P, S + A))
					break;
				TRACE(("R_68K_16 overflow\n"));
				return B_BAD_DATA;

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

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

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

			case R_68K_PC8:
				if (write_8(P, (S + A - P)))
					break;
				TRACE(("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;
				TRACE(("R_68K_GOT16 overflow\n"));
				return B_BAD_DATA;

			case R_68K_GOT8:
				REQUIRE_GOT;
				if (write_8_check(P, (G + A - P)))
					break;
				TRACE(("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;
				TRACE(("R_68K_GOT16 overflow\n"));
				return B_BAD_DATA;

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

			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;
				TRACE(("R_68K_PLT16 overflow\n"));
				return B_BAD_DATA;

			case R_68K_PLT8:
				REQUIRE_PLT;
				if (write_8_check(P, (L + A - P)))
					break;
				TRACE(("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;
				TRACE(("R_68K_PLT16O overflow\n"));
				return B_BAD_DATA;

			case R_68K_PLT8O:
				REQUIRE_PLT;
				if (write_8_check(P, (L + A)))
					break;
				TRACE(("R_68K_PLT8O overflow\n"));
				return B_BAD_DATA;
			case R_386_GOT32:
				final_val = G + A;
				break;
			case R_386_PLT32:
				final_val = L + A - (addr_t)P;
				break;
#endif
			case R_68K_COPY:
				/* what ? */
				continue;
			case R_68K_GLOB_DAT:
				write_32(P, S/* + A*/);
				break;
			case R_68K_JMP_SLOT:
				//XXX ? write_32(P, (G + A));
				write_32(P, S);
				break;
#if 0
			case R_386_JMP_SLOT:
				write_32(P, S);
				break;
#endif
			case R_68K_RELATIVE:
				write_32(P, B + A);
				break;

#if 0
			case R_386_GOTOFF:
				final_val = S + A - GOT;
				break;
			case R_386_GOTPC:
				final_val = GOT + A - P;
				break;
#endif
			default:
				TRACE(("unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info)));
				return B_NOT_ALLOWED;
		}

		*P = final_val;
	}

# undef P
# undef A
# undef B

	return B_NO_ERROR;
}
コード例 #2
0
ファイル: arch_elf.cpp プロジェクト: SummerSnail2014/haiku
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;
}