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