• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
      • Kestrel-books
      • X86isa
        • Program-execution
        • Sdm-instruction-set-summary
        • Tlb
        • Running-linux
        • Introduction
        • Asmtest
        • X86isa-build-instructions
        • Publications
        • Contributors
        • Machine
          • X86isa-state
          • Syscalls
          • Cpuid
          • Linear-memory
          • Rflag-specifications
          • Characterizing-undefined-behavior
          • Top-level-memory
            • Rme32
            • Rime32
            • Gen-read-function
            • Rme256
            • Rme128
            • Rime64
            • Rime16
            • Rme80
            • Rme64
            • Rme48
            • Rme16
            • Gen-write-function
            • Rme-size
            • Rme08
            • Rime08
            • Rime-size
            • Wme-size
            • Wime-size
            • Wme32
            • Wime32
            • Wme80
            • Wme64
              • Wme48
              • Wme256
              • Wme16
              • Wme128
              • Wime64
              • Wime16
              • Address-aligned-p
              • Wme08
              • Wime08
            • App-view
            • X86-decoder
            • Physical-memory
            • Decoding-and-spec-utils
            • Instructions
            • Register-readers-and-writers
            • X86-modes
            • Segmentation
            • Other-non-deterministic-computations
            • Environment
            • Paging
          • Implemented-opcodes
          • To-do
          • Proof-utilities
          • Peripherals
          • Model-validation
          • Modelcalls
          • Concrete-simulation-examples
          • Utils
          • Debugging-code-proofs
        • Axe
        • Execloader
      • Math
      • Testing-utilities
    • Top-level-memory

    Wme64

    Write an unsigned 64-bit value to memory via an effective address.

    Signature
    (wme64 proc-mode eff-addr seg-reg val check-alignment? x86) 
      → 
    (mv flg x86-new)
    Arguments
    check-alignment? — Guard (booleanp check-alignment?).
    Returns
    x86-new — Type (x86p x86-new), given (x86p x86).

    The effective address eff-addr is translated to a canonical linear address. If this translation is successful and no other error occurs (like alignment errors), then wml64 is called.

    Prior to the effective address translation, we check whether write access is allowed. In 32-bit mode, write access is allowed in data segments (DS, ES, FS, GS, and SS) if the W bit in the segment descriptor is 1; write access is disallowed in code segments (this is not explicitly mentioned in Intel manual, May'18, Volume 3, Section 3.4.5.1, but it seems reasonable). In 64-bit mode, the W bit is ignored (see Atmel manual, Dec'17, Volume 2, Section 4.8.1); by analogy, we allow write access to the code segment as well. These checks may be slightly optimized using the invariant that SS.W must be 1 when SS is loaded.

    Definitions and Theorems

    Function: wme64$inline

    (defun wme64$inline (proc-mode eff-addr
                                   seg-reg val check-alignment? x86)
     (declare (xargs :stobjs (x86)))
     (declare (type (integer 0 4) proc-mode)
              (type (signed-byte 64) eff-addr)
              (type (integer 0 5) seg-reg)
              (type (unsigned-byte 64) val))
     (declare (xargs :guard (booleanp check-alignment?)))
     (b*
      (((when
         (and
          (/= proc-mode 0)
          (or (= seg-reg 1)
              (b* ((attr (loghead 16 (seg-hidden-attri seg-reg x86)))
                   (w (data-segment-descriptor-attributesbits->w attr)))
                (= w 0)))))
        (mv (list :non-writable-segment eff-addr seg-reg)
            x86))
       ((mv flg lin-addr)
        (ea-to-la proc-mode eff-addr seg-reg 8 x86))
       ((when flg) (mv flg x86))
       ((unless (or (not check-alignment?)
                    (address-aligned-p lin-addr 8 nil)))
        (mv (list :unaligned-linear-address lin-addr)
            x86)))
      (wml64 lin-addr val x86)))

    Theorem: x86p-of-wme64.x86-new

    (defthm x86p-of-wme64.x86-new
      (implies (x86p x86)
               (b* (((mv ?flg ?x86-new)
                     (wme64$inline proc-mode eff-addr
                                   seg-reg val check-alignment? x86)))
                 (x86p x86-new)))
      :rule-classes :rewrite)

    Theorem: wme64-when-64-bit-modep-and-not-fs/gs

    (defthm wme64-when-64-bit-modep-and-not-fs/gs
      (implies (and (not (equal seg-reg 4))
                    (not (equal seg-reg 5))
                    (canonical-address-p eff-addr)
                    (or (not check-alignment?)
                        (address-aligned-p eff-addr 8 nil)))
               (equal (wme64 0 eff-addr
                             seg-reg val check-alignment? x86)
                      (wml64 eff-addr val x86))))

    Theorem: wme64-unaligned-when-64-bit-modep-and-not-fs/gs

    (defthm wme64-unaligned-when-64-bit-modep-and-not-fs/gs
      (implies (and (not (equal seg-reg 4))
                    (not (equal seg-reg 5))
                    (not (or (not check-alignment?)
                             (address-aligned-p eff-addr 8 nil)))
                    (canonical-address-p eff-addr))
               (equal (wme64 0 eff-addr
                             seg-reg val check-alignment? x86)
                      (list (list :unaligned-linear-address eff-addr)
                            x86))))

    Theorem: wme64-when-64-bit-modep-and-fs/gs

    (defthm wme64-when-64-bit-modep-and-fs/gs
      (implies
           (or (equal seg-reg 4) (equal seg-reg 5))
           (equal (wme64 0 eff-addr
                         seg-reg val check-alignment? x86)
                  (b* (((mv flg lin-addr)
                        (b* (((mv base & &)
                              (segment-base-and-bounds 0 seg-reg x86))
                             (lin-addr (i64 (+ base (n64 eff-addr)))))
                          (if (canonical-address-p lin-addr)
                              (mv nil lin-addr)
                            (mv (list :non-canonical-address lin-addr)
                                0))))
                       ((when flg) (mv flg x86))
                       ((unless (or (not check-alignment?)
                                    (address-aligned-p lin-addr 8 nil)))
                        (mv (list :unaligned-linear-address lin-addr)
                            x86)))
                    (wml64 lin-addr val x86)))))