#!/usr/bin/env python3

import os
import sys
import struct
import parser
from collections import namedtuple
import ctypes
import argparse
import re
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

#  global variables
pd_complete = ''
inputfile = ''
outputfile = ''
list_of_pde = {}
num_of_regions = 0
read_buff = ''
raw_info = []

struct_mmu_regions_tuple = {"start_addr", "size", "permissions"}
mmu_region_details = namedtuple("mmu_region_details",
                                "pde_index page_entries_info")

valid_pages_inside_pde = namedtuple("valid_pages_inside_pde", "start_addr size \
                                pte_valid_addr_start \
                                pte_valid_addr_end \
                                permissions")

mmu_region_details_pdpt = namedtuple("mmu_region_details_pdpt",
                                     "pdpte_index pd_entries")

page_tables_list = []
pd_tables_list = []
pd_start_addr = 0
validation_issue_memory_overlap = [False, 0, -1]
output_offset = 0
print_string_pde_list = ''
pde_pte_string = {}
FourMB = (1024 * 4096)  # In Bytes

#  Constants
PAGE_ENTRY_PRESENT = 1
PAGE_ENTRY_READ_WRITE = 1 << 1
PAGE_ENTRY_USER_SUPERVISOR = 1 << 2
PAGE_ENTRY_PWT = 0 << 3
PAGE_ENTRY_PCD = 0 << 4
PAGE_ENTRY_ACCESSED = 0 << 5  # this is a read only field
PAGE_ENTRY_DIRTY = 0 << 6  # this is a read only field
PAGE_ENTRY_PAT = 0 << 7
PAGE_ENTRY_GLOBAL = 0 << 8
PAGE_ENTRY_ALLOC = 1 << 9
PAGE_ENTRY_CUSTOM = 0 << 10
#############

#*****************************************************************************#
# class for 4Kb Mode


class PageMode_4kb:
    total_pages = 1023
    write_page_entry_bin = "I"
    size_addressed_per_pde = (1024 * 4096)  # 4MB In Bytes

    # return the page directory number for the give address
    def get_pde_number(self, value):
        return (value >> 22) & 0x3FF

    # return the page table number for the given address
    def get_pte_number(self, value):
        return (value >> 12) & 0x3FF

    # get the total number of pd available
    def get_number_of_pd(self):
        return len(list_of_pde.keys())

    # the return value will have the page address and it is assumed
    # to be a 4096 boundary
    # hence the output of this API will be a 20bit address of the page table
    def address_of_page_table(self, page_table_number):
        global pd_start_addr

        # location from where the Page tables will be written
        PT_start_addr = pd_start_addr + 4096
        return ((PT_start_addr +
                 (page_tables_list.index(page_table_number) * 4096) >> 12))

    #   union x86_mmu_pde_pt {
    # 	u32_t  value;
    # 	struct {
    # 		u32_t p:1;
    # 		u32_t rw:1;
    # 		u32_t us:1;
    # 		u32_t pwt:1;
    # 		u32_t pcd:1;
    # 		u32_t a:1;
    # 		u32_t ignored1:1;
    # 		u32_t ps:1;
    # 		u32_t ignored2:4;
    # 		u32_t page_table:20;
    # 	};
    # };
    def get_binary_pde_value(self, value):
        perms = value.page_entries_info[0].permissions

        present = PAGE_ENTRY_PRESENT
        read_write = check_bits(perms, [1, 29]) << 1
        user_mode = check_bits(perms, [2, 28]) << 2

        pwt = PAGE_ENTRY_PWT
        pcd = PAGE_ENTRY_PCD
        a = PAGE_ENTRY_ACCESSED
        ps = 0 << 7  # this is a read only field
        page_table = self.address_of_page_table(value.pde_index) << 12
        return (present |
                read_write |
                user_mode |
                pwt |
                pcd |
                a |
                ps |
                page_table)

    # union x86_mmu_pte {
    # 	u32_t  value;
    # 	struct {
    # 		u32_t p:1;
    # 		u32_t rw:1;
    # 		u32_t us:1;
    # 		u32_t pwt:1;
    # 		u32_t pcd:1;
    # 		u32_t a:1;
    # 		u32_t d:1;
    # 		u32_t pat:1;
    # 		u32_t g:1;
    # 		u32_t alloc:1;
    # 		u32_t custom:2;
    # 		u32_t page:20;
    # 	};
    # };
    def get_binary_pte_value(self, value, pte, perm_for_pte):
        present = PAGE_ENTRY_PRESENT
        read_write = ((perm_for_pte >> 1) & 0x1) << 1
        user_mode = ((perm_for_pte >> 2) & 0x1) << 2
        pwt = PAGE_ENTRY_PWT
        pcd = PAGE_ENTRY_PCD
        a = PAGE_ENTRY_ACCESSED
        d = PAGE_ENTRY_DIRTY
        pat = PAGE_ENTRY_PAT
        g = PAGE_ENTRY_GLOBAL
        alloc = PAGE_ENTRY_ALLOC
        custom = PAGE_ENTRY_CUSTOM

        # This points to the actual memory in the HW
        # totally 20 bits to rep the phy address
        # first 10 is the number got from pde and next 10 is pte
        page_table = ((value.pde_index << 10) | pte) << 12

        binary_value = (present | read_write | user_mode |
                        pwt | pcd | a | d | pat | g | alloc | custom |
                        page_table)
        return binary_value

    def populate_required_structs(self):
        for region in raw_info:
            pde_index = self.get_pde_number(region[0])
            pte_valid_addr_start = self.get_pte_number(region[0])

            # Get the end of the page table entries
            # Since a memory region can take up only a few entries in the Page
            # table, this helps us get the last valid PTE.
            pte_valid_addr_end = self.get_pte_number(region[0] +
                                                     region[1] - 1)

            mem_size = region[1]

            # In-case the start address aligns with a page table entry other
            # than zero and the mem_size is greater than (1024*4096) i.e 4MB
            # in case where it overflows the currenty PDE's range then limit the
            # PTE to 1024 and so make the mem_size reflect the actual size taken
            # up in the current PDE
            if (region[1] + (pte_valid_addr_start * 4096)) >= \
               (self.size_addressed_per_pde):

                pte_valid_addr_end = self.total_pages
                mem_size = (((self.total_pages + 1) -
                             pte_valid_addr_start) * 4096)

            self.set_pde_pte_values(pde_index, region[0], mem_size,
                                    pte_valid_addr_start,
                                    pte_valid_addr_end,
                                    region[2])

            if pde_index not in page_tables_list:
                page_tables_list.append(pde_index)

            # IF the current pde couldn't fit the entire requested region size
            # then there is a need to create new PDEs to match the size.
            # Here the overflow_size represents the size that couldn't be fit
            # inside the current PDE, this is will now to used to create a
            # new PDE/PDEs so the size remaining will be
            # requested size - allocated size(in the current PDE)

            overflow_size = region[1] - mem_size

            # create all the extra PDEs needed to fit the requested size
            # this loop starts from the current pde till the last pde that is
            # needed the last pde is calcualted as the (start_addr + size) >>
            # 22
            if overflow_size != 0:
                for extra_pde in range(pde_index + 1, self.get_pde_number(
                        region[0] + region[1]) + 1):

                    # new pde's start address
                    # each page directory entry has a addr range of (1024 *4096)
                    # thus the new PDE start address is a multiple of that
                    # number
                    extra_pde_start_address = (extra_pde *
                    (self.size_addressed_per_pde))

                    # the start address of and extra pde will always be 0
                    # and the end address is calculated with the new pde's start
                    # address and the overflow_size
                    extra_pte_valid_addr_end = self.get_pte_number(
                        extra_pde_start_address + overflow_size - 1)

                    # if the overflow_size couldn't be fit inside this new pde
                    # then need another pde and so we now need to limit the end
                    # of the PTE to 1024 and set the size of this new region to
                    # the max possible
                    extra_region_size = overflow_size
                    if overflow_size >= (self.size_addressed_per_pde):
                        extra_region_size = self.size_addressed_per_pde
                        extra_pte_valid_addr_end = self.total_pages

                    # load the new PDE's details

                    self.set_pde_pte_values(extra_pde,
                                            extra_pde_start_address,
                                            extra_region_size,
                                            0,
                                            extra_pte_valid_addr_end,
                                            region[2])

                    # for the next iteration of the loop the size needs to
                    # decreased.
                    overflow_size -= extra_region_size

                    # print(hex_32(overflow_size),extra_pde)
                    if extra_pde not in page_tables_list:
                        page_tables_list.append(extra_pde)

                    if overflow_size == 0:
                        break

        page_tables_list.sort()

    # update the tuple values for the memory regions needed
    def set_pde_pte_values(self, pde_index, address, mem_size,
                           pte_valid_addr_start, pte_valid_addr_end, perm):

        pages_tuple = valid_pages_inside_pde(
            start_addr=address,
            size=mem_size,
            pte_valid_addr_start=pte_valid_addr_start,
            pte_valid_addr_end=pte_valid_addr_end,
            permissions=perm)

        mem_region_values = mmu_region_details(pde_index=pde_index,
                                               page_entries_info=[])

        mem_region_values.page_entries_info.append(pages_tuple)

        if pde_index in list_of_pde.keys():
            # this step adds the new page info to the exsisting pages info
            list_of_pde[pde_index].page_entries_info.append(pages_tuple)
        else:
            list_of_pde[pde_index] = mem_region_values

    def page_directory_create_binary_file(self):
        global output_buffer
        global output_offset
        for pde in range(self.total_pages + 1):
            binary_value = 0  # the page directory entry is not valid

            # if i have a valid entry to populate
            if pde in sorted(list_of_pde.keys()):
                value = list_of_pde[pde]
                binary_value = self.get_binary_pde_value(value)
                self.pde_verbose_output(pde, binary_value)

            struct.pack_into(self.write_page_entry_bin,
                             output_buffer,
                             output_offset,
                             binary_value)

            output_offset += struct.calcsize(self.write_page_entry_bin)

    def page_table_create_binary_file(self):
        global output_buffer
        global output_offset

        for key, value in sorted(list_of_pde.items()):
            for pte in range(self.total_pages + 1):
                binary_value = 0  # the page directory entry is not valid

                valid_pte = 0
                for i in value.page_entries_info:
                    temp_value = ((pte >= i.pte_valid_addr_start) and
                                  (pte <= i.pte_valid_addr_end))
                    if temp_value:
                        perm_for_pte = i.permissions
                    valid_pte |= temp_value

                # if i have a valid entry to populate
                if valid_pte:
                    binary_value = self.get_binary_pte_value(value,
                                                             pte,
                                                             perm_for_pte)
                    self.pte_verbose_output(key, pte, binary_value)

                struct.pack_into(self.write_page_entry_bin,
                                 output_buffer,
                                 output_offset,
                                 binary_value)
                output_offset += struct.calcsize(self.write_page_entry_bin)

    # To populate the binary file the module struct needs a buffer of the
    # excat size. This returns the size needed for the given set of page
    # tables.
    def set_binary_file_size(self):
        binary_size = ctypes.create_string_buffer((4096) +
                                                  (len(list_of_pde.keys()) *
                                                   4096))
        return binary_size

    # prints the details of the pde
    def verbose_output(self):

        print("\nTotal Page directory entries " + str(self.get_number_of_pd()))
        count = 0
        for key, value in list_of_pde.items():
            for i in value.page_entries_info:
                count += 1
                print("In Page directory entry " +
                      format_string(value.pde_index) +
                      ": valid start address = " +
                      hex_32(i.start_addr) + ", end address = " +
                      hex_32((i.pte_valid_addr_end + 1) * 4096 - 1 +
                             (value.pde_index * (FourMB))))

    # print all the tables for a given page table mode
    def print_all_page_table_info(self):
        self.pde_print_elements()
        self.pte_print_elements()

    def pde_verbose_output(self, pde, binary_value):
        if args.verbose is False:
            return

        global print_string_pde_list

        present = format_string(binary_value & 0x1)
        read_write = format_string((binary_value >> 1) & 0x1)
        user_mode = format_string((binary_value >> 2) & 0x1)
        pwt = format_string((binary_value >> 3) & 0x1)
        pcd = format_string((binary_value >> 4) & 0x1)
        a = format_string((binary_value >> 5) & 0x1)
        ignored1 = format_string(0)
        ps = format_string((binary_value >> 7) & 0x1)
        ignored2 = format_string(0000)
        page_table_addr = format_string(hex((binary_value >> 12) & 0xFFFFF))

        print_string_pde_list += (format_string(str(pde)) +
                                  " | " +
                                  (present) +
                                  " | " +
                                  (read_write) + " | " +
                                  (user_mode) + " | " +
                                  (pwt) + " | " +
                                  (pcd) + " | " +
                                  (a) + " | " +
                                  (ps) + " | " +
                                  page_table_addr + "\n"
                                  )

    def pde_print_elements(self):
        global print_string_pde_list
        print("PAGE DIRECTORY ")
        print(format_string("PDE") + " | " +
              format_string('P') + " | " +
              format_string('rw') + " | " +
              format_string('us') + " | " +
              format_string('pwt') + " | " +
              format_string('pcd') + " | " +
              format_string('a') + " | " +
              format_string('ps') + " | " +
              format_string('Addr page table'))
        print(print_string_pde_list)
        print("END OF PAGE DIRECTORY")

    def pte_verbose_output(self, pde, pte, binary_value):
        global pde_pte_string

        present = format_string((binary_value >> 0) & 0x1)
        read_write = format_string((binary_value >> 1) & 0x1)
        user_mode = format_string((binary_value >> 2) & 0x1)
        pwt = format_string((binary_value >> 3) & 0x1)
        pcd = format_string((binary_value >> 4) & 0x1)
        a = format_string((binary_value >> 5) & 0x1)
        d = format_string((binary_value >> 6) & 0x1)
        pat = format_string((binary_value >> 7) & 0x1)
        g = format_string((binary_value >> 8) & 0x1)
        alloc = format_string((binary_value >> 9) & 0x1)
        custom = format_string((binary_value >> 10) & 0x3)
        page_table_addr = hex_20((binary_value >> 12) & 0xFFFFF)

        print_string_list = (format_string(str(pte)) + " | " +
                             (present) + " | " +
                             (read_write) + " | " +
                             (user_mode) + " | " +
                             (pwt) + " | " +
                             (pcd) + " | " +
                             (a) + " | " +
                             (d) + " | " +
                             (pat) + " | " +
                             (g) + " | " +
                             (alloc) + " | " +
                             (custom) + " | " +
                             page_table_addr + "\n"
                             )

        if pde in pde_pte_string.keys():
            pde_pte_string[pde] += (print_string_list)
        else:
            pde_pte_string[pde] = print_string_list

    def pte_print_elements(self):
        global pde_pte_string

        for pde, print_string in sorted(pde_pte_string.items()):
            print("\nPAGE TABLE " + str(pde))

            print(format_string("PTE") + " | " +
                  format_string('P') + " | " +
                  format_string('rw') + " | " +
                  format_string('us') + " | " +
                  format_string('pwt') + " | " +
                  format_string('pcd') + " | " +
                  format_string('a') + " | " +
                  format_string('d') + " | " +
                  format_string('pat') + " | " +
                  format_string('g') + " | " +
                  format_string('alloc') + " | " +
                  format_string('custom') + " | " +
                  format_string('page addr'))
            print(print_string)
            print("END OF PAGE TABLE " + str(pde))


#*****************************************************************************#
# class for PAE 4KB Mode
class PageMode_PAE:
    total_pages = 511
    write_page_entry_bin = "Q"
    size_addressed_per_pde = (512 * 4096)  # 2MB In Bytes
    size_addressed_per_pdpte = (512 * size_addressed_per_pde)  # In Bytes
    list_of_pdpte = {}
    pdpte_print_string = {}
    print_string_pdpte_list = ''

    # TODO enable all page tables on just a flag

    def __init__(self):
        for i in range(4):
            self.list_of_pdpte[i] = mmu_region_details_pdpt(pdpte_index=i,
                                                            pd_entries={})

    # return the pdpte number for the give address
    def get_pdpte_number(self, value):
        return (value >> 30) & 0x3

    # return the page directory number for the give address
    def get_pde_number(self, value):
        return (value >> 21) & 0x1FF

    # return the page table number for the given address
    def get_pte_number(self, value):
        return (value >> 12) & 0x1FF

    def get_number_of_pd(self):
        return len(self.get_pdpte_list())

    def get_pdpte_list(self):
        return list({temp[0] for temp in pd_tables_list})

    # the return value will have the page address and it is assumed to be a 4096
    # boundary.hence the output of this API will be a 20bit address of the page
    # table
    def address_of_page_table(self, pdpte, page_table_number):
        global pd_start_addr

        # first page given to page directory pointer
        # and 2nd page till 5th page are used for storing the page directories.

        # set the max pdpte used. this tells how many pd are needed after
        # that we start keeping the pt
        PT_start_addr = self.get_number_of_pd() * 4096 +\
            pd_start_addr + 4096
        return (PT_start_addr +
                (pd_tables_list.index([pdpte, page_table_number]) *
                 4096) >> 12)

    #   union x86_mmu_pae_pde {
    # 	u64_t  value;
    # 	struct {
    # 		u64_t p:1;
    # 		u64_t rw:1;
    # 		u64_t us:1;
    # 		u64_t pwt:1;
    # 		u64_t pcd:1;
    # 		u64_t a:1;
    # 		u64_t ignored1:1;
    # 		u64_t ps:1;
    # 		u64_t ignored2:4;
    # 		u64_t page_table:20;
    # 		u64_t igonred3:29;
    # 		u64_t xd:1;
    # 	};
    # };

    def get_binary_pde_value(self, pdpte, value):
        perms = value.page_entries_info[0].permissions

        present = PAGE_ENTRY_PRESENT
        read_write = check_bits(perms, [1, 29]) << 1
        user_mode = check_bits(perms, [2, 28]) << 2

        pwt = PAGE_ENTRY_PWT
        pcd = PAGE_ENTRY_PCD
        a = PAGE_ENTRY_ACCESSED
        ps = 0 << 7  # set to make sure that the phy page is 4KB
        page_table = self.address_of_page_table(pdpte, value.pde_index) << 12
        xd = check_bits(perms, [62, 63]) << 63
        return (present |
                read_write |
                user_mode |
                pwt |
                pcd |
                a |
                ps |
                page_table |
                xd)

    # union x86_mmu_pae_pte {
    # 	u64_t  value;
    # 	struct {
    # 		u64_t p:1;
    # 		u64_t rw:1;
    # 		u64_t us:1;
    # 		u64_t pwt:1;
    # 		u64_t pcd:1;
    # 		u64_t a:1;
    # 		u64_t d:1;
    # 		u64_t pat:1;
    # 		u64_t g:1;
    # 		u64_t ignore:3;
    # 		u64_t page:20;
    # 		u64_t igonred3:29;
    # 		u64_t xd:1;
    # 	};
    # };
    def get_binary_pte_value(self, value, pde, pte, perm_for_pte):
        present = PAGE_ENTRY_PRESENT
        read_write = perm_for_pte & PAGE_ENTRY_READ_WRITE
        user_mode = perm_for_pte & PAGE_ENTRY_USER_SUPERVISOR
        pwt = PAGE_ENTRY_PWT
        pcd = PAGE_ENTRY_PCD
        a   = PAGE_ENTRY_ALLOC
        d   = PAGE_ENTRY_DIRTY
        pat = PAGE_ENTRY_PAT
        g   = PAGE_ENTRY_GLOBAL

        # This points to the actual memory in the HW
        # totally 20 bits to rep the phy address
        # first 2bits is from pdpte then 9bits is the number got from pde and
        # next 9bits is pte
        page_table = ((value.pdpte_index << 18) | (pde << 9) | pte) << 12

        xd = ((perm_for_pte >> 63) & 0x1) << 63

        binary_value = (present | read_write | user_mode |
                        pwt | pcd | a | d | pat | g |
                        page_table | xd)
        return binary_value

    def clean_up_unused_pdpte(self):
        self.list_of_pdpte = {key: value for key, value in
                              self.list_of_pdpte.items()
                              if value.pd_entries != {}}

    # update the tuple values for the memory regions needed
    def set_pde_pte_values(self, pdpte, pde_index, address, mem_size,
                           pte_valid_addr_start, pte_valid_addr_end, perm):

        pages_tuple = valid_pages_inside_pde(
            start_addr=address,
            size=mem_size,
            pte_valid_addr_start=pte_valid_addr_start,
            pte_valid_addr_end=pte_valid_addr_end,
            permissions=perm)

        mem_region_values = mmu_region_details(pde_index=pde_index,
                                               page_entries_info=[])

        mem_region_values.page_entries_info.append(pages_tuple)

        if pde_index in self.list_of_pdpte[pdpte].pd_entries.keys():
            # this step adds the new page info to the exsisting pages info
            self.list_of_pdpte[pdpte].pd_entries[pde_index].\
                page_entries_info.append(pages_tuple)
        else:
            self.list_of_pdpte[pdpte].pd_entries[pde_index] = mem_region_values

    def populate_required_structs(self):
        for region in raw_info:
            pdpte_index = self.get_pdpte_number(region[0])
            pde_index = self.get_pde_number(region[0])
            pte_valid_addr_start = self.get_pte_number(region[0])

            # Get the end of the page table entries
            # Since a memory region can take up only a few entries in the Page
            # table, this helps us get the last valid PTE.
            pte_valid_addr_end = self.get_pte_number(region[0] +
                                                     region[1] - 1)

            mem_size = region[1]

            # In-case the start address aligns with a page table entry other
            # than zero and the mem_size is greater than (1024*4096) i.e 4MB
            # in case where it overflows the currenty PDE's range then limit the
            # PTE to 1024 and so make the mem_size reflect the actual size
            # taken up in the current PDE
            if (region[1] + (pte_valid_addr_start * 4096)) >= \
               (self.size_addressed_per_pde):

                pte_valid_addr_end = self.total_pages
                mem_size = (((self.total_pages + 1) -
                             pte_valid_addr_start) * 4096)

            self.set_pde_pte_values(pdpte_index,
                                    pde_index,
                                    region[0],
                                    mem_size,
                                    pte_valid_addr_start,
                                    pte_valid_addr_end,
                                    region[2])

            if [pdpte_index, pde_index] not in pd_tables_list:
                pd_tables_list.append([pdpte_index, pde_index])

            # IF the current pde couldn't fit the entire requested region
            # size then there is a need to create new PDEs to match the size.
            # Here the overflow_size represents the size that couldn't be fit
            # inside the current PDE, this is will now to used to create a new
            # PDE/PDEs so the size remaining will be
            # requested size - allocated size(in the current PDE)

            overflow_size = region[1] - mem_size

            # create all the extra PDEs needed to fit the requested size
            # this loop starts from the current pde till the last pde that is
            # needed the last pde is calcualted as the (start_addr + size) >>
            # 22
            if overflow_size != 0:
                for extra_pdpte in range(pdpte_index,
                                         self.get_pdpte_number(region[0] +
                                                               region[1]) + 1):
                    for extra_pde in range(pde_index + 1, self.get_pde_number(
                            region[0] + region[1]) + 1):

                        # new pde's start address
                        # each page directory entry has a addr range of
                        # (1024 *4096) thus the new PDE start address is a
                        # multiple of that number
                        extra_pde_start_address = (extra_pde *
                        (self.size_addressed_per_pde))

                        # the start address of and extra pde will always be 0
                        # and the end address is calculated with the new
                        # pde's start address and the overflow_size
                        extra_pte_valid_addr_end = (
                        self.get_pte_number(extra_pde_start_address +
                                            overflow_size - 1))

                        # if the overflow_size couldn't be fit inside this new
                        # pde then need another pde and so we now need to limit
                        # the end of the PTE to 1024 and set the size of this
                        # new region to the max possible
                        extra_region_size = overflow_size
                        if overflow_size >= (self.size_addressed_per_pde):
                            extra_region_size = self.size_addressed_per_pde
                            extra_pte_valid_addr_end = self.total_pages

                        # load the new PDE's details

                        self.set_pde_pte_values(extra_pdpte,
                                                extra_pde,
                                                extra_pde_start_address,
                                                extra_region_size,
                                                0,
                                                extra_pte_valid_addr_end,
                                                region[2])

                        # for the next iteration of the loop the size needs
                        # to decreased
                        overflow_size -= extra_region_size

                        if [extra_pdpte, extra_pde] not in pd_tables_list:
                            pd_tables_list.append([extra_pdpte, extra_pde])

                        if overflow_size == 0:
                            break

        pd_tables_list.sort()
        self.clean_up_unused_pdpte()

    def pdpte_create_binary_file(self):
        global output_buffer
        global output_offset
        global pd_start_addr

        # pae needs a pdpte at 32byte aligned address

        # Even though we have only 4 entries in the pdpte we need to move
        # the output_offset variable to the next page to start pushing
        # the pd contents
        for pdpte in range(self.total_pages + 1):
            if pdpte in self.get_pdpte_list():
                present = 1 << 0
                pwt = 0 << 3
                pcd = 0 << 4
                addr_of_pd = (((pd_start_addr + 4096) +
                               self.get_pdpte_list().index(pdpte) *
                               4096) >> 12) << 12
                binary_value = (present | pwt | pcd | addr_of_pd)
                self.pdpte_verbose_output(pdpte, binary_value)
            else:
                binary_value = 0

            struct.pack_into(self.write_page_entry_bin,
                             output_buffer,
                             output_offset,
                             binary_value)

            output_offset += struct.calcsize(self.write_page_entry_bin)

    def page_directory_create_binary_file(self):
        global output_buffer
        global output_offset
        pdpte_number_count = 0
        for pdpte, pde_info in self.list_of_pdpte.items():

            pde_number_count = 0
            for pde in range(self.total_pages + 1):
                binary_value = 0  # the page directory entry is not valid

                # if i have a valid entry to populate
                # if pde in sorted(list_of_pde.keys()):
                if pde in sorted(pde_info.pd_entries.keys()):
                    value = pde_info.pd_entries[pde]
                    binary_value = self.get_binary_pde_value(pdpte, value)
                    self.pde_verbose_output(pdpte, pde, binary_value)

                pde_number_count += 1
                struct.pack_into(self.write_page_entry_bin,
                                 output_buffer,
                                 output_offset,
                                 binary_value)

                output_offset += struct.calcsize(self.write_page_entry_bin)

    def page_table_create_binary_file(self):
        global output_buffer
        global output_offset

        pdpte_number_count = 0
        for pdpte, pde_info in sorted(self.list_of_pdpte.items()):
            pdpte_number_count += 1
            for pde, pte_info in sorted(pde_info.pd_entries.items()):
                pte_number_count = 0
                for pte in range(self.total_pages + 1):
                    binary_value = 0  # the page directory entry is not valid

                    valid_pte = 0
                    # go through all the valid pages inside the pde to
                    # figure out if we need to populate this pte
                    for i in pte_info.page_entries_info:
                        temp_value = ((pte >= i.pte_valid_addr_start) and
                                      (pte <= i.pte_valid_addr_end))
                        if temp_value:
                            perm_for_pte = i.permissions
                        valid_pte |= temp_value

                    # if i have a valid entry to populate
                    if valid_pte:
                        binary_value = self.get_binary_pte_value(pde_info,
                                                                 pde,
                                                                 pte,
                                                                 perm_for_pte)
                        pte_number_count += 1
                        self.pte_verbose_output(pdpte, pde, pte, binary_value)

                    # print(binary_value, (self.write_page_entry_bin))

                    struct.pack_into(self.write_page_entry_bin,
                                     output_buffer,
                                     output_offset,
                                     binary_value)
                    output_offset += struct.calcsize(self.write_page_entry_bin)


    # To populate the binary file the module struct needs a buffer of the
    # excat size This returns the size needed for the given set of page tables.
    def set_binary_file_size(self):
        pages_for_pdpte = 1
        pages_for_pd = self.get_number_of_pd()
        pages_for_pt = len(pd_tables_list)
        binary_size = ctypes.create_string_buffer((pages_for_pdpte +
                                                   pages_for_pd +
                                                   pages_for_pt) * 4096)
        return binary_size

    # prints the details of the pde
    def verbose_output(self):
        print("\nTotal Page directory Page pointer entries " +
              str(self.get_number_of_pd()))
        count = 0
        for pdpte, pde_info in sorted(self.list_of_pdpte.items()):
            print(
                "In page directory page table pointer " +
                format_string(pdpte))

            for pde, pte_info in sorted(pde_info.pd_entries.items()):
                for pte in pte_info.page_entries_info:
                    count += 1
                    print("    In Page directory entry " + format_string(pde) +
                          ": valid start address = " +
                          hex_32(pte.start_addr) + ", end address = " +
                          hex_32((pte.pte_valid_addr_end + 1) * 4096 - 1 +
                                 (pde * (self.size_addressed_per_pde)) +
                                 (pdpte * self.size_addressed_per_pdpte)))

    def pdpte_verbose_output(self, pdpte, binary_value):
        if args.verbose is False:
            return

        present = format_string(binary_value & 0x1)
        pwt = format_string((binary_value >> 3) & 0x1)
        pcd = format_string((binary_value >> 4) & 0x1)
        page_table_addr = format_string(hex((binary_value >> 12) & 0xFFFFF))

        self.print_string_pdpte_list += (format_string(str(pdpte)) +
                                         " | " + (present) + " | " +
                                         (pwt) + " | " +
                                         (pcd) + " | " +
                                         page_table_addr + "\n")

    def pdpte_print_elements(self):
        print("\nPAGE DIRECTORIES POINTER ")
        print(format_string("PDPTE") + " | " +
              format_string('P') + " | " +
              format_string('pwt') + " | " +
              format_string('pcd') + " | " +
              format_string('Addr'))
        print(self.print_string_pdpte_list)
        print("END OF PAGE DIRECTORY POINTER")

    def pde_verbose_output(self, pdpte, pde, binary_value):
        if args.verbose is False:
            return

        global print_string_pde_list

        present = format_string(binary_value & 0x1)
        read_write = format_string((binary_value >> 1) & 0x1)
        user_mode = format_string((binary_value >> 2) & 0x1)
        pwt = format_string((binary_value >> 3) & 0x1)
        pcd = format_string((binary_value >> 4) & 0x1)
        a = format_string((binary_value >> 5) & 0x1)
        ignored1 = format_string(0)
        ps = format_string((binary_value >> 7) & 0x1)
        ignored2 = format_string(0000)
        page_table_addr = format_string(hex((binary_value >> 12) & 0xFFFFF))
        xd = format_string((binary_value >> 63) & 0x1)

        print_string_pde_list = (format_string(str(pde)) + " | " +
                                 (present) + " | " +
                                 (read_write) + " | " +
                                 (user_mode) + " | " +
                                 (pwt) + " | " +
                                 (pcd) + " | " +
                                 (a) + " | " +
                                 (ps) + " | " +
                                 page_table_addr + " | " +
                                 (xd) + "\n")

        if pdpte in self.pdpte_print_string.keys():
            self.pdpte_print_string[pdpte] += (print_string_pde_list)
        else:
            self.pdpte_print_string[pdpte] = print_string_pde_list

    # print all the tables for a given page table mode
    def print_all_page_table_info(self):
        self.pdpte_print_elements()
        self.pde_print_elements()
        self.pte_print_elements()

    def pde_print_elements(self):
        global print_string_pde_list

        for pdpte, print_string in sorted(self.pdpte_print_string.items()):
            print("\n PAGE DIRECTORIES for PDPT " + str(pdpte))
            print(format_string("PDE") + " | " +
                  format_string('P') + " | " +
                  format_string('rw') + " | " +
                  format_string('us') + " | " +
                  format_string('pwt') + " | " +
                  format_string('pcd') + " | " +
                  format_string('a') + " | " +
                  format_string('ps') + " | " +
                  format_string('Addr') + " | " +
                  format_string('xd'))
            print(print_string)
            print("END OF PAGE DIRECTORIES for PDPT " + str(pdpte))

    def pte_verbose_output(self, pdpte, pde, pte, binary_value):
        global pde_pte_string

        present = format_string((binary_value >> 0) & 0x1)
        read_write = format_string((binary_value >> 1) & 0x1)
        user_mode = format_string((binary_value >> 2) & 0x1)
        pwt = format_string((binary_value >> 3) & 0x1)
        pcd = format_string((binary_value >> 4) & 0x1)
        a = format_string((binary_value >> 5) & 0x1)
        d = format_string((binary_value >> 6) & 0x1)
        pat = format_string((binary_value >> 7) & 0x1)
        g = format_string((binary_value >> 8) & 0x1)
        page_table_addr = hex_20((binary_value >> 12) & 0xFFFFF)
        xd = format_string((binary_value >> 63) & 0x1)

        print_string_list = (format_string(str(pte)) + " | " +
                             (present) + " | " +
                             (read_write) + " | " +
                             (user_mode) + " | " +
                             (pwt) + " | " +
                             (pcd) + " | " +
                             (a) + " | " +
                             (d) + " | " +
                             (pat) + " | " +
                             (g) + " | " +
                             page_table_addr + " | " +
                             (xd) + "\n"
                             )

        if (pdpte, pde) in pde_pte_string.keys():
            pde_pte_string[(pdpte, pde)] += (print_string_list)
        else:
            pde_pte_string[(pdpte, pde)] = print_string_list

    def pte_print_elements(self):
        global pde_pte_string

        for (pdpte, pde), print_string in sorted(pde_pte_string.items()):
            print(
                "\nPAGE TABLE for PDPTE = " +
                str(pdpte) +
                " and PDE = " +
                str(pde))

            print(format_string("PTE") + " | " +
                  format_string('P') + " | " +
                  format_string('rw') + " | " +
                  format_string('us') + " | " +
                  format_string('pwt') + " | " +
                  format_string('pcd') + " | " +
                  format_string('a') + " | " +
                  format_string('d') + " | " +
                  format_string('pat') + " | " +
                  format_string('g') + " | " +
                  format_string('Page Addr') + " | " +
                  format_string('xd'))
            print(print_string)
            print("END OF PAGE TABLE " + str(pde))


#*****************************************************************************#


def print_list_of_pde(list_of_pde):
    for key, value in list_of_pde.items():
        print(key, value)
        print('\n')


# read the binary from the input file and populate a dict for
# start address of mem region
# size of the region - so page tables entries will be created with this
# read write permissions

def read_mmu_list_marshal_param(page_mode):

    global read_buff
    global page_tables_list
    global pd_start_addr
    global validation_issue_memory_overlap
    read_buff = input_file.read()
    input_file.close()

    # read contents of the binary file first 2 values read are
    # num_of_regions and page directory start address both calculated and
    # populated by the linker
    num_of_regions, pd_start_addr = struct.unpack_from(
        header_values_format, read_buff, 0)

    # a offset used to remember next location to read in the binary
    size_read_from_binary = struct.calcsize(header_values_format)

    # for each of the regions mentioned in the binary loop and populate all the
    # required parameters
    for region in range(num_of_regions):
        basic_mem_region_values = struct.unpack_from(struct_mmu_regions_format,
                                                     read_buff,
                                                     size_read_from_binary)
        size_read_from_binary += struct.calcsize(struct_mmu_regions_format)

        # ignore zero sized memory regions
        if basic_mem_region_values[1] == 0:
            continue

        # validate for memory overlap here
        for i in raw_info:
            start_location = basic_mem_region_values[0]
            end_location = basic_mem_region_values[0] + \
                basic_mem_region_values[1]

            overlap_occurred = ((start_location >= i[0]) and
                                (start_location <= (i[0] + i[1]))) and \
                ((end_location >= i[0]) and
                 (end_location <= i[0] + i[1]))

            if overlap_occurred:
                validation_issue_memory_overlap = [
                    True,
                    start_location,
                    page_mode.get_pde_number(start_location)]
                return

        # add the retrived info another list
        raw_info.append(basic_mem_region_values)


def validate_pde_regions():
    # validation for correct page alignment of the regions
    for key, value in list_of_pde.items():
        for pages_inside_pde in value.page_entries_info:
            if pages_inside_pde.start_addr & (0xFFF) != 0:
                print("Memory Regions are not page aligned",
                      hex(pages_inside_pde.start_addr))
                sys.exit(2)

            # validation for correct page alignment of the regions
            if pages_inside_pde.size & (0xFFF) != 0:
                print("Memory Regions size is not page aligned",
                      hex(pages_inside_pde.size))
                sys.exit(2)

    # validation for spiling of the regions across various
    if validation_issue_memory_overlap[0] == True:
        print("Memory Regions are overlapping at memory address " +
              str(hex(validation_issue_memory_overlap[1])) +
              " with Page directory Entry number " +
              str(validation_issue_memory_overlap[2]))
        sys.exit(2)


def check_bits(val, bits):
    for b in bits:
        if val & (1 << b):
            return 1
    return 0


# Read the parameters passed to the file
def parse_args():
    global args

    parser = argparse.ArgumentParser(description=__doc__,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument("-e", "--big-endian", action="store_true",
                        help="Target encodes data in big-endian format"
                        "(little endian is the default)")

    parser.add_argument("-i", "--input",
                        help="Input file from which MMU regions are read.")
    parser.add_argument("-k", "--kernel",
                        help="Zephyr kernel image")
    parser.add_argument("-o", "--output",
                        help="Output file into which the page tables are written.")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="Lists all the relavent data generated.")
    args = parser.parse_args()


