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