Exemplo n.º 1
0
Arquivo: lisp.c Projeto: qyqx/wisp
object_t *symbol_name (object_t * lst)
{
  DOC ("Return symbol name as string.");
  REQ (lst, 1, c_sym ("symbol-name"));
  if (!SYMBOLP (CAR (lst)))
    THROW (wrong_type, UPREF (CAR (lst)));
  return c_strs (xstrdup (SYMNAME (CAR (lst))));
}
Exemplo n.º 2
0
status_t
get_nth_symbol(image_id imageID, int32 num, char *nameBuffer,
	int32 *_nameLength, int32 *_type, void **_location)
{
	int32 count = 0, j;
	uint32 i;
	image_t *image;

	rld_lock();

	// get the image from those who have been already initialized
	image = find_loaded_image_by_id(imageID, false);
	if (image == NULL) {
		rld_unlock();
		return B_BAD_IMAGE_ID;
	}

	// iterate through all the hash buckets until we've found the one
	for (i = 0; i < HASHTABSIZE(image); i++) {
		for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
			elf_sym *symbol = &image->syms[j];

			if (count == num) {
				const char* symbolName = SYMNAME(image, symbol);
				strlcpy(nameBuffer, symbolName, *_nameLength);
				*_nameLength = strlen(symbolName);

				void* location = (void*)(symbol->st_value
					+ image->regions[0].delta);
				int32 type;
				if (symbol->Type() == STT_FUNC)
					type = B_SYMBOL_TYPE_TEXT;
				else if (symbol->Type() == STT_OBJECT)
					type = B_SYMBOL_TYPE_DATA;
				else
					type = B_SYMBOL_TYPE_ANY;
					// TODO: check with the return types of that BeOS function

				patch_defined_symbol(image, symbolName, &location, &type);

				if (_type != NULL)
					*_type = type;
				if (_location != NULL)
					*_location = location;
				goto out;
			}
			count++;
		}
	}
out:
	rld_unlock();

	if (num != count)
		return B_BAD_INDEX;

	return B_OK;
}
Exemplo n.º 3
0
static void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym)
{

	dprintf("symbol at %p, in image %p\n", sym, image);

	dprintf(" name index %d, '%s'\n", sym->st_name, SYMNAME(image, sym));
	dprintf(" st_value 0x%x\n", sym->st_value);
	dprintf(" st_size %d\n", sym->st_size);
	dprintf(" st_info 0x%x\n", sym->st_info);
	dprintf(" st_other 0x%x\n", sym->st_other);
	dprintf(" st_shndx %d\n", sym->st_shndx);
}
Exemplo n.º 4
0
static struct Elf32_Sym *elf_find_symbol(struct elf_image_info *image, const char *name)
{
	unsigned int hash;
	unsigned int i;

	if(!image->dynamic_ptr)
		return NULL;

	hash = elf_hash(name) % HASHTABSIZE(image);
//	dprintf("elf_find_symbol: hash %d on '%s'\n", hash, name);
	for(i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; i = HASHCHAINS(image)[i]) {
		if(!strcmp(SYMNAME(image, &image->syms[i]), name)) {
			return &image->syms[i];
		}
	}

