Skip to content

Instantly share code, notes, and snippets.

@Furao
Created March 19, 2025 15:13
Show Gist options
  • Save Furao/7a8f2760be97b78a9b273b5fc19e6e2a to your computer and use it in GitHub Desktop.
Save Furao/7a8f2760be97b78a9b273b5fc19e6e2a to your computer and use it in GitHub Desktop.
x86 mmu table dump
#define NX_BIT 0x8000000000000000ULL
#define WR_BIT (1<<1)
#define PS_BIT (1<<7)
#define TABLE_LEN 512
#define ADDR_MASK (~0xFFFULL)
void dump_entry(uint64_t paddr, uint64_t entry, int level) {
bool ex = (entry & NX_BIT) == 0;
bool w = (entry & WR_BIT) != 0;
uint64_t vaddr = entry & ADDR_MASK & ~(NX_BIT);
printf("p %p v %p", paddr, vaddr);
if (level == 0) {
printf(" 4KB");
}
else if (level == 1) {
printf(" 2MB");
}
else {
printf(" 1GB");
}
if (w) {
printf(" rw");
}
else {
printf(" r");
}
if (ex) {
printf(" ex");
}
printf("\n");
}
void dump_pml4_table(uint64_t table_addr) {
uint64_t *pml4 = table_addr;
for(int i = 0; i<TABLE_LEN; i++) {
if (pml4[i] != 0) {
// printf("pml4 %u: %p\n",i, pml4[i]);
uint64_t addr = pml4[i] & ADDR_MASK;
uint64_t *pdpt = addr;
for(int j = 0; j<TABLE_LEN; j++) {
if (pdpt[j] != 0) {
// printf("\tpdpt %u: %p\n",j, pdpt[j]);
if (pdpt[j]&PS_BIT) {
uint64_t paddr = j*(1<<30);
dump_entry(paddr, pdpt[j], 2);
continue;
}
uint64_t pdpt_addr = pdpt[j] & ADDR_MASK;
uint64_t *pde = pdpt_addr;
for(int k = 0; k<TABLE_LEN; k++) {
if (pde[k] != 0) {
// printf("\t\tpde %u: %p\n",k, pde[k]);
if (pde[k] & PS_BIT) {
uint64_t paddr = j*(1<<30) + k*(1<<21);
dump_entry(paddr, pde[k], 1);
continue;
}
uint64_t pte_addr = pde[k] & ADDR_MASK;
uint64_t *pte = pte_addr;
for(int m = 0; m<TABLE_LEN; m++) {
if (pte[m] != 0) {
// printf("\t\t\tpte %u: %p\n",m, pte[m]);
uint64_t paddr = j*(1<<30) + k*(1<<21) + m*(1<<12);
dump_entry(paddr, pte[m], 0);
}
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment