#!/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 = []

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 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 = 0
        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 < 2:
            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 < 2:
            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_table):

    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_table.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="count", default=0,
                        help="Print debugging information. Multiple "
                             "invocations increase verbosity")
    args = parser.parse_args()
    if "VERBOSE" in os.environ:
        args.verbose = 1


# the format for writing in the binary file would be decided by the
# endian selected
def set_struct_endian_format(page_table):
    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_table.write_page_entry_bin = (endian_string +
                                      page_table.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_table):
    if args.verbose == 0:
        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_table.verbose_output()

    if args.verbose > 1:
        page_table.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")


def main():
    global output_buffer
    parse_args()

    # select the page table needed
    page_table = PageMode_PAE()

    set_struct_endian_format(page_table)

    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_table)

    # populate the required structs
    page_table.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_table.set_binary_file_size()

    try:
        page_table.pdpte_create_binary_file()
    except BaseException:
        pass
    page_table.page_directory_create_binary_file()
    page_table.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_table)


if __name__ == "__main__":
    main()