# the format for writing in the binary file would be decided by the
# endian selected
def set_struct_endian_format(page_mode):
    endian_string = "<"
    if args.big_endian is True:
        endian_string = ">"
    global struct_mmu_regions_format
    global header_values_format

    struct_mmu_regions_format = endian_string + "IIQ"
    header_values_format = endian_string + "II"
    page_mode.write_page_entry_bin = (endian_string +
                                      page_mode.write_page_entry_bin)


def format_string(input_str):
    output_str = '{0: <5}'.format(str(input_str))
    return output_str

# format for 32bit hex value
def hex_32(input_value):
    output_value = "{0:#0{1}x}".format(input_value, 10)
    return output_value

# format for 20bit hex value
def hex_20(input_value):
    output_value = "{0:#0{1}x}".format(input_value, 7)
    return output_value


def verbose_output(page_mode):
    if args.verbose is False:
        return

    print("\nMemory Regions as defined:")
    for info in raw_info:
        print("Memory region start address = " + hex_32(info[0]) +
              ", Memory size = " + hex_32(info[1]) +
              ", Permission = " + hex(info[2]))

    page_mode.verbose_output()
    page_mode.print_all_page_table_info()

# build sym table
def get_symbols(obj):
    for section in obj.iter_sections():
        if isinstance(section, SymbolTableSection):
            return {sym.name: sym.entry.st_value
                    for sym in section.iter_symbols()}

    raise LookupError("Could not find symbol table")


# determine which paging mode was selected
def get_page_mode():
    with open(args.kernel, "rb") as fp:
        kernel = ELFFile(fp)
        sym = get_symbols(kernel)
    try:
        return sym["CONFIG_X86_PAE_MODE"]
    except BaseException:
        return 0


def main():
    global output_buffer
    parse_args()

    # select the page table needed
    if get_page_mode():
        page_mode = PageMode_PAE()
    else:
        page_mode = PageMode_4kb()

    set_struct_endian_format(page_mode)

    global input_file
    input_file = open(args.input, 'rb')

    global binary_output_file
    binary_output_file = open(args.output, 'wb')

    # inputfile= file_name
    read_mmu_list_marshal_param(page_mode)

    # populate the required structs
    page_mode.populate_required_structs()

    # validate the inputs
    validate_pde_regions()

    # The size of the output buffer has to match the number of bytes we write
    # this corresponds to the number of page tables gets created.
    output_buffer = page_mode.set_binary_file_size()

    try:
        page_mode.pdpte_create_binary_file()
    except BaseException:
        pass
    page_mode.page_directory_create_binary_file()
    page_mode.page_table_create_binary_file()

    # write the binary data into the file
    binary_output_file.write(output_buffer)
    binary_output_file.close()

    # verbose output needed by the build system
    verbose_output(page_mode)


if __name__ == "__main__":
    main()
