return _DESCR_ATTR_TAG_ARM[tag] + d_entry[val]
+def describe_note_gnu_property_x86_feature_1(value):
+ descs = []
+ for mask, desc in _DESCR_NOTE_GNU_PROPERTY_X86_FEATURE_1_FLAGS:
+ if value & mask:
+ descs.append(desc)
+ return 'x86 feature: ' + ', '.join(descs)
+
def describe_note_gnu_properties(properties):
descriptions = []
for prop in properties:
prop_desc = ' <corrupt length: 0x%x>' % sz
else:
prop_desc = 'no copy on protected'
+ elif t == 'GNU_PROPERTY_X86_FEATURE_1_AND':
+ if sz != 4:
+ prop_desc = ' <corrupt length: 0x%x>' % sz
+ else:
+ prop_desc = describe_note_gnu_property_x86_feature_1(d)
elif _DESCR_NOTE_GNU_PROPERTY_TYPE_LOPROC <= t <= _DESCR_NOTE_GNU_PROPERTY_TYPE_HIPROC:
prop_desc = '<processor-specific type 0x%x data: %s >' % (t, bytes2hex(d, sep=' '))
elif _DESCR_NOTE_GNU_PROPERTY_TYPE_LOUSER <= t <= _DESCR_NOTE_GNU_PROPERTY_TYPE_HIUSER:
ELF_NOTE_OS_SYLLABLE='Syllable',
)
+
# Values in GNU .note.gnu.property notes (n_type=='NT_GNU_PROPERTY_TYPE_0') have
# different formats which need to be parsed/described differently
_DESCR_NOTE_GNU_PROPERTY_TYPE_LOPROC=0xc0000000
_DESCR_NOTE_GNU_PROPERTY_TYPE_LOUSER=0xe0000000
_DESCR_NOTE_GNU_PROPERTY_TYPE_HIUSER=0xffffffff
+
+# Bit masks for GNU_PROPERTY_X86_FEATURE_1_xxx flags in the form
+# (mask, flag_description) in the desired output order
+_DESCR_NOTE_GNU_PROPERTY_X86_FEATURE_1_FLAGS = (
+ (1, 'IBT'),
+ (2, 'SHSTK'),
+ (4, 'LAM_U48'),
+ (8, 'LAM_U57'),
+)
+
+
def _reverse_dict(d, low_priority=()):
"""
This is a tiny helper function to "reverse" the keys/values of a dictionary
ENUM_NOTE_GNU_PROPERTY_TYPE = dict(
GNU_PROPERTY_STACK_SIZE=1,
GNU_PROPERTY_NO_COPY_ON_PROTECTED=2,
+ GNU_PROPERTY_X86_FEATURE_1_AND=0xc0000002,
_default_=Pass,
)
+ENUM_GNU_PROPERTY_X86_FEATURE_1_FLAGS = dict(
+ GNU_PROPERTY_X86_FEATURE_1_IBT=1,
+ GNU_PROPERTY_X86_FEATURE_1_SHSTK=2,
+ GNU_PROPERTY_X86_FEATURE_1_LAM_U48=4,
+ GNU_PROPERTY_X86_FEATURE_1_LAM_U57=8,
+ _default_=Pass
+)
+
ENUM_RELOC_TYPE_ARM = dict(
R_ARM_NONE=0,
R_ARM_PC24=1,
return roundup(ctx.pr_datasz, 2) - ctx.pr_datasz
return roundup(ctx.pr_datasz, 3) - ctx.pr_datasz
+ def classify_pr_data(ctx):
+ if type(ctx.pr_type) is not str:
+ return None
+ if ctx.pr_type.startswith('GNU_PROPERTY_X86_'):
+ return ('GNU_PROPERTY_X86_*', 4, 0)
+ return (ctx.pr_type, ctx.pr_datasz, self.elfclass)
+
self.Elf_Prop = Struct('Elf_Prop',
Enum(self.Elf_word('pr_type'), **ENUM_NOTE_GNU_PROPERTY_TYPE),
self.Elf_word('pr_datasz'),
- Switch('pr_data',
- lambda ctx: (ctx.pr_type, ctx.pr_datasz, self.elfclass),
- {
+ Switch('pr_data', classify_pr_data, {
('GNU_PROPERTY_STACK_SIZE', 4, 32): self.Elf_word('pr_data'),
- ('GNU_PROPERTY_STACK_SIZE', 8, 64): self.Elf_word64('pr_data')
+ ('GNU_PROPERTY_STACK_SIZE', 8, 64): self.Elf_word64('pr_data'),
+ ('GNU_PROPERTY_X86_*', 4, 0): self.Elf_word('pr_data'),
},
default=Field('pr_data', lambda ctx: ctx.pr_datasz)
),
for note in section.iter_notes():
self._emitline("\nDisplaying notes found in: {}".format(
section.name))
- self._emitline(' Owner Data size Description')
+ self._emitline(' Owner Data size Description')
self._emitline(' %s %s\t%s' % (
note['n_name'].ljust(20),
self._format_hex(note['n_descsz'], fieldsize=8),
* ELF executable (to also have a PT_GNU_PROPERTY program header):
* gcc -DEXE -c note_gnu_property.S -o /tmp/x.o
* ld /tmp/x.o -o note_gnu_property.elf
- * strip
*/
// https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf
// Unknown property types for testing purposes
#define GNU_PROPERTY_TEST_UNKNOWN 0x12345678
-#define GNU_PROPERTY_TEST_UNKNOWN_PROC 0xc1234567
-#define GNU_PROPERTY_TEST_UNKNOWN_USER 0xe1234567
+#define GNU_PROPERTY_TEST_UNKNOWN_PROC (GNU_PROPERTY_LOPROC + 0x1234567)
+#define GNU_PROPERTY_TEST_UNKNOWN_USER (GNU_PROPERTY_LOUSER + 0x1234567)
+// https://gitlab.com/x86-psABIs/x86-64-ABI/
// https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/x86-64-psABI
-#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
-#define GNU_PROPERTY_X86_FEATURE_1_IBT 0x00000001
-#define GNU_PROPERTY_X86_FEATURE_1_SHSTK 0x00000002
+#define GNU_PROPERTY_X86_UINT32_AND_LO 0xc0000002
+#define GNU_PROPERTY_X86_UINT32_AND_HI 0xc0007fff
+#define GNU_PROPERTY_X86_UINT32_OR_LO 0xc0008000
+#define GNU_PROPERTY_X86_UINT32_OR_HI 0xc000ffff
+#define GNU_PROPERTY_X86_UINT32_OR_AND_LO 0xc0010000
+#define GNU_PROPERTY_X86_UINT32_OR_AND_HI 0xc0017fff
+
+#define GNU_PROPERTY_X86_FEATURE_1_AND (GNU_PROPERTY_X86_UINT32_AND_LO + 0)
+#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0)
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1)
+#define GNU_PROPERTY_X86_FEATURE_1_LAM_U48 (1U << 2)
+#define GNU_PROPERTY_X86_FEATURE_1_LAM_U57 (1U << 3)
#ifdef __x86_64__
#define ALIGN .p2align 3
ALIGN
#endif
-/* TODO: add support for these later...
-6: .long GNU_PROPERTY_X86_FEATURE_1_AND // pr_type.
- .long 8f - 7f // pr_datasz
-7:
- .long GNU_PROPERTY_X86_FEATURE_1_IBT|GNU_PROPERTY_X86_FEATURE_1_SHSTK
-8:
+11: .long GNU_PROPERTY_X86_FEATURE_1_AND // pr_type.
+ .long 13f - 12f // pr_datasz
+12:
+ // Not sure if LAM_U48 and LAM_U57 make sense together, readelf does not
+ // seem to complain and outputs both.
+ .long GNU_PROPERTY_X86_FEATURE_1_IBT \
+ | GNU_PROPERTY_X86_FEATURE_1_SHSTK \
+ | GNU_PROPERTY_X86_FEATURE_1_LAM_U48 \
+ | GNU_PROPERTY_X86_FEATURE_1_LAM_U57
+13:
ALIGN
-*/
end: