查看虚拟内存和物理内存映射

#include <iostream>
#include <fstream>
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>

struct Page
{
	uint64_t address;
	uint64_t entry[512]; 	
};

uint64_t get_phys_address(uint64_t entry)
{
	static const uint64_t mask = (1LL << 63) | ((1 << 12) - 1);
	return entry & ~mask;
}

bool writable(uint64_t entry)
{
	return (entry & (1 << 1)) != 0;
}

bool executable(uint64_t entry)
{
	return (entry & (1LL << 63)) == 0;
}

bool user_mode(uint64_t entry)
{
	return (entry & (1 << 2)) != 0;
}

void print_entry(FILE* fp, int level, uint64_t entry, uint64_t virtual_address)
{
	fprintf(fp, "%d\t0x%016lx\t0x%016lx\t%d\t%d\t%d\n", level, get_phys_address(entry), virtual_address, writable(entry), executable(entry), user_mode(entry));
}

void dump(FILE* fp, const Page*& page, int level, uint64_t virtual_address)
{
	const Page* cur_page = page++;
	for (int i = 0; i < 512; i++)
	{
		const uint64_t entry = cur_page->entry[i];
		const uint64_t child_virtual_address = (virtual_address << 9) | i;
		if (level > 0)
		{
			if (entry & 1)
			{
				if (!(entry&(1<<7)))
				{
					dump(fp, page, level - 1, child_virtual_address);
				}
				else
				{
					print_entry(fp, level, entry, child_virtual_address << (level * 9 + 12));
				}
			}
		}
		else
		{
			
			if (entry)
			{
				print_entry(fp, level, entry, child_virtual_address << 12);
			}
		}
	}
}

void dump_pagetable(FILE* fp)
{
	std::ifstream ifs("/proc/page_table_3", std::ios::binary);
	if (!ifs)
	{
		return;
	}
	std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
	const Page* page = (const Page*)&content[0];
	const Page* end_page = (const Page*)(&content[0] + content.length());
	dump(fp, page, 3, 0);
	std::cout << (const void*)end_page << '\t' <<  (const void*)page << std::endl;
	std::flush(std::cout);
}

int main()
{
	const int N = 1024 * 1024 * 8;
	const bool hugetable = true;
	const bool do_fork = false;

	char* m = (char*)mmap(NULL, N, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | (hugetable ? MAP_HUGETLB: 0), -1, 0); 
			std::cout << *m << std::endl;
	FILE* fp = NULL;
	if (do_fork)
	{
		pid_t pid = fork();	
		if (pid == 0)
		{
			fp = fopen("/home/fractal/lecture/child.log", "w");
		}
		else
		{
			fp = fopen("/home/fractal/lecture/father.log", "w");
		}
	}
	else
	{
		fp = fopen("/home/fractal/lecture/father.log", "w");
	}

	fprintf(fp, "mmap address: %p\n", m);
	dump_pagetable(fp);

	fclose(fp);
	while (true)
	{
		usleep(10000);
	}
	return 0;
}

https://github.com/jethrogb/ptdump

https://github.com/gongyiling/cpp_lecture/blob/main/pagetable.cpp

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值