Changeset View
Changeset View
Standalone View
Standalone View
ELF/Relocations.cpp
Show First 20 Lines • Show All 842 Lines • ▼ Show 20 Lines | template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | ||||
// the GOT slot will be fixed at load-time. | // the GOT slot will be fixed at load-time. | ||||
RelType Type; | RelType Type; | ||||
if (Sym.isTls()) | if (Sym.isTls()) | ||||
Type = Target->TlsGotRel; | Type = Target->TlsGotRel; | ||||
else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) | else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) | ||||
Type = Target->RelativeRel; | Type = Target->RelativeRel; | ||||
else | else | ||||
Type = Target->GotRel; | Type = Target->GotRel; | ||||
InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}); | InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}, R_ABS, | ||||
Target->GotRel); | |||||
// REL type relocations don't have addend fields unlike RELAs, and | |||||
// their addends are stored to the section to which they are applied. | |||||
// So, store addends if we need to. | |||||
// | |||||
// This is ugly -- the difference between REL and RELA should be | |||||
// handled in a better way. It's a TODO. | |||||
if (!Config->IsRela && !Preemptible) | |||||
InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym}); | |||||
} | } | ||||
// The reason we have to do this early scan is as follows | // The reason we have to do this early scan is as follows | ||||
// * To mmap the output file, we need to know the size | // * To mmap the output file, we need to know the size | ||||
// * For that, we need to know how many dynamic relocs we will have. | // * For that, we need to know how many dynamic relocs we will have. | ||||
// It might be possible to avoid this by outputting the file with write: | // It might be possible to avoid this by outputting the file with write: | ||||
// * Write the allocated output sections, computing addresses. | // * Write the allocated output sections, computing addresses. | ||||
// * Apply relocations, recording which ones require a dynamic reloc. | // * Apply relocations, recording which ones require a dynamic reloc. | ||||
▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Lines | if (IsConstant) { | ||||
continue; | continue; | ||||
} | } | ||||
// If the output being produced is position independent, the final value | // If the output being produced is position independent, the final value | ||||
// is still not known. In that case we still need some help from the | // is still not known. In that case we still need some help from the | ||||
// dynamic linker. We can however do better than just copying the incoming | // dynamic linker. We can however do better than just copying the incoming | ||||
// relocation. We can process some of it and and just ask the dynamic | // relocation. We can process some of it and and just ask the dynamic | ||||
// linker to add the load address. | // linker to add the load address. | ||||
if (Config->IsRela) { | |||||
InX::RelaDyn->addReloc( | |||||
{Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}); | |||||
} else { | |||||
// In REL, addends are stored to the target section. | |||||
InX::RelaDyn->addReloc( | InX::RelaDyn->addReloc( | ||||
{Target->RelativeRel, &Sec, Offset, true, &Sym, 0}); | {Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}, Expr, Type); | ||||
Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |||||
} | |||||
} | } | ||||
} | } | ||||
template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { | template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { | ||||
if (S.AreRelocsRela) | if (S.AreRelocsRela) | ||||
scanRelocs<ELFT>(S, S.relas<ELFT>()); | scanRelocs<ELFT>(S, S.relas<ELFT>()); | ||||
else | else | ||||
scanRelocs<ELFT>(S, S.rels<ELFT>()); | scanRelocs<ELFT>(S, S.rels<ELFT>()); | ||||
▲ Show 20 Lines • Show All 367 Lines • Show Last 20 Lines |