	return NULL;
}
Exemplo n.º 5
0
// this function first tries to see if the first image and it's already resolved symbol is okay, otherwise
// it tries to link against the shared_image
// XXX gross hack and needs to be done better
int elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *sym, struct elf_image_info *shared_image, const char *sym_prepend,addr_t *sym_addr)
{
	struct Elf32_Sym *sym2;
	char new_symname[512];

	switch(sym->st_shndx) {
		case SHN_UNDEF:
			// patch the symbol name
			strlcpy(new_symname, sym_prepend, sizeof(new_symname));
			strlcat(new_symname, SYMNAME(image, sym), sizeof(new_symname));

			// it's undefined, must be outside this image, try the other image
			sym2 = elf_find_symbol(shared_image, new_symname);
			if(!sym2) {
				dprintf("elf_resolve_symbol: could not resolve symbol '%s'\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			// make sure they're the same type
			if(ELF32_ST_TYPE(sym->st_info) != ELF32_ST_TYPE(sym2->st_info)) {
				dprintf("elf_resolve_symbol: found symbol '%s' in shared image but wrong type\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			if(ELF32_ST_BIND(sym2->st_info) != STB_GLOBAL && ELF32_ST_BIND(sym2->st_info) != STB_WEAK) {
				dprintf("elf_resolve_symbol: found symbol '%s' but not exported\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			*sym_addr = sym2->st_value + shared_image->regions[0].delta;
			return NO_ERROR;
		case SHN_ABS:
			*sym_addr = sym->st_value;
			return NO_ERROR;
		case SHN_COMMON:
			// XXX finish this
			dprintf("elf_resolve_symbol: COMMON symbol, finish me!\n");
			return ERR_NOT_IMPLEMENTED;
		default:
			// standard symbol
			*sym_addr = sym->st_value + image->regions[0].delta;
			return NO_ERROR;
	}
}
Exemplo n.º 6
0
/* handles single-byte characters, implicit length */
ptr S_intern(const unsigned char *s) {
  iptr n = strlen((const char *)s);
  iptr hc = hash(s, n);
  iptr idx = hc % S_G.oblist_length;
  ptr sym;
  bucket *b;

  tc_mutex_acquire()

  b = S_G.oblist[idx];
  while (b != NULL) {
    sym = b->sym;
    if (!GENSYMP(sym)) {
       ptr str = SYMNAME(sym);
       if (Sstring_length(str) == n) {
          iptr i;
          for (i = 0; ; i += 1) {
            if (i == n) {
               tc_mutex_release()
               return sym;
            }
            if (Sstring_ref(str, i) != s[i]) break;
          }
       }
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
/* Take an address to symbol. Taken from the OpenBeOS version of the newos kernel. */
int elf_reverse_lookup_symbol(addr_t address, addr_t *base_address, char *text, int len)
{
	struct elf_image_info **ptr;
	struct elf_image_info *image;
	struct Elf32_Sym *sym;
	struct elf_image_info *found_image;
	struct Elf32_Sym *found_sym;
	long found_delta;
	unsigned int i,j;
	int rv;

	PRINT(("looking up %p\n",(void *)address));

	mutex_lock(&image_lock);

	found_sym = 0;
	found_image = 0;
	found_delta = 0x7fffffff;
	for(ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
		image = *ptr;

		PRINT((" image %p, base = %p, size = %p\n", image, (void *)image->regions[0].start, (void *)image->regions[0].size));
		if ((address < image->regions[0].start) || (address >= (image->regions[0].start + image->regions[0].size)))
			continue;

		PRINT((" searching...\n"));
		found_image = image;
		for (i = 0; i < HASHTABSIZE(image); i++) {
			for(j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
				long d;
				sym = &image->syms[j];

				PRINT(("  %p looking at %s, type = %d, bind = %d, addr = %p\n",sym,SYMNAME(image, sym),ELF32_ST_TYPE(sym->st_info),ELF32_ST_BIND(sym->st_info),(void *)sym->st_value));
				PRINT(("  symbol: %lx (%x + %lx)\n", sym->st_value + image->regions[0].delta, sym->st_value, image->regions[0].delta));

				if (ELF32_ST_TYPE(sym->st_info) != STT_FUNC)
					continue;

				d = (long)address - (long)(sym->st_value + image->regions[0].delta);
				if ((d >= 0) && (d < found_delta)) {
					found_delta = d;
					found_sym = sym;
				}
			}
		}
		break;
	}
	if (found_sym == 0) {
		PRINT(("symbol not found!\n"));
		strlcpy(text, "symbol not found", len);
		rv = ERR_NOT_FOUND;
	} else {
		PRINT(("symbol at %p, in image %p\n", found_sym, found_image));
		PRINT(("name index %d, '%s'\n", found_sym->st_name, SYMNAME(found_image, found_sym)));
		PRINT(("addr = %#lx, offset = %#lx\n",(found_sym->st_value + found_image->regions[0].delta),found_delta));
		// XXX should honor len here
//		sprintf(text, "<%#lx:%s + %#lx> %s", (found_sym->st_value + found_image->regions[0].delta), SYMNAME(found_image, found_sym), found_delta, found_image->name);
		strncpy(text, SYMNAME(found_image, found_sym), len);
		text[len-1] = 0;
		*base_address = found_sym->st_value + found_image->regions[0].delta;
		rv = 0;
	}

	mutex_unlock(&image_lock);
	return rv;
}
Exemplo n.º 9
0
static status_t
relocate_rela(image_t* rootImage, image_t* image, Elf64_Rela* rel,
	size_t relLength, SymbolLookupCache* cache)
{
	for (size_t i = 0; i < relLength / 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;
		image_t* symbolImage = NULL;

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

			status_t status = resolve_symbol(rootImage, image, sym, cache,
				&symAddr, &symbolImage);
			if (status != B_OK) {
				TRACE(("resolve symbol \"%s\" returned: %" B_PRId32 "\n",
					SYMNAME(image, sym), status));
				printf("resolve symbol \"%s\" returned: %" B_PRId32 "\n",
					SYMNAME(image, sym), status);
				return status;
			}
		}

		// Address of the relocation.
		Elf64_Addr relocAddr = image->regions[0].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:
			case R_X86_64_GLOB_DAT:
			case R_X86_64_JUMP_SLOT:
				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_RELATIVE:
				relocValue = image->regions[0].delta + rel[i].r_addend;
				break;
			case R_X86_64_DTPMOD64:
				relocValue = symbolImage == NULL
							? image->dso_tls_id : symbolImage->dso_tls_id;
				break;
			case R_X86_64_DTPOFF32:
			case R_X86_64_DTPOFF64:
				relocValue = symAddr;
				break;
			default:
				TRACE(("unhandled relocation type %d\n", type));
				return B_BAD_DATA;
		}

		*(Elf64_Addr *)relocAddr = relocValue;
	}

	return B_OK;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
static int
relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *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 B	(image->regions[0].delta)

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

		switch (type) {
			case R_386_32:
			case R_386_PC32:
			case R_386_GLOB_DAT:
			case R_386_JMP_SLOT:
			case R_386_GOTOFF:
			{
				struct 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_386_NONE:
				continue;
			case R_386_32:
				final_val = S + A;
				break;
			case R_386_PC32:
				final_val = S + A - (addr_t)P;
				break;
#if 0
			case R_386_GOT32:
				final_val = G + A;
				break;
			case R_386_PLT32:
				final_val = L + A - (addr_t)P;
				break;
#endif
			case R_386_COPY:
				/* what ? */
				continue;
			case R_386_GLOB_DAT:
				final_val = S;
				break;
			case R_386_JMP_SLOT:
				final_val = S;
				break;
			case R_386_RELATIVE:
				final_val = 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;
}
Exemplo n.º 13
0
status_t
get_nearest_symbol_at_address(void* address, image_id* _imageID,
	char** _imagePath, char** _symbolName, int32* _type, void** _location)
{
	rld_lock();

	image_t* image = find_loaded_image_by_address((addr_t)address);
	if (image == NULL) {
		rld_unlock();
		return B_BAD_VALUE;
	}

	elf_sym* foundSymbol = NULL;
	addr_t foundLocation = (addr_t)NULL;

	bool found = false;
	for (uint32 i = 0; i < HASHTABSIZE(image) && !found; i++) {
		for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
				j = HASHCHAINS(image)[j]) {
			elf_sym *symbol = &image->syms[j];
			addr_t location = symbol->st_value + image->regions[0].delta;

			if (location <= (addr_t)address	&& location >= foundLocation) {
				foundSymbol = symbol;
				foundLocation = location;

				// jump out if we have an exact match
				if (foundLocation == (addr_t)address) {
					found = true;
					break;
				}
			}
		}
	}

	if (_imageID != NULL)
		*_imageID = image->id;
	if (_imagePath != NULL)
		*_imagePath = image->path;

	if (foundSymbol != NULL) {
		*_symbolName = SYMNAME(image, foundSymbol);

		if (_type != NULL) {
			if (foundSymbol->Type() == STT_FUNC)
				*_type = B_SYMBOL_TYPE_TEXT;
			else if (foundSymbol->Type() == STT_OBJECT)
				*_type = B_SYMBOL_TYPE_DATA;
			else
				*_type = B_SYMBOL_TYPE_ANY;
			// TODO: check with the return types of that BeOS function
		}

		if (_location != NULL)
			*_location = (void*)foundLocation;
	} else {
		*_symbolName = NULL;
		if (_location != NULL)
			*_location = NULL;
	}

	rld_unlock();
	return B_OK;
}
Exemplo n.º 14
0
char	*boot, *proto, *dev;

#if 0
#ifdef __ELF__
#define SYMNAME(a)	a
#else
#define SYMNAME(a)	__CONCAT("_",a)
#endif
#else
/* XXX: Hack in libc nlist works with both formats */
#define SYMNAME(a)	__CONCAT("_",a)
#endif

struct nlist nl[] = {
#define X_BLOCKTABLE	0
	{ {SYMNAME("block_table")} },
#define X_BLOCKCOUNT	1
	{ {SYMNAME("block_count")} },
#define X_BLOCKSIZE	2
	{ {SYMNAME("block_size")} },
	{ {NULL} }
};
daddr_t	*block_table;		/* block number array in prototype image */
int32_t	*block_count_p;		/* size of this array */
int32_t	*block_size_p;		/* filesystem block size */
int32_t	max_block_count;

char		*loadprotoblocks __P((char *, size_t *));
int		loadblocknums __P((char *, int));
static void	devread __P((int, void *, daddr_t, size_t, char *));
static void	usage __P((void));