[PATCH 4/8] mmap_cache: record protection bits

Masatake YAMATO yamato at redhat.com
Fri Jan 26 20:36:40 UTC 2018


To make mmap_cache reusable, this change records protection bits of
mmap entry.

* defs.h (MMAP_CACHE_PROT_*): New enums.
* mmap_cache.c (build_mmpa_cache): Don't ignore entries that are not
  executable. Just record the protection bits here.
* unwind.c (print_stack_frame): Ignore entries that are not executable
  here.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 defs.h       |  9 +++++++++
 mmap_cache.c | 27 ++++++++++++++++++++++-----
 unwind.c     |  4 +++-
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index a653c852..093acc3f 100644
--- a/defs.h
+++ b/defs.h
@@ -715,14 +715,23 @@ struct mmap_cache_t {
 	 * start_addr  is 0x7fabbb09b000
 	 * end_addr    is 0x7fabbb09f000
 	 * mmap_offset is 0x179000
+	 * protections is MMAP_CACHE_PROT_READABLE|MMAP_CACHE_PROT_EXECUTABLE
 	 * binary_filename is "/lib/libc-2.11.1.so"
 	 */
 	unsigned long start_addr;
 	unsigned long end_addr;
 	unsigned long mmap_offset;
+	unsigned char protections;
 	char *binary_filename;
 };
 
+enum mmap_cache_protection {
+	MMAP_CACHE_PROT_READABLE   = 1 << 0,
+	MMAP_CACHE_PROT_WRITABLE   = 1 << 1,
+	MMAP_CACHE_PROT_EXECUTABLE = 1 << 2,
+	MMAP_CACHE_PROT_SHARED     = 1 << 3,
+};
+
 enum mmap_cache_rebuild_result {
 	MMAP_CACHE_REBUILD_NOCACHE,
 	MMAP_CACHE_REBUILD_READY,
diff --git a/mmap_cache.c b/mmap_cache.c
index 01ff3938..a121b852 100644
--- a/mmap_cache.c
+++ b/mmap_cache.c
@@ -66,16 +66,26 @@ build_mmap_cache(struct tcb *tcp)
 	while (fgets(buffer, sizeof(buffer), fp) != NULL) {
 		struct mmap_cache_t *entry;
 		unsigned long start_addr, end_addr, mmap_offset;
+		char read_bit;
+		char write_bit;
 		char exec_bit;
+		char shared_bit;
 		char binary_path[sizeof(buffer)];
 
-		if (sscanf(buffer, "%lx-%lx %*c%*c%c%*c %lx %*x:%*x %*d %[^\n]",
-			   &start_addr, &end_addr, &exec_bit,
-			   &mmap_offset, binary_path) != 5)
+		if (sscanf(buffer, "%lx-%lx %c%c%c%c %lx %*x:%*x %*d %[^\n]",
+			   &start_addr, &end_addr,
+			   &read_bit, &write_bit, &exec_bit, &shared_bit,
+			   &mmap_offset, binary_path) != 8)
 			continue;
 
-		/* ignore mappings that have no PROT_EXEC bit set */
-		if (exec_bit != 'x')
+		/* skip mappings having unknown protection */
+		if (!(read_bit == '-' || read_bit == 'r'))
+			continue;
+		if (!(write_bit == '-' || write_bit == 'w'))
+			continue;
+		if (!(exec_bit == '-' || exec_bit == 'x'))
+			continue;
+		if (!(shared_bit == 'p' || shared_bit == 's'))
 			continue;
 
 		if (end_addr < start_addr) {
@@ -114,6 +124,13 @@ build_mmap_cache(struct tcb *tcp)
 		entry->start_addr = start_addr;
 		entry->end_addr = end_addr;
 		entry->mmap_offset = mmap_offset;
+		entry->protections = (
+			0
+			| ((read_bit   == 'r')? MMAP_CACHE_PROT_READABLE  : 0)
+			| ((write_bit  == 'w')? MMAP_CACHE_PROT_WRITABLE  : 0)
+			| ((exec_bit   == 'x')? MMAP_CACHE_PROT_EXECUTABLE: 0)
+			| ((shared_bit == 's')? MMAP_CACHE_PROT_SHARED    : 0)
+			);
 		entry->binary_filename = xstrdup(binary_path);
 		tcp->mmap_cache_size++;
 	}
diff --git a/unwind.c b/unwind.c
index c527d9a2..c3f56709 100644
--- a/unwind.c
+++ b/unwind.c
@@ -135,7 +135,9 @@ print_stack_frame(struct tcb *tcp,
 	}
 
 	cur_mmap_cache = mmap_cache_search(tcp, ip);
-	if (cur_mmap_cache) {
+	if (cur_mmap_cache
+	    /* ignore mappings that have no PROT_EXEC bit set */
+	    && (cur_mmap_cache->protections & MMAP_CACHE_PROT_EXECUTABLE)) {
 		unsigned long true_offset;
 		unw_word_t function_offset;
 
-- 
2.14.3





More information about the Strace-devel mailing list