From c6d46cf97304d829fba6085544aab577be3c6249 Mon Sep 17 00:00:00 2001
From: midipix <writeonce@midipix.org>
Date: Mon, 18 Dec 2017 12:22:15 +0000
Subject: pe_get_ldr_entry_from_addr(): initial implementation.

---
 include/pemagine/pe_ldso.h            |  1 +
 include/pemagine/pemagine.h           |  2 ++
 project/common.mk                     |  1 +
 src/ldso/pe_get_ldr_entry_from_addr.c | 63 +++++++++++++++++++++++++++++++++++
 4 files changed, 67 insertions(+)
 create mode 100644 src/ldso/pe_get_ldr_entry_from_addr.c

diff --git a/include/pemagine/pe_ldso.h b/include/pemagine/pe_ldso.h
index 2d81774..30019c5 100644
--- a/include/pemagine/pe_ldso.h
+++ b/include/pemagine/pe_ldso.h
@@ -12,6 +12,7 @@
 #define pe_get_export_symbol_info           __ldso_get_export_symbol_info
 #define pe_get_first_module_handle          __ldso_get_first_module_handle
 #define pe_get_framework_runtime_data       __ldso_get_framework_runtime_data
+#define pe_get_ldr_entry_from_addr          __ldso_get_ldr_entry_from_addr
 #define pe_get_image_coff_hdr_addr          __ldso_get_image_coff_hdr_addr
 #define pe_get_image_data_dirs_addr         __ldso_get_image_data_dirs_addr
 #define pe_get_image_dos_hdr_addr           __ldso_get_image_dos_hdr_addr
diff --git a/include/pemagine/pemagine.h b/include/pemagine/pemagine.h
index 283d579..99ba86a 100644
--- a/include/pemagine/pemagine.h
+++ b/include/pemagine/pemagine.h
@@ -241,6 +241,8 @@ pe_api void *				pe_get_kernel32_module_handle	(void);
 /* ldso */
 pe_api wchar16_t *			pe_get_peb_command_line(void);
 pe_api wchar16_t *			pe_get_peb_environment_block(void);
+pe_api struct pe_ldr_tbl_entry *	pe_get_ldr_entry_from_addr(const void * addr);
+
 
 pe_api int32_t				pe_get_framework_runtime_data(
 						struct pe_framework_runtime_data **	rtdata,
diff --git a/project/common.mk b/project/common.mk
index 5ff3a1e..bb39af8 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -11,6 +11,7 @@ API_SRCS = \
 	src/headers/pe_get_image_special_hdr_addr.c \
 	src/imports/pe_enum_image_import_hdrs.c \
 	src/ldso/pe_get_framework_runtime_data.c \
+	src/ldso/pe_get_ldr_entry_from_addr.c \
 	src/ldso/pe_get_peb_strings.c \
 	src/ldso/pe_find_framework_loader.c \
 	src/ldso/pe_load_framework_loader.c \
diff --git a/src/ldso/pe_get_ldr_entry_from_addr.c b/src/ldso/pe_get_ldr_entry_from_addr.c
new file mode 100644
index 0000000..69f01f5
--- /dev/null
+++ b/src/ldso/pe_get_ldr_entry_from_addr.c
@@ -0,0 +1,63 @@
+/*****************************************************************************/
+/*  pemagination: a (virtual) tour into portable bits and executable bytes   */
+/*  Copyright (C) 2013--2017  Z. Gilboa                                      */
+/*  Released under GPLv2 and GPLv3; see COPYING.PEMAGINE.                    */
+/*****************************************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+#include "pe_os.h"
+
+struct ldr_entry_addr_ctx {
+	uintptr_t			addr;
+	struct pe_ldr_tbl_entry *	entry;
+};
+
+static int ldr_entry_addr_compare(
+	struct pe_ldr_tbl_entry *	image_ldr_tbl_entry,
+	enum pe_callback_reason		reason,
+	void *				context)
+{
+	uintptr_t			base;
+	uintptr_t			cap;
+	struct ldr_entry_addr_ctx *	ctx;
+
+	switch (reason) {
+		case PE_CALLBACK_REASON_INIT:
+		case PE_CALLBACK_REASON_INFO:
+		case PE_CALLBACK_REASON_QUERY:
+			return 1;
+
+		case PE_CALLBACK_REASON_DONE:
+			return 0;
+
+		case PE_CALLBACK_REASON_ERROR:
+			return OS_STATUS_INTERNAL_ERROR;
+
+		case PE_CALLBACK_REASON_ITEM:
+			break;
+	}
+
+	ctx  = (struct ldr_entry_addr_ctx *)context;
+	base = (uintptr_t)image_ldr_tbl_entry->dll_base;
+	cap  = base + image_ldr_tbl_entry->size_of_image;
+
+	if ((ctx->addr >= base) && (ctx->addr < cap)) {
+		ctx->entry =  image_ldr_tbl_entry;
+		return 0;
+	}
+
+	return 1;
+}
+
+struct pe_ldr_tbl_entry * pe_get_ldr_entry_from_addr(const void * addr)
+{
+	struct ldr_entry_addr_ctx ctx = {(uintptr_t)addr,0};
+
+	if (pe_enum_modules_in_load_order(
+			ldr_entry_addr_compare,
+			&ctx))
+		return 0;
+
+	return ctx.entry;
+}
-- 
cgit v1.2.3