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

[MC/MachO] Make some MachObjectWriter methods more generic. NFC.

Hardcode less values in some mach-o header writing routines and pass them
as argument. Doing so will allow reusing this code in llvm-dsymutil.

llvm-svn: 246007
This commit is contained in:
Frederic Riss 2015-08-26 05:09:46 +00:00
parent a891830996
commit ce46c4efed
2 changed files with 38 additions and 31 deletions

View File

@ -159,19 +159,21 @@ public:
/// @} /// @}
void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
bool SubsectionsViaSymbols); unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
/// Write a segment load command. /// Write a segment load command.
/// ///
/// \param NumSections The number of sections in this segment. /// \param NumSections The number of sections in this segment.
/// \param SectionDataSize The total size of the sections. /// \param SectionDataSize The total size of the sections.
void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
uint64_t VMAddr, uint64_t VMSize,
uint64_t SectionDataStartOffset, uint64_t SectionDataStartOffset,
uint64_t SectionDataSize); uint64_t SectionDataSize, uint32_t MaxProt,
uint32_t InitProt);
void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, void writeSection(const MCAsmLayout &Layout, const MCSection &Sec,
const MCSection &Sec, uint64_t FileOffset, uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
uint64_t RelocationsStart, unsigned NumRelocations); uint64_t RelocationsStart, unsigned NumRelocations);
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,

View File

@ -117,7 +117,8 @@ uint64_t MachObjectWriter::getPaddingSize(const MCSection *Sec,
return OffsetToAlignment(EndAddr, NextSec.getAlignment()); return OffsetToAlignment(EndAddr, NextSec.getAlignment());
} }
void MachObjectWriter::writeHeader(unsigned NumLoadCommands, void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
unsigned NumLoadCommands,
unsigned LoadCommandsSize, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols) { bool SubsectionsViaSymbols) {
uint32_t Flags = 0; uint32_t Flags = 0;
@ -136,7 +137,7 @@ void MachObjectWriter::writeHeader(unsigned NumLoadCommands,
write32(TargetObjectWriter->getCPUType()); write32(TargetObjectWriter->getCPUType());
write32(TargetObjectWriter->getCPUSubtype()); write32(TargetObjectWriter->getCPUSubtype());
write32(MachO::MH_OBJECT); write32(Type);
write32(NumLoadCommands); write32(NumLoadCommands);
write32(LoadCommandsSize); write32(LoadCommandsSize);
write32(Flags); write32(Flags);
@ -151,10 +152,10 @@ void MachObjectWriter::writeHeader(unsigned NumLoadCommands,
/// ///
/// \param NumSections The number of sections in this segment. /// \param NumSections The number of sections in this segment.
/// \param SectionDataSize The total size of the sections. /// \param SectionDataSize The total size of the sections.
void MachObjectWriter::writeSegmentLoadCommand(unsigned NumSections, void MachObjectWriter::writeSegmentLoadCommand(
uint64_t VMSize, StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize,
uint64_t SectionDataStartOffset, uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt,
uint64_t SectionDataSize) { uint32_t InitProt) {
// struct segment_command (56 bytes) or // struct segment_command (56 bytes) or
// struct segment_command_64 (72 bytes) // struct segment_command_64 (72 bytes)
@ -169,31 +170,32 @@ void MachObjectWriter::writeSegmentLoadCommand(unsigned NumSections,
NumSections * (is64Bit() ? sizeof(MachO::section_64) : NumSections * (is64Bit() ? sizeof(MachO::section_64) :
sizeof(MachO::section))); sizeof(MachO::section)));
writeBytes("", 16); assert(Name.size() <= 16);
writeBytes(Name, 16);
if (is64Bit()) { if (is64Bit()) {
write64(0); // vmaddr write64(VMAddr); // vmaddr
write64(VMSize); // vmsize write64(VMSize); // vmsize
write64(SectionDataStartOffset); // file offset write64(SectionDataStartOffset); // file offset
write64(SectionDataSize); // file size write64(SectionDataSize); // file size
} else { } else {
write32(0); // vmaddr write32(VMAddr); // vmaddr
write32(VMSize); // vmsize write32(VMSize); // vmsize
write32(SectionDataStartOffset); // file offset write32(SectionDataStartOffset); // file offset
write32(SectionDataSize); // file size write32(SectionDataSize); // file size
} }
// maxprot // maxprot
write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE); write32(MaxProt);
// initprot // initprot
write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE); write32(InitProt);
write32(NumSections); write32(NumSections);
write32(0); // flags write32(0); // flags
assert(OS.tell() - Start == SegmentLoadCommandSize); assert(OS.tell() - Start == SegmentLoadCommandSize);
} }
void MachObjectWriter::writeSection(const MCAssembler &Asm, void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
const MCAsmLayout &Layout, const MCSection &Sec, uint64_t VMAddr,
const MCSection &Sec, uint64_t FileOffset, uint64_t FileOffset, unsigned Flags,
uint64_t RelocationsStart, uint64_t RelocationsStart,
unsigned NumRelocations) { unsigned NumRelocations) {
uint64_t SectionSize = Layout.getSectionAddressSize(&Sec); uint64_t SectionSize = Layout.getSectionAddressSize(&Sec);
@ -214,18 +216,14 @@ void MachObjectWriter::writeSection(const MCAssembler &Asm,
writeBytes(Section.getSectionName(), 16); writeBytes(Section.getSectionName(), 16);
writeBytes(Section.getSegmentName(), 16); writeBytes(Section.getSegmentName(), 16);
if (is64Bit()) { if (is64Bit()) {
write64(getSectionAddress(&Sec)); // address write64(VMAddr); // address
write64(SectionSize); // size write64(SectionSize); // size
} else { } else {
write32(getSectionAddress(&Sec)); // address write32(VMAddr); // address
write32(SectionSize); // size write32(SectionSize); // size
} }
write32(FileOffset); write32(FileOffset);
unsigned Flags = Section.getTypeAndAttributes();
if (Section.hasInstructions())
Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!"); assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
write32(Log2_32(Section.getAlignment())); write32(Log2_32(Section.getAlignment()));
write32(NumRelocations ? RelocationsStart : 0); write32(NumRelocations ? RelocationsStart : 0);
@ -776,18 +774,25 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
SectionDataFileSize += SectionDataPadding; SectionDataFileSize += SectionDataPadding;
// Write the prolog, starting with the header and load command... // Write the prolog, starting with the header and load command...
writeHeader(NumLoadCommands, LoadCommandsSize, writeHeader(MachO::MH_OBJECT, NumLoadCommands, LoadCommandsSize,
Asm.getSubsectionsViaSymbols()); Asm.getSubsectionsViaSymbols());
writeSegmentLoadCommand(NumSections, VMSize, uint32_t Prot =
SectionDataStart, SectionDataSize); MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
writeSegmentLoadCommand("", NumSections, 0, VMSize, SectionDataStart,
SectionDataSize, Prot, Prot);
// ... and then the section headers. // ... and then the section headers.
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
for (const MCSection &Sec : Asm) { for (const MCSection &Section : Asm) {
const auto &Sec = cast<MCSectionMachO>(Section);
std::vector<RelAndSymbol> &Relocs = Relocations[&Sec]; std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
unsigned NumRelocs = Relocs.size(); unsigned NumRelocs = Relocs.size();
uint64_t SectionStart = SectionDataStart + getSectionAddress(&Sec); uint64_t SectionStart = SectionDataStart + getSectionAddress(&Sec);
writeSection(Asm, Layout, Sec, SectionStart, RelocTableEnd, NumRelocs); unsigned Flags = Sec.getTypeAndAttributes();
if (Sec.hasInstructions())
Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
writeSection(Layout, Sec, getSectionAddress(&Sec), SectionStart, Flags,
RelocTableEnd, NumRelocs);
RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info); RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
} }