Пример #1
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}