<commit_before>
import misc

include "globals.pxi"


cdef class Gdt:
    def __init__(self, Segments segments):
        self.segments = segments
    cdef reset(self):
        self.table.csResetData()
    cdef loadTablePosition(self, unsigned long long tableBase, unsigned short tableLimit):
        self.tableBase, self.tableLimit = tableBase, tableLimit
        if (self.tableLimit >= GDT_HARD_LIMIT):
            self.segments.main.exitError("GDT::loadTablePosition: tableLimit {0:#06x} >= GDT_HARD_LIMIT {1:#06x}.",\
               self.tableLimit, GDT_HARD_LIMIT)
            return
        self.tableLimit += 1 # move the increment up could cause an overflow
    cdef loadTableData(self):
        self.table.csWrite(0, (<Mm>self.segments.main.mm).mmPhyRead(self.tableBase, self.tableLimit), self.tableLimit)
    cdef tuple getBaseLimit(self):
        return self.tableBase, self.tableLimit
    cdef tuple getEntry(self, unsigned short num):
        cdef unsigned long long entryData
        cdef unsigned long base, limit
        cdef unsigned char accessByte, flags
        if (not num):
            self.segments.main.exitError("GDT::getEntry: num == 0!")
            return None
        entryData = self.table.csReadValueUnsigned((num&0xfff8), 8)
        limit = entryData&BITMASK_WORD
        base  = (entryData>>16)&0xffffff
        accessByte = (entryData>>40)&BITMASK_BYTE
        flags  = (entryData>>52)&0xf
        limit |= (( entryData>>48)&0xf)<<16
        base  |= ( (entryData>>56)&BITMASK_BYTE)<<24
        return base, limit, accessByte, flags
    cdef unsigned char getSegSize(self, unsigned short num):
        if ((<unsigned char>(<tuple>self.getEntry(num))[3]) & GDT_FLAG_SIZE):
            return OP_SIZE_DWORD
        return OP_SIZE_WORD
    cdef unsigned char getSegAccess(self, unsigned short num):
        return (<unsigned char>(<tuple>self.getEntry(num))[2])
    cdef unsigned char isSegPresent(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_PRESENT)!=0
    cdef unsigned char isCodeSeg(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_EXECUTABLE)!=0
    ### isSegReadableWritable:
    ### if codeseg, return True if readable, else False
    ### if dataseg, return True if writable, else False
    cdef unsigned char isSegReadableWritable(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_READABLE_WRITABLE)!=0
    cdef unsigned char isSegConforming(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_CONFORMING)!=0
    cdef unsigned char getSegDPL(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_DPL)>>5
    cdef unsigned char checkAccessAllowed(self, unsigned short num, unsigned char isStackSegment):
        if (num == 0 or \
            (isStackSegment and ( num&3 != self.segments.main.cpu.registers.cpl or self.getSegDPL(num) != self.segments.main.cpu.registers.cpl)) or \
            0):
            raise misc.ChemuException(CPU_EXCEPTION_GP, num)
        elif (not self.isSegPresent(num)):
            if (isStackSegment):
                raise misc.ChemuException(CPU_EXCEPTION_SS, num)
            else:
                raise misc.ChemuException(CPU_EXCEPTION_NP, num)
    cdef unsigned char checkReadAllowed(self, unsigned short num, unsigned char doException):
        if (num&0xfff8 == 0 or (self.isCodeSeg(num) and not self.isSegReadableWritable(num))):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, 0)
            return False
        return True
    cdef unsigned char checkWriteAllowed(self, unsigned short num, unsigned char doException):
        if (num&0xfff8 == 0 or self.isCodeSeg(num) or not self.isSegReadableWritable(num)):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, 0)
            return False
        return True
    cdef unsigned char checkSegmentLoadAllowed(self, unsigned short num, unsigned char loadStackSegment, unsigned char doException):
        cdef unsigned char numSegDPL = self.getSegDPL(num)
        if (num&0xfff8 == 0 and loadStackSegment):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, num)
            return False
        elif (not self.isSegPresent(num)):
            if (doException):
                if (loadStackSegment):
                    raise misc.ChemuException(CPU_EXCEPTION_SS, num)
                else:
                    raise misc.ChemuException(CPU_EXCEPTION_NP, num)
            return False
        elif (loadStackSegment):
            if ((num&3 != self.segments.main.cpu.registers.cpl or numSegDPL != self.segments.main.cpu.registers.cpl) or \
                (not self.isCodeSeg(num) and not self.isSegReadableWritable(num))):
                  if (doException):
                      raise misc.ChemuException(CPU_EXCEPTION_GP, num)
                  return False
        else: # not loadStackSegment
            if ( ((not self.isCodeSeg(num) or not self.isSegConforming(num)) and (num&3 > numSegDPL and self.segments.main.cpu.registers.cpl > numSegDPL)) or \
                 (self.isCodeSeg(num) and not self.isSegReadableWritable(num)) ):
                if (doException):
                    raise misc.ChemuException(CPU_EXCEPTION_GP, num)
                return False
        return True
    cdef run(self):
        self.table = ConfigSpace(GDT_HARD_LIMIT)
        self.table.run()


