SH_FLAGS.SHF_WRITE, SH_FLAGS.SHF_ALLOC, SH_FLAGS.SHF_EXECINSTR,
SH_FLAGS.SHF_MERGE, SH_FLAGS.SHF_STRINGS, SH_FLAGS.SHF_INFO_LINK,
SH_FLAGS.SHF_LINK_ORDER, SH_FLAGS.SHF_OS_NONCONFORMING,
- SH_FLAGS.SHF_GROUP, SH_FLAGS.SHF_TLS, SH_FLAGS.SHF_EXCLUDE):
+ SH_FLAGS.SHF_GROUP, SH_FLAGS.SHF_TLS, SH_FLAGS.SHF_MASKOS,
+ SH_FLAGS.SHF_EXCLUDE):
s += _DESCR_SH_FLAGS[flag] if (x & flag) else ''
if x & SH_FLAGS.SHF_MASKPROC:
s += 'p'
SH_FLAGS.SHF_OS_NONCONFORMING: 'O',
SH_FLAGS.SHF_GROUP: 'G',
SH_FLAGS.SHF_TLS: 'T',
+ SH_FLAGS.SHF_MASKOS: 'o',
SH_FLAGS.SHF_EXCLUDE: 'E',
}
self.Elf_Chdr = Struct('Elf_Chdr', *fields)
def _create_rel(self):
- r_info = self.Elf_xword('r_info')
-
- # r_info is also taken apart into r_info_sym and r_info_type, plus
- # r_info_type2 and r_info_type3 on ELF64 MIPS. This is done in Value
- # to avoid endianity issues while parsing.
+ # r_info is also taken apart into r_info_sym and r_info_type. This is
+ # done in Value to avoid endianity issues while parsing.
if self.elfclass == 32:
- fields = [Value('r_info_sym',
+ fields = [self.Elf_xword('r_info'),
+ Value('r_info_sym',
lambda ctx: (ctx['r_info'] >> 8) & 0xFFFFFF),
Value('r_info_type',
lambda ctx: ctx['r_info'] & 0xFF)]
elif self.e_machine == 'EM_MIPS': # ELF64 MIPS
- # The r_info field in MIPS ELF64 binaries (called r_raw_info, here)
- # isn't a 64-bit field, but rather two 32-bit fields (the symbol
- # index, then three bytes for relocation types). See the
- # specification:
- # <https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf>
- # Note that the specification describes the fields more directly,
- # but here we stick to the general "r_info" field to be compatible
- # with other architectures and simplify testing.
-
- def compute_r_info(ctx):
- raw = ctx['r_raw_info']
- if not self.little_endian:
- return raw
- # little endian requires an additional byteswap
- return (((raw & 0xffffffff) << 32)
- | ((raw >> 56) & 0xff)
- | ((raw >> 40) & 0xff00)
- | ((raw >> 24) & 0xff0000)
- | ((raw >> 8) & 0xff000000))
-
- r_info = self.Elf_xword('r_raw_info')
fields = [
- Value('r_info', compute_r_info),
- Value('r_info_sym',
- lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF),
- Value('r_info_type3',
- lambda ctx: (ctx['r_info'] >> 16) & 0xFF),
- Value('r_info_type2',
- lambda ctx: (ctx['r_info'] >> 8) & 0xFF),
- Value('r_info_type',
- lambda ctx: ctx['r_info'] & 0xFF)
+ # The MIPS ELF64 specification
+ # (https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf)
+ # provides a non-standard relocation structure definition.
+ self.Elf_word('r_sym'),
+ self.Elf_byte('r_ssym'),
+ self.Elf_byte('r_type3'),
+ self.Elf_byte('r_type2'),
+ self.Elf_byte('r_type'),
+
+ # Synthetize usual fields for compatibility with other
+ # architectures. This allows relocation consumers (including
+ # our readelf tests) to work without worrying about MIPS64
+ # oddities.
+ Value('r_info_sym', lambda ctx: ctx['r_sym']),
+ Value('r_info_ssym', lambda ctx: ctx['r_ssym']),
+ Value('r_info_type', lambda ctx: ctx['r_type']),
+ Value('r_info_type2', lambda ctx: ctx['r_type2']),
+ Value('r_info_type3', lambda ctx: ctx['r_type3']),
+ Value('r_info',
+ lambda ctx: (ctx['r_sym'] << 32)
+ | (ctx['r_ssym'] << 24)
+ | (ctx['r_type3'] << 16)
+ | (ctx['r_type2'] << 8)
+ | ctx['r_type']),
]
else: # Other 64 ELFs
- fields = [Value('r_info_sym',
+ fields = [self.Elf_xword('r_info'),
+ Value('r_info_sym',
lambda ctx: (ctx['r_info'] >> 32) & 0xFFFFFFFF),
Value('r_info_type',
lambda ctx: ctx['r_info'] & 0xFFFFFFFF)]
self.Elf_Rel = Struct('Elf_Rel',
- self.Elf_addr('r_offset'),
- r_info,
- *fields
- )
+ self.Elf_addr('r_offset'),
+ *fields)
+
+ fields_and_addend = fields + [self.Elf_sxword('r_addend')]
self.Elf_Rela = Struct('Elf_Rela',
- self.Elf_addr('r_offset'),
- r_info,
- *(fields + [self.Elf_sxword('r_addend')])
+ self.Elf_addr('r_offset'),
+ *fields_and_addend
)
def _create_dyn(self):