Blame src/ldso/pe_get_ldr_entry_from_addr.c

c6d46c
/*****************************************************************************/
c6d46c
/*  pemagination: a (virtual) tour into portable bits and executable bytes   */
c6d46c
/*  Copyright (C) 2013--2017  Z. Gilboa                                      */
c6d46c
/*  Released under GPLv2 and GPLv3; see COPYING.PEMAGINE.                    */
c6d46c
/*****************************************************************************/
c6d46c
c6d46c
#include <psxtypes/psxtypes.h>
c6d46c
#include <pemagine/pemagine.h>
c6d46c
#include "pe_os.h"
c6d46c
c6d46c
struct ldr_entry_addr_ctx {
c6d46c
	uintptr_t			addr;
c6d46c
	struct pe_ldr_tbl_entry *	entry;
c6d46c
};
c6d46c
c6d46c
static int ldr_entry_addr_compare(
c6d46c
	struct pe_ldr_tbl_entry *	image_ldr_tbl_entry,
c6d46c
	enum pe_callback_reason		reason,
c6d46c
	void *				context)
c6d46c
{
c6d46c
	uintptr_t			base;
c6d46c
	uintptr_t			cap;
c6d46c
	struct ldr_entry_addr_ctx *	ctx;
c6d46c
c6d46c
	switch (reason) {
c6d46c
		case PE_CALLBACK_REASON_INIT:
c6d46c
		case PE_CALLBACK_REASON_INFO:
c6d46c
		case PE_CALLBACK_REASON_QUERY:
c6d46c
			return 1;
c6d46c
c6d46c
		case PE_CALLBACK_REASON_DONE:
c6d46c
			return 0;
c6d46c
c6d46c
		case PE_CALLBACK_REASON_ERROR:
c6d46c
			return OS_STATUS_INTERNAL_ERROR;
c6d46c
c6d46c
		case PE_CALLBACK_REASON_ITEM:
c6d46c
			break;
c6d46c
	}
c6d46c
c6d46c
	ctx  = (struct ldr_entry_addr_ctx *)context;
c6d46c
	base = (uintptr_t)image_ldr_tbl_entry->dll_base;
c6d46c
	cap  = base + image_ldr_tbl_entry->size_of_image;
c6d46c
c6d46c
	if ((ctx->addr >= base) && (ctx->addr < cap)) {
c6d46c
		ctx->entry =  image_ldr_tbl_entry;
c6d46c
		return 0;
c6d46c
	}
c6d46c
c6d46c
	return 1;
c6d46c
}
c6d46c
c6d46c
struct pe_ldr_tbl_entry * pe_get_ldr_entry_from_addr(const void * addr)
c6d46c
{
c6d46c
	struct ldr_entry_addr_ctx ctx = {(uintptr_t)addr,0};
c6d46c
c6d46c
	if (pe_enum_modules_in_load_order(
c6d46c
			ldr_entry_addr_compare,
c6d46c
			&ctx))
c6d46c
		return 0;
c6d46c
c6d46c
	return ctx.entry;
c6d46c
}