forked from OSchip/llvm-project
[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:
parent
b39156d068
commit
75c0c7050a
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue