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();
120 unsigned NumLoadCommands,
121 unsigned LoadCommandsSize,
122 bool SubsectionsViaSymbols) {
125 if (SubsectionsViaSymbols)
136 write32(TargetObjectWriter->getCPUType());
137 write32(TargetObjectWriter->getCPUSubtype());
156 StringRef Name,
unsigned NumSections, uint64_t VMAddr, uint64_t VMSize,
157 uint64_t SectionDataStartOffset, uint64_t SectionDataSize,
uint32_t MaxProt,
165 unsigned SegmentLoadCommandSize =
169 write32(SegmentLoadCommandSize +
178 write64(SectionDataStartOffset);
183 write32(SectionDataStartOffset);
198 uint64_t FileOffset,
unsigned Flags,
199 uint64_t RelocationsStart,
200 unsigned NumRelocations) {
229 write32(NumRelocations ? RelocationsStart : 0);
232 write32(IndirectSymBase.lookup(&Sec));
297 MachObjectWriter::MachSymbolData *
298 MachObjectWriter::findSymbolData(
const MCSymbol &Sym) {
299 for (
auto *SymbolData :
300 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
301 for (MachSymbolData &Entry : *SymbolData)
302 if (Entry.Symbol == &Sym)
315 S = &Ref->getSymbol();
325 uint8_t SectionIndex = MSD.SectionIndex;
328 bool IsAlias = Symbol != AliasedSymbol;
331 MachSymbolData *AliaseeInfo;
333 AliaseeInfo = findSymbolData(*AliasedSymbol);
335 SectionIndex = AliaseeInfo->SectionIndex;
336 Symbol = AliasedSymbol;
363 Address = AliaseeInfo->StringIndex;
380 bool EncodeAsAltEntry =
381 IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
382 write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
404 const std::vector<std::string> &Options,
bool is64Bit)
407 for (
const std::string &Option : Options)
408 Size += Option.size() + 1;
409 return alignTo(Size, is64Bit ? 8 : 4);
413 const std::vector<std::string> &Options)
419 write32(MachO::LC_LINKER_OPTION);
423 for (
const std::string &Option : Options) {
426 BytesWritten += Option.size() + 1;
439 bool &IsPCRel, uint64_t &FixedValue) {
440 TargetObjectWriter->recordRelocation(
this, Asm, Layout, Fragment, Fixup,
464 "' not in a symbol pointer or stub section");
469 unsigned IndirectIndex = 0;
479 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
495 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
503 cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(
true);
510 std::vector<MachSymbolData> &ExternalSymbolData,
511 std::vector<MachSymbolData> &UndefinedSymbolData) {
516 ie = Asm.
end(); it != ie; ++it, ++Index)
517 SectionIndexMap[&*it] = Index;
518 assert(Index <= 256 &&
"Too many sections!");
525 StringTable.add(
Symbol.getName());
527 StringTable.finalize();
544 MSD.StringIndex = StringTable.getOffset(
Symbol.getName());
546 if (
Symbol.isUndefined()) {
547 MSD.SectionIndex = 0;
548 UndefinedSymbolData.push_back(MSD);
549 }
else if (
Symbol.isAbsolute()) {
550 MSD.SectionIndex = 0;
551 ExternalSymbolData.push_back(MSD);
553 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
554 assert(MSD.SectionIndex &&
"Invalid section index!");
555 ExternalSymbolData.push_back(MSD);
570 MSD.StringIndex = StringTable.getOffset(
Symbol.getName());
572 if (
Symbol.isAbsolute()) {
573 MSD.SectionIndex = 0;
574 LocalSymbolData.push_back(MSD);
576 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
577 assert(MSD.SectionIndex &&
"Invalid section index!");
578 LocalSymbolData.push_back(MSD);
583 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
584 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
588 for (
auto *SymbolData :
589 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
590 for (MachSymbolData &Entry : *SymbolData)
591 Entry.Symbol->setIndex(Index++);
594 for (RelAndSymbol &Rel : Relocations[&
Section]) {
599 unsigned Index = Rel.Sym->getIndex();
602 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
604 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
611 uint64_t StartAddress = 0;
613 StartAddress =
alignTo(StartAddress, Sec->getAlignment());
614 SectionAddress[Sec] = StartAddress;
646 bool InSet,
bool IsPCRel)
const {
673 bool hasReliableSymbolDifference =
isX86_64();
674 if (!hasReliableSymbolDifference) {
715 UndefinedSymbolData);
717 unsigned NumSections = Asm.
size();
723 unsigned NumLoadCommands = 1;
724 uint64_t LoadCommandsSize =
is64Bit() ?
729 if (VersionInfo.
Major != 0) {
736 if (NumDataRegions) {
750 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
751 UndefinedSymbolData.size();
753 NumLoadCommands += 2;
768 uint64_t SectionDataSize = 0;
769 uint64_t SectionDataFileSize = 0;
777 VMSize = std::max(VMSize, Address + Size);
779 if (Sec.isVirtualSection())
782 SectionDataSize = std::max(SectionDataSize, Address + Size);
783 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
790 SectionDataFileSize += SectionDataPadding;
794 Asm.getSubsectionsViaSymbols());
798 SectionDataSize, Prot, Prot);
801 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
803 const auto &Sec = cast<MCSectionMachO>(
Section);
804 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
805 unsigned NumRelocs = Relocs.size();
807 unsigned Flags = Sec.getTypeAndAttributes();
808 if (Sec.hasInstructions())
811 RelocTableEnd, NumRelocs);
816 if (VersionInfo.
Major != 0) {
817 assert(VersionInfo.
Update < 256 &&
"unencodable update target version");
818 assert(VersionInfo.
Minor < 256 &&
"unencodable minor target version");
819 assert(VersionInfo.
Major < 65536 &&
"unencodable major target version");
821 (VersionInfo.
Major << 16);
823 switch (VersionInfo.
Kind) {
825 LCType = MachO::LC_VERSION_MIN_MACOSX;
828 LCType = MachO::LC_VERSION_MIN_IPHONEOS;
831 LCType = MachO::LC_VERSION_MIN_TVOS;
834 LCType = MachO::LC_VERSION_MIN_WATCHOS;
844 uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
845 if (NumDataRegions) {
846 uint64_t DataRegionsOffset = RelocTableEnd;
847 uint64_t DataRegionsSize = NumDataRegions * 8;
853 uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
856 DataInCodeTableEnd, LOHSize);
860 unsigned FirstLocalSymbol = 0;
861 unsigned NumLocalSymbols = LocalSymbolData.size();
862 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
863 unsigned NumExternalSymbols = ExternalSymbolData.size();
864 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
865 unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
866 unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
867 unsigned NumSymTabSymbols =
868 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
869 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
870 uint64_t IndirectSymbolOffset = 0;
873 if (NumIndirectSymbols)
874 IndirectSymbolOffset = LOHTableEnd;
877 uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
881 SymbolTableOffset + NumSymTabSymbols * (
is64Bit() ?
885 StringTableOffset, StringTable.getSize());
888 FirstExternalSymbol, NumExternalSymbols,
889 FirstUndefinedSymbol, NumUndefinedSymbols,
890 IndirectSymbolOffset, NumIndirectSymbols);
894 for (
const auto &Option : Asm.getLinkerOptions())
899 Asm.writeSectionData(&Sec, Layout);
912 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
913 for (
const RelAndSymbol &Rel :
make_range(Relocs.rbegin(), Relocs.rend())) {
921 it = Asm.data_region_begin(), ie = Asm.data_region_end();
927 <<
" start: " << Start <<
"(" << Data->
Start->
getName() <<
")"
928 <<
" end: " << End <<
"(" << Data->
End->
getName() <<
")"
929 <<
" size: " << End - Start
941 Asm.getLOHContainer().emit(*
this, Layout);
951 it = Asm.indirect_symbol_begin(),
952 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
959 if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
961 if (it->Symbol->isAbsolute())
968 write32(it->Symbol->getIndex());
974 for (
auto *SymbolData :
975 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
976 for (MachSymbolData &Entry : *SymbolData)
986 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)
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 doesSymbolRequireExternRelocation(const MCSymbol &S)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
raw_pwrite_stream & getStream()
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 ...
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)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
unsigned getAlignment() const
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
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.
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const override
struct fuzzer::@269 Flags
Encapsulates the layout of an assembly file at a particular point in time.
std::vector< DataRegionData >::const_iterator const_data_region_iterator
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.
void writeSegmentLoadCommand(StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt, uint32_t InitProt)
Write a segment load command.
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
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
void write32(uint32_t Value)
bool isAbsolute(bool SetUsed=true) const
isAbsolute - Check if this is an absolute symbol.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
The instances of the Type class are immutable: once they are created, they are never changed...
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const
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.
static const unsigned End
void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
bool isInSection(bool SetUsed=true) const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
const MCSymbolRefExpr * getSymB() const
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...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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)
void writeSection(const MCAsmLayout &Layout, const MCSection &Sec, uint64_t VMAddr, uint64_t FileOffset, unsigned Flags, uint64_t RelocationsStart, unsigned NumRelocations)
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.
An iterator type that allows iterating over the pointees via some other iterator. ...
S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread local structures.
MachO::SectionType getType() const
static const char * Target
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
bool isDefined(bool SetUsed=true) const
isDefined - Check if this symbol is defined (i.e., it has an address).
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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.
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
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.
StringRef getSegmentName() const
uint64_t getCommonSize() const
Return the size of a 'common' symbol.
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
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.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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.
MCFragment * getFragment(bool SetUsed=true) const
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int64_t getConstant() const
bool isPrivateExtern() const
bool operator<(int64_t V1, const APSInt &V2)
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.
StringRef - Represent a constant reference to a string, i.e.
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.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
unsigned Flags
Flags describing additional information on this fixup kind.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).