freebsd-skq/contrib/elftoolchain
John Baldwin eb81f38a62 Fix objcopy for little-endian MIPS64 objects.
MIPS64 does not store the 'r_info' field of a relocation table entry as
a 64-bit value consisting of a 32-bit symbol index in the high 32 bits
and a 32-bit type in the low 32 bits as on other architectures.  Instead,
the 64-bit 'r_info' field is really a 32-bit symbol index followed by four
individual byte type fields.  For big-endian MIPS64, treating this as a
64-bit integer happens to be compatible with the layout expected by other
architectures (symbol index in upper 32-bits of resulting "native" 64-bit
integer).  However, for little-endian MIPS64 the parsed 64-bit integer
contains the symbol index in the low 32 bits and the 4 individual byte
type fields in the upper 32-bits (but as if the upper 32-bits were
byte-swapped).

To cope, add two helper routines in gelf_getrel.c to translate between the
correct native 'r_info' value and the value obtained after the normal
byte-swap translation.  Use these routines in gelf_getrel(), gelf_getrela(),
gelf_update_rel(), and gelf_update_rela().  This fixes 'readelf -r' on
little-endian MIPS64 objects which was previously decoding incorrect
relocations as well as 'objcopy: invalid symbox index' warnings from
objcopy when extracting debug symbols from kernel modules.

Even with this fixed, objcopy was still crashing when trying to extract
debug symbols from little-endian MIPS64 modules.  The workaround in
gelf_*rel*() depends on the current ELF object having a valid ELF header
so that the 'e_machine' field can be compared against EM_MIPS.  objcopy
was parsing the relocation entries to possibly rewrite the 'r_info' fields
in the update_relocs() function before writing the initial ELF header to
the destination object file.  Move the initial write of the ELF header
earlier before copy_contents() so that update_relocs() uses the correct
symbol index values.

Note that this change should really go upstream.  The binutils readelf
source has a similar hack for MIPS64EL though I implemented this version
from scratch using the MIPS64 ABI PDF as a reference.

Discussed with:	jkoshy
Reviewed by:	emaste, imp
Approved by:	re (gjb, kib)
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D15734
2018-09-05 20:51:53 +00:00
..
addr2line Update ELF Tool Chain to upstream r3520 2017-04-17 23:56:48 +00:00
ar Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
brandelf Use the in-tree sys/elf_common.h to build libelftc. 2016-06-05 23:05:14 +00:00
common Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
cxxfilt revert r308465: c++filt: flush output after newline 2017-05-01 01:56:11 +00:00
elfcopy Fix objcopy for little-endian MIPS64 objects. 2018-09-05 20:51:53 +00:00
elfdump Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
libdwarf Add DW_LANG_* definitions from DWARF 4 and 5. 2018-06-09 14:50:38 +00:00
libelf Fix objcopy for little-endian MIPS64 objects. 2018-09-05 20:51:53 +00:00
libelftc Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
libpe Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
nm Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00
readelf readelf: display NT_GNU_PROPERTY_TYPE_0 note name 2018-08-10 10:37:25 +00:00
size Update to ELF Tool Chain r3475 2016-05-20 17:24:34 +00:00
strings Update ELF Tool Chain to r3614 2018-04-27 13:59:24 +00:00