-//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
+//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#include "ELFObjectWriter.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELF.h"
+#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ELF.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/StringSwitch.h"
-
+#include "llvm/Support/ErrorHandling.h"
#include <vector>
using namespace llvm;
#undef DEBUG_TYPE
#define DEBUG_TYPE "reloc-info"
+namespace {
+class ELFObjectWriter : public MCObjectWriter {
+ protected:
+
+ static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+ static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
+ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
+ static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
+ bool Used, bool Renamed);
+ static bool isLocal(const MCSymbolData &Data, bool isSignature,
+ bool isUsedInReloc);
+ static bool IsELFMetaDataSection(const MCSectionData &SD);
+ static uint64_t DataSectionSize(const MCSectionData &SD);
+ static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
+ const MCSectionData &SD);
+ static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
+ const MCSectionData &SD);
+
+ void WriteDataSectionData(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCSectionELF &Section);
+
+ /*static bool isFixupKindX86RIPRel(unsigned Kind) {
+ return Kind == X86::reloc_riprel_4byte ||
+ Kind == X86::reloc_riprel_4byte_movq_load;
+ }*/
+
+ /// ELFSymbolData - Helper struct for containing some precomputed
+ /// information on symbols.
+ struct ELFSymbolData {
+ MCSymbolData *SymbolData;
+ uint64_t StringIndex;
+ uint32_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const ELFSymbolData &RHS) const {
+ if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
+ return true;
+ if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
+ return false;
+ return SymbolData->getSymbol().getName() <
+ RHS.SymbolData->getSymbol().getName();
+ }
+ };
+
+ /// The target specific ELF writer instance.
+ llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
+
+ SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+ SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
+ DenseMap<const MCSymbol *, const MCSymbol *> Renames;
+
+ llvm::DenseMap<const MCSectionData*,
+ std::vector<ELFRelocationEntry> > Relocations;
+ DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
+
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
+
+ SmallString<256> StringTable;
+ std::vector<ELFSymbolData> LocalSymbolData;
+ std::vector<ELFSymbolData> ExternalSymbolData;
+ std::vector<ELFSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+ bool NeedsGOT;
+
+ bool NeedsSymtabShndx;
+
+ // This holds the symbol table index of the last local symbol.
+ unsigned LastLocalSymbolIndex;
+ // This holds the .strtab section index.
+ unsigned StringTableIndex;
+ // This holds the .symtab section index.
+ unsigned SymbolTableIndex;
+
+ unsigned ShstrtabIndex;
+
+
+ const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
+
+ // TargetObjectWriter wrappers.
+ const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
+ }
+ const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup,
+ IsPCRel);
+ }
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool hasRelocationAddend() const {
+ return TargetObjectWriter->hasRelocationAddend();
+ }
+ unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel, bool IsRelocWithSymbol,
+ int64_t Addend) const {
+ return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel,
+ IsRelocWithSymbol, Addend);
+ }
+
+ public:
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+ raw_ostream &_OS, bool IsLittleEndian)
+ : MCObjectWriter(_OS, IsLittleEndian),
+ TargetObjectWriter(MOTW),
+ NeedsGOT(false), NeedsSymtabShndx(false) {
+ }
+
+ virtual ~ELFObjectWriter();
+
+ void WriteWord(uint64_t W) {
+ if (is64Bit())
+ Write64(W);
+ else
+ Write32(W);
+ }
+
+ void StringLE16(char *buf, uint16_t Value) {
+ buf[0] = char(Value >> 0);
+ buf[1] = char(Value >> 8);
+ }
+
+ void StringLE32(char *buf, uint32_t Value) {
+ StringLE16(buf, uint16_t(Value >> 0));
+ StringLE16(buf + 2, uint16_t(Value >> 16));
+ }
+
+ void StringLE64(char *buf, uint64_t Value) {
+ StringLE32(buf, uint32_t(Value >> 0));
+ StringLE32(buf + 4, uint32_t(Value >> 32));
+ }
+
+ void StringBE16(char *buf ,uint16_t Value) {
+ buf[0] = char(Value >> 8);
+ buf[1] = char(Value >> 0);
+ }
+
+ void StringBE32(char *buf, uint32_t Value) {
+ StringBE16(buf, uint16_t(Value >> 16));
+ StringBE16(buf + 2, uint16_t(Value >> 0));
+ }
+
+ void StringBE64(char *buf, uint64_t Value) {
+ StringBE32(buf, uint32_t(Value >> 32));
+ StringBE32(buf + 4, uint32_t(Value >> 0));
+ }
+
+ void String8(MCDataFragment &F, uint8_t Value) {
+ char buf[1];
+ buf[0] = Value;
+ F.getContents().append(&buf[0], &buf[1]);
+ }
+
+ void String16(MCDataFragment &F, uint16_t Value) {
+ char buf[2];
+ if (isLittleEndian())
+ StringLE16(buf, Value);
+ else
+ StringBE16(buf, Value);
+ F.getContents().append(&buf[0], &buf[2]);
+ }
+
+ void String32(MCDataFragment &F, uint32_t Value) {
+ char buf[4];
+ if (isLittleEndian())
+ StringLE32(buf, Value);
+ else
+ StringBE32(buf, Value);
+ F.getContents().append(&buf[0], &buf[4]);
+ }
+
+ void String64(MCDataFragment &F, uint64_t Value) {
+ char buf[8];
+ if (isLittleEndian())
+ StringLE64(buf, Value);
+ else
+ StringBE64(buf, Value);
+ F.getContents().append(&buf[0], &buf[8]);
+ }
+
+ void WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
+ unsigned NumberOfSections);
+
+ void WriteSymbolEntry(MCDataFragment *SymtabF,
+ MCDataFragment *ShndxF,
+ uint64_t name, uint8_t info,
+ uint64_t value, uint64_t size,
+ uint8_t other, uint32_t shndx,
+ bool Reserved);
+
+ void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
+ ELFSymbolData &MSD,
+ const MCAsmLayout &Layout);
+
+ typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
+ void WriteSymbolTable(MCDataFragment *SymtabF,
+ MCDataFragment *ShndxF,
+ const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap);
+
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
+ const MCSymbol *S);
+
+ // Map from a group section to the signature symbol
+ typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
+ // Map from a signature symbol to the group section
+ typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
+ // Map from a section to the section with the relocations
+ typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
+ // Map from a section to its offset
+ typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
+
+ /// ComputeSymbolTable - Compute the symbol table data
+ ///
+ /// \param Asm - The assembler.
+ /// \param SectionIndexMap - Maps a section to its index.
+ /// \param RevGroupMap - Maps a signature symbol to the group section.
+ /// \param NumRegularSections - Number of non-relocation sections.
+ void ComputeSymbolTable(MCAssembler &Asm,
+ const SectionIndexMapTy &SectionIndexMap,
+ RevGroupMapTy RevGroupMap,
+ unsigned NumRegularSections);
+
+ void ComputeIndexMap(MCAssembler &Asm,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ RelMapTy &RelMap);
+
+ void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
+ const RelMapTy &RelMap);
+
+ void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ // Create the sections that show up in the symbol table. Currently
+ // those are the .note.GNU-stack section and the group sections.
+ void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ GroupMapTy &GroupMap,
+ RevGroupMapTy &RevGroupMap,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
+ const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const SectionOffsetMapTy &SectionOffsetMap);
+
+ void ComputeSectionOrder(MCAssembler &Asm,
+ std::vector<const MCSectionELF*> &Sections);
+
+ void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
+ uint64_t Address, uint64_t Offset,
+ uint64_t Size, uint32_t Link, uint32_t Info,
+ uint64_t Alignment, uint64_t EntrySize);
+
+ void WriteRelocationsFragment(const MCAssembler &Asm,
+ MCDataFragment *F,
+ const MCSectionData *SD);
+
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteSection(MCAssembler &Asm,
+ const SectionIndexMapTy &SectionIndexMap,
+ uint32_t GroupSymbolIndex,
+ uint64_t Offset, uint64_t Size, uint64_t Alignment,
+ const MCSectionELF &Section);
+ };
+}
+
bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
const MCFixupKindInfo &FKI =
Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
{}
// Emit the ELF header.
-void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
+void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
unsigned NumberOfSections) {
// ELF Header
// ----------
sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
- Write32(getEFlags());
+ Write32(Asm.getELFHeaderEFlags());
// e_ehsize = ELF header size
Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
Data.getSymbol().isVariable();
+ // Binding and Type share the same byte as upper and lower nibbles
uint8_t Binding = MCELF::GetBinding(OrigData);
- uint8_t Visibility = MCELF::GetVisibility(OrigData);
uint8_t Type = MCELF::GetType(Data);
-
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
- uint8_t Other = Visibility;
+
+ // Other and Visibility share the same byte with Visability using the lower
+ // 2 bits
+ uint8_t Visibility = MCELF::GetVisibility(OrigData);
+ uint8_t Other = MCELF::getOther(OrigData) <<
+ (ELF_Other_Shift - ELF_STV_Shift);
+ Other |= Visibility;
uint64_t Value = SymbolValue(Data, Layout);
uint64_t Size = 0;
const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
const MCValue &Target,
- const MCFragment &F,
+ const MCFragment &F,
const MCFixup &Fixup,
bool IsPCRel) const {
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
if (ASymbol.isUndefined()) {
if (Renamed)
return Renamed;
- return &ASymbol;
+ return undefinedExplicitRelSym(Target, Fixup, IsPCRel);
}
if (SD.isExternal()) {
MCSymbolData &SD = Asm.getSymbolData(ASymbol);
MCFragment *F = SD.getFragment();
- Index = F->getParent()->getOrdinal() + 1;
-
- // Offset of the symbol in the section
- Value += Layout.getSymbolOffset(&SD);
+ if (F) {
+ Index = F->getParent()->getOrdinal() + 1;
+ // Offset of the symbol in the section
+ Value += Layout.getSymbolOffset(&SD);
+ } else {
+ Index = 0;
+ }
} else {
if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
WeakrefUsedInReloc.insert(RelocSymbol);
Index = -1;
}
Addend = Value;
- // Compensate for the addend on i386.
- if (is64Bit())
+ if (hasRelocationAddend())
Value = 0;
}
uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
Fixup.getOffset();
- // FIXME: no tests cover this. Is adjustFixupOffset dead code?
- TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset);
-
if (!hasRelocationAddend())
Addend = 0;
else
assert(isInt<32>(Addend));
- ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
+ ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
Relocations[Fragment->getParent()].push_back(ERE);
}
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
if (NeedsGOT) {
- llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
+ StringRef Name = "_GLOBAL_OFFSET_TABLE_";
MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
Data.setExternal(true);
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
- if (NumRegularSections > ELF::SHN_LORESERVE)
+ if (Index >= ELF::SHN_LORESERVE)
NeedsSymtabShndx = true;
}
else
EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
+ unsigned Flags = 0;
+ StringRef Group = "";
+ if (Section.getFlags() & ELF::SHF_GROUP) {
+ Flags = ELF::SHF_GROUP;
+ Group = Section.getGroup()->getName();
+ }
+
const MCSectionELF *RelaSection =
Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
- ELF::SHT_RELA : ELF::SHT_REL, 0,
+ ELF::SHT_RELA : ELF::SHT_REL, Flags,
SectionKind::getReadOnly(),
- EntrySize, "");
+ EntrySize, Group);
RelMap[&Section] = RelaSection;
Asm.getOrCreateSectionData(*RelaSection);
}
MCDataFragment *F,
const MCSectionData *SD) {
std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
- // sort by the r_offset just like gnu as does
- array_pod_sort(Relocs.begin(), Relocs.end());
+
+ // Sort the relocation entries. Most targets just sort by r_offset, but some
+ // (e.g., MIPS) have additional constraints.
+ TargetObjectWriter->sortRelocs(Asm, Relocs);
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
ELFRelocationEntry entry = Relocs[e - i - 1];
entry.Index += LocalSymbolData.size();
if (is64Bit()) {
String64(*F, entry.r_offset);
+ if (TargetObjectWriter->isN64()) {
+ String32(*F, entry.Index);
- struct ELF::Elf64_Rela ERE64;
- ERE64.setSymbolAndType(entry.Index, entry.Type);
- String64(*F, ERE64.r_info);
-
+ String8(*F, TargetObjectWriter->getRSsym(entry.Type));
+ String8(*F, TargetObjectWriter->getRType3(entry.Type));
+ String8(*F, TargetObjectWriter->getRType2(entry.Type));
+ String8(*F, TargetObjectWriter->getRType(entry.Type));
+ }
+ else {
+ struct ELF::Elf64_Rela ERE64;
+ ERE64.setSymbolAndType(entry.Index, entry.Type);
+ String64(*F, ERE64.r_info);
+ }
if (hasRelocationAddend())
String64(*F, entry.r_addend);
} else {
}
}
-static int compareBySuffix(const void *a, const void *b) {
- const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
- const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
- const StringRef &NameA = secA->getSectionName();
- const StringRef &NameB = secB->getSectionName();
+static int compareBySuffix(const MCSectionELF *const *a,
+ const MCSectionELF *const *b) {
+ const StringRef &NameA = (*a)->getSectionName();
+ const StringRef &NameB = (*b)->getSectionName();
const unsigned sizeA = NameA.size();
const unsigned sizeB = NameB.size();
const unsigned len = std::min(sizeA, sizeB);
// The first entry of a string table holds a null character so skip
// section 0.
uint64_t Index = 1;
- F->getContents() += '\x00';
+ F->getContents().push_back('\x00');
for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
const MCSectionELF &Section = *Sections[I];
SectionStringTableIndex[&Section] = Index;
Index += Name.size() + 1;
- F->getContents() += Name;
- F->getContents() += '\x00';
+ F->getContents().append(Name.begin(), Name.end());
+ F->getContents().push_back('\x00');
}
}
case ELF::SHT_FINI_ARRAY:
case ELF::SHT_PREINIT_ARRAY:
case ELF::SHT_X86_64_UNWIND:
+ case ELF::SHT_MIPS_REGINFO:
+ case ELF::SHT_MIPS_OPTIONS:
// Nothing to do.
break;
break;
}
+ if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
+ Section.getType() == ELF::SHT_ARM_EXIDX) {
+ StringRef SecName(Section.getSectionName());
+ if (SecName == ".ARM.exidx") {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(".text",
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ } else if (SecName.startswith(".ARM.exidx")) {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1),
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ }
+ }
+
WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
Alignment, Section.getEntrySize());
void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCSectionELF &Section) {
- uint64_t FileOff = OS.tell();
const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
- uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
+ uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
WriteZeros(Padding);
- FileOff += Padding;
-
- FileOff += GetSectionFileSize(Layout, SD);
if (IsELFMetaDataSection(SD)) {
for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
++i) {
const MCFragment &F = *i;
assert(F.getKind() == MCFragment::FT_Data);
- WriteBytes(cast<MCDataFragment>(F).getContents().str());
+ WriteBytes(cast<MCDataFragment>(F).getContents());
}
} else {
Asm.writeSectionData(&SD, Layout);
}
// Write out the ELF header ...
- WriteHeader(SectionHeaderOffset, NumSections + 1);
+ WriteHeader(Asm, SectionHeaderOffset, NumSections + 1);
// ... then the regular sections ...
// + because of .shstrtab
for (unsigned i = 0; i < NumRegularSections + 1; ++i)
WriteDataSectionData(Asm, Layout, *Sections[i]);
- FileOff = OS.tell();
- uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
+ uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
WriteZeros(Padding);
// ... then the section header table ...
WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
SectionOffsetMap);
- FileOff = OS.tell();
-
// ... and then the remaining sections ...
for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
WriteDataSectionData(Asm, Layout, *Sections[i]);