From c1f90212147e9d933ea3e66255ec07abe6d55b1a Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Fri, 5 Jan 2018 13:54:59 -0800 Subject: [PATCH] Don't include 'meta-tag' markers in descriptions of ENUM_D_TAG (#176) Fixes #150 --- elftools/elf/descriptions.py | 57 +++++++++++++++++++++--------------- test/test_dynamic.py | 13 ++++++++ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index f8b6f9b..8dc6414 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -463,30 +463,39 @@ _DESCR_NOTE_ABI_TAG_OS = dict( ELF_NOTE_OS_SYLLABLE='Syllable', ) - -_DESCR_RELOC_TYPE_i386 = dict( - (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_i386)) - - -_DESCR_RELOC_TYPE_x64 = dict( - (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_x64)) - - -_DESCR_RELOC_TYPE_ARM = dict( - (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_ARM)) - - -_DESCR_RELOC_TYPE_AARCH64 = dict( - (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_AARCH64)) - - -_DESCR_RELOC_TYPE_MIPS = dict( - (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_MIPS)) - - -_DESCR_D_TAG = dict( - (v, k) for k, v in iteritems(ENUM_D_TAG)) - +def _reverse_dict(d, low_priority=()): + """ + This is a tiny helper function to "reverse" the keys/values of a dictionary + provided in the first argument, i.e. {k: v} becomes {v: k}. + + The second argument (optional) provides primitive control over what to do in + the case of conflicting values - if a value is present in this list, it will + not override any other entries of the same value. + """ + out = {} + for k, v in iteritems(d): + if v in out and k in low_priority: + continue + out[v] = k + return out + +_DESCR_RELOC_TYPE_i386 = _reverse_dict(ENUM_RELOC_TYPE_i386) +_DESCR_RELOC_TYPE_x64 = _reverse_dict(ENUM_RELOC_TYPE_x64) +_DESCR_RELOC_TYPE_ARM = _reverse_dict(ENUM_RELOC_TYPE_ARM) +_DESCR_RELOC_TYPE_AARCH64 = _reverse_dict(ENUM_RELOC_TYPE_AARCH64) +_DESCR_RELOC_TYPE_MIPS = _reverse_dict(ENUM_RELOC_TYPE_MIPS) + +_low_priority_D_TAG = ( + # these are 'meta-tags' marking semantics of numeric ranges of the enum + # they should not override other tags with the same numbers + # see https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-42444.html + 'DT_LOOS', + 'DT_HIOS', + 'DT_LOPROC', + 'DT_HIPROC', + 'DT_ENCODING', +) +_DESCR_D_TAG = _reverse_dict(ENUM_D_TAG, low_priority=_low_priority_D_TAG) _DESCR_ATTR_TAG_ARM = dict( TAG_FILE='File Attributes', diff --git a/test/test_dynamic.py b/test/test_dynamic.py index 5284a1c..9b242f0 100644 --- a/test/test_dynamic.py +++ b/test/test_dynamic.py @@ -10,6 +10,8 @@ import os from elftools.elf.elffile import ELFFile from elftools.common.exceptions import ELFError from elftools.elf.dynamic import DynamicTag +from elftools.elf.enums import ENUM_D_TAG +from elftools.elf.descriptions import _DESCR_D_TAG, _low_priority_D_TAG class TestDynamicTag(unittest.TestCase): @@ -19,6 +21,17 @@ class TestDynamicTag(unittest.TestCase): with self.assertRaises(ELFError): dt = DynamicTag('', None) + def test_tag_priority(self): + for tag in _low_priority_D_TAG: + val = ENUM_D_TAG[tag] + # if the low priority tag is present in the descriptions, + # assert that it has not overridden any other tag + if _DESCR_D_TAG[val] == tag: + for tag2 in ENUM_D_TAG: + if tag2 == tag: + continue + self.assertNotEqual(ENUM_D_TAG[tag2], val) + class TestDynamic(unittest.TestCase): """Tests for the Dynamic class.""" -- 2.30.2