1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

Move class methods out-of-line. This reduces the indentation, and is more in

line with LLVM's general coding style.
No functionality change.

llvm-svn: 133645
This commit is contained in:
Bill Wendling 2011-06-22 21:07:27 +00:00
parent 5640b59656
commit 19f2f807eb

View File

@ -120,6 +120,153 @@ private:
return SectionAddress.lookup(SD);
}
uint64_t getSymbolAddress(const MCSymbolData* SD,
const MCAsmLayout &Layout) const;
uint64_t getFragmentAddress(const MCFragment *Fragment,
const MCAsmLayout &Layout) const {
return getSectionAddress(Fragment->getParent()) +
Layout.getFragmentOffset(Fragment);
}
uint64_t getPaddingSize(const MCSectionData *SD,
const MCAsmLayout &Layout) const;
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
bool _IsLittleEndian)
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
}
/// @name Target Writer Proxy Accessors
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool isARM() const {
uint32_t CPUType = TargetObjectWriter->getCPUType() & ~mach::CTFM_ArchMask;
return CPUType == mach::CTM_ARM;
}
/// @}
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols);
/// WriteSegmentLoadCommand - Write a segment load command.
///
/// \arg NumSections - The number of sections in this segment.
/// \arg SectionDataSize - The total size of the sections.
void WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize);
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations);
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
uint32_t StringTableOffset,
uint32_t StringTableSize);
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 WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
// exactly what the encoder wanted. This will catch several classes of
// problems:
//
// - Relocation entry bugs, the two algorithms are unlikely to have the same
// exact bug.
//
// - Relaxation issues, where we forget to relax something.
//
// - Input errors, where something cannot be correctly encoded. 'as' allows
// these through in many cases.
static bool isFixupKindRIPRel(unsigned Kind) {
return Kind == X86::reloc_riprel_4byte ||
Kind == X86::reloc_riprel_4byte_movq_load;
}
void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
void RecordScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue);
void RecordARMScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue);
void RecordARMMovwMovtRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
void RecordTLVPRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
unsigned &Log2Size);
void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue);
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue);
void BindIndirectSymbols(MCAssembler &Asm);
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
/// \param StringIndexMap [out] - Map from symbol names to offsets in the
/// string table.
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
std::vector<MachSymbolData> &UndefinedSymbolData);
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const;
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
} // end anonymous namespace
uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
const MCAsmLayout &Layout) const {
const MCSymbol &S = SD->getSymbol();
@ -150,14 +297,9 @@ private:
return getSectionAddress(SD->getFragment()->getParent()) +
Layout.getSymbolOffset(SD);
}
uint64_t getFragmentAddress(const MCFragment *Fragment,
const MCAsmLayout &Layout) const {
return getSectionAddress(Fragment->getParent()) +
Layout.getFragmentOffset(Fragment);
}
}
uint64_t getPaddingSize(const MCSectionData *SD,
uint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD,
const MCAsmLayout &Layout) const {
uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
unsigned Next = SD->getLayoutOrder() + 1;
@ -168,26 +310,10 @@ private:
if (NextSD.getSection().isVirtualSection())
return 0;
return OffsetToAlignment(EndAddr, NextSD.getAlignment());
}
}
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
bool _IsLittleEndian)
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
}
/// @name Target Writer Proxy Accessors
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool isARM() const {
uint32_t CPUType = TargetObjectWriter->getCPUType() & ~mach::CTFM_ArchMask;
return CPUType == mach::CTM_ARM;
}
/// @}
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
unsigned LoadCommandsSize,
bool SubsectionsViaSymbols) {
uint32_t Flags = 0;
@ -214,13 +340,13 @@ public:
assert(OS.tell() - Start ==
(is64Bit() ? macho::Header64Size : macho::Header32Size));
}
}
/// WriteSegmentLoadCommand - Write a segment load command.
///
/// \arg NumSections - The number of sections in this segment.
/// \arg SectionDataSize - The total size of the sections.
void WriteSegmentLoadCommand(unsigned NumSections,
/// WriteSegmentLoadCommand - Write a segment load command.
///
/// \arg NumSections - The number of sections in this segment.
/// \arg SectionDataSize - The total size of the sections.
void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize) {
@ -256,11 +382,14 @@ public:
Write32(0); // flags
assert(OS.tell() - Start == SegmentLoadCommandSize);
}
}
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations) {
void MachObjectWriter::WriteSection(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCSectionData &SD,
uint64_t FileOffset,
uint64_t RelocationsStart,
unsigned NumRelocations) {
uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
// The offset is unused for virtual sections.
@ -303,9 +432,10 @@ public:
assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size :
macho::Section32Size));
}
}
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
uint32_t NumSymbols,
uint32_t StringTableOffset,
uint32_t StringTableSize) {
// struct symtab_command (24 bytes)
@ -321,9 +451,9 @@ public:
Write32(StringTableSize);
assert(OS.tell() - Start == macho::SymtabLoadCommandSize);
}
}
void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
uint32_t NumLocalSymbols,
uint32_t FirstExternalSymbol,
uint32_t NumExternalSymbols,
@ -358,9 +488,9 @@ public:
Write32(0); // nlocrel
assert(OS.tell() - Start == macho::DysymtabLoadCommandSize);
}
}
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) {
void MachObjectWriter::WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) {
MCSymbolData &Data = *MSD.SymbolData;
const MCSymbol &Symbol = Data.getSymbol();
uint8_t Type = 0;
@ -423,29 +553,13 @@ public:
Write64(Address);
else
Write32(Address);
}
}
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
// exactly what the encoder wanted. This will catch several classes of
// problems:
//
// - Relocation entry bugs, the two algorithms are unlikely to have the same
// exact bug.
//
// - Relaxation issues, where we forget to relax something.
//
// - Input errors, where something cannot be correctly encoded. 'as' allows
// these through in many cases.
static bool isFixupKindRIPRel(unsigned Kind) {
return Kind == X86::reloc_riprel_4byte ||
Kind == X86::reloc_riprel_4byte_movq_load;
}
void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
void MachObjectWriter::RecordX86_64Relocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind());
@ -464,11 +578,11 @@ public:
Value = Target.getConstant();
if (IsPCRel) {
// Compensate for the relocation offset, Darwin x86_64 relocations only
// have the addend and appear to have attempted to define it to be the
// actual expression addend without the PCrel bias. However, instructions
// with data following the relocation are not accommodated for (see comment
// below regarding SIGNED{1,2,4}), so it isn't exactly that either.
// Compensate for the relocation offset, Darwin x86_64 relocations only have
// the addend and appear to have attempted to define it to be the actual
// expression addend without the PCrel bias. However, instructions with data
// following the relocation are not accommodated for (see comment below
// regarding SIGNED{1,2,4}), so it isn't exactly that either.
Value += 1LL << Log2Size;
}
@ -477,11 +591,10 @@ public:
Type = macho::RIT_X86_64_Unsigned;
Index = 0;
// FIXME: I believe this is broken, I don't think the linker can
// understand it. I think it would require a local relocation, but I'm not
// sure if that would work either. The official way to get an absolute
// PCrel relocation is to use an absolute symbol (which we don't support
// yet).
// FIXME: I believe this is broken, I don't think the linker can understand
// it. I think it would require a local relocation, but I'm not sure if that
// would work either. The official way to get an absolute PCrel relocation
// is to use an absolute symbol (which we don't support yet).
if (IsPCRel) {
IsExtern = 1;
Type = macho::RIT_X86_64_Branch;
@ -507,14 +620,14 @@ public:
// The support for the situation where one or both of the symbols would
// require a local relocation is handled just like if the symbols were
// external. This is certainly used in the case of debug sections where
// the section has only temporary symbols and thus the symbols don't have
// base symbols. This is encoded using the section ordinal and
// non-extern relocation entries.
// external. This is certainly used in the case of debug sections where the
// section has only temporary symbols and thus the symbols don't have base
// symbols. This is encoded using the section ordinal and non-extern
// relocation entries.
// Darwin 'as' doesn't emit correct relocations for this (it ends up with
// a single SIGNED relocation); reject it for now. Except the case where
// both symbols don't have a base, equal but both NULL.
// Darwin 'as' doesn't emit correct relocations for this (it ends up with a
// single SIGNED relocation); reject it for now. Except the case where both
// symbols don't have a base, equal but both NULL.
if (A_Base == B_Base && A_Base)
report_fatal_error("unsupported relocation with identical base");
@ -624,15 +737,15 @@ public:
// containing L<foo>. Generally, this shouldn't occur but it does
// happen when we have a RIPrel instruction with data following the
// relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel
// adjustment Darwin x86_64 uses, the offset is still negative and
// the linker has no way to recognize this.
// adjustment Darwin x86_64 uses, the offset is still negative and the
// linker has no way to recognize this.
//
// To work around this, Darwin uses several special relocation types
// to indicate the offsets. However, the specification or
// implementation of these seems to also be incomplete; they should
// adjust the addend as well based on the actual encoded instruction
// (the additional bias), but instead appear to just look at the
// final offset.
// (the additional bias), but instead appear to just look at the final
// offset.
switch (-(Target.getConstant() + (1LL << Log2Size))) {
case 1: Type = macho::RIT_X86_64_Signed1; break;
case 2: Type = macho::RIT_X86_64_Signed2; break;
@ -650,10 +763,10 @@ public:
if (Modifier == MCSymbolRefExpr::VK_GOT) {
Type = macho::RIT_X86_64_GOT;
} else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) {
// GOTPCREL is allowed as a modifier on non-PCrel instructions, in
// which case all we do is set the PCrel bit in the relocation entry;
// this is used with exception handling, for example. The source is
// required to include any necessary offset directly.
// GOTPCREL is allowed as a modifier on non-PCrel instructions, in which
// case all we do is set the PCrel bit in the relocation entry; this is
// used with exception handling, for example. The source is required to
// include any necessary offset directly.
Type = macho::RIT_X86_64_GOT;
IsPCRel = 1;
} else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
@ -677,12 +790,13 @@ public:
(IsExtern << 27) |
(Type << 28));
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void RecordScatteredRelocation(const MCAssembler &Asm,
void MachObjectWriter::RecordScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
const MCFixup &Fixup,
MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue) {
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
@ -712,8 +826,8 @@ public:
// Select the appropriate difference relocation type.
//
// Note that there is no longer any semantic difference between these two
// relocation types from the linkers point of view, this is done solely
// for pedantic compatibility with 'as'.
// relocation types from the linkers point of view, this is done solely for
// pedantic compatibility with 'as'.
Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference :
(unsigned)macho::RIT_Generic_LocalDifference;
Value2 = getSymbolAddress(B_SD, Layout);
@ -741,12 +855,13 @@ public:
macho::RF_Scattered);
MRE.Word1 = Value;
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void RecordARMScatteredRelocation(const MCAssembler &Asm,
void MachObjectWriter::RecordARMScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
const MCFixup &Fixup,
MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue) {
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
@ -800,12 +915,13 @@ public:
macho::RF_Scattered);
MRE.Word1 = Value;
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void RecordARMMovwMovtRelocation(const MCAssembler &Asm,
void MachObjectWriter::RecordARMMovwMovtRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
@ -840,9 +956,9 @@ public:
// Relocations are written out in reverse order, so the PAIR comes first.
// ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field:
//
// For these two r_type relocations they always have a pair following them
// and the r_length bits are used differently. The encoding of the
// r_length is as follows:
// For these two r_type relocations they always have a pair following them and
// the r_length bits are used differently. The encoding of the r_length is as
// follows:
// low bit of r_length:
// 0 - :lower16: for movw instructions
// 1 - :upper16: for movt instructions
@ -894,12 +1010,13 @@ public:
macho::RF_Scattered);
MRE.Word1 = Value;
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void RecordTLVPRelocation(const MCAssembler &Asm,
void MachObjectWriter::RecordTLVPRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP &&
!is64Bit() &&
@ -915,8 +1032,8 @@ public:
// We're only going to have a second symbol in pic mode and it'll be a
// subtraction from the picbase. For 32-bit pic the addend is the difference
// between the picbase and the next address. For 32-bit static the addend
// is zero.
// between the picbase and the next address. For 32-bit static the addend is
// zero.
if (Target.getSymB()) {
// If this is a subtraction then we're pcrel.
uint32_t FixupAddress =
@ -939,9 +1056,9 @@ public:
(1 << 27) | // Extern
(macho::RIT_Generic_TLV << 28)); // Type
Relocations[Fragment->getParent()].push_back(MRE);
}
}
static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
bool MachObjectWriter::getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
unsigned &Log2Size) {
RelocType = unsigned(macho::RIT_Vanilla);
Log2Size = ~0U;
@ -1004,10 +1121,13 @@ public:
Log2Size = llvm::Log2_32(4);
return true;
}
}
void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue) {
}
void MachObjectWriter::RecordARMRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
unsigned Log2Size;
unsigned RelocType = macho::RIT_Vanilla;
@ -1016,8 +1136,8 @@ public:
return;
}
// If this is a difference or a defined symbol plus an offset, then we need
// a scattered relocation entry. Differences always require scattered
// If this is a difference or a defined symbol plus an offset, then we need a
// scattered relocation entry. Differences always require scattered
// relocations.
if (Target.getSymB()) {
if (RelocType == macho::RIT_ARM_Half ||
@ -1034,8 +1154,8 @@ public:
SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
// FIXME: For other platforms, we need to use scattered relocations for
// internal relocations with offsets. If this is an internal relocation
// with an offset, it also needs a scattered relocation entry.
// internal relocations with offsets. If this is an internal relocation with
// an offset, it also needs a scattered relocation entry.
//
// Is this right for ARM?
uint32_t Offset = Target.getConstant();
@ -1070,6 +1190,7 @@ public:
if (doesSymbolRequireExternRelocation(SD)) {
IsExtern = 1;
Index = SD->getIndex();
// For external relocations, make sure to offset the fixup value to
// compensate for the addend of the symbol address, if it was
// undefined. This occurs with weak definitions, for example.
@ -1098,11 +1219,14 @@ public:
(IsExtern << 27) |
(Type << 28));
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue) {
void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
// FIXME: These needs to be factored into the target Mach-O writer.
if (isARM()) {
RecordARMRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
@ -1123,9 +1247,9 @@ public:
return;
}
// If this is a difference or a defined symbol plus an offset, then we need
// a scattered relocation entry.
// Differences always require scattered relocations.
// If this is a difference or a defined symbol plus an offset, then we need a
// scattered relocation entry. Differences always require scattered
// relocations.
if (Target.getSymB())
return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,
Target, Log2Size, FixedValue);
@ -1135,8 +1259,8 @@ public:
if (Target.getSymA())
SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
// If this is an internal relocation with an offset, it also needs a
// scattered relocation entry.
// If this is an internal relocation with an offset, it also needs a scattered
// relocation entry.
uint32_t Offset = Target.getConstant();
if (IsPCRel)
Offset += 1 << Log2Size;
@ -1198,13 +1322,13 @@ public:
(IsExtern << 27) |
(Type << 28));
Relocations[Fragment->getParent()].push_back(MRE);
}
}
void BindIndirectSymbols(MCAssembler &Asm) {
void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
// This is the point where 'as' creates actual symbols for indirect symbols
// (in the following two passes). It would be easier for us to do this
// sooner when we see the attribute, but that makes getting the order in the
// symbol table much more complicated than it is worth.
// (in the following two passes). It would be easier for us to do this sooner
// when we see the attribute, but that makes getting the order in the symbol
// table much more complicated than it is worth.
//
// FIXME: Revisit this when the dust settles.
@ -1248,14 +1372,14 @@ public:
if (Created)
Entry.setFlags(Entry.getFlags() | 0x0001);
}
}
}
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
/// \param StringIndexMap [out] - Map from symbol names to offsets in the
/// string table.
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
/// \param StringIndexMap [out] - Map from symbol names to offsets in the
/// string table.
void MachObjectWriter::ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
std::vector<MachSymbolData> &UndefinedSymbolData) {
@ -1362,9 +1486,9 @@ public:
// The string table is padded to a multiple of 4.
while (StringTable.size() % 4)
StringTable += '\x00';
}
}
void computeSectionAddresses(const MCAssembler &Asm,
void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout) {
uint64_t StartAddress = 0;
const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
@ -1373,14 +1497,15 @@ public:
StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
SectionAddress[SD] = StartAddress;
StartAddress += Layout.getSectionAddressSize(SD);
// Explicitly pad the section to match the alignment requirements of the
// following one. This is for 'gas' compatibility, it shouldn't
/// strictly be necessary.
StartAddress += getPaddingSize(SD, Layout);
}
}
}
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) {
void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) {
computeSectionAddresses(Asm, Layout);
// Create symbol data for any indirect symbols.
@ -1389,9 +1514,9 @@ public:
// Compute symbol table information and bind symbol indices.
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
UndefinedSymbolData);
}
}
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
bool MachObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
const MCFragment &FB,
bool InSet,
@ -1413,13 +1538,12 @@ public:
if (IsPCRel) {
// The simple (Darwin, except on x86_64) way of dealing with this was to
// assume that any reference to a temporary symbol *must* be a temporary
// symbol in the same atom, unless the sections differ. Therefore, any
// PCrel relocation to a temporary symbol (in the same section) is fully
// symbol in the same atom, unless the sections differ. Therefore, any PCrel
// relocation to a temporary symbol (in the same section) is fully
// resolved. This also works in conjunction with absolutized .set, which
// requires the compiler to use .set to absolutize the differences between
// symbols which the compiler knows to be assembly time constants, so we
// don't need to worry about considering symbol differences fully
// resolved.
// don't need to worry about considering symbol differences fully resolved.
if (!Asm.getBackend().hasReliableSymbolDifference()) {
if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB)
@ -1447,9 +1571,9 @@ public:
// Otherwise, we can't prove this is fully resolved.
return false;
}
}
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
void MachObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
unsigned NumSections = Asm.size();
// The section data starts after the header, the segment load command (and
@ -1468,8 +1592,8 @@ public:
macho::DysymtabLoadCommandSize);
}
// Compute the total size of the section data, as well as its file size and
// vm size.
// Compute the total size of the section data, as well as its file size and vm
// size.
uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
macho::Header32Size) + LoadCommandsSize;
uint64_t SectionDataSize = 0;
@ -1612,9 +1736,6 @@ public:
// Write the string table.
OS << StringTable.str();
}
}
};
}
MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW,