1d4c55
commit 340097d0b50eff9d3058e06c6989ae398c653d4a
1d4c55
Author: Florian Weimer <fweimer@redhat.com>
1d4c55
Date:   Thu Sep 22 12:10:41 2022 +0200
1d4c55
1d4c55
    elf: Extract glibcelf constants from <elf.h>
1d4c55
    
1d4c55
    The need to maintain elf/elf.h and scripts/glibcelf.py in parallel
1d4c55
    results in a backporting hazard: they need to be kept in sync to
1d4c55
    avoid elf/tst-glibcelf consistency check failures.  glibcelf (unlike
1d4c55
    tst-glibcelf) does not use the C implementation to extract constants.
1d4c55
    This applies the additional glibcpp syntax checks to <elf.h>.
1d4c55
    
1d4c55
    This  changereplaces the types derived from Python enum types with
1d4c55
    custom types _TypedConstant, _IntConstant, and _FlagConstant.  These
1d4c55
    types have fewer safeguards, but this also allows incremental
1d4c55
    construction and greater flexibility for grouping constants among
1d4c55
    the types.  Architectures-specific named constants are now added
1d4c55
    as members into their superclasses (but value-based lookup is
1d4c55
    still restricted to generic constants only).
1d4c55
    
1d4c55
    Consequently, check_duplicates in elf/tst-glibcelf has been adjusted
1d4c55
    to accept differently-named constants of the same value if their
1d4c55
    subtypes are distinct.  The ordering check for named constants
1d4c55
    has been dropped because they are no longer strictly ordered.
1d4c55
    
1d4c55
    Further test adjustments: Some of the type names are different.
1d4c55
    The new types do not support iteration (because it is unclear
1d4c55
    whether iteration should cover the all named values (including
1d4c55
    architecture-specific constants), or only the generic named values),
1d4c55
    so elf/tst-glibcelf now uses by_name explicit (to get all constants).
1d4c55
    PF_HP_SBP and PF_PARISC_SBP are now of distinct types (PfHP and
1d4c55
    PfPARISC), so they are how both present on the Python side.  EM_NUM
1d4c55
    and PT_NUM are filtered (which was an oversight in the old
1d4c55
    conversion).
1d4c55
    
1d4c55
    The new version of glibcelf should also be compatible with earlier
1d4c55
    Python versions because it no longer depends on the enum module and its
1d4c55
    advanced features.
1d4c55
    
1d4c55
    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
1d4c55
1d4c55
diff --git a/elf/tst-glibcelf.py b/elf/tst-glibcelf.py
1d4c55
index e5026e2289df206b..a5bff45eae55edea 100644
1d4c55
--- a/elf/tst-glibcelf.py
1d4c55
+++ b/elf/tst-glibcelf.py
1d4c55
@@ -18,7 +18,6 @@
1d4c55
 # <https://www.gnu.org/licenses/>.
1d4c55
 
1d4c55
 import argparse
1d4c55
-import enum
1d4c55
 import sys
1d4c55
 
1d4c55
 import glibcelf
1d4c55
@@ -45,11 +44,57 @@ def find_constant_prefix(name):
1d4c55
 
1d4c55
 def find_enum_types():
1d4c55
     """A generator for OpenIntEnum and IntFlag classes in glibcelf."""
1d4c55
+    classes = set((glibcelf._TypedConstant, glibcelf._IntConstant,
1d4c55
+                   glibcelf._FlagConstant))
1d4c55
     for obj in vars(glibcelf).values():
1d4c55
-        if isinstance(obj, type) and obj.__bases__[0] in (
1d4c55
-                glibcelf._OpenIntEnum, enum.Enum, enum.IntFlag):
1d4c55
+        if isinstance(obj, type) and obj not in classes \
1d4c55
+           and obj.__bases__[0] in classes:
1d4c55
             yield obj
1d4c55
 
1d4c55
+def check_basic():
1d4c55
+    """Check basic functionality of the constant classes."""
1d4c55
+
1d4c55
+    if glibcelf.Pt.PT_NULL is not glibcelf.Pt(0):
1d4c55
+        error('Pt(0) not interned')
1d4c55
+    if glibcelf.Pt(17609) is glibcelf.Pt(17609):
1d4c55
+        error('Pt(17609) unexpectedly interned')
1d4c55
+    if glibcelf.Pt(17609) == glibcelf.Pt(17609):
1d4c55
+        pass
1d4c55
+    else:
1d4c55
+        error('Pt(17609) equality')
1d4c55
+    if glibcelf.Pt(17610) == glibcelf.Pt(17609):
1d4c55
+        error('Pt(17610) equality')
1d4c55
+
1d4c55
+    if str(glibcelf.Pt.PT_NULL) != 'PT_NULL':
1d4c55
+        error('str(PT_NULL)')
1d4c55
+    if str(glibcelf.Pt(17609)) != '17609':
1d4c55
+        error('str(Pt(17609))')
1d4c55
+
1d4c55
+    if repr(glibcelf.Pt.PT_NULL) != 'PT_NULL':
1d4c55
+        error('repr(PT_NULL)')
1d4c55
+    if repr(glibcelf.Pt(17609)) != 'Pt(17609)':
1d4c55
+        error('repr(Pt(17609))')
1d4c55
+
1d4c55
+    if glibcelf.Pt('PT_AARCH64_MEMTAG_MTE') \
1d4c55
+       is not glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
1d4c55
+        error('PT_AARCH64_MEMTAG_MTE identity')
1d4c55
+    if glibcelf.Pt(0x70000002) is glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
1d4c55
+        error('Pt(0x70000002) identity')
1d4c55
+    if glibcelf.PtAARCH64(0x70000002) is not glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
1d4c55
+        error('PtAARCH64(0x70000002) identity')
1d4c55
+    if glibcelf.Pt.PT_AARCH64_MEMTAG_MTE.short_name != 'AARCH64_MEMTAG_MTE':
1d4c55
+        error('PT_AARCH64_MEMTAG_MTE short name')
1d4c55
+
1d4c55
+    # Special cases for int-like Shn.
1d4c55
+    if glibcelf.Shn(32) == glibcelf.Shn.SHN_XINDEX:
1d4c55
+        error('Shn(32)')
1d4c55
+    if glibcelf.Shn(32) + 0 != 32:
1d4c55
+        error('Shn(32) + 0')
1d4c55
+    if 32 in glibcelf.Shn:
1d4c55
+        error('32 in Shn')
1d4c55
+    if 0 not in glibcelf.Shn:
1d4c55
+        error('0 not in Shn')
1d4c55
+
1d4c55
 def check_duplicates():
