42 #define DEBUG_TYPE "mc" 46 IndirectSymBase.clear();
48 LocalSymbolData.clear();
49 ExternalSymbolData.clear();
50 UndefinedSymbolData.clear();
61 if (cast<MCSymbolMachO>(S).isWeakDefinition())
70 return Symbol->getName() < RHS.Symbol->getName();
133 unsigned NumLoadCommands,
134 unsigned LoadCommandsSize,
135 bool SubsectionsViaSymbols) {
138 if (SubsectionsViaSymbols)
163 void MachObjectWriter::writeWithPadding(
StringRef Str, uint64_t
Size) {
174 StringRef Name,
unsigned NumSections, uint64_t VMAddr, uint64_t VMSize,
175 uint64_t SectionDataStartOffset, uint64_t SectionDataSize,
uint32_t MaxProt,
183 unsigned SegmentLoadCommandSize =
191 writeWithPadding(Name, 16);
193 W.
write<uint64_t>(VMAddr);
194 W.
write<uint64_t>(VMSize);
195 W.
write<uint64_t>(SectionDataStartOffset);
196 W.
write<uint64_t>(SectionDataSize);
215 uint64_t FileOffset,
unsigned Flags,
216 uint64_t RelocationsStart,
217 unsigned NumRelocations) {
236 W.
write<uint64_t>(VMAddr);
314 MachObjectWriter::MachSymbolData *
315 MachObjectWriter::findSymbolData(
const MCSymbol &Sym) {
316 for (
auto *SymbolData :
317 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
318 for (MachSymbolData &Entry : *SymbolData)
319 if (Entry.Symbol == &Sym)
332 S = &
Ref->getSymbol();
342 uint8_t SectionIndex = MSD.SectionIndex;
345 bool IsAlias = Symbol != AliasedSymbol;
348 MachSymbolData *AliaseeInfo;
350 AliaseeInfo = findSymbolData(*AliasedSymbol);
352 SectionIndex = AliaseeInfo->SectionIndex;
353 Symbol = AliasedSymbol;
380 Address = AliaseeInfo->StringIndex;
397 bool EncodeAsAltEntry =
398 IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
399 W.
write<uint16_t>(cast<MCSymbolMachO>(
Symbol)->getEncodedFlags(EncodeAsAltEntry));
401 W.
write<uint64_t>(Address);
421 const std::vector<std::string> &Options,
bool is64Bit)
424 for (
const std::string &Option : Options)
425 Size += Option.size() + 1;
426 return alignTo(Size, is64Bit ? 8 : 4);
430 const std::vector<std::string> &Options)
440 for (
const std::string &Option : Options) {
442 W.
OS << Option <<
'\0';
443 BytesWritten += Option.size() + 1;
456 uint64_t &FixedValue) {
457 TargetObjectWriter->recordRelocation(
this, Asm, Layout, Fragment, Fixup,
481 "' not in a symbol pointer or stub section");
486 unsigned IndirectIndex = 0;
496 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
512 IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
520 cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(
true);
527 std::vector<MachSymbolData> &ExternalSymbolData,
528 std::vector<MachSymbolData> &UndefinedSymbolData) {
533 ie = Asm.
end(); it != ie; ++it, ++
Index)
534 SectionIndexMap[&*it] = Index;
535 assert(Index <= 256 &&
"Too many sections!");
563 if (
Symbol.isUndefined()) {
564 MSD.SectionIndex = 0;
565 UndefinedSymbolData.push_back(MSD);
566 }
else if (
Symbol.isAbsolute()) {
567 MSD.SectionIndex = 0;
568 ExternalSymbolData.push_back(MSD);
570 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
571 assert(MSD.SectionIndex &&
"Invalid section index!");
572 ExternalSymbolData.push_back(MSD);
589 if (
Symbol.isAbsolute()) {
590 MSD.SectionIndex = 0;
591 LocalSymbolData.push_back(MSD);
593 MSD.SectionIndex = SectionIndexMap.
lookup(&
Symbol.getSection());
594 assert(MSD.SectionIndex &&
"Invalid section index!");
595 LocalSymbolData.push_back(MSD);
605 for (
auto *SymbolData :
606 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
607 for (MachSymbolData &Entry : *SymbolData)
608 Entry.Symbol->setIndex(Index++);
611 for (RelAndSymbol &Rel : Relocations[&
Section]) {
616 unsigned Index = Rel.Sym->getIndex();
619 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
621 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
628 uint64_t StartAddress = 0;
630 StartAddress =
alignTo(StartAddress, Sec->getAlignment());
631 SectionAddress[Sec] = StartAddress;
663 bool InSet,
bool IsPCRel)
const {
690 bool hasReliableSymbolDifference =
isX86_64();
691 if (!hasReliableSymbolDifference) {
740 uint64_t StartOffset =
W.
OS.
tell();
744 UndefinedSymbolData);
746 unsigned NumSections = Asm.
size();
752 unsigned NumLoadCommands = 1;
753 uint64_t LoadCommandsSize =
is64Bit() ?
758 if (VersionInfo.Major != 0) {
760 if (VersionInfo.EmitBuildVersion)
768 if (NumDataRegions) {
782 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
783 UndefinedSymbolData.size();
785 NumLoadCommands += 2;
800 uint64_t SectionDataSize = 0;
801 uint64_t SectionDataFileSize = 0;
809 VMSize =
std::max(VMSize, Address + Size);
811 if (Sec.isVirtualSection())
814 SectionDataSize =
std::max(SectionDataSize, Address + Size);
815 SectionDataFileSize =
std::max(SectionDataFileSize, Address + FileSize);
822 SectionDataFileSize += SectionDataPadding;
826 Asm.getSubsectionsViaSymbols());
830 SectionDataSize, Prot, Prot);
833 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
835 const auto &Sec = cast<MCSectionMachO>(
Section);
836 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
837 unsigned NumRelocs = Relocs.size();
839 unsigned Flags = Sec.getTypeAndAttributes();
840 if (Sec.hasInstructions())
843 RelocTableEnd, NumRelocs);
848 if (VersionInfo.Major != 0) {
850 assert(!V.empty() &&
"empty version");
851 unsigned Update = V.getSubminor() ? *V.getSubminor() : 0;
852 unsigned Minor = V.getMinor() ? *V.getMinor() : 0;
853 assert(Update < 256 &&
"unencodable update target version");
854 assert(Minor < 256 &&
"unencodable minor target version");
855 assert(V.getMajor() < 65536 &&
"unencodable major target version");
856 return Update | (Minor << 8) | (V.getMajor() << 16);
858 uint32_t EncodedVersion = EncodeVersion(
859 VersionTuple(VersionInfo.Major, VersionInfo.Minor, VersionInfo.Update));
860 uint32_t SDKVersion = !VersionInfo.SDKVersion.empty()
861 ? EncodeVersion(VersionInfo.SDKVersion)
863 if (VersionInfo.EmitBuildVersion) {
882 uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
883 if (NumDataRegions) {
884 uint64_t DataRegionsOffset = RelocTableEnd;
885 uint64_t DataRegionsSize = NumDataRegions * 8;
891 uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
894 DataInCodeTableEnd, LOHSize);
898 unsigned FirstLocalSymbol = 0;
899 unsigned NumLocalSymbols = LocalSymbolData.size();
900 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
901 unsigned NumExternalSymbols = ExternalSymbolData.size();
902 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
903 unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
904 unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
905 unsigned NumSymTabSymbols =
906 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
907 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
908 uint64_t IndirectSymbolOffset = 0;
911 if (NumIndirectSymbols)
912 IndirectSymbolOffset = LOHTableEnd;
915 uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
918 uint64_t StringTableOffset =
919 SymbolTableOffset + NumSymTabSymbols * (
is64Bit() ?
923 StringTableOffset, StringTable.
getSize());
926 FirstExternalSymbol, NumExternalSymbols,
927 FirstUndefinedSymbol, NumUndefinedSymbols,
928 IndirectSymbolOffset, NumIndirectSymbols);
932 for (
const auto &Option : Asm.getLinkerOptions())
937 Asm.writeSectionData(
W.
OS, &Sec, Layout);
950 std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
951 for (
const RelAndSymbol &Rel :
make_range(Relocs.rbegin(), Relocs.rend())) {
959 it = Asm.data_region_begin(), ie = Asm.data_region_end();
972 <<
" end: " << End <<
"(" << Data->
End->
getName() <<
")" 973 <<
" size: " << End - Start <<
"\n");
975 W.
write<uint16_t>(End - Start);
984 Asm.getLOHContainer().emit(*
this, Layout);
994 it = Asm.indirect_symbol_begin(),
995 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
1002 if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
1004 if (it->Symbol->isAbsolute())
1017 for (
auto *SymbolData :
1018 {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
1019 for (MachSymbolData &Entry : *SymbolData)
1026 return W.
OS.
tell() - StartOffset;
1029 std::unique_ptr<MCObjectWriter>
1032 return llvm::make_unique<MachObjectWriter>(std::move(MOTW), OS,
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.
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in the Reserved2 field.
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This represents a section on a Mach-O system (used by Mac OS X).
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
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.
This class represents lattice values for constants.
bool isVariable() const
isVariable - Check if this is a variable symbol.
This represents an "assembler immediate".
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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...
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
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...
bool isCommon() const
Is this a 'common' symbol.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
unsigned getAlignment() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
support::endian::Writer W
enum llvm::DataRegionData::KindTy Kind
int64_t getConstant() const
const MCSymbolRefExpr * getSymB() const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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)
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const override
Encapsulates the layout of an assembly file at a particular point in time.
bool isSymbolLinkerVisible(const MCSymbol &SD) const
Check whether a particular symbol is visible to the linker and is required in the symbol table...
Base class for the full range of assembler expressions which are needed for parsing.
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
The access may reference the value stored in memory.
Represent a reference to a symbol from inside an expression.
StringRef getSectionName() const
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const
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)
void write(raw_ostream &OS) const
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
size_t add(CachedHashStringRef S)
Add a string to the builder.
uint64_t getEmitSize(const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const
Get the size of the directives if emitted.
unsigned getStubSize() const
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
const VersionInfoType & getVersionInfo() const
MachO deployment target version information.
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
StringRef getSegmentName() const
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
constexpr bool isPowerOf2_32(uint32_t Value)
Return 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 void reset()
lifetime management
MCFixupKind
Extensible enumeration to represent the type of a fixup.
struct { bool EmitBuildVersion VersionInfoType
MachO specific deployment target version info.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
const MCSymbolRefExpr * getSymA() const
uint64_t getCommonSize() const
Return the size of a 'common' symbol.
std::vector< DataRegionData >::const_iterator const_data_region_iterator
const MCSymbol * getAtom() const
void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
std::vector< IndirectSymbolData >::const_iterator const_indirect_symbol_iterator
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
void finalize()
Analyze the strings and build the final table.
MachO::SectionType getType() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
void sort(IteratorTy Start, IteratorTy End)
PowerPC TLS Dynamic Call Fixup
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.
size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
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()
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
void write(ArrayRef< value_type > Val)
virtual bool isVirtualSection() const =0
Check whether this section is "virtual", that is has no actual object file contents.
MCAsmBackend & getBackend() const
const MCSymbol & getSymbol() const
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
MCFragment * getFragment(bool SetUsed=true) const
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.
bool getSubsectionsViaSymbols() const
MCLOHContainer & getLOHContainer()
static unsigned ComputeLinkerOptionsLoadCommandSize(const std::vector< std::string > &Options, bool is64Bit)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
Target - Wrapper for Target specific information.
MCSection * getParent() const
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
void computeSymbolTable(MCAssembler &Asm, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
Compute the symbol table data.
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const
Represents a version number in the form major[.minor[.subminor[.build]]].
std::unique_ptr< MCObjectWriter > createMachObjectWriter(std::unique_ptr< MCMachObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override
Write the object file and returns the number of bytes written.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getLayoutOrder() const
Target independent information on a fixup kind.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::vector< IndirectSymbolData >::iterator indirect_symbol_iterator
uint64_t getSectionAddress(const MCSection *Sec) const
StringRef getName() const
getName - Get the symbol name.
An abstract base class for streams implementations that also support a pwrite operation.
void reset() override
lifetime management
uint64_t getSectionFileSize(const MCSection *Sec) const
Get the data size of the given section, as emitted to the object file.
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())
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool operator<(int64_t V1, const APSInt &V2)
static MachO::LoadCommandType getLCFromMCVM(MCVersionMinType Type)
LLVM Value Representation.
indirect_symbol_iterator indirect_symbol_end()
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 tell() const
tell - Return the current offset with the file.
StringRef - Represent a constant reference to a string, i.e.
void bindIndirectSymbols(MCAssembler &Asm)
std::vector< DataRegionData > & getDataRegions()
bool isPrivateExtern() const
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
unsigned Flags
Flags describing additional information on this fixup kind.