• Rick Edgecombe's avatar
    x86: Separate out x86_regset for 32 and 64 bit · d28abd23
    Rick Edgecombe authored
    In fill_thread_core_info() the ptrace accessible registers are collected
    for a core file to be written out as notes. The note array is allocated
    from a size calculated by iterating the user regset view, and counting the
    regsets that have a non-zero core_note_type. However, this only allows for
    there to be non-zero core_note_type at the end of the regset view. If
    there are any in the middle, fill_thread_core_info() will overflow the
    note allocation, as it iterates over the size of the view and the
    allocation would be smaller than that.
    
    To apparently avoid this problem, x86_32_regsets and x86_64_regsets need
    to be constructed in a special way. They both draw their indices from a
    shared enum x86_regset, but 32 bit and 64 bit don't all support the same
    regsets and can be compiled in at the same time in the case of
    IA32_EMULATION. So this enum has to be laid out in a special way such that
    there are no gaps for both x86_32_regsets and x86_64_regsets. This
    involves ordering them just right by creating aliases for enum’s that
    are only in one view or the other, or creating multiple versions like
    REGSET32_IOPERM/REGSET64_IOPERM.
    
    So the collection of the registers tries to minimize the size of the
    allocation, but it doesn’t quite work. Then the x86 ptrace side works
    around it by constructing the enum just right to avoid a problem. In the
    end there is no functional problem, but it is somewhat strange and
    fragile.
    
    It could also be improved like this [1], by better utilizing the smaller
    array, but this still wastes space in the regset array’s if they are not
    carefully crafted to avoid gaps. Instead, just fully separate out the
    enums and give them separate 32 and 64 enum names. Add some bitsize-free
    defines for REGSET_GENERAL and REGSET_FP since they are the only two
    referred to in bitsize generic code.
    
    While introducing a bunch of new 32/64 enums, change the pattern of the
    name from REGSET_FOO32 to REGSET32_FOO to better indicate that the 32 is
    in reference to the CPU mode and not the register size, as suggested by
    Eric Biederman.
    
    This should have no functional change and is only changing how constants
    are generated and referred to.
    
    [1] https://lore.kernel.org/lkml/20180717162502.32274-1-yu-cheng.yu@intel.com/Signed-off-by: default avatarRick Edgecombe <rick.p.edgecombe@intel.com>
    Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Link: https://lore.kernel.org/all/20221021221803.10910-2-rick.p.edgecombe%40intel.com
    d28abd23
ptrace.c 34.7 KB