1d4c55
     """Verifies that enum types do not have duplicate values.
1d4c55
 
1d4c55
@@ -59,17 +104,16 @@ def check_duplicates():
1d4c55
     global_seen = {}
1d4c55
     for typ in find_enum_types():
1d4c55
         seen = {}
1d4c55
-        last = None
1d4c55
-        for (name, e) in typ.__members__.items():
1d4c55
+        for (name, e) in typ.by_name.items():
1d4c55
             if e.value in seen:
1d4c55
-                error('{} has {}={} and {}={}'.format(
1d4c55
-                    typ, seen[e.value], e.value, name, e.value))
1d4c55
-                last = e
1d4c55
+                other = seen[e.value]
1d4c55
+                # Value conflicts only count if they are between
1d4c55
+                # the same base type.
1d4c55
+                if e.__class__ is typ and other.__class__ is typ:
1d4c55
+                    error('{} has {}={} and {}={}'.format(
1d4c55
+                        typ, other, e.value, name, e.value))
1d4c55
             else:
1d4c55
                 seen[e.value] = name
1d4c55
-                if last is not None and last.value > e.value:
1d4c55
-                    error('{} has {}={} after {}={}'.format(
1d4c55
-                        typ, name, e.value, last.name, last.value))
1d4c55
                 if name in global_seen:
1d4c55
                     error('{} used in {} and {}'.format(
1d4c55
                         name, global_seen[name], typ))
1d4c55
@@ -81,7 +125,7 @@ def check_constant_prefixes():
1d4c55
     seen = set()
1d4c55
     for typ in find_enum_types():
1d4c55
         typ_prefix = None
1d4c55
-        for val in typ:
1d4c55
+        for val in typ.by_name.values():
1d4c55
             prefix = find_constant_prefix(val.name)
1d4c55
             if prefix is None:
1d4c55
                 error('constant {!r} for {} has unknown prefix'.format(
1d4c55
@@ -113,7 +157,6 @@ def find_elf_h_constants(cc):
1d4c55
 # used in <elf.h>.
1d4c55
 glibcelf_skipped_aliases = (
1d4c55
     ('EM_ARC_A5', 'EM_ARC_COMPACT'),
1d4c55
-    ('PF_PARISC_SBP', 'PF_HP_SBP')
1d4c55
 )
1d4c55
 
1d4c55
 # Constants that provide little value and are not included in
1d4c55
@@ -146,6 +189,7 @@ DT_VALRNGLO
1d4c55
 DT_VERSIONTAGNUM
1d4c55
 ELFCLASSNUM
1d4c55
 ELFDATANUM
1d4c55
+EM_NUM
1d4c55
 ET_HIOS
1d4c55
 ET_HIPROC
1d4c55
 ET_LOOS
1d4c55
@@ -159,6 +203,7 @@ PT_HISUNW
1d4c55
 PT_LOOS
1d4c55
 PT_LOPROC
1d4c55
 PT_LOSUNW
1d4c55
+PT_NUM
1d4c55
 SHF_MASKOS
1d4c55
 SHF_MASKPROC
1d4c55
 SHN_HIOS
1d4c55
@@ -193,7 +238,7 @@ def check_constant_values(cc):
1d4c55
     """Checks the values of <elf.h> constants against glibcelf."""
1d4c55
 
1d4c55
     glibcelf_constants = {
1d4c55
-        e.name: e for typ in find_enum_types() for e in typ}
1d4c55
+        e.name: e for typ in find_enum_types() for e in typ.by_name.values()}
1d4c55
     elf_h_constants = find_elf_h_constants(cc=cc)
1d4c55
 
1d4c55
     missing_in_glibcelf = (set(elf_h_constants) - set(glibcelf_constants)
1d4c55
@@ -229,12 +274,13 @@ def check_constant_values(cc):
1d4c55
     for name in sorted(set(glibcelf_constants) & set(elf_h_constants)):
1d4c55
         glibcelf_value = glibcelf_constants[name].value
1d4c55
         elf_h_value = int(elf_h_constants[name])
1d4c55
-        # On 32-bit architectures <elf.h> as some constants that are
1d4c55
+        # On 32-bit architectures <elf.h> has some constants that are
1d4c55
         # parsed as signed, while they are unsigned in glibcelf.  So
1d4c55
         # far, this only affects some flag constants, so special-case
1d4c55
         # them here.
1d4c55
         if (glibcelf_value != elf_h_value
1d4c55
-            and not (isinstance(glibcelf_constants[name], enum.IntFlag)
1d4c55
+            and not (isinstance(glibcelf_constants[name],
1d4c55
+                                glibcelf._FlagConstant)
1d4c55
                      and glibcelf_value == 1 << 31
1d4c55
                      and elf_h_value == -(1 << 31))):
1d4c55
             error('{}: glibcelf has {!r}, <elf.h> has {!r}'.format(
1d4c55
@@ -266,6 +312,7 @@ def main():
1d4c55
                         help='C compiler (including options) to use')
1d4c55
     args = parser.parse_args()
1d4c55
 
1d4c55
+    check_basic()
1d4c55
     check_duplicates()
1d4c55
     check_constant_prefixes()
1d4c55
     check_constant_values(cc=args.cc)
1d4c55
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
1d4c55
index 5c8f46f590722384..420cb21943b28bba 100644
1d4c55
--- a/scripts/glibcelf.py
1d4c55
+++ b/scripts/glibcelf.py
1d4c55
@@ -25,711 +25,445 @@ parsing it.
1d4c55
 """
1d4c55
 
1d4c55
 import collections
1d4c55
-import enum
1d4c55
+import functools
1d4c55
+import os
1d4c55
 import struct
1d4c55
 
1d4c55
-if not hasattr(enum, 'IntFlag'):
1d4c55
-    import sys
1d4c55
-    sys.stdout.write(
1d4c55
-        'warning: glibcelf.py needs Python 3.6 for enum support\n')
1d4c55
-    sys.exit(77)
1d4c55
+import glibcpp
1d4c55
+
1d4c55
+class _MetaNamedValue(type):
1d4c55
+    """Used to set up _NamedValue subclasses."""
1d4c55
 
1d4c55
-class _OpenIntEnum(enum.IntEnum):
1d4c55
-    """Integer enumeration that supports arbitrary int values."""
1d4c55
     @classmethod
1d4c55
-    def _missing_(cls, value):
1d4c55
-        # See enum.IntFlag._create_pseudo_member_.  This allows
1d4c55
-        # creating of enum constants with arbitrary integer values.
1d4c55
-        pseudo_member = int.__new__(cls, value)
1d4c55
-        pseudo_member._name_ = None
1d4c55
-        pseudo_member._value_ = value
1d4c55
-        return pseudo_member
1d4c55
+    def __prepare__(metacls, cls, bases, **kwds):
1d4c55
+        # Indicates an int-based class.  Needed for types like Shn.
1d4c55
+        int_based = False
1d4c55
+        for base in bases:
1d4c55
+            if issubclass(base, int):
1d4c55
+                int_based = int
1d4c55
+                break
1d4c55
+        return dict(by_value={},
1d4c55
+                    by_name={},
1d4c55
+                    prefix=None,
1d4c55
+                    _int_based=int_based)
1d4c55
 
1d4c55
-    def __repr__(self):
1d4c55
-        name = self._name_
1d4c55
-        if name is not None:
1d4c55
-            # The names have prefixes like SHT_, implying their type.
1d4c55
-            return name
1d4c55
-        return '{}({})'.format(self.__class__.__name__, self._value_)
1d4c55
+    def __contains__(self, other):
1d4c55
+        return other in self.by_value
1d4c55
+
1d4c55
+class _NamedValue(metaclass=_MetaNamedValue):
1d4c55
+    """Typed, named integer constants.
1d4c55
+
1d4c55
+    Constants have the following instance attributes:
1d4c55
+
1d4c55
+    name: The full name of the constant (e.g., "PT_NULL").
1d4c55
+    short_name: The name with of the constant without the prefix ("NULL").
1d4c55
+    value: The integer value of the constant.
1d4c55
+
1d4c55
+    The following class attributes are available:
1d4c55
+
1d4c55
+    by_value: A dict mapping integers to constants.
1d4c55
+    by_name: A dict mapping strings to constants.
1d4c55
+    prefix: A string that is removed from the start of short names, or None.
1d4c55
+
1d4c55
+    """
1d4c55
+
1d4c55
+    def __new__(cls, arg0, arg1=None):
1d4c55
+        """Instance creation.
1d4c55
+
1d4c55
+        For the one-argument form, the argument must be a string, an
1d4c55
+        int, or an instance of this class.  Strings are looked up via
1d4c55
+        by_name.  Values are looked up via by_value; if value lookup
1d4c55
+        fails, a new unnamed instance is returned.  Instances of this
1d4c55
+        class a re returned as-is.
1d4c55
+
1d4c55
+        The two-argument form expects the name (a string) and the
1d4c55
+        value (an integer).  A new instance is created in this case.
1d4c55
+        The instance is not registered in the by_value/by_name
1d4c55
+        dictionaries (but the caller can do that).
1d4c55
+
1d4c55
+        """
1d4c55
+
1d4c55
+        typ0 = type(arg0)
1d4c55
+        if arg1 is None:
1d4c55
+            if isinstance(typ0, cls):
1d4c55
+                # Re-use the existing object.
1d4c55
+                return arg0
1d4c55
+            if typ0 is int:
1d4c55
+                by_value = cls.by_value
1d4c55
+                try:
1d4c55
+                    return by_value[arg0]
1d4c55
+                except KeyError:
1d4c55
+                    # Create a new object of the requested value.
1d4c55
+                    if cls._int_based:
1d4c55
+                        result = int.__new__(cls, arg0)
1d4c55
+                    else:
1d4c55
+                        result = object.__new__(cls)
1d4c55
+                    result.value = arg0
1d4c55
+                    result.name = None
1d4c55
+                    return result
1d4c55
+            if typ0 is str:
1d4c55
+                by_name = cls.by_name
1d4c55
+                try:
1d4c55
+                    return by_name[arg0]
1d4c55
+                except KeyError:
1d4c55
+                    raise ValueError('unknown {} constant: {!r}'.format(
1d4c55
+                        cls.__name__, arg0))
1d4c55
+        else:
1d4c55
+            # Types for the two-argument form are rigid.
1d4c55
+            if typ0 is not str and typ0 is not None:
1d4c55
+                raise ValueError('type {} of name {!r} should be str'.format(
1d4c55
+                    typ0.__name__, arg0))
1d4c55
+            if type(arg1) is not int:
1d4c55
+                raise ValueError('type {} of value {!r} should be int'.format(
1d4c55
+                    type(arg1).__name__, arg1))
1d4c55
+            # Create a new named constants.
1d4c55
+            if cls._int_based:
1d4c55
+                result = int.__new__(cls, arg1)
1d4c55
+            else:
1d4c55
+                result = object.__new__(cls)
1d4c55
+            result.value = arg1
1d4c55
+            result.name = arg0
1d4c55
+            # Set up the short_name attribute.
1d4c55
+            prefix = cls.prefix
1d4c55
+            if prefix and arg0.startswith(prefix):
1d4c55
+                result.short_name = arg0[len(prefix):]
1d4c55
+            else:
1d4c55
+                result.short_name = arg0
1d4c55
+            return result
1d4c55
 
1d4c55
     def __str__(self):
1d4c55
-        name = self._name_
1d4c55
-        if name is not None:
1d4c55
+        name = self.name
1d4c55
+        if name:
1d4c55
+            return name
1d4c55
+        else:
1d4c55
+            return str(self.value)
1d4c55
+
1d4c55
+    def __repr__(self):
1d4c55
+        name = self.name
1d4c55
+        if name:
1d4c55
             return name
