+/// EmitRelocations - Emit relocations
+void ELFWriter::EmitRelocations() {
+
+ // Create Relocation sections for each section which needs it.
+ for (unsigned i=0, e=SectionList.size(); i != e; ++i) {
+ ELFSection &S = *SectionList[i];
+
+ // This section does not have relocations
+ if (!S.hasRelocations()) continue;
+
+ // Get the relocation section for section 'S'
+ bool HasRelA = TEW->hasRelocationAddend();
+ ELFSection &RelSec = getRelocSection(S.getName(), HasRelA,
+ TEW->getPrefELFAlignment());
+
+ // 'Link' - Section hdr idx of the associated symbol table
+ // 'Info' - Section hdr idx of the section to which the relocation applies
+ ELFSection &SymTab = getSymbolTableSection();
+ RelSec.Link = SymTab.SectionIdx;
+ RelSec.Info = S.SectionIdx;
+ RelSec.EntSize = TEW->getRelocationEntrySize();
+
+ // Get the relocations from Section
+ std::vector<MachineRelocation> Relos = S.getRelocations();
+ for (std::vector<MachineRelocation>::iterator MRI = Relos.begin(),
+ MRE = Relos.end(); MRI != MRE; ++MRI) {
+ MachineRelocation &MR = *MRI;
+
+ // Offset from the start of the section containing the symbol
+ unsigned Offset = MR.getMachineCodeOffset();
+
+ // Symbol index in the symbol table
+ unsigned SymIdx = 0;
+
+ // Target specific ELF relocation type
+ unsigned RelType = TEW->getRelocationType(MR.getRelocationType());
+
+ // Constant addend used to compute the value to be stored
+ // into the relocatable field
+ int64_t Addend = 0;
+
+ // There are several machine relocations types, and each one of
+ // them needs a different approach to retrieve the symbol table index.
+ if (MR.isGlobalValue()) {
+ const GlobalValue *G = MR.getGlobalValue();
+ SymIdx = GblSymLookup[G];
+ Addend = TEW->getAddendForRelTy(RelType);
+ } else {
+ // Get the symbol index for the section symbol referenced
+ // by the relocation
+ unsigned SectionIdx = MR.getConstantVal();
+ SymIdx = SectionList[SectionIdx]->Sym->SymTabIdx;
+ Addend = (uint64_t)MR.getResultPointer();
+ }
+
+ // Get the relocation entry and emit to the relocation section
+ ELFRelocation Rel(Offset, SymIdx, RelType, HasRelA, Addend);
+ EmitRelocation(RelSec, Rel, HasRelA);
+ }
+ }
+}
+
+/// EmitRelocation - Write relocation 'Rel' to the relocation section 'Rel'
+void ELFWriter::EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel,
+ bool HasRelA) {
+ RelSec.emitWord(Rel.getOffset());
+ RelSec.emitWord(Rel.getInfo(is64Bit));
+ if (HasRelA)
+ RelSec.emitWord(Rel.getAddend());
+}