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