1d4c55
-        return str(self._value_)
1d4c55
+        else:
1d4c55
+            return '{}({})'.format(self.__class__.__name__, self.value)
1d4c55
+
1d4c55
+    def __setattr__(self, name, value):
1d4c55
+        # Prevent modification of the critical attributes once they
1d4c55
+        # have been set.
1d4c55
+        if name in ('name', 'value', 'short_name') and hasattr(self, name):
1d4c55
+            raise AttributeError('can\'t set attribute {}'.format(name))
1d4c55
+        object.__setattr__(self, name, value)
1d4c55
+
1d4c55
+@functools.total_ordering
1d4c55
+class _TypedConstant(_NamedValue):
1d4c55
+    """Base class for integer-valued optionally named constants.
1d4c55
+
1d4c55
+    This type is not an integer type.
1d4c55
+
1d4c55
+    """
1d4c55
+
1d4c55
+    def __eq__(self, other):
1d4c55
+        return isinstance(other, self.__class__) and self.value == other.value
1d4c55
+
1d4c55
+    def __lt__(self, other):
1d4c55
+        return isinstance(other, self.__class__) and self.value <= other.value
1d4c55
+
1d4c55
+    def __hash__(self):
1d4c55
+        return hash(self.value)
1d4c55
+
1d4c55
+class _IntConstant(_NamedValue, int):
1d4c55
+    """Base class for integer-like optionally named constants.
1d4c55
+
1d4c55
+    Instances compare equal to the integer of the same value, and can
1d4c55
+    be used in integer arithmetic.
1d4c55
+
1d4c55
+    """
1d4c55
 
1d4c55
-class ElfClass(_OpenIntEnum):
1d4c55
+    pass
1d4c55
+
1d4c55
+class _FlagConstant(_TypedConstant, int):
1d4c55
+    pass
1d4c55
+
1d4c55
+def _parse_elf_h():
1d4c55
+    """Read ../elf/elf.h and return a dict with the constants in it."""
1d4c55
+
1d4c55
+    path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
1d4c55
+                        '..', 'elf', 'elf.h')
1d4c55
+    class TokenizerReporter:
1d4c55
+        """Report tokenizer errors to standard output."""
1d4c55
+
1d4c55
+        def __init__(self):
1d4c55
+            self.errors = 0
1d4c55
+
1d4c55
+        def error(self, token, message):
1d4c55
+            self.errors += 1
1d4c55
+            print('{}:{}:{}: error: {}'.format(
1d4c55
+                path, token.line, token.column, message))
1d4c55
+
1d4c55
+    reporter = TokenizerReporter()
1d4c55
+    with open(path) as inp:
1d4c55
+        tokens = glibcpp.tokenize_c(inp.read(), reporter)
1d4c55
+    if reporter.errors:
1d4c55
+        raise IOError('parse error in elf.h')
1d4c55
+
1d4c55
+    class MacroReporter:
1d4c55
+        """Report macro errors to standard output."""
1d4c55
+
1d4c55
+        def __init__(self):
1d4c55
+            self.errors = 0
1d4c55
+
1d4c55
+        def error(self, line, message):
1d4c55
+            errors += 1
1d4c55
+            print('{}:{}: error: {}'.format(path, line, message))
1d4c55
+
1d4c55
+        def note(self, line, message):
1d4c55
+            print('{}:{}: note: {}'.format(path, line, message))
1d4c55
+
1d4c55
+    reporter = MacroReporter()
1d4c55
+    result = glibcpp.macro_eval(glibcpp.macro_definitions(tokens), reporter)
1d4c55
+    if reporter.errors:
1d4c55
+        raise IOError('parse error in elf.h')
1d4c55
+
1d4c55
+    return result
1d4c55
+_elf_h = _parse_elf_h()
1d4c55
+del _parse_elf_h
1d4c55
+_elf_h_processed = set()
1d4c55
+
1d4c55
+def _register_elf_h(cls, prefix=None, skip=(), ranges=False, parent=None):
1d4c55
+    prefix = prefix or cls.prefix
1d4c55
+    if not prefix:
1d4c55
+        raise ValueError('missing prefix for {}'.format(cls.__name__))
1d4c55
+    by_value = cls.by_value
1d4c55
+    by_name = cls.by_name
1d4c55
+    processed = _elf_h_processed
1d4c55
+
1d4c55
+    skip = set(skip)
1d4c55
+    skip.add(prefix + 'NUM')
1d4c55
+    if ranges:
1d4c55
+        skip.add(prefix + 'LOOS')
1d4c55
+        skip.add(prefix + 'HIOS')
1d4c55
+        skip.add(prefix + 'LOPROC')
1d4c55
+        skip.add(prefix + 'HIPROC')
1d4c55
+        cls.os_range = (_elf_h[prefix + 'LOOS'], _elf_h[prefix + 'HIOS'])
1d4c55
+        cls.proc_range = (_elf_h[prefix + 'LOPROC'], _elf_h[prefix + 'HIPROC'])
1d4c55
+
1d4c55
+    # Inherit the prefix from the parent if not set.
1d4c55
+    if parent and cls.prefix is None and parent.prefix is not None:
1d4c55
+        cls.prefix = parent.prefix
1d4c55
+
1d4c55
+    processed_len_start = len(processed)
1d4c55
+    for name, value in _elf_h.items():
1d4c55
+        if name in skip or name in processed:
1d4c55
+            continue
1d4c55
+        if name.startswith(prefix):
1d4c55
+            processed.add(name)
1d4c55
+            if value in by_value:
1d4c55
+                raise ValueError('duplicate value {}: {}, {}'.format(
1d4c55
+                    value, name, by_value[value]))
1d4c55
+            obj = cls(name, value)
1d4c55
+            by_value[value] = obj
1d4c55
+            by_name[name] = obj
1d4c55
+            setattr(cls, name, obj)
1d4c55
+            if parent:
1d4c55
+                # Make the symbolic name available through the parent as well.
1d4c55
+                parent.by_name[name] = obj
1d4c55
+                setattr(parent, name, obj)
1d4c55
+
1d4c55
+    if len(processed) == processed_len_start:
1d4c55
+        raise ValueError('nothing matched prefix {!r}'.format(prefix))
1d4c55
+
1d4c55
+class ElfClass(_TypedConstant):
1d4c55
     """ELF word size.  Type of EI_CLASS values."""
1d4c55
-    ELFCLASSNONE = 0
1d4c55
-    ELFCLASS32 = 1
1d4c55
-    ELFCLASS64 = 2
1d4c55
+_register_elf_h(ElfClass, prefix='ELFCLASS')
1d4c55
 
1d4c55
-class ElfData(_OpenIntEnum):
1d4c55
+class ElfData(_TypedConstant):
1d4c55
     """ELF endianess.  Type of EI_DATA values."""
1d4c55
-    ELFDATANONE = 0
1d4c55
-    ELFDATA2LSB = 1
1d4c55
-    ELFDATA2MSB = 2
1d4c55
+_register_elf_h(ElfData, prefix='ELFDATA')
1d4c55
 
1d4c55
-class Machine(_OpenIntEnum):
1d4c55
+class Machine(_TypedConstant):
1d4c55
     """ELF machine type.  Type of values in Ehdr.e_machine field."""
1d4c55
-    EM_NONE = 0
1d4c55
-    EM_M32 = 1
1d4c55
-    EM_SPARC = 2
1d4c55
-    EM_386 = 3
1d4c55
-    EM_68K = 4
1d4c55
-    EM_88K = 5
1d4c55
-    EM_IAMCU = 6
1d4c55
-    EM_860 = 7
1d4c55
-    EM_MIPS = 8
1d4c55
-    EM_S370 = 9
1d4c55
-    EM_MIPS_RS3_LE = 10
1d4c55
-    EM_PARISC = 15
1d4c55
-    EM_VPP500 = 17
1d4c55
-    EM_SPARC32PLUS = 18
1d4c55
-    EM_960 = 19
1d4c55
-    EM_PPC = 20
1d4c55
-    EM_PPC64 = 21
1d4c55
-    EM_S390 = 22
1d4c55
-    EM_SPU = 23
1d4c55
-    EM_V800 = 36
1d4c55
-    EM_FR20 = 37
1d4c55
-    EM_RH32 = 38
1d4c55
-    EM_RCE = 39
1d4c55
-    EM_ARM = 40
1d4c55
-    EM_FAKE_ALPHA = 41
1d4c55
-    EM_SH = 42
1d4c55
-    EM_SPARCV9 = 43
1d4c55
-    EM_TRICORE = 44
1d4c55
-    EM_ARC = 45
1d4c55
-    EM_H8_300 = 46
1d4c55
-    EM_H8_300H = 47
1d4c55
-    EM_H8S = 48
1d4c55
-    EM_H8_500 = 49
1d4c55
-    EM_IA_64 = 50
1d4c55
-    EM_MIPS_X = 51
1d4c55
-    EM_COLDFIRE = 52
1d4c55
-    EM_68HC12 = 53
1d4c55
-    EM_MMA = 54
1d4c55
-    EM_PCP = 55
1d4c55
-    EM_NCPU = 56
1d4c55
-    EM_NDR1 = 57
1d4c55
-    EM_STARCORE = 58
1d4c55
-    EM_ME16 = 59
1d4c55
-    EM_ST100 = 60
1d4c55
-    EM_TINYJ = 61
1d4c55
-    EM_X86_64 = 62
1d4c55
-    EM_PDSP = 63
1d4c55
-    EM_PDP10 = 64
1d4c55
-    EM_PDP11 = 65
1d4c55
-    EM_FX66 = 66
1d4c55
-    EM_ST9PLUS = 67
1d4c55
-    EM_ST7 = 68
1d4c55
-    EM_68HC16 = 69
1d4c55
-    EM_68HC11 = 70
1d4c55
-    EM_68HC08 = 71
1d4c55
-    EM_68HC05 = 72
1d4c55
-    EM_SVX = 73
1d4c55
-    EM_ST19 = 74
1d4c55
-    EM_VAX = 75
1d4c55
-    EM_CRIS = 76
1d4c55
-    EM_JAVELIN = 77
1d4c55
-    EM_FIREPATH = 78
1d4c55
-    EM_ZSP = 79
1d4c55
-    EM_MMIX = 80
1d4c55
-    EM_HUANY = 81
1d4c55
-    EM_PRISM = 82
1d4c55
-    EM_AVR = 83
1d4c55
-    EM_FR30 = 84
1d4c55
-    EM_D10V = 85
1d4c55
-    EM_D30V = 86
1d4c55
-    EM_V850 = 87
1d4c55
-    EM_M32R = 88
1d4c55
-    EM_MN10300 = 89
1d4c55
-    EM_MN10200 = 90
1d4c55
-    EM_PJ = 91
1d4c55
-    EM_OPENRISC = 92
1d4c55
-    EM_ARC_COMPACT = 93
1d4c55
-    EM_XTENSA = 94
1d4c55
-    EM_VIDEOCORE = 95
1d4c55
-    EM_TMM_GPP = 96
1d4c55
-    EM_NS32K = 97
1d4c55
-    EM_TPC = 98
1d4c55
-    EM_SNP1K = 99
1d4c55
-    EM_ST200 = 100
1d4c55
-    EM_IP2K = 101
1d4c55
-    EM_MAX = 102
1d4c55
-    EM_CR = 103
1d4c55
-    EM_F2MC16 = 104
1d4c55
-    EM_MSP430 = 105
1d4c55
-    EM_BLACKFIN = 106
1d4c55
-    EM_SE_C33 = 107
1d4c55
-    EM_SEP = 108
1d4c55
-    EM_ARCA = 109
1d4c55
-    EM_UNICORE = 110
1d4c55
-    EM_EXCESS = 111
1d4c55
-    EM_DXP = 112
1d4c55
-    EM_ALTERA_NIOS2 = 113
1d4c55
-    EM_CRX = 114
1d4c55
-    EM_XGATE = 115
1d4c55
-    EM_C166 = 116
1d4c55
-    EM_M16C = 117
1d4c55
-    EM_DSPIC30F = 118
1d4c55
-    EM_CE = 119
1d4c55
-    EM_M32C = 120
1d4c55
-    EM_TSK3000 = 131
1d4c55
-    EM_RS08 = 132
1d4c55
-    EM_SHARC = 133
1d4c55
-    EM_ECOG2 = 134
1d4c55
-    EM_SCORE7 = 135
1d4c55
-    EM_DSP24 = 136
1d4c55
-    EM_VIDEOCORE3 = 137
1d4c55
-    EM_LATTICEMICO32 = 138
1d4c55
-    EM_SE_C17 = 139
1d4c55
-    EM_TI_C6000 = 140
1d4c55
-    EM_TI_C2000 = 141
1d4c55
-    EM_TI_C5500 = 142
1d4c55
-    EM_TI_ARP32 = 143
1d4c55
-    EM_TI_PRU = 144
1d4c55
-    EM_MMDSP_PLUS = 160
1d4c55
-    EM_CYPRESS_M8C = 161
1d4c55
-    EM_R32C = 162
1d4c55
-    EM_TRIMEDIA = 163
1d4c55
-    EM_QDSP6 = 164
1d4c55
-    EM_8051 = 165
1d4c55
-    EM_STXP7X = 166
1d4c55
-    EM_NDS32 = 167
1d4c55
-    EM_ECOG1X = 168
1d4c55
-    EM_MAXQ30 = 169
1d4c55
-    EM_XIMO16 = 170
1d4c55
-    EM_MANIK = 171
1d4c55
-    EM_CRAYNV2 = 172
1d4c55
-    EM_RX = 173
1d4c55
-    EM_METAG = 174
1d4c55
-    EM_MCST_ELBRUS = 175
1d4c55
-    EM_ECOG16 = 176
1d4c55
-    EM_CR16 = 177
1d4c55
-    EM_ETPU = 178
1d4c55
-    EM_SLE9X = 179
1d4c55
-    EM_L10M = 180
1d4c55
-    EM_K10M = 181
1d4c55
-    EM_AARCH64 = 183
1d4c55
-    EM_AVR32 = 185
1d4c55
-    EM_STM8 = 186
1d4c55
-    EM_TILE64 = 187
1d4c55
-    EM_TILEPRO = 188
1d4c55
-    EM_MICROBLAZE = 189
1d4c55
-    EM_CUDA = 190
1d4c55
-    EM_TILEGX = 191
1d4c55
-    EM_CLOUDSHIELD = 192
1d4c55
-    EM_COREA_1ST = 193
1d4c55
-    EM_COREA_2ND = 194
1d4c55
-    EM_ARCV2 = 195
1d4c55
-    EM_OPEN8 = 196
1d4c55
-    EM_RL78 = 197
1d4c55
-    EM_VIDEOCORE5 = 198
1d4c55
-    EM_78KOR = 199
1d4c55
-    EM_56800EX = 200
1d4c55
-    EM_BA1 = 201
1d4c55
-    EM_BA2 = 202
1d4c55
-    EM_XCORE = 203
1d4c55
-    EM_MCHP_PIC = 204
1d4c55
-    EM_INTELGT = 205
1d4c55
-    EM_KM32 = 210
1d4c55
-    EM_KMX32 = 211
1d4c55
-    EM_EMX16 = 212
1d4c55
-    EM_EMX8 = 213
1d4c55
-    EM_KVARC = 214
1d4c55
-    EM_CDP = 215
1d4c55
-    EM_COGE = 216
1d4c55
-    EM_COOL = 217
1d4c55
-    EM_NORC = 218
1d4c55
-    EM_CSR_KALIMBA = 219
1d4c55
-    EM_Z80 = 220
1d4c55
-    EM_VISIUM = 221
1d4c55
-    EM_FT32 = 222
1d4c55
-    EM_MOXIE = 223
1d4c55
-    EM_AMDGPU = 224
1d4c55
-    EM_RISCV = 243
1d4c55
-    EM_BPF = 247
1d4c55
-    EM_CSKY = 252
1d4c55
-    EM_LOONGARCH = 258
1d4c55
-    EM_NUM = 259
1d4c55
-    EM_ALPHA = 0x9026
1d4c55
-
1d4c55
-class Et(_OpenIntEnum):
1d4c55
+    prefix = 'EM_'
1d4c55
+_register_elf_h(Machine, skip=('EM_ARC_A5',))
1d4c55
+
1d4c55
+class Et(_TypedConstant):
1d4c55
     """ELF file type.  Type of ET_* values and the Ehdr.e_type field."""
1d4c55
-    ET_NONE = 0
1d4c55
-    ET_REL = 1
1d4c55
-    ET_EXEC = 2
1d4c55
-    ET_DYN = 3
1d4c55
-    ET_CORE = 4
1d4c55
+    prefix = 'ET_'
1d4c55
+_register_elf_h(Et, ranges=True)
1d4c55
 
1d4c55
-class Shn(_OpenIntEnum):
1d4c55
+class Shn(_IntConstant):
1d4c55
     """ELF reserved section indices."""
1d4c55
-    SHN_UNDEF = 0
1d4c55
-    SHN_BEFORE = 0xff00
1d4c55
-    SHN_AFTER = 0xff01
1d4c55
-    SHN_ABS = 0xfff1
1d4c55
-    SHN_COMMON = 0xfff2
1d4c55
-    SHN_XINDEX = 0xffff
1d4c55
-
1d4c55
-class ShnMIPS(enum.Enum):
1d4c55
+    prefix = 'SHN_'
1d4c55
+class ShnMIPS(Shn):
1d4c55
     """Supplemental SHN_* constants for EM_MIPS."""
1d4c55
-    SHN_MIPS_ACOMMON = 0xff00
1d4c55
-    SHN_MIPS_TEXT = 0xff01
1d4c55
-    SHN_MIPS_DATA = 0xff02
1d4c55
-    SHN_MIPS_SCOMMON = 0xff03
1d4c55
-    SHN_MIPS_SUNDEFINED = 0xff04
1d4c55
-
1d4c55
-class ShnPARISC(enum.Enum):
1d4c55
+class ShnPARISC(Shn):
1d4c55
     """Supplemental SHN_* constants for EM_PARISC."""
