@@ -1294,6 +1294,14 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
12941294 addInt (IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
12951295 }
12961296 }
1297+ if (InX::RelrDyn && !InX::RelrDyn->Relocs .empty ()) {
1298+ addInSec (Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
1299+ InX::RelrDyn);
1300+ addSize (Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
1301+ InX::RelrDyn->getParent ());
1302+ addInt (Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
1303+ sizeof (Elf_Relr));
1304+ }
12971305 // .rel[a].plt section usually consists of two parts, containing plt and
12981306 // iplt relocations. It is possible to have only iplt relocations in the
12991307 // output. In that case RelaPlt is empty and have zero offset, the same offset
@@ -1466,6 +1474,11 @@ void RelocationBaseSection::finalizeContents() {
14661474 getParent ()->Link = Link;
14671475}
14681476
1477+ RelrBaseSection::RelrBaseSection ()
1478+ : SyntheticSection(SHF_ALLOC,
1479+ Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
1480+ Config->Wordsize, " .relr.dyn" ) {}
1481+
14691482template <class ELFT >
14701483static void encodeDynamicReloc (typename ELFT::Rela *P,
14711484 const DynamicReloc &Rel) {
@@ -1694,6 +1707,97 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
16941707 return RelocData.size () != OldSize;
16951708}
16961709
1710+ template <class ELFT > RelrSection<ELFT>::RelrSection() {
1711+ this ->Entsize = Config->Wordsize ;
1712+ }
1713+
1714+ template <class ELFT > bool RelrSection<ELFT>::updateAllocSize() {
1715+ // This function computes the contents of an SHT_RELR packed relocation
1716+ // section.
1717+ //
1718+ // Proposal for adding SHT_RELR sections to generic-abi is here:
1719+ // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
1720+ //
1721+ // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
1722+ // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
1723+ //
1724+ // i.e. start with an address, followed by any number of bitmaps. The address
1725+ // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
1726+ // relocations each, at subsequent offsets following the last address entry.
1727+ //
1728+ // The bitmap entries must have 1 in the least significant bit. The assumption
1729+ // here is that an address cannot have 1 in lsb. Odd addresses are not
1730+ // supported.
1731+ //
1732+ // Excluding the least significant bit in the bitmap, each non-zero bit in
1733+ // the bitmap represents a relocation to be applied to a corresponding machine
1734+ // word that follows the base address word. The second least significant bit
1735+ // represents the machine word immediately following the initial address, and
1736+ // each bit that follows represents the next word, in linear order. As such,
1737+ // a single bitmap can encode up to 31 relocations in a 32-bit object, and
1738+ // 63 relocations in a 64-bit object.
1739+ //
1740+ // This encoding has a couple of interesting properties:
1741+ // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
1742+ // even means address, odd means bitmap.
1743+ // 2. Just a simple list of addresses is a valid encoding.
1744+
1745+ size_t OldSize = RelrRelocs.size ();
1746+ RelrRelocs.clear ();
1747+
1748+ // Number of bits to use for the relocation offsets bitmap.
1749+ // These many relative relocations can be encoded in a single entry.
1750+ const size_t NBits = 8 * Config->Wordsize - 1 ;
1751+
1752+ // Get offsets for all relative relocations and sort them.
1753+ std::vector<uint64_t > Offsets;
1754+ for (const RelativeReloc &Rel : Relocs) {
1755+ Offsets.push_back (Rel.getOffset ());
1756+ }
1757+ std::sort (Offsets.begin (), Offsets.end ());
1758+
1759+ uint64_t Base = 0 ;
1760+ typename std::vector<uint64_t >::iterator Curr = Offsets.begin ();
1761+ while (Curr != Offsets.end ()) {
1762+ uint64_t Current = *Curr;
1763+ assert (Current % 2 == 0 );
1764+
1765+ uint64_t Bits = 0 ;
1766+ typename std::vector<uint64_t >::iterator Next = Curr;
1767+ if (Base > 0 && Base <= Current) {
1768+ while (Next != Offsets.end ()) {
1769+ uint64_t Delta = *Next - Base;
1770+ // If Next is too far out, it cannot be folded into Curr.
1771+ if (Delta >= NBits * Config->Wordsize )
1772+ break ;
1773+ // If Next is not a multiple of wordsize away, it cannot
1774+ // be folded into Curr.
1775+ if (Delta % Config->Wordsize != 0 )
1776+ break ;
1777+ // Next can be folded into Curr, add it to the bitmap.
1778+ Bits |= 1ULL << (Delta / Config->Wordsize );
1779+ ++Next;
1780+ }
1781+ }
1782+
1783+ if (Bits == 0 ) {
1784+ RelrRelocs.push_back (Elf_Relr (Current));
1785+ // This is not a continuation entry, only one offset was
1786+ // consumed. Set base offset for subsequent bitmap entries.
1787+ Base = Current + Config->Wordsize ;
1788+ ++Curr;
1789+ } else {
1790+ RelrRelocs.push_back (Elf_Relr ((Bits << 1 ) | 1 ));
1791+ // This is a continuation entry encoding multiple offsets
1792+ // in a bitmap. Advance base offset by NBits words.
1793+ Base += NBits * Config->Wordsize ;
1794+ Curr = Next;
1795+ }
1796+ }
1797+
1798+ return RelrRelocs.size () != OldSize;
1799+ }
1800+
16971801SymbolTableBaseSection::SymbolTableBaseSection (StringTableSection &StrTabSec)
16981802 : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t )SHF_ALLOC : 0,
16991803 StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
@@ -2893,6 +2997,7 @@ MipsRldMapSection *InX::MipsRldMap;
28932997PltSection *InX::Plt;
28942998PltSection *InX::Iplt;
28952999RelocationBaseSection *InX::RelaDyn;
3000+ RelrBaseSection *InX::RelrDyn;
28963001RelocationBaseSection *InX::RelaPlt;
28973002RelocationBaseSection *InX::RelaIplt;
28983003StringTableSection *InX::ShStrTab;
@@ -2954,6 +3059,11 @@ template class elf::AndroidPackedRelocationSection<ELF32BE>;
29543059template class elf ::AndroidPackedRelocationSection<ELF64LE>;
29553060template class elf ::AndroidPackedRelocationSection<ELF64BE>;
29563061
3062+ template class elf ::RelrSection<ELF32LE>;
3063+ template class elf ::RelrSection<ELF32BE>;
3064+ template class elf ::RelrSection<ELF64LE>;
3065+ template class elf ::RelrSection<ELF64BE>;
3066+
29573067template class elf ::SymbolTableSection<ELF32LE>;
29583068template class elf ::SymbolTableSection<ELF32BE>;
29593069template class elf ::SymbolTableSection<ELF64LE>;
0 commit comments