]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
[mips] add support for the "creative" GNU extensions and IRIX hilarity around MIPS...
authoradrian <adrian@FreeBSD.org>
Sun, 21 Aug 2016 00:48:41 +0000 (00:48 +0000)
committeradrian <adrian@FreeBSD.org>
Sun, 21 Aug 2016 00:48:41 +0000 (00:48 +0000)
commit0517ffff03847943c4a26b85fb44bd7ed5d31c14
treed17da29ba7a88e74c84e4969b746bfcf74c0627f
parent383d1ec924cada5cd072135121693715cd03971c
[mips] add support for the "creative" GNU extensions and IRIX hilarity around MIPS LO16/HI16 relocations.

This was .. an interesting headache.

There are two halves:

* The earlier IRIX stuff (yes, early) occasionally would do dead
  code removal and generate multiple consecutive LO16 entries.
  If this is done for REL entries then it's fine - there's no
  state kept between them.  But gcc 5.x seems to do this for
  RELA entries.

eg:

HI1 LO1 HI2 LO2 LO3 HI4 LO4

.. in this instance, LO2 should affect HI2, but LO3 doesn't at all
affect anything.  The matching HI3 was in code that was deleted
as "dead code".

Then, the next one:

* A "GCC extension" allows for multiple HI entries before a LO entry;
  and all of those HI entries use the first LO entry as their basis
  for RELA offset calculations.

It does this so GCC can also do dead code deletion without necessarily
having to geneate fake relocation entries for balanced HI/LO RELA
entries.

eg:

HI1 LO1 HI2 HI3 HI4 LO4 LO5 HI6 LO6 LO7

in this instance, HI{2,3,4} are the same relocation as LO4 (eg .bss)
and need to be buffered until LO4 - then the RELA offset is applied
from LO4 to HI{2,3,4} calculations.

/And/, the AHL from HI4 is used during the LO4 relocation calculation,
just like in the normal (ie, before this commit) implementation.

Then, LO5 doesn't trigger anything - the HI "buffer" is empty,
so there are no HI relocations to flush out.

HI6/LO6 are normal, and LO7 doesn't trigger any HI updates.

Tested:

* AR9344 SoC, kernel modules, using gcc-5.3 (mips-gcc-5.3.0 package)

Notes:

* Yes, I do feel dirty having written this code.

Reviewed by: imp (after a handful of "this should be on fire" moments wrt gcc and this code)
sys/mips/mips/elf_machdep.c