1d4c55
-    SHN_PARISC_ANSI_COMMON = 0xff00
1d4c55
-    SHN_PARISC_HUGE_COMMON = 0xff01
1d4c55
+_register_elf_h(ShnMIPS, prefix='SHN_MIPS_', parent=Shn)
1d4c55
+_register_elf_h(ShnPARISC, prefix='SHN_PARISC_', parent=Shn)
1d4c55
+_register_elf_h(Shn, skip='SHN_LORESERVE SHN_HIRESERVE'.split(), ranges=True)
1d4c55
 
1d4c55
-class Sht(_OpenIntEnum):
1d4c55
+class Sht(_TypedConstant):
1d4c55
     """ELF section types.  Type of SHT_* values."""
1d4c55
-    SHT_NULL = 0
1d4c55
-    SHT_PROGBITS = 1
1d4c55
-    SHT_SYMTAB = 2
1d4c55
-    SHT_STRTAB = 3
1d4c55
-    SHT_RELA = 4
1d4c55
-    SHT_HASH = 5
1d4c55
-    SHT_DYNAMIC = 6
1d4c55
-    SHT_NOTE = 7
1d4c55
-    SHT_NOBITS = 8
1d4c55
-    SHT_REL = 9
1d4c55
-    SHT_SHLIB = 10
1d4c55
-    SHT_DYNSYM = 11
1d4c55
-    SHT_INIT_ARRAY = 14
1d4c55
-    SHT_FINI_ARRAY = 15
1d4c55
-    SHT_PREINIT_ARRAY = 16
1d4c55
-    SHT_GROUP = 17
1d4c55
-    SHT_SYMTAB_SHNDX = 18
1d4c55
-    SHT_RELR = 19
1d4c55
-    SHT_GNU_ATTRIBUTES = 0x6ffffff5
1d4c55
-    SHT_GNU_HASH = 0x6ffffff6
1d4c55
-    SHT_GNU_LIBLIST = 0x6ffffff7
1d4c55
-    SHT_CHECKSUM = 0x6ffffff8
1d4c55
-    SHT_SUNW_move = 0x6ffffffa
1d4c55
-    SHT_SUNW_COMDAT = 0x6ffffffb
1d4c55
-    SHT_SUNW_syminfo = 0x6ffffffc
1d4c55
-    SHT_GNU_verdef = 0x6ffffffd
1d4c55
-    SHT_GNU_verneed = 0x6ffffffe
1d4c55
-    SHT_GNU_versym = 0x6fffffff
1d4c55
-
1d4c55
-class ShtALPHA(enum.Enum):
1d4c55
+    prefix = 'SHT_'
1d4c55
+class ShtALPHA(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_ALPHA."""
1d4c55
-    SHT_ALPHA_DEBUG = 0x70000001
1d4c55
-    SHT_ALPHA_REGINFO = 0x70000002
1d4c55
-
1d4c55
-class ShtARM(enum.Enum):
1d4c55
+class ShtARM(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_ARM."""
1d4c55
-    SHT_ARM_EXIDX = 0x70000001
1d4c55
-    SHT_ARM_PREEMPTMAP = 0x70000002
1d4c55
-    SHT_ARM_ATTRIBUTES = 0x70000003
1d4c55
-
1d4c55
-class ShtCSKY(enum.Enum):
1d4c55
+class ShtCSKY(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_CSKY."""
1d4c55
-    SHT_CSKY_ATTRIBUTES = 0x70000001
1d4c55
-
1d4c55
-class ShtIA_64(enum.Enum):
1d4c55
+class ShtIA_64(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_IA_64."""
1d4c55
-    SHT_IA_64_EXT = 0x70000000
1d4c55
-    SHT_IA_64_UNWIND = 0x70000001
1d4c55
-
1d4c55
-class ShtMIPS(enum.Enum):
1d4c55
+class ShtMIPS(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_MIPS."""
1d4c55
-    SHT_MIPS_LIBLIST = 0x70000000
1d4c55
-    SHT_MIPS_MSYM = 0x70000001
1d4c55
-    SHT_MIPS_CONFLICT = 0x70000002
1d4c55
-    SHT_MIPS_GPTAB = 0x70000003
1d4c55
-    SHT_MIPS_UCODE = 0x70000004
1d4c55
-    SHT_MIPS_DEBUG = 0x70000005
1d4c55
-    SHT_MIPS_REGINFO = 0x70000006
1d4c55
-    SHT_MIPS_PACKAGE = 0x70000007
1d4c55
-    SHT_MIPS_PACKSYM = 0x70000008
1d4c55
-    SHT_MIPS_RELD = 0x70000009
1d4c55
-    SHT_MIPS_IFACE = 0x7000000b
1d4c55
-    SHT_MIPS_CONTENT = 0x7000000c
1d4c55
-    SHT_MIPS_OPTIONS = 0x7000000d
1d4c55
-    SHT_MIPS_SHDR = 0x70000010
1d4c55
-    SHT_MIPS_FDESC = 0x70000011
1d4c55
-    SHT_MIPS_EXTSYM = 0x70000012
1d4c55
-    SHT_MIPS_DENSE = 0x70000013
1d4c55
-    SHT_MIPS_PDESC = 0x70000014
1d4c55
-    SHT_MIPS_LOCSYM = 0x70000015
1d4c55
-    SHT_MIPS_AUXSYM = 0x70000016
1d4c55
-    SHT_MIPS_OPTSYM = 0x70000017
1d4c55
-    SHT_MIPS_LOCSTR = 0x70000018
1d4c55
-    SHT_MIPS_LINE = 0x70000019
1d4c55
-    SHT_MIPS_RFDESC = 0x7000001a
1d4c55
-    SHT_MIPS_DELTASYM = 0x7000001b
1d4c55
-    SHT_MIPS_DELTAINST = 0x7000001c
1d4c55
-    SHT_MIPS_DELTACLASS = 0x7000001d
1d4c55
-    SHT_MIPS_DWARF = 0x7000001e
1d4c55
-    SHT_MIPS_DELTADECL = 0x7000001f
1d4c55
-    SHT_MIPS_SYMBOL_LIB = 0x70000020
1d4c55
-    SHT_MIPS_EVENTS = 0x70000021
1d4c55
-    SHT_MIPS_TRANSLATE = 0x70000022
1d4c55
-    SHT_MIPS_PIXIE = 0x70000023
1d4c55
-    SHT_MIPS_XLATE = 0x70000024
1d4c55
-    SHT_MIPS_XLATE_DEBUG = 0x70000025
1d4c55
-    SHT_MIPS_WHIRL = 0x70000026
1d4c55
-    SHT_MIPS_EH_REGION = 0x70000027
1d4c55
-    SHT_MIPS_XLATE_OLD = 0x70000028
1d4c55
-    SHT_MIPS_PDR_EXCEPTION = 0x70000029
1d4c55
-    SHT_MIPS_XHASH = 0x7000002b
1d4c55
-
1d4c55
-class ShtPARISC(enum.Enum):
1d4c55
+class ShtPARISC(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_PARISC."""
1d4c55
-    SHT_PARISC_EXT = 0x70000000
1d4c55
-    SHT_PARISC_UNWIND = 0x70000001
1d4c55
-    SHT_PARISC_DOC = 0x70000002
1d4c55
-
1d4c55
-class ShtRISCV(enum.Enum):
1d4c55
+class ShtRISCV(Sht):
1d4c55
     """Supplemental SHT_* constants for EM_RISCV."""
1d4c55
-    SHT_RISCV_ATTRIBUTES = 0x70000003
1d4c55
-
1d4c55
-class Pf(enum.IntFlag):
1d4c55
+_register_elf_h(ShtALPHA, prefix='SHT_ALPHA_', parent=Sht)
1d4c55
+_register_elf_h(ShtARM, prefix='SHT_ARM_', parent=Sht)
1d4c55
+_register_elf_h(ShtCSKY, prefix='SHT_CSKY_', parent=Sht)
1d4c55
+_register_elf_h(ShtIA_64, prefix='SHT_IA_64_', parent=Sht)
1d4c55
+_register_elf_h(ShtMIPS, prefix='SHT_MIPS_', parent=Sht)
1d4c55
+_register_elf_h(ShtPARISC, prefix='SHT_PARISC_', parent=Sht)
1d4c55
+_register_elf_h(ShtRISCV, prefix='SHT_RISCV_', parent=Sht)
1d4c55
+_register_elf_h(Sht, ranges=True,
1d4c55
+                skip='SHT_LOSUNW SHT_HISUNW SHT_LOUSER SHT_HIUSER'.split())
1d4c55
+
1d4c55
+class Pf(_FlagConstant):
1d4c55
     """Program header flags.  Type of Phdr.p_flags values."""
1d4c55
-    PF_X = 1
1d4c55
-    PF_W = 2
1d4c55
-    PF_R = 4
1d4c55
-
1d4c55
-class PfARM(enum.IntFlag):
1d4c55
+    prefix = 'PF_'
1d4c55
+class PfARM(Pf):
1d4c55
     """Supplemental PF_* flags for EM_ARM."""
1d4c55
-    PF_ARM_SB = 0x10000000
1d4c55
-    PF_ARM_PI = 0x20000000
1d4c55
-    PF_ARM_ABS = 0x40000000
1d4c55
-
1d4c55
-class PfPARISC(enum.IntFlag):
1d4c55
-    """Supplemental PF_* flags for EM_PARISC."""
1d4c55
-    PF_HP_PAGE_SIZE = 0x00100000
1d4c55
-    PF_HP_FAR_SHARED = 0x00200000
1d4c55
-    PF_HP_NEAR_SHARED = 0x00400000
1d4c55
-    PF_HP_CODE = 0x01000000
1d4c55
-    PF_HP_MODIFY = 0x02000000
1d4c55
-    PF_HP_LAZYSWAP = 0x04000000
1d4c55
-    PF_HP_SBP = 0x08000000
1d4c55
-
1d4c55
-class PfIA_64(enum.IntFlag):
1d4c55
+class PfHP(Pf):
1d4c55
+    """Supplemental PF_* flags for HP-UX."""
1d4c55
+class PfIA_64(Pf):
1d4c55
     """Supplemental PF_* flags for EM_IA_64."""
1d4c55
-    PF_IA_64_NORECOV = 0x80000000
1d4c55
-
1d4c55
-class PfMIPS(enum.IntFlag):
1d4c55
+class PfMIPS(Pf):
1d4c55
     """Supplemental PF_* flags for EM_MIPS."""
1d4c55
-    PF_MIPS_LOCAL = 0x10000000
1d4c55
-
1d4c55
-class Shf(enum.IntFlag):
1d4c55
+class PfPARISC(Pf):
1d4c55
+    """Supplemental PF_* flags for EM_PARISC."""
1d4c55
+_register_elf_h(PfARM, prefix='PF_ARM_', parent=Pf)
1d4c55
+_register_elf_h(PfHP, prefix='PF_HP_', parent=Pf)
1d4c55
+_register_elf_h(PfIA_64, prefix='PF_IA_64_', parent=Pf)
1d4c55
+_register_elf_h(PfMIPS, prefix='PF_MIPS_', parent=Pf)
1d4c55
+_register_elf_h(PfPARISC, prefix='PF_PARISC_', parent=Pf)
1d4c55
+_register_elf_h(Pf, skip='PF_MASKOS PF_MASKPROC'.split())
1d4c55
+
1d4c55
+class Shf(_FlagConstant):
1d4c55
     """Section flags.  Type of Shdr.sh_type values."""
1d4c55
-    SHF_WRITE = 1 << 0
1d4c55
-    SHF_ALLOC = 1 << 1
1d4c55
-    SHF_EXECINSTR = 1 << 2
1d4c55
-    SHF_MERGE = 1 << 4
1d4c55
-    SHF_STRINGS = 1 << 5
1d4c55
-    SHF_INFO_LINK = 1 << 6
1d4c55
-    SHF_LINK_ORDER = 1 << 7
1d4c55
-    SHF_OS_NONCONFORMING = 256
1d4c55
-    SHF_GROUP = 1 << 9
1d4c55
-    SHF_TLS = 1 << 10
1d4c55
-    SHF_COMPRESSED = 1 << 11
1d4c55
-    SHF_GNU_RETAIN = 1 << 21
1d4c55
-    SHF_ORDERED = 1 << 30
1d4c55
-    SHF_EXCLUDE = 1 << 31
1d4c55
-
1d4c55
-class ShfALPHA(enum.IntFlag):
1d4c55
+    prefix = 'SHF_'
1d4c55
+class ShfALPHA(Shf):
1d4c55
     """Supplemental SHF_* constants for EM_ALPHA."""
1d4c55
-    SHF_ALPHA_GPREL = 0x10000000
1d4c55
-
1d4c55
-class ShfARM(enum.IntFlag):
1d4c55
+class ShfARM(Shf):
1d4c55
     """Supplemental SHF_* constants for EM_ARM."""
1d4c55
-    SHF_ARM_ENTRYSECT = 0x10000000
1d4c55
-    SHF_ARM_COMDEF = 0x80000000
1d4c55
-
1d4c55
-class ShfIA_64(enum.IntFlag):
1d4c55
+class ShfIA_64(Shf):
1d4c55
     """Supplemental SHF_* constants for EM_IA_64."""
1d4c55
-    SHF_IA_64_SHORT  = 0x10000000
1d4c55
-    SHF_IA_64_NORECOV = 0x20000000
1d4c55
-
1d4c55
-class ShfMIPS(enum.IntFlag):
1d4c55
+class ShfMIPS(Shf):
1d4c55
     """Supplemental SHF_* constants for EM_MIPS."""
1d4c55
-    SHF_MIPS_GPREL = 0x10000000
1d4c55
-    SHF_MIPS_MERGE = 0x20000000
1d4c55
-    SHF_MIPS_ADDR = 0x40000000
1d4c55
-    SHF_MIPS_STRINGS = 0x80000000
1d4c55
-    SHF_MIPS_NOSTRIP = 0x08000000
1d4c55
-    SHF_MIPS_LOCAL = 0x04000000
1d4c55
-    SHF_MIPS_NAMES = 0x02000000
1d4c55
-    SHF_MIPS_NODUPE = 0x01000000
1d4c55
-
1d4c55
-class ShfPARISC(enum.IntFlag):
1d4c55
+class ShfPARISC(Shf):
1d4c55
     """Supplemental SHF_* constants for EM_PARISC."""
1d4c55
-    SHF_PARISC_SHORT = 0x20000000
1d4c55
-    SHF_PARISC_HUGE = 0x40000000
1d4c55
-    SHF_PARISC_SBP = 0x80000000
1d4c55
-
1d4c55
-class Stb(_OpenIntEnum):
1d4c55
+_register_elf_h(ShfALPHA, prefix='SHF_ALPHA_', parent=Shf)
1d4c55
+_register_elf_h(ShfARM, prefix='SHF_ARM_', parent=Shf)
1d4c55
+_register_elf_h(ShfIA_64, prefix='SHF_IA_64_', parent=Shf)
1d4c55
+_register_elf_h(ShfMIPS, prefix='SHF_MIPS_', parent=Shf)
1d4c55
+_register_elf_h(ShfPARISC, prefix='SHF_PARISC_', parent=Shf)
1d4c55
+_register_elf_h(Shf, skip='SHF_MASKOS SHF_MASKPROC'.split())
1d4c55
+
1d4c55
+class Stb(_TypedConstant):
1d4c55
     """ELF symbol binding type."""
1d4c55
-    STB_LOCAL = 0
1d4c55
-    STB_GLOBAL = 1
1d4c55
-    STB_WEAK = 2
1d4c55
-    STB_GNU_UNIQUE = 10
1d4c55
-    STB_MIPS_SPLIT_COMMON = 13
1d4c55
+    prefix = 'STB_'
1d4c55
+_register_elf_h(Stb, ranges=True)
1d4c55
 
1d4c55
-class Stt(_OpenIntEnum):
1d4c55
+class Stt(_TypedConstant):
1d4c55
     """ELF symbol type."""
1d4c55
-    STT_NOTYPE = 0
1d4c55
-    STT_OBJECT = 1
1d4c55
-    STT_FUNC = 2
1d4c55
-    STT_SECTION = 3
1d4c55
-    STT_FILE = 4
1d4c55
-    STT_COMMON = 5
1d4c55
-    STT_TLS = 6
1d4c55
-    STT_GNU_IFUNC = 10
1d4c55
-
1d4c55
-class SttARM(enum.Enum):
1d4c55
+    prefix = 'STT_'
1d4c55
+class SttARM(Sht):
1d4c55
     """Supplemental STT_* constants for EM_ARM."""
1d4c55
-    STT_ARM_TFUNC = 13
1d4c55
-    STT_ARM_16BIT = 15
1d4c55
-
1d4c55
-class SttPARISC(enum.Enum):
1d4c55
+class SttPARISC(Sht):
1d4c55
     """Supplemental STT_* constants for EM_PARISC."""
1d4c55
-    STT_HP_OPAQUE = 11
1d4c55
-    STT_HP_STUB = 12
1d4c55
-    STT_PARISC_MILLICODE = 13
1d4c55
-
1d4c55
-class SttSPARC(enum.Enum):
1d4c55
+class SttSPARC(Sht):
1d4c55
     """Supplemental STT_* constants for EM_SPARC."""
1d4c55
     STT_SPARC_REGISTER = 13
1d4c55
-
1d4c55
-class SttX86_64(enum.Enum):
1d4c55
+class SttX86_64(Sht):
1d4c55
     """Supplemental STT_* constants for EM_X86_64."""
1d4c55
-    SHT_X86_64_UNWIND = 0x70000001
1d4c55
+_register_elf_h(SttARM, prefix='STT_ARM_', parent=Stt)
1d4c55
+_register_elf_h(SttPARISC, prefix='STT_PARISC_', parent=Stt)
1d4c55
+_register_elf_h(SttSPARC, prefix='STT_SPARC_', parent=Stt)
1d4c55
+_register_elf_h(Stt, ranges=True)
1d4c55
+
1d4c55
 
1d4c55
-class Pt(_OpenIntEnum):
1d4c55
+class Pt(_TypedConstant):
1d4c55
     """ELF program header types.  Type of Phdr.p_type."""
1d4c55
-    PT_NULL = 0
1d4c55
-    PT_LOAD = 1
1d4c55
-    PT_DYNAMIC = 2
1d4c55
-    PT_INTERP = 3
1d4c55
-    PT_NOTE = 4
1d4c55
-    PT_SHLIB = 5
1d4c55
-    PT_PHDR = 6
1d4c55
-    PT_TLS = 7
1d4c55
-    PT_NUM = 8
1d4c55
-    PT_GNU_EH_FRAME = 0x6474e550
1d4c55
-    PT_GNU_STACK = 0x6474e551
1d4c55
-    PT_GNU_RELRO = 0x6474e552
1d4c55
-    PT_GNU_PROPERTY = 0x6474e553
1d4c55
-    PT_SUNWBSS = 0x6ffffffa
1d4c55
-    PT_SUNWSTACK = 0x6ffffffb
1d4c55
-
1d4c55
-class PtAARCH64(enum.Enum):
1d4c55
+    prefix = 'PT_'
1d4c55
+class PtAARCH64(Pt):
1d4c55
     """Supplemental PT_* constants for EM_AARCH64."""
1d4c55
-    PT_AARCH64_MEMTAG_MTE = 0x70000002
1d4c55
-
1d4c55
-class PtARM(enum.Enum):
1d4c55
+class PtARM(Pt):
1d4c55
     """Supplemental PT_* constants for EM_ARM."""
1d4c55
-    PT_ARM_EXIDX = 0x70000001
1d4c55
-
1d4c55
-class PtIA_64(enum.Enum):
1d4c55
+class PtHP(Pt):
1d4c55
+    """Supplemental PT_* constants for HP-U."""
1d4c55
+class PtIA_64(Pt):
1d4c55
     """Supplemental PT_* constants for EM_IA_64."""
1d4c55
-    PT_IA_64_HP_OPT_ANOT = 0x60000012
1d4c55
-    PT_IA_64_HP_HSL_ANOT = 0x60000013
1d4c55
-    PT_IA_64_HP_STACK = 0x60000014
1d4c55
-    PT_IA_64_ARCHEXT = 0x70000000
1d4c55
-    PT_IA_64_UNWIND = 0x70000001
1d4c55
-
1d4c55
-class PtMIPS(enum.Enum):
1d4c55
+class PtMIPS(Pt):
1d4c55
     """Supplemental PT_* constants for EM_MIPS."""
1d4c55
-    PT_MIPS_REGINFO = 0x70000000
1d4c55
-    PT_MIPS_RTPROC = 0x70000001
1d4c55
-    PT_MIPS_OPTIONS = 0x70000002
1d4c55
-    PT_MIPS_ABIFLAGS = 0x70000003
1d4c55
-
1d4c55
-class PtPARISC(enum.Enum):
1d4c55
+class PtPARISC(Pt):
1d4c55
     """Supplemental PT_* constants for EM_PARISC."""
1d4c55
-    PT_HP_TLS = 0x60000000
1d4c55
-    PT_HP_CORE_NONE = 0x60000001
1d4c55
-    PT_HP_CORE_VERSION = 0x60000002
1d4c55
-    PT_HP_CORE_KERNEL = 0x60000003
1d4c55
-    PT_HP_CORE_COMM = 0x60000004
1d4c55
-    PT_HP_CORE_PROC = 0x60000005
1d4c55
-    PT_HP_CORE_LOADABLE = 0x60000006
1d4c55
-    PT_HP_CORE_STACK = 0x60000007
1d4c55
-    PT_HP_CORE_SHM = 0x60000008
1d4c55
-    PT_HP_CORE_MMF = 0x60000009
1d4c55
-    PT_HP_PARALLEL = 0x60000010
1d4c55
-    PT_HP_FASTBIND = 0x60000011
1d4c55
-    PT_HP_OPT_ANNOT = 0x60000012
1d4c55
-    PT_HP_HSL_ANNOT = 0x60000013
1d4c55
-    PT_HP_STACK = 0x60000014
1d4c55
-    PT_PARISC_ARCHEXT = 0x70000000
1d4c55
-    PT_PARISC_UNWIND = 0x70000001
1d4c55
-
1d4c55
-class PtRISCV(enum.Enum):
1d4c55
+class PtRISCV(Pt):
1d4c55
     """Supplemental PT_* constants for EM_RISCV."""
1d4c55
-    PT_RISCV_ATTRIBUTES = 0x70000003
1d4c55
-
1d4c55
-class Dt(_OpenIntEnum):
1d4c55
+_register_elf_h(PtAARCH64, prefix='PT_AARCH64_', parent=Pt)
1d4c55
+_register_elf_h(PtARM, prefix='PT_ARM_', parent=Pt)
1d4c55
+_register_elf_h(PtHP, prefix='PT_HP_', parent=Pt)
1d4c55
+_register_elf_h(PtIA_64, prefix='PT_IA_64_', parent=Pt)
1d4c55
+_register_elf_h(PtMIPS, prefix='PT_MIPS_', parent=Pt)
1d4c55
+_register_elf_h(PtPARISC, prefix='PT_PARISC_', parent=Pt)
1d4c55
+_register_elf_h(PtRISCV, prefix='PT_RISCV_', parent=Pt)
1d4c55
+_register_elf_h(Pt, skip='PT_LOSUNW PT_HISUNW'.split(), ranges=True)
1d4c55
+
1d4c55
+class Dt(_TypedConstant):
1d4c55
     """ELF dynamic segment tags.  Type of Dyn.d_val."""
1d4c55
-    DT_NULL = 0
1d4c55
-    DT_NEEDED = 1
1d4c55
-    DT_PLTRELSZ = 2
1d4c55
-    DT_PLTGOT = 3
1d4c55
-    DT_HASH = 4
1d4c55
-    DT_STRTAB = 5
1d4c55
-    DT_SYMTAB = 6
1d4c55
-    DT_RELA = 7
1d4c55
-    DT_RELASZ = 8
1d4c55
-    DT_RELAENT = 9
1d4c55
-    DT_STRSZ = 10
1d4c55
-    DT_SYMENT = 11
1d4c55
-    DT_INIT = 12
1d4c55
-    DT_FINI = 13
1d4c55
-    DT_SONAME = 14
1d4c55
-    DT_RPATH = 15
1d4c55
-    DT_SYMBOLIC = 16
1d4c55
-    DT_REL = 17
1d4c55
-    DT_RELSZ = 18
1d4c55
-    DT_RELENT = 19
1d4c55
-    DT_PLTREL = 20
1d4c55
-    DT_DEBUG = 21
1d4c55
-    DT_TEXTREL = 22
1d4c55
-    DT_JMPREL = 23
1d4c55
-    DT_BIND_NOW = 24
1d4c55
-    DT_INIT_ARRAY = 25
1d4c55
-    DT_FINI_ARRAY = 26
1d4c55
-    DT_INIT_ARRAYSZ = 27
1d4c55
-    DT_FINI_ARRAYSZ = 28
1d4c55
-    DT_RUNPATH = 29
1d4c55
-    DT_FLAGS = 30
1d4c55
-    DT_PREINIT_ARRAY = 32
1d4c55
-    DT_PREINIT_ARRAYSZ = 33
1d4c55
-    DT_SYMTAB_SHNDX = 34
1d4c55
-    DT_RELRSZ = 35
1d4c55
-    DT_RELR = 36
1d4c55
-    DT_RELRENT = 37
1d4c55
-    DT_GNU_PRELINKED = 0x6ffffdf5
1d4c55
-    DT_GNU_CONFLICTSZ = 0x6ffffdf6
1d4c55
-    DT_GNU_LIBLISTSZ = 0x6ffffdf7
1d4c55
-    DT_CHECKSUM = 0x6ffffdf8
1d4c55
-    DT_PLTPADSZ = 0x6ffffdf9
1d4c55
-    DT_MOVEENT = 0x6ffffdfa
1d4c55
-    DT_MOVESZ = 0x6ffffdfb
1d4c55
-    DT_FEATURE_1 = 0x6ffffdfc
1d4c55
-    DT_POSFLAG_1 = 0x6ffffdfd
1d4c55
-    DT_SYMINSZ = 0x6ffffdfe
1d4c55
-    DT_SYMINENT = 0x6ffffdff
1d4c55
-    DT_GNU_HASH = 0x6ffffef5
1d4c55
-    DT_TLSDESC_PLT = 0x6ffffef6
1d4c55
-    DT_TLSDESC_GOT = 0x6ffffef7
1d4c55
-    DT_GNU_CONFLICT = 0x6ffffef8
1d4c55
-    DT_GNU_LIBLIST = 0x6ffffef9
1d4c55
-    DT_CONFIG = 0x6ffffefa
1d4c55
-    DT_DEPAUDIT = 0x6ffffefb
1d4c55
-    DT_AUDIT = 0x6ffffefc
1d4c55
-    DT_PLTPAD = 0x6ffffefd
1d4c55
-    DT_MOVETAB = 0x6ffffefe
1d4c55
-    DT_SYMINFO = 0x6ffffeff
1d4c55
-    DT_VERSYM = 0x6ffffff0
1d4c55
-    DT_RELACOUNT = 0x6ffffff9
1d4c55
-    DT_RELCOUNT = 0x6ffffffa
1d4c55
-    DT_FLAGS_1 = 0x6ffffffb
1d4c55
-    DT_VERDEF = 0x6ffffffc
1d4c55
-    DT_VERDEFNUM = 0x6ffffffd
1d4c55
-    DT_VERNEED = 0x6ffffffe
1d4c55
-    DT_VERNEEDNUM = 0x6fffffff
1d4c55
-    DT_AUXILIARY = 0x7ffffffd
1d4c55
-    DT_FILTER = 0x7fffffff
1d4c55
-
1d4c55
-class DtAARCH64(enum.Enum):
1d4c55
+    prefix = 'DT_'
1d4c55
+class DtAARCH64(Dt):
1d4c55
     """Supplemental DT_* constants for EM_AARCH64."""
1d4c55
-    DT_AARCH64_BTI_PLT = 0x70000001
1d4c55
-    DT_AARCH64_PAC_PLT = 0x70000003
1d4c55
-    DT_AARCH64_VARIANT_PCS = 0x70000005
1d4c55
-
1d4c55
-class DtALPHA(enum.Enum):
1d4c55
+class DtALPHA(Dt):
1d4c55
     """Supplemental DT_* constants for EM_ALPHA."""
1d4c55
-    DT_ALPHA_PLTRO = 0x70000000
1d4c55
-
1d4c55
-class DtALTERA_NIOS2(enum.Enum):
1d4c55
+class DtALTERA_NIOS2(Dt):
1d4c55
     """Supplemental DT_* constants for EM_ALTERA_NIOS2."""
1d4c55
-    DT_NIOS2_GP = 0x70000002
1d4c55
-
1d4c55
-class DtIA_64(enum.Enum):
1d4c55
+class DtIA_64(Dt):
1d4c55
     """Supplemental DT_* constants for EM_IA_64."""
1d4c55
-    DT_IA_64_PLT_RESERVE = 0x70000000
1d4c55
-
1d4c55
-class DtMIPS(enum.Enum):
1d4c55
+class DtMIPS(Dt):
1d4c55
     """Supplemental DT_* constants for EM_MIPS."""
1d4c55
-    DT_MIPS_RLD_VERSION = 0x70000001
1d4c55
-    DT_MIPS_TIME_STAMP = 0x70000002
1d4c55
-    DT_MIPS_ICHECKSUM = 0x70000003
1d4c55
-    DT_MIPS_IVERSION = 0x70000004
1d4c55
-    DT_MIPS_FLAGS = 0x70000005
1d4c55
-    DT_MIPS_BASE_ADDRESS = 0x70000006
1d4c55
-    DT_MIPS_MSYM = 0x70000007
1d4c55
-    DT_MIPS_CONFLICT = 0x70000008
1d4c55
-    DT_MIPS_LIBLIST = 0x70000009
1d4c55
-    DT_MIPS_LOCAL_GOTNO = 0x7000000a
1d4c55
-    DT_MIPS_CONFLICTNO = 0x7000000b
1d4c55
-    DT_MIPS_LIBLISTNO = 0x70000010
1d4c55
-    DT_MIPS_SYMTABNO = 0x70000011
1d4c55
-    DT_MIPS_UNREFEXTNO = 0x70000012
1d4c55
-    DT_MIPS_GOTSYM = 0x70000013
1d4c55
-    DT_MIPS_HIPAGENO = 0x70000014
1d4c55
-    DT_MIPS_RLD_MAP = 0x70000016
1d4c55
-    DT_MIPS_DELTA_CLASS = 0x70000017
1d4c55
-    DT_MIPS_DELTA_CLASS_NO = 0x70000018
1d4c55
-    DT_MIPS_DELTA_INSTANCE = 0x70000019
1d4c55
-    DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a
1d4c55
-    DT_MIPS_DELTA_RELOC = 0x7000001b
1d4c55
-    DT_MIPS_DELTA_RELOC_NO = 0x7000001c
1d4c55
-    DT_MIPS_DELTA_SYM = 0x7000001d
1d4c55
-    DT_MIPS_DELTA_SYM_NO = 0x7000001e
1d4c55
-    DT_MIPS_DELTA_CLASSSYM = 0x70000020
1d4c55
-    DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021
1d4c55
-    DT_MIPS_CXX_FLAGS = 0x70000022
1d4c55
-    DT_MIPS_PIXIE_INIT = 0x70000023
1d4c55
-    DT_MIPS_SYMBOL_LIB = 0x70000024
1d4c55
-    DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025
1d4c55
-    DT_MIPS_LOCAL_GOTIDX = 0x70000026
1d4c55
-    DT_MIPS_HIDDEN_GOTIDX = 0x70000027
1d4c55
-    DT_MIPS_PROTECTED_GOTIDX = 0x70000028
1d4c55
-    DT_MIPS_OPTIONS = 0x70000029
1d4c55
-    DT_MIPS_INTERFACE = 0x7000002a
1d4c55
-    DT_MIPS_DYNSTR_ALIGN = 0x7000002b
1d4c55
-    DT_MIPS_INTERFACE_SIZE = 0x7000002c
1d4c55
-    DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d
1d4c55
-    DT_MIPS_PERF_SUFFIX = 0x7000002e
1d4c55
-    DT_MIPS_COMPACT_SIZE = 0x7000002f
1d4c55
-    DT_MIPS_GP_VALUE = 0x70000030
1d4c55
-    DT_MIPS_AUX_DYNAMIC = 0x70000031
1d4c55
-    DT_MIPS_PLTGOT = 0x70000032
1d4c55
-    DT_MIPS_RWPLT = 0x70000034
1d4c55
-    DT_MIPS_RLD_MAP_REL = 0x70000035
1d4c55
-    DT_MIPS_XHASH = 0x70000036
1d4c55
-
1d4c55
-class DtPPC(enum.Enum):
1d4c55
+class DtPPC(Dt):
1d4c55
     """Supplemental DT_* constants for EM_PPC."""
1d4c55
-    DT_PPC_GOT = 0x70000000
1d4c55
-    DT_PPC_OPT = 0x70000001
1d4c55
-
1d4c55
-class DtPPC64(enum.Enum):
1d4c55
+class DtPPC64(Dt):
1d4c55
     """Supplemental DT_* constants for EM_PPC64."""
1d4c55
-    DT_PPC64_GLINK = 0x70000000
1d4c55
-    DT_PPC64_OPD = 0x70000001
1d4c55
-    DT_PPC64_OPDSZ = 0x70000002
1d4c55
-    DT_PPC64_OPT = 0x70000003
1d4c55
-
1d4c55
-class DtRISCV(enum.Enum):
1d4c55
+class DtRISCV(Dt):
1d4c55
     """Supplemental DT_* constants for EM_RISCV."""
1d4c55
-    DT_RISCV_VARIANT_CC = 0x70000001
1d4c55
-
1d4c55
-class DtSPARC(enum.Enum):
1d4c55
+class DtSPARC(Dt):
1d4c55
     """Supplemental DT_* constants for EM_SPARC."""
1d4c55
-    DT_SPARC_REGISTER = 0x70000001
1d4c55
+_dt_skip = '''
1d4c55
+DT_ENCODING DT_PROCNUM
1d4c55
+DT_ADDRRNGLO DT_ADDRRNGHI DT_ADDRNUM
1d4c55
+DT_VALRNGLO DT_VALRNGHI DT_VALNUM
1d4c55
+DT_VERSIONTAGNUM DT_EXTRANUM
1d4c55
+DT_AARCH64_NUM
1d4c55
+DT_ALPHA_NUM
1d4c55
+DT_IA_64_NUM
1d4c55
+DT_MIPS_NUM
1d4c55
+DT_PPC_NUM
1d4c55
+DT_PPC64_NUM
1d4c55
+DT_SPARC_NUM
1d4c55
+'''.strip().split()
1d4c55
+_register_elf_h(DtAARCH64, prefix='DT_AARCH64_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtALPHA, prefix='DT_ALPHA_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtALTERA_NIOS2, prefix='DT_NIOS2_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtIA_64, prefix='DT_IA_64_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtMIPS, prefix='DT_MIPS_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtPPC, prefix='DT_PPC_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtPPC64, prefix='DT_PPC64_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtRISCV, prefix='DT_RISCV_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(DtSPARC, prefix='DT_SPARC_', skip=_dt_skip, parent=Dt)
1d4c55
+_register_elf_h(Dt, skip=_dt_skip, ranges=True)
1d4c55
+del _dt_skip
1d4c55
+
1d4c55
+# Constant extraction is complete.
1d4c55
+del _register_elf_h
1d4c55
+del _elf_h
1d4c55
 
1d4c55
 class StInfo:
1d4c55
     """ELF symbol binding and type.  Type of the Sym.st_info field."""