From: Andreas Ziegler Date: Thu, 4 Oct 2018 12:15:49 +0000 (+0200) Subject: Provide enums for DT_FLAGS and DT_FLAGS_1 (#200) X-Git-Tag: v0.26~35 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9f3bf5db24a3122b4a0e199289876c49506de9cc;p=pyelftools.git Provide enums for DT_FLAGS and DT_FLAGS_1 (#200) * Provide enums for DT_FLAGS and DT_FLAGS_1 This change adds two enums with the name to value mappings for the two flags fields in the dynamic section. The values and corresponding names are taken from the elf/elf.h file in the most recent glibc version. The enums are also used to print the names instead of the raw hex values for DT_FLAGS and DT_FLAGS_1 in scripts/readelf.py. Fixes: #189 * Add test file for DT_FLAGS/DT_FLAGS_1 parsing The test file has the DF_BIND_NOW and DF_ORIGIN flags set in DT_FLAGS as well as DF_1_NOW, DF_1_GLOBAL, DF_1_NOOPEN and DF_1_ORIGIN flags in DF_FLAGS_1. This is the source code for the dt_flags.elf file: #include int function(const char *arg){ printf("Hello, %s!", arg); return 0; } and was compiled using the following command line: $ gcc -shared -m32 \ -Wl,-rpath,'$ORIGIN/lib',-z,global,-z,origin,-z,nodlopen,-z,now \ -o testfiles_for_readelf/dt_flags.elf dt_flags.c --- diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index 022b074..5e8ff6e 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -10,7 +10,7 @@ from .enums import ( ENUM_D_TAG, ENUM_E_VERSION, ENUM_P_TYPE_BASE, ENUM_SH_TYPE_BASE, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_MIPS, - ENUM_ATTR_TAG_ARM) + ENUM_ATTR_TAG_ARM, ENUM_DT_FLAGS, ENUM_DT_FLAGS_1) from .constants import P_FLAGS, SH_FLAGS, SUNW_SYMINFO_FLAGS, VER_FLAGS from ..common.py3compat import iteritems @@ -119,6 +119,16 @@ def describe_dyn_tag(x): return _DESCR_D_TAG.get(x, _unknown) +def describe_dt_flags(x): + return ' '.join(key[3:] for key, val in + sorted(ENUM_DT_FLAGS.items(), key=lambda t: t[1]) if x & val) + + +def describe_dt_flags_1(x): + return ' '.join(key[5:] for key, val in + sorted(ENUM_DT_FLAGS_1.items(), key=lambda t: t[1]) if x & val) + + def describe_syminfo_flags(x): return ''.join(_DESCR_SYMINFO_FLAGS[flag] for flag in ( SUNW_SYMINFO_FLAGS.SYMINFO_FLG_CAP, diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py index e37effa..1ccbda6 100644 --- a/elftools/elf/enums.py +++ b/elftools/elf/enums.py @@ -605,6 +605,45 @@ ENUM_D_TAG.update(ENUM_D_TAG_SOLARIS) for k in ENUMMAP_EXTRA_D_TAG_MACHINE: ENUM_D_TAG.update(ENUMMAP_EXTRA_D_TAG_MACHINE[k]) +ENUM_DT_FLAGS = dict( + DF_ORIGIN=0x1, + DF_SYMBOLIC=0x2, + DF_TEXTREL=0x4, + DF_BIND_NOW=0x8, + DF_STATIC_TLS=0x10, +) + +ENUM_DT_FLAGS_1 = dict( + DF_1_NOW=0x1, + DF_1_GLOBAL=0x2, + DF_1_GROUP=0x4, + DF_1_NODELETE=0x8, + DF_1_LOADFLTR=0x10, + DF_1_INITFIRST=0x20, + DF_1_NOOPEN=0x40, + DF_1_ORIGIN=0x80, + DF_1_DIRECT=0x100, + DF_1_TRANS=0x200, + DF_1_INTERPOSE=0x400, + DF_1_NODEFLIB=0x800, + DF_1_NODUMP=0x1000, + DF_1_CONFALT=0x2000, + DF_1_ENDFILTEE=0x4000, + DF_1_DISPRELDNE=0x8000, + DF_1_DISPRELPND=0x10000, + DF_1_NODIRECT=0x20000, + DF_1_IGNMULDEF=0x40000, + DF_1_NOKSYMS=0x80000, + DF_1_NOHDR=0x100000, + DF_1_EDITED=0x200000, + DF_1_NORELOC=0x400000, + DF_1_SYMINTPOSE=0x800000, + DF_1_GLOBAUDIT=0x1000000, + DF_1_SINGLETON=0x2000000, + DF_1_STUB=0x4000000, + DF_1_PIE=0x8000000, +) + ENUM_RELOC_TYPE_MIPS = dict( R_MIPS_NONE=0, R_MIPS_16=1, diff --git a/scripts/readelf.py b/scripts/readelf.py index 8535119..087218a 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -37,7 +37,8 @@ from elftools.elf.descriptions import ( describe_sh_type, describe_sh_flags, describe_symbol_type, describe_symbol_bind, describe_symbol_visibility, describe_symbol_shndx, describe_reloc_type, describe_dyn_tag, - describe_ver_flags, describe_note, describe_attr_tag_arm + describe_dt_flags, describe_dt_flags_1, describe_ver_flags, describe_note, + describe_attr_tag_arm ) from elftools.elf.constants import E_FLAGS from elftools.elf.constants import E_FLAGS_MASKS @@ -425,6 +426,10 @@ class ReadElf(object): parsed = 'Library soname: [%s]' % tag.soname elif tag.entry.d_tag.endswith(('SZ', 'ENT')): parsed = '%i (bytes)' % tag['d_val'] + elif tag.entry.d_tag == 'DT_FLAGS': + parsed = describe_dt_flags(tag.entry.d_val) + elif tag.entry.d_tag == 'DT_FLAGS_1': + parsed = 'Flags: %s' % describe_dt_flags_1(tag.entry.d_val) elif tag.entry.d_tag.endswith(('NUM', 'COUNT')): parsed = '%i' % tag['d_val'] elif tag.entry.d_tag == 'DT_PLTREL': diff --git a/test/testfiles_for_readelf/dt_flags.elf b/test/testfiles_for_readelf/dt_flags.elf new file mode 100644 index 0000000..17574dd Binary files /dev/null and b/test/testfiles_for_readelf/dt_flags.elf differ