31 IndirectSymBase.clear();
33 LocalSymbolData.clear();
34 ExternalSymbolData.clear();
35 UndefinedSymbolData.clear();
56 return SymbolData->getSymbol().getName() <
57 RHS.SymbolData->getSymbol().getName();
125 unsigned LoadCommandsSize,
126 bool SubsectionsViaSymbols) {
129 if (SubsectionsViaSymbols)
135 uint64_t Start =
OS.
tell();
140 Write32(TargetObjectWriter->getCPUType());
141 Write32(TargetObjectWriter->getCPUSubtype());
150 assert(
OS.
tell() - Start ==
160 uint64_t SectionDataStartOffset,
161 uint64_t SectionDataSize) {
165 uint64_t Start =
OS.
tell();
168 unsigned SegmentLoadCommandSize =
172 Write32(SegmentLoadCommandSize +
180 Write64(SectionDataStartOffset);
185 Write32(SectionDataStartOffset);
195 assert(
OS.
tell() - Start == SegmentLoadCommandSize);
202 uint64_t RelocationsStart,
203 unsigned NumRelocations) {
215 uint64_t Start =
OS.
tell();
232 Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
236 Write32(NumRelocations ? RelocationsStart : 0);
239 Write32(IndirectSymBase.lookup(&SD));
250 uint32_t StringTableOffset,
251 uint32_t StringTableSize) {
254 uint64_t Start =
OS.
tell();
268 uint32_t NumLocalSymbols,
269 uint32_t FirstExternalSymbol,
270 uint32_t NumExternalSymbols,
271 uint32_t FirstUndefinedSymbol,
272 uint32_t NumUndefinedSymbols,
273 uint32_t IndirectSymbolOffset,
274 uint32_t NumIndirectSymbols) {
277 uint64_t Start =
OS.
tell();
310 uint64_t Address = 0;
342 assert((1U << Log2Size) ==
Align &&
"Invalid 'common' alignment!");
348 Flags = (Flags & 0xF0FF) | (Log2Size << 8);
370 uint64_t Start =
OS.
tell();
382 const std::vector<std::string> &Options,
bool is64Bit)
385 for (
unsigned i = 0, e = Options.size(); i != e; ++i)
386 Size += Options[i].size() + 1;
391 const std::vector<std::string> &Options)
394 uint64_t Start =
OS.
tell();
397 Write32(MachO::LC_LINKER_OPTIONS);
401 for (
unsigned i = 0, e = Options.size(); i != e; ++i) {
403 const std::string &Option = Options[i];
404 WriteBytes(Option.c_str(), Option.size() + 1);
405 BytesWritten += Option.size() + 1;
411 assert(
OS.
tell() - Start == Size);
420 uint64_t &FixedValue) {
421 TargetObjectWriter->RecordRelocation(
this, Asm, Layout, Fragment, Fixup,
438 cast<MCSectionMachO>(it->SectionData->getSection());
445 "' not in a symbol pointer or stub section");
450 unsigned IndirectIndex = 0;
454 cast<MCSectionMachO>(it->SectionData->getSection());
460 IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
470 cast<MCSectionMachO>(it->SectionData->getSection());
477 IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
496 std::vector<MachSymbolData> &LocalSymbolData,
497 std::vector<MachSymbolData> &ExternalSymbolData,
498 std::vector<MachSymbolData> &UndefinedSymbolData) {
503 ie = Asm.
end(); it != ie; ++it, ++Index)
504 SectionIndexMap[&it->getSection()] = Index;
505 assert(Index <= 256 &&
"Too many sections!");
509 StringTable +=
'\x00';
529 uint64_t &Entry = StringIndexMap[Symbol.
getName()];
531 Entry = StringTable.
size();
532 StringTable += Symbol.
getName();
533 StringTable +=
'\x00';
538 MSD.StringIndex = Entry;
541 MSD.SectionIndex = 0;
544 MSD.SectionIndex = 0;
545 ExternalSymbolData.push_back(MSD);
548 assert(MSD.SectionIndex &&
"Invalid section index!");
549 ExternalSymbolData.push_back(MSD);
565 uint64_t &Entry = StringIndexMap[Symbol.
getName()];
567 Entry = StringTable.
size();
568 StringTable += Symbol.
getName();
569 StringTable +=
'\x00';
574 MSD.StringIndex = Entry;
577 MSD.SectionIndex = 0;
581 assert(MSD.SectionIndex &&
"Invalid section index!");
582 LocalSymbolData.push_back(MSD);
587 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
588 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
592 for (
unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
593 LocalSymbolData[i].SymbolData->setIndex(Index++);
594 for (
unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
595 ExternalSymbolData[i].SymbolData->setIndex(Index++);
596 for (
unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
597 UndefinedSymbolData[i].SymbolData->setIndex(Index++);
600 while (StringTable.
size() % 4)
601 StringTable +=
'\x00';
606 uint64_t StartAddress = 0;
608 for (
int i = 0, n = Order.
size(); i != n ; ++i) {
636 const_cast<MCSymbol*>(&SD.
getSymbol())->setAbsolute();
654 UndefinedSymbolData);
662 bool IsPCRel)
const {
710 if (!TargetObjectWriter->useAggressiveSymbolFolding())
729 if (A_Base == B_Base)
738 unsigned NumSections = Asm.
size();
742 unsigned NumLoadCommands = 1;
743 uint64_t LoadCommandsSize =
is64Bit() ?
749 if (NumDataRegions) {
755 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
756 UndefinedSymbolData.size();
758 NumLoadCommands += 2;
764 const std::vector<std::vector<std::string> > &LinkerOptions =
766 for (
unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
776 uint64_t SectionDataSize = 0;
777 uint64_t SectionDataFileSize = 0;
780 ie = Asm.
end(); it != ie; ++it) {
787 VMSize = std::max(VMSize, Address + Size);
792 SectionDataSize = std::max(SectionDataSize, Address + Size);
793 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
800 SectionDataFileSize += SectionDataPadding;
806 SectionDataStart, SectionDataSize);
809 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
811 ie = Asm.
end(); it != ie; ++it) {
812 std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
813 unsigned NumRelocs = Relocs.size();
815 WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
820 uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
821 if (NumDataRegions) {
822 uint64_t DataRegionsOffset = RelocTableEnd;
823 uint64_t DataRegionsSize = NumDataRegions * 8;
830 unsigned FirstLocalSymbol = 0;
831 unsigned NumLocalSymbols = LocalSymbolData.size();
832 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
833 unsigned NumExternalSymbols = ExternalSymbolData.size();
834 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
835 unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
837 unsigned NumSymTabSymbols =
838 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
839 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
840 uint64_t IndirectSymbolOffset = 0;
843 if (NumIndirectSymbols)
844 IndirectSymbolOffset = DataInCodeTableEnd;
847 uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
850 uint64_t StringTableOffset =
851 SymbolTableOffset + NumSymTabSymbols * (
is64Bit() ?
855 StringTableOffset, StringTable.
size());
858 FirstExternalSymbol, NumExternalSymbols,
859 FirstUndefinedSymbol, NumUndefinedSymbols,
860 IndirectSymbolOffset, NumIndirectSymbols);
864 for (
unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
870 ie = Asm.
end(); it != ie; ++it) {
874 for (
unsigned int i = 0; i < Pad; ++i)
883 ie = Asm.
end(); it != ie; ++it) {
886 std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
887 for (
unsigned i = 0, e = Relocs.size(); i != e; ++i) {
888 Write32(Relocs[e - i - 1].r_word0);
889 Write32(Relocs[e - i - 1].r_word1);
905 <<
" start: " << Start <<
"(" << Data->
Start->
getName() <<
")"
906 <<
" end: " << End <<
"(" << Data->
End->
getName() <<
")"
907 <<
" size: " << End - Start
923 static_cast<const MCSectionMachO&
>(it->SectionData->getSection());
926 if (it->Symbol->isDefined() &&
928 uint32_t
Flags = MachO::INDIRECT_SYMBOL_LOCAL;
929 if (it->Symbol->isAbsolute())
930 Flags |= MachO::INDIRECT_SYMBOL_ABS;
942 for (
unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
944 for (
unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
946 for (
unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
950 OS << StringTable.
str();
956 bool IsLittleEndian) {
size_t indirect_symbol_size() const
void markAbsoluteVariableSymbols(MCAssembler &Asm, const MCAsmLayout &Layout)
void push_back(const T &Elt)
virtual void reset()
lifetime management
void WriteZeros(unsigned N)
void setFlags(uint32_t Value)
setFlags - Set the (implementation defined) symbol flags.
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
const MCSymbol & getSymbol() const
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols)
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
void Write32(uint32_t Value)
void WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize)
bool hasInstructions() const
const MCSymbol & getSymbol() const
void WriteBytes(const SmallVectorImpl< char > &ByteVec, unsigned ZeroFillSize=0)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
symbol_iterator symbol_begin()
enum llvm::DataRegionData::KindTy Kind
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
void WriteLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
uint64_t getIndex() const
getIndex - Get the (implementation defined) index.
const MCSection & getSection() const
uint64_t getSymbolAddress(const MCSymbolData *SD, const MCAsmLayout &Layout) const
std::vector< DataRegionData >::const_iterator const_data_region_iterator
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
uint64_t getCommonSize() const
getCommonSize - Return the size of a 'common' symbol.
uint64_t tell() const
tell - Return the current offset with the file.
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
uint64_t getSectionAddress(const MCSectionData *SD) const
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSectionData &SD, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations)
StringRef getSectionName() const
MCFragment * getFragment() const
unsigned getStubSize() const
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
const MCSection & getSection() const
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout)
Write the object file.
MCSectionData * getParent() const
void Write8(uint8_t Value)
unsigned getLayoutOrder() const
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
virtual void reset()
lifetime management
MCFixupKind
MCFixupKind - Extensible enumeration to represent the type of a fixup.
MCSymbolData * getAtom() const
void Write64(uint64_t Value)
llvm::SmallVectorImpl< MCSectionData * > & getSectionOrder()
uint64_t getSectionFileSize(const MCSectionData *SD) const
Get the data size of the given section, as emitted to the object file. This may include additional pa...
data_region_iterator data_region_begin()
const MCSymbolRefExpr * getSymB() const
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
SectionAddrMap SectionAddress
MCSymbolData & getOrCreateSymbolData(const MCSymbol &Symbol, bool *Created=0)
bool isSymbolLinkerVisible(const MCSymbol &SD) const
MCSymbolData & getSymbolData(const MCSymbol &Symbol) const
void Write16(uint16_t Value)
std::vector< std::vector< std::string > > & getLinkerOptions()
indirect_symbol_iterator indirect_symbol_begin()
const MCSymbolRefExpr * getSymA() const
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, bool InSet, bool IsPCRel) const
unsigned getCommonAlignment() const
getCommonAlignment - Return the alignment of a 'common' symbol.
virtual bool isVirtualSection() const =0
unsigned getAlignment() const
uint64_t getPaddingSize(const MCSectionData *SD, const MCAsmLayout &Layout) const
bool isCommon() const
isCommon - Is this a 'common' symbol.
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
static unsigned ComputeLinkerOptionsLoadCommandSize(const std::vector< std::string > &Options, bool is64Bit)
uint64_t getSymbolOffset(const MCSymbolData *SD) const
Get the offset of the given symbol, as computed in the current layout.
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
uint64_t getSectionAddressSize(const MCSectionData *SD) const
Get the address space size of the given section, as it effects layout. This may differ from the size ...
unsigned Log2_32(uint32_t Value)
StringRef str() const
Explicit conversion to StringRef.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
StringRef getSegmentName() const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
bool doesSymbolRequireExternRelocation(const MCSymbolData *SD)
bool getSubsectionsViaSymbols() const
StringRef getName() const
getName - Get the symbol name.
const MCSymbol & AliasedSymbol() const
void BindIndirectSymbols(MCAssembler &Asm)
MCAsmBackend & getBackend() const
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
bool hasReliableSymbolDifference() const
data_region_iterator data_region_end()
MCFixupKindInfo - Target independent information on a fixup kind.
bool isVariable() const
isVariable - Check if this is a variable symbol.
int64_t getConstant() const
unsigned getTypeAndAttributes() const
LLVM Value Representation.
ValueT lookup(const KeyT &Val) const
bool isPrivateExtern() const
indirect_symbol_iterator indirect_symbol_end()
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
void writeSectionData(const MCSectionData *Section, const MCAsmLayout &Layout) const
Emit the section contents using the given object writer.
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)
Record a relocation entry.
bool isPowerOf2_32(uint32_t Value)
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
void ComputeSymbolTable(MCAssembler &Asm, SmallString< 256 > &StringTable, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
std::vector< DataRegionData > & getDataRegions()
std::vector< IndirectSymbolData >::iterator indirect_symbol_iterator
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
getFixupKindInfo - Get information on a fixup kind.
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
MCObjectWriter * createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
unsigned Flags
Flags describing additional information on this fixup kind.
symbol_iterator symbol_end()