cdef class Idt:
    def __init__(self, Segments segments):
        self.segments = segments
    cdef reset(self):
        self.table.csResetData()
    cdef loadTable(self, unsigned long long tableBase, unsigned short tableLimit):
        self.tableBase, self.tableLimit = tableBase, tableLimit
        if (self.tableLimit >= IDT_HARD_LIMIT):
            self.segments.main.exitError("IDT::loadTablePosition: tableLimit {0:#06x} >= IDT_HARD_LIMIT {1:#06x}.",\
               self.tableLimit, IDT_HARD_LIMIT)
            return
        self.tableLimit += 1 # move the increment up could cause an overflow
        self.table.csWrite(0, (<Mm>self.segments.main.mm).mmPhyRead(self.tableBase, self.tableLimit), self.tableLimit)
    cdef tuple getBaseLimit(self):
        return self.tableBase, self.tableLimit
    cdef tuple getEntry(self, unsigned char num):
        cdef unsigned long long entryData
        cdef unsigned long entryEip
        cdef unsigned short entrySegment
        cdef unsigned char entryType, entrySize, entryNeededDPL, entryPresent
        entryData = (<Mm>self.segments.main.mm).mmPhyReadValueUnsigned((num*8), 8)
        entryEip = ((entryData>>48)&BITMASK_WORD) # interrupt eip: upper word
        entryEip <<= 16
        entryEip |= entryData&BITMASK_WORD # interrupt eip: lower word
        entrySegment = (entryData>>16)&BITMASK_WORD # interrupt segment
        entryType = (entryData>>40)&0x7 # interrupt type
        entryNeededDPL = (entryData>>45)&0x3 # interrupt: Need this DPL
        entryPresent = (entryData>>47)&1 # is interrupt present
        entrySize = (entryData>>43)&1 # interrupt size: 1==32bit; 0==16bit; entrySize is 4 for 32bit, 2 for 16bit
        if (entrySize!=0): entrySize = OP_SIZE_DWORD
        else: entrySize = OP_SIZE_WORD
        return entrySegment, entryEip, entryType, entrySize, entryNeededDPL, entryPresent
    cdef unsigned char isEntryPresent(self, unsigned char num):
        return (<unsigned char>self.table.csReadValueUnsigned((num*8)+2, 1)>>7)&1 # is interrupt present
    cdef unsigned char getEntryNeededDPL(self, unsigned char num):<commit_msg>commit... fix for part 2/3<commit_after>
import misc

include "globals.pxi"


cdef class Gdt:
    def __init__(self, Segments segments):
        self.segments = segments
    cdef reset(self):
        self.table.csResetData()
    cdef loadTablePosition(self, unsigned long long tableBase, unsigned short tableLimit):
        self.tableBase, self.tableLimit = tableBase, tableLimit
        if (self.tableLimit >= GDT_HARD_LIMIT):
            self.segments.main.exitError("GDT::loadTablePosition: tableLimit {0:#06x} >= GDT_HARD_LIMIT {1:#06x}.",\
               self.tableLimit, GDT_HARD_LIMIT)
            return
        self.tableLimit += 1 # move the increment up could cause an overflow
    cdef loadTableData(self):
        self.table.csWrite(0, (<Mm>self.segments.main.mm).mmPhyRead(self.tableBase, self.tableLimit), self.tableLimit)
    cdef tuple getBaseLimit(self):
        return self.tableBase, self.tableLimit
    cdef tuple getEntry(self, unsigned short num):
        cdef unsigned long long entryData
        cdef unsigned long base, limit
        cdef unsigned char accessByte, flags
        if (not num):
            self.segments.main.exitError("GDT::getEntry: num == 0!")
            return None
        entryData = self.table.csReadValueUnsigned((num&0xfff8), 8)
        limit = entryData&BITMASK_WORD
        base  = (entryData>>16)&0xffffff
        accessByte = (entryData>>40)&BITMASK_BYTE
        flags  = (entryData>>52)&0xf
        limit |= (( entryData>>48)&0xf)<<16
        base  |= ( (entryData>>56)&BITMASK_BYTE)<<24
        return base, limit, accessByte, flags
    cdef unsigned char getSegSize(self, unsigned short num):
        if ((<unsigned char>(<tuple>self.getEntry(num))[3]) & GDT_FLAG_SIZE):
            return OP_SIZE_DWORD
        return OP_SIZE_WORD
    cdef unsigned char getSegAccess(self, unsigned short num):
        return (<unsigned char>(<tuple>self.getEntry(num))[2])
    cdef unsigned char isSegPresent(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_PRESENT)!=0
    cdef unsigned char isCodeSeg(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_EXECUTABLE)!=0
    ### isSegReadableWritable:
    ### if codeseg, return True if readable, else False
    ### if dataseg, return True if writable, else False
    cdef unsigned char isSegReadableWritable(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_READABLE_WRITABLE)!=0
    cdef unsigned char isSegConforming(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_CONFORMING)!=0
    cdef unsigned char getSegDPL(self, unsigned short num):
        return (self.getSegAccess(num) & GDT_ACCESS_DPL)>>5
    cdef unsigned char checkAccessAllowed(self, unsigned short num, unsigned char isStackSegment):
        if (num == 0 or \
            (isStackSegment and ( num&3 != self.segments.main.cpu.registers.cpl or self.getSegDPL(num) != self.segments.main.cpu.registers.cpl)) or \
            0):
            raise misc.ChemuException(CPU_EXCEPTION_GP, num)
        elif (not self.isSegPresent(num)):
            if (isStackSegment):
                raise misc.ChemuException(CPU_EXCEPTION_SS, num)
            else:
                raise misc.ChemuException(CPU_EXCEPTION_NP, num)
    cdef unsigned char checkReadAllowed(self, unsigned short num, unsigned char doException):
        if (num&0xfff8 == 0 or (self.isCodeSeg(num) and not self.isSegReadableWritable(num))):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, 0)
            return False
        return True
    cdef unsigned char checkWriteAllowed(self, unsigned short num, unsigned char doException):
        if (num&0xfff8 == 0 or self.isCodeSeg(num) or not self.isSegReadableWritable(num)):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, 0)
            return False
        return True
    cdef unsigned char checkSegmentLoadAllowed(self, unsigned short num, unsigned char loadStackSegment, unsigned char doException):
        cdef unsigned char numSegDPL = self.getSegDPL(num)
        if (num&0xfff8 == 0 and loadStackSegment):
            if (doException):
                raise misc.ChemuException(CPU_EXCEPTION_GP, num)
            return False
        elif (not self.isSegPresent(num)):
            if (doException):
                if (loadStackSegment):
                    raise misc.ChemuException(CPU_EXCEPTION_SS, num)
                else:
                    raise misc.ChemuException(CPU_EXCEPTION_NP, num)
            return False
        elif (loadStackSegment):
            if ((num&3 != self.segments.main.cpu.registers.cpl or numSegDPL != self.segments.main.cpu.registers.cpl) or \
                (not self.isCodeSeg(num) and not self.isSegReadableWritable(num))):
                  if (doException):
                      raise misc.ChemuException(CPU_EXCEPTION_GP, num)
                  return False
        else: # not loadStackSegment
            if ( ((not self.isCodeSeg(num) or not self.isSegConforming(num)) and (num&3 > numSegDPL and self.segments.main.cpu.registers.cpl > numSegDPL)) or \
                 (self.isCodeSeg(num) and not self.isSegReadableWritable(num)) ):
                if (doException):
                    raise misc.ChemuException(CPU_EXCEPTION_GP, num)
                return False
        return True
    cdef run(self):
        self.table = ConfigSpace(GDT_HARD_LIMIT)
        self.table.run()


cdef class Idt:
    def __init__(self, Segments segments):
        self.segments = segments
    cdef reset(self):
        self.table.csResetData()
    cdef loadTable(self, unsigned long long tableBase, unsigned short tableLimit):
        self.tableBase, self.tableLimit = tableBase, tableLimit
        if (self.tableLimit >= IDT_HARD_LIMIT):
            self.segments.main.exitError("IDT::loadTablePosition: tableLimit {0:#06x} >= IDT_HARD_LIMIT {1:#06x}.",\
               self.tableLimit, IDT_HARD_LIMIT)
            return
        self.tableLimit += 1 # move the increment up could cause an overflow
        self.table.csWrite(0, (<Mm>self.segments.main.mm).mmPhyRead(self.tableBase, self.tableLimit), self.tableLimit)
    cdef tuple getBaseLimit(self):
        return self.tableBase, self.tableLimit
    cdef tuple getEntry(self, unsigned char num):
        cdef unsigned long long entryData
        cdef unsigned long entryEip
        cdef unsigned short entrySegment
        cdef unsigned char entryType, entrySize, entryNeededDPL, entryPresent
        entryData = self.table.csReadValueUnsigned((num*8), 8)
        entryEip = ((entryData>>48)&BITMASK_WORD) # interrupt eip: upper word
        entryEip <<= 16
        entryEip |= entryData&BITMASK_WORD # interrupt eip: lower word
        entrySegment = (entryData>>16)&BITMASK_WORD # interrupt segment
        entryType = (entryData>>40)&0x7 # interrupt type
        entryNeededDPL = (entryData>>45)&0x3 # interrupt: Need this DPL
        entryPresent = (entryData>>47)&1 # is interrupt present
        entrySize = (entryData>>43)&1 # interrupt size: 1==32bit; 0==16bit; entrySize is 4 for 32bit, 2 for 16bit
        if (entrySize!=0): entrySize = OP_SIZE_DWORD
        else: entrySize = OP_SIZE_WORD
        return entrySegment, entryEip, entryType, entrySize, entryNeededDPL, entryPresent
    cdef unsigned char isEntryPresent(self, unsigned char num):
        return (<unsigned char>self.table.csReadValueUnsigned((num*8)+2, 1)>>7)&1 # is interrupt present
    cdef unsigned char getEntryNeededDPL(self, unsigned char num):
{'fraction_non_alphanumeric': 0.09604110401159344, 'fraction_numerical': 0.01330610631710691, 'mean_word_length': 2.817450339451848, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 82, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6665179', 'n_tokens_mistral': 4621, 'n_tokens_neox': 4455, 'n_words': 1131}