29 #define DEBUG_TYPE "mc"
33 IndirectSymBase.clear();
35 LocalSymbolData.clear();
36 ExternalSymbolData.clear();
37 UndefinedSymbolData.clear();
48 if (cast<MCSymbolMachO>(S).isWeakDefinition())
57 return Symbol->getName() < RHS.Symbol->getName();
121 unsigned LoadCommandsSize,
122 bool SubsectionsViaSymbols) {
125 if (SubsectionsViaSymbols)
131 uint64_t Start =
OS.
tell();
136 write32(TargetObjectWriter->getCPUType());
137 write32(TargetObjectWriter->getCPUSubtype());
146 assert(
OS.
tell() - Start ==
156 uint64_t SectionDataStartOffset,
157 uint64_t SectionDataSize) {
161 uint64_t Start =
OS.
tell();
164 unsigned SegmentLoadCommandSize =
168 write32(SegmentLoadCommandSize +
176 write64(SectionDataStartOffset);
181 write32(SectionDataStartOffset);
191 assert(
OS.
tell() - Start == SegmentLoadCommandSize);
196 const MCSection &Sec, uint64_t FileOffset,
197 uint64_t RelocationsStart,
198 unsigned NumRelocations) {
211 uint64_t Start =
OS.
tell();
231 write32(NumRelocations ? RelocationsStart : 0);
234 write32(IndirectSymBase.lookup(&Sec));
246 uint32_t StringTableSize) {
249 uint64_t Start =
OS.
tell();
263 uint32_t NumLocalSymbols,
264 uint32_t FirstExternalSymbol,
265 uint32_t NumExternalSymbols,
266 uint32_t FirstUndefinedSymbol,
267 uint32_t NumUndefinedSymbols,
268 uint32_t IndirectSymbolOffset,
269 uint32_t NumIndirectSymbols) {
272 uint64_t Start =
OS.
tell();
299 MachObjectWriter::MachSymbolData *
300 MachObjectWriter::findSymbolData(
const MCSymbol &Sym) {
301 for (
auto *SymbolData :
302 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
303 for (MachSymbolData &Entry : *SymbolData)
304 if (Entry.Symbol == &Sym)
317 S = &Ref->getSymbol();
327 uint8_t SectionIndex = MSD.SectionIndex;
330 bool IsAlias = Symbol != AliasedSymbol;
333 MachSymbolData *AliaseeInfo;
335 AliaseeInfo = findSymbolData(*AliasedSymbol);
337 SectionIndex = AliaseeInfo->SectionIndex;
338 Symbol = AliasedSymbol;
365 Address = AliaseeInfo->StringIndex;
382 write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags());
392 uint64_t Start =
OS.
tell();
404 const std::vector<std::string> &Options,
bool is64Bit)
407 for (
const std::string &Option : Options)
408 Size += Option.size() + 1;
413 const std::vector<std::string> &Options)
416 uint64_t Start =
OS.
tell();
423 for (
const std::string &Option : Options) {
425 writeBytes(Option.c_str(), Option.size() + 1);
426 BytesWritten += Option.size() + 1;
432 assert(
OS.
tell() - Start == Size);
439 bool &IsPCRel, uint64_t &FixedValue) {
440 TargetObjectWriter->recordRelocation(
this, Asm, Layout, Fragment, Fixup,
463 "' not in a symbol pointer or stub section");
468 unsigned IndirectIndex = 0;
477 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
493 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
501 cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(
true);
508 std::vector<MachSymbolData> &ExternalSymbolData,
509 std::vector<MachSymbolData> &UndefinedSymbolData) {
514 ie = Asm.
end(); it != ie; ++it, ++Index)
515 SectionIndexMap[&*it] = Index;
516 assert(Index <= 256 &&
"Too many sections!");
544 if (
Symbol.isUndefined()) {
545 MSD.SectionIndex = 0;
546 UndefinedSymbolData.push_back(MSD);
547 }
else if (
Symbol.isAbsolute()) {
548 MSD.SectionIndex = 0;
549 ExternalSymbolData.push_back(MSD);
551 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
552 assert(MSD.SectionIndex &&
"Invalid section index!");
553 ExternalSymbolData.push_back(MSD);
570 if (
Symbol.isAbsolute()) {
571 MSD.SectionIndex = 0;
572 LocalSymbolData.push_back(MSD);
574 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
575 assert(MSD.SectionIndex &&
"Invalid section index!");
576 LocalSymbolData.push_back(MSD);
581 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
582 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
586 for (
auto *SymbolData :
587 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
588 for (MachSymbolData &Entry : *SymbolData)
589 Entry.Symbol->setIndex(Index++);
592 for (RelAndSymbol &Rel : Relocations[&
Section]) {
597 unsigned Index = Rel.Sym->getIndex();
598 assert(isInt<24>(Index));
600 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
602 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
609 uint64_t StartAddress = 0;
612 SectionAddress[Sec] = StartAddress;
632 bool InSet,
bool IsPCRel)
const {
659 bool hasReliableSymbolDifference =
isX86_64();
660 if (!hasReliableSymbolDifference) {
701 UndefinedSymbolData);
703 unsigned NumSections = Asm.
size();
709 unsigned NumLoadCommands = 1;
710 uint64_t LoadCommandsSize =
is64Bit() ?
715 if (VersionInfo.
Major != 0) {
722 if (NumDataRegions) {
736 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
737 UndefinedSymbolData.size();
739 NumLoadCommands += 2;
754 uint64_t SectionDataSize = 0;
755 uint64_t SectionDataFileSize = 0;
763 VMSize = std::max(VMSize, Address + Size);
765 if (Sec.isVirtualSection())
768 SectionDataSize = std::max(SectionDataSize, Address + Size);
769 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
776 SectionDataFileSize += SectionDataPadding;
780 Asm.getSubsectionsViaSymbols());
782 SectionDataStart, SectionDataSize);
785 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
787 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
788 unsigned NumRelocs = Relocs.size();
790 writeSection(Asm, Layout, Sec, SectionStart, RelocTableEnd, NumRelocs);
795 if (VersionInfo.
Major != 0) {
796 assert(VersionInfo.
Update < 256 &&
"unencodable update target version");
797 assert(VersionInfo.
Minor < 256 &&
"unencodable minor target version");
798 assert(VersionInfo.
Major < 65536 &&
"unencodable major target version");
799 uint32_t EncodedVersion = VersionInfo.
Update | (VersionInfo.
Minor << 8) |
800 (VersionInfo.
Major << 16);
809 uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
810 if (NumDataRegions) {
811 uint64_t DataRegionsOffset = RelocTableEnd;
812 uint64_t DataRegionsSize = NumDataRegions * 8;
818 uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
821 DataInCodeTableEnd, LOHSize);
825 unsigned FirstLocalSymbol = 0;
826 unsigned NumLocalSymbols = LocalSymbolData.size();
827 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
828 unsigned NumExternalSymbols = ExternalSymbolData.size();
829 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
830 unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
831 unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
832 unsigned NumSymTabSymbols =
833 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
834 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
835 uint64_t IndirectSymbolOffset = 0;
838 if (NumIndirectSymbols)
839 IndirectSymbolOffset = LOHTableEnd;
842 uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
846 SymbolTableOffset + NumSymTabSymbols * (
is64Bit() ?
850 StringTableOffset, StringTable.
data().
size());
853 FirstExternalSymbol, NumExternalSymbols,
854 FirstUndefinedSymbol, NumUndefinedSymbols,
855 IndirectSymbolOffset, NumIndirectSymbols);
859 for (
const auto &Option : Asm.getLinkerOptions())
864 Asm.writeSectionData(&Sec, Layout);
877 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
878 for (
const RelAndSymbol &Rel :
make_range(Relocs.rbegin(), Relocs.rend())) {
886 it = Asm.data_region_begin(), ie = Asm.data_region_end();
892 <<
" start: " << Start <<
"(" << Data->
Start->
getName() <<
")"
893 <<
" end: " << End <<
"(" << Data->
End->
getName() <<
")"
894 <<
" size: " << End - Start
904 unsigned Start =
OS.
tell();
906 Asm.getLOHContainer().emit(*
this, Layout);
909 assert(
OS.
tell() - Start == LOHSize);
916 it = Asm.indirect_symbol_begin(),
917 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
924 if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
926 if (it->Symbol->isAbsolute())
933 write32(it->Symbol->getIndex());
939 for (
auto *SymbolData :
940 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
941 for (MachSymbolData &Entry : *SymbolData)
951 bool IsLittleEndian) {
Instances of this class represent a uniqued identifier for a section in the current translation unit...
S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in the Reserved2 field.
void WriteZeros(unsigned N)
MCSectionMachO - This represents a section on a Mach-O system (used by Mac OS X). ...
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
const MCSymbol & getSymbol() const
bool hasInstructions() const
size_t size() const
size - Get the string size.
bool doesSymbolRequireExternRelocation(const MCSymbol &S)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
void write64(uint64_t Value)
This represents an "assembler immediate".
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
uint64_t getSectionAddress(const MCSection *Sec) const
void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
uint64_t getEmitSize(const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const
Get the size of the directives if emitted.
const VersionMinInfoType & getVersionMinInfo() const
MachO deployment target version information.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
void registerSymbol(const MCSymbol &Symbol, bool *Created=nullptr)
unsigned getAlignment() const
void finalize(Kind kind)
Analyze the strings and build the final table.
void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations)
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
enum llvm::DataRegionData::KindTy Kind
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 writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override
Write the object file.
Encapsulates the layout of an assembly file at a particular point in time.
std::vector< DataRegionData >::const_iterator const_data_region_iterator
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
Base class for the full range of assembler expressions which are needed for parsing.
Represent a reference to a symbol from inside an expression.
uint64_t tell() const
tell - Return the current offset with the file.
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
StringRef getSectionName() const
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
unsigned getStubSize() const
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
void write32(uint32_t Value)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
The instances of the Type class are immutable: once they are created, they are never changed...
void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize)
Write a segment load command.
static bool is64Bit(const char *name)
virtual void reset()
lifetime management
MCFixupKind
Extensible enumeration to represent the type of a fixup.
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
MCFragment * getFragment() const
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
StringRef add(StringRef s)
Add a string to the builder.
const MCSymbolRefExpr * getSymB() const
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
void write16(uint16_t Value)
bool isSymbolLinkerVisible(const MCSymbol &SD) const
Check whether a particular symbol is visible to the linker and is required in the symbol table...
PowerPC TLS Dynamic Call Fixup
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
std::vector< std::vector< std::string > > & getLinkerOptions()
void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
indirect_symbol_iterator indirect_symbol_begin()
const MCSymbolRefExpr * getSymA() const
virtual bool isVirtualSection() const =0
Check whether this section is "virtual", that is has no actual object file contents.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
An iterator type that allows iterating over the pointees via some other iterator. ...
MachO::SectionType getType() const
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
MCLOHContainer & getLOHContainer()
static unsigned ComputeLinkerOptionsLoadCommandSize(const std::vector< std::string > &Options, bool is64Bit)
MCSection * getParent() const
size_t getOffset(StringRef s)
Get the offest of a string in the string table.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Target - Wrapper for Target specific information.
MachO specific deployment target version info.
MCObjectWriter * createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
StringRef getSegmentName() const
uint64_t getCommonSize() const
Return the size of a 'common' symbol.
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
StringRef data()
Retrieve the string table data.
bool getSubsectionsViaSymbols() const
void computeSymbolTable(MCAssembler &Asm, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
Compute the symbol table data.
const MCSymbol * getAtom() const
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override
Record a relocation entry.
StringRef getName() const
getName - Get the symbol name.
unsigned getLayoutOrder() const
MCAsmBackend & getBackend() const
bool isCommon() const
Is this a 'common' symbol.
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Target independent information on a fixup kind.
void writeBytes(const SmallVectorImpl< char > &ByteVec, unsigned ZeroFillSize=0)
bool isVariable() const
isVariable - Check if this is a variable symbol.
An abstract base class for streams implementations that also support a pwrite operation.
void reset() override
lifetime management
bool isVirtualSection() const override
Check whether this section is "virtual", that is has no actual object file contents.
int64_t getConstant() const
const ARM::ArchExtKind Kind
bool isPrivateExtern() const
bool operator<(int64_t V1, const APSInt &V2)
unsigned getTypeAndAttributes() const
LLVM Value Representation.
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)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
uint64_t getSectionFileSize(const MCSection *Sec) const
Get the data size of the given section, as emitted to the object file.
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
void bindIndirectSymbols(MCAssembler &Asm)
std::vector< DataRegionData > & getDataRegions()
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const
std::vector< IndirectSymbolData >::iterator indirect_symbol_iterator
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
unsigned Flags
Flags describing additional information on this fixup kind.