MC: Change object writers to use endian::Writer. NFCI.
Part of PR37466. Differential Revision: https://reviews.llvm.org/D47040 llvm-svn: 332861
This commit is contained in:
parent
168d04d544
commit
f17b149d8c
|
@ -116,11 +116,16 @@ class MachObjectWriter : public MCObjectWriter {
|
|||
|
||||
MachSymbolData *findSymbolData(const MCSymbol &Sym);
|
||||
|
||||
void writeWithPadding(StringRef Str, uint64_t Size);
|
||||
|
||||
public:
|
||||
MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
|
||||
raw_pwrite_stream &OS, bool IsLittleEndian)
|
||||
: MCObjectWriter(OS, IsLittleEndian),
|
||||
TargetObjectWriter(std::move(MOTW)) {}
|
||||
TargetObjectWriter(std::move(MOTW)),
|
||||
W(OS, IsLittleEndian ? support::little : support::big) {}
|
||||
|
||||
support::endian::Writer W;
|
||||
|
||||
const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
|
||||
|
||||
|
|
|
@ -160,10 +160,12 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||
bool ZLibStyle, unsigned Alignment);
|
||||
|
||||
public:
|
||||
support::endian::Writer W;
|
||||
|
||||
ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
|
||||
raw_pwrite_stream &OS, bool IsLittleEndian)
|
||||
: MCObjectWriter(OS, IsLittleEndian),
|
||||
TargetObjectWriter(std::move(MOTW)) {}
|
||||
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(std::move(MOTW)),
|
||||
W(OS, IsLittleEndian ? support::little : support::big) {}
|
||||
|
||||
~ELFObjectWriter() override = default;
|
||||
|
||||
|
@ -175,16 +177,15 @@ public:
|
|||
MCObjectWriter::reset();
|
||||
}
|
||||
|
||||
void WriteWord(uint64_t W) {
|
||||
void WriteWord(uint64_t Word) {
|
||||
if (is64Bit())
|
||||
write64(W);
|
||||
W.write<uint64_t>(Word);
|
||||
else
|
||||
write32(W);
|
||||
W.write<uint32_t>(Word);
|
||||
}
|
||||
|
||||
template <typename T> void write(T Val) {
|
||||
support::endian::write(getStream(), Val,
|
||||
IsLittleEndian ? support::little : support::big);
|
||||
W.write(Val);
|
||||
}
|
||||
|
||||
void writeHeader(const MCAssembler &Asm);
|
||||
|
@ -255,8 +256,8 @@ public:
|
|||
} // end anonymous namespace
|
||||
|
||||
void ELFObjectWriter::align(unsigned Alignment) {
|
||||
uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
|
||||
WriteZeros(Padding);
|
||||
uint64_t Padding = OffsetToAlignment(W.OS.tell(), Alignment);
|
||||
W.OS.write_zeros(Padding);
|
||||
}
|
||||
|
||||
unsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) {
|
||||
|
@ -325,47 +326,50 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
|
|||
// emitWord method behaves differently for ELF32 and ELF64, writing
|
||||
// 4 bytes in the former and 8 in the latter.
|
||||
|
||||
writeBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3]
|
||||
W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
|
||||
|
||||
write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
|
||||
W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
|
||||
|
||||
// e_ident[EI_DATA]
|
||||
write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
|
||||
W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
|
||||
: ELF::ELFDATA2MSB);
|
||||
|
||||
write8(ELF::EV_CURRENT); // e_ident[EI_VERSION]
|
||||
W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
|
||||
// e_ident[EI_OSABI]
|
||||
write8(TargetObjectWriter->getOSABI());
|
||||
write8(0); // e_ident[EI_ABIVERSION]
|
||||
W.OS << char(TargetObjectWriter->getOSABI());
|
||||
W.OS << char(0); // e_ident[EI_ABIVERSION]
|
||||
|
||||
WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
|
||||
W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
|
||||
|
||||
write16(ELF::ET_REL); // e_type
|
||||
W.write<uint16_t>(ELF::ET_REL); // e_type
|
||||
|
||||
write16(TargetObjectWriter->getEMachine()); // e_machine = target
|
||||
W.write<uint16_t>(TargetObjectWriter->getEMachine()); // e_machine = target
|
||||
|
||||
write32(ELF::EV_CURRENT); // e_version
|
||||
W.write<uint32_t>(ELF::EV_CURRENT); // e_version
|
||||
WriteWord(0); // e_entry, no entry point in .o file
|
||||
WriteWord(0); // e_phoff, no program header for .o
|
||||
WriteWord(0); // e_shoff = sec hdr table off in bytes
|
||||
|
||||
// e_flags = whatever the target wants
|
||||
write32(Asm.getELFHeaderEFlags());
|
||||
W.write<uint32_t>(Asm.getELFHeaderEFlags());
|
||||
|
||||
// e_ehsize = ELF header size
|
||||
write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
|
||||
W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
|
||||
: sizeof(ELF::Elf32_Ehdr));
|
||||
|
||||
write16(0); // e_phentsize = prog header entry size
|
||||
write16(0); // e_phnum = # prog header entries = 0
|
||||
W.write<uint16_t>(0); // e_phentsize = prog header entry size
|
||||
W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
|
||||
|
||||
// e_shentsize = Section header entry size
|
||||
write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
|
||||
W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
|
||||
: sizeof(ELF::Elf32_Shdr));
|
||||
|
||||
// e_shnum = # of section header ents
|
||||
write16(0);
|
||||
W.write<uint16_t>(0);
|
||||
|
||||
// e_shstrndx = Section # of '.shstrtab'
|
||||
assert(StringTableIndex < ELF::SHN_LORESERVE);
|
||||
write16(StringTableIndex);
|
||||
W.write<uint16_t>(StringTableIndex);
|
||||
}
|
||||
|
||||
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
|
||||
|
@ -784,7 +788,7 @@ void ELFObjectWriter::computeSymbolTable(
|
|||
SymbolTableIndex = addToSectionTable(SymtabSection);
|
||||
|
||||
align(SymtabSection->getAlignment());
|
||||
uint64_t SecStart = getStream().tell();
|
||||
uint64_t SecStart = W.OS.tell();
|
||||
|
||||
// The first entry is the undefined symbol entry.
|
||||
Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
|
||||
|
@ -900,7 +904,7 @@ void ELFObjectWriter::computeSymbolTable(
|
|||
assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
|
||||
}
|
||||
|
||||
uint64_t SecEnd = getStream().tell();
|
||||
uint64_t SecEnd = W.OS.tell();
|
||||
SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
|
||||
|
||||
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
|
||||
|
@ -910,12 +914,12 @@ void ELFObjectWriter::computeSymbolTable(
|
|||
}
|
||||
assert(SymtabShndxSectionIndex != 0);
|
||||
|
||||
SecStart = getStream().tell();
|
||||
SecStart = W.OS.tell();
|
||||
const MCSectionELF *SymtabShndxSection =
|
||||
SectionTable[SymtabShndxSectionIndex - 1];
|
||||
for (uint32_t Index : ShndxIndexes)
|
||||
write(Index);
|
||||
SecEnd = getStream().tell();
|
||||
SecEnd = W.OS.tell();
|
||||
SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
|
||||
}
|
||||
|
||||
|
@ -976,8 +980,8 @@ bool ELFObjectWriter::maybeWriteCompression(
|
|||
const StringRef Magic = "ZLIB";
|
||||
if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
|
||||
return false;
|
||||
write(ArrayRef<char>(Magic.begin(), Magic.size()));
|
||||
writeBE64(Size);
|
||||
W.OS << Magic;
|
||||
support::endian::write(W.OS, Size, support::big);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -996,7 +1000,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
|
|||
MAI->compressDebugSections() != DebugCompressionType::None;
|
||||
if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
|
||||
SectionName == ".debug_frame") {
|
||||
Asm.writeSectionData(getStream(), &Section, Layout);
|
||||
Asm.writeSectionData(W.OS, &Section, Layout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1013,14 +1017,14 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
|
|||
StringRef(UncompressedData.data(), UncompressedData.size()),
|
||||
CompressedContents)) {
|
||||
consumeError(std::move(E));
|
||||
getStream() << UncompressedData;
|
||||
W.OS << UncompressedData;
|
||||
return;
|
||||
}
|
||||
|
||||
bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
|
||||
if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
|
||||
ZlibStyle, Sec.getAlignment())) {
|
||||
getStream() << UncompressedData;
|
||||
W.OS << UncompressedData;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1034,7 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
|
|||
else
|
||||
// Add "z" prefix to section name. This is zlib-gnu style.
|
||||
MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str());
|
||||
getStream() << CompressedContents;
|
||||
W.OS << CompressedContents;
|
||||
}
|
||||
|
||||
void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
|
||||
|
@ -1039,14 +1043,14 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
|
|||
uint32_t Link, uint32_t Info,
|
||||
uint64_t Alignment,
|
||||
uint64_t EntrySize) {
|
||||
write32(Name); // sh_name: index into string table
|
||||
write32(Type); // sh_type
|
||||
W.write<uint32_t>(Name); // sh_name: index into string table
|
||||
W.write<uint32_t>(Type); // sh_type
|
||||
WriteWord(Flags); // sh_flags
|
||||
WriteWord(Address); // sh_addr
|
||||
WriteWord(Offset); // sh_offset
|
||||
WriteWord(Size); // sh_size
|
||||
write32(Link); // sh_link
|
||||
write32(Info); // sh_info
|
||||
W.write<uint32_t>(Link); // sh_link
|
||||
W.write<uint32_t>(Info); // sh_info
|
||||
WriteWord(Alignment); // sh_addralign
|
||||
WriteWord(EntrySize); // sh_entsize
|
||||
}
|
||||
|
@ -1116,7 +1120,7 @@ void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
|
|||
|
||||
const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
|
||||
const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
|
||||
StrTabBuilder.write(getStream());
|
||||
StrTabBuilder.write(W.OS);
|
||||
return StrtabSection;
|
||||
}
|
||||
|
||||
|
@ -1226,12 +1230,12 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
align(Section.getAlignment());
|
||||
|
||||
// Remember the offset into the file for this section.
|
||||
uint64_t SecStart = getStream().tell();
|
||||
uint64_t SecStart = W.OS.tell();
|
||||
|
||||
const MCSymbolELF *SignatureSymbol = Section.getGroup();
|
||||
writeSectionData(Asm, Section, Layout);
|
||||
|
||||
uint64_t SecEnd = getStream().tell();
|
||||
uint64_t SecEnd = W.OS.tell();
|
||||
SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
|
||||
|
||||
MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
|
||||
|
@ -1263,7 +1267,7 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
align(Group->getAlignment());
|
||||
|
||||
// Remember the offset into the file for this section.
|
||||
uint64_t SecStart = getStream().tell();
|
||||
uint64_t SecStart = W.OS.tell();
|
||||
|
||||
const MCSymbol *SignatureSymbol = Group->getGroup();
|
||||
assert(SignatureSymbol);
|
||||
|
@ -1273,7 +1277,7 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
write(SecIndex);
|
||||
}
|
||||
|
||||
uint64_t SecEnd = getStream().tell();
|
||||
uint64_t SecEnd = W.OS.tell();
|
||||
SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
|
||||
}
|
||||
|
||||
|
@ -1284,54 +1288,52 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
align(RelSection->getAlignment());
|
||||
|
||||
// Remember the offset into the file for this section.
|
||||
uint64_t SecStart = getStream().tell();
|
||||
uint64_t SecStart = W.OS.tell();
|
||||
|
||||
writeRelocations(Asm,
|
||||
cast<MCSectionELF>(*RelSection->getAssociatedSection()));
|
||||
|
||||
uint64_t SecEnd = getStream().tell();
|
||||
uint64_t SecEnd = W.OS.tell();
|
||||
SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
|
||||
}
|
||||
|
||||
{
|
||||
uint64_t SecStart = getStream().tell();
|
||||
uint64_t SecStart = W.OS.tell();
|
||||
const MCSectionELF *Sec = createStringTable(Ctx);
|
||||
uint64_t SecEnd = getStream().tell();
|
||||
uint64_t SecEnd = W.OS.tell();
|
||||
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
||||
}
|
||||
|
||||
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
|
||||
align(NaturalAlignment);
|
||||
|
||||
const uint64_t SectionHeaderOffset = getStream().tell();
|
||||
const uint64_t SectionHeaderOffset = W.OS.tell();
|
||||
|
||||
// ... then the section header table ...
|
||||
writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
|
||||
|
||||
uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE)
|
||||
? (uint16_t)ELF::SHN_UNDEF
|
||||
: SectionTable.size() + 1;
|
||||
if (sys::IsLittleEndianHost != IsLittleEndian)
|
||||
sys::swapByteOrder(NumSections);
|
||||
uint16_t NumSections = support::endian::byte_swap<uint16_t>(
|
||||
(SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
|
||||
: SectionTable.size() + 1,
|
||||
W.Endian);
|
||||
unsigned NumSectionsOffset;
|
||||
|
||||
auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
|
||||
if (is64Bit()) {
|
||||
uint64_t Val = SectionHeaderOffset;
|
||||
if (sys::IsLittleEndianHost != IsLittleEndian)
|
||||
sys::swapByteOrder(Val);
|
||||
getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
|
||||
offsetof(ELF::Elf64_Ehdr, e_shoff));
|
||||
uint64_t Val =
|
||||
support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
|
||||
Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
|
||||
offsetof(ELF::Elf64_Ehdr, e_shoff));
|
||||
NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
|
||||
} else {
|
||||
uint32_t Val = SectionHeaderOffset;
|
||||
if (sys::IsLittleEndianHost != IsLittleEndian)
|
||||
sys::swapByteOrder(Val);
|
||||
getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
|
||||
offsetof(ELF::Elf32_Ehdr, e_shoff));
|
||||
uint32_t Val =
|
||||
support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
|
||||
Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
|
||||
offsetof(ELF::Elf32_Ehdr, e_shoff));
|
||||
NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
|
||||
}
|
||||
getStream().pwrite(reinterpret_cast<char *>(&NumSections),
|
||||
sizeof(NumSections), NumSectionsOffset);
|
||||
Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
|
||||
NumSectionsOffset);
|
||||
}
|
||||
|
||||
bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
|
||||
|
|
|
@ -36,7 +36,7 @@ void MCLOHDirective::emit_impl(raw_ostream &OutStream,
|
|||
|
||||
void MCLOHDirective::emit(MachObjectWriter &ObjWriter,
|
||||
const MCAsmLayout &Layout) const {
|
||||
raw_ostream &OutStream = ObjWriter.getStream();
|
||||
raw_ostream &OutStream = ObjWriter.W.OS;
|
||||
emit_impl(OutStream, ObjWriter, Layout);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,24 +141,29 @@ void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
|
|||
// struct mach_header (28 bytes) or
|
||||
// struct mach_header_64 (32 bytes)
|
||||
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
|
||||
W.write<uint32_t>(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
|
||||
|
||||
write32(TargetObjectWriter->getCPUType());
|
||||
write32(TargetObjectWriter->getCPUSubtype());
|
||||
W.write<uint32_t>(TargetObjectWriter->getCPUType());
|
||||
W.write<uint32_t>(TargetObjectWriter->getCPUSubtype());
|
||||
|
||||
write32(Type);
|
||||
write32(NumLoadCommands);
|
||||
write32(LoadCommandsSize);
|
||||
write32(Flags);
|
||||
W.write<uint32_t>(Type);
|
||||
W.write<uint32_t>(NumLoadCommands);
|
||||
W.write<uint32_t>(LoadCommandsSize);
|
||||
W.write<uint32_t>(Flags);
|
||||
if (is64Bit())
|
||||
write32(0); // reserved
|
||||
W.write<uint32_t>(0); // reserved
|
||||
|
||||
assert(
|
||||
getStream().tell() - Start ==
|
||||
(is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header)));
|
||||
assert(W.OS.tell() - Start == (is64Bit() ? sizeof(MachO::mach_header_64)
|
||||
: sizeof(MachO::mach_header)));
|
||||
}
|
||||
|
||||
void MachObjectWriter::writeWithPadding(StringRef Str, uint64_t Size) {
|
||||
assert(Size >= Str.size());
|
||||
W.OS << Str;
|
||||
W.OS.write_zeros(Size - Str.size());
|
||||
}
|
||||
|
||||
/// writeSegmentLoadCommand - Write a segment load command.
|
||||
|
@ -172,38 +177,37 @@ void MachObjectWriter::writeSegmentLoadCommand(
|
|||
// struct segment_command (56 bytes) or
|
||||
// struct segment_command_64 (72 bytes)
|
||||
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
unsigned SegmentLoadCommandSize =
|
||||
is64Bit() ? sizeof(MachO::segment_command_64):
|
||||
sizeof(MachO::segment_command);
|
||||
write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
|
||||
write32(SegmentLoadCommandSize +
|
||||
W.write<uint32_t>(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
|
||||
W.write<uint32_t>(SegmentLoadCommandSize +
|
||||
NumSections * (is64Bit() ? sizeof(MachO::section_64) :
|
||||
sizeof(MachO::section)));
|
||||
|
||||
assert(Name.size() <= 16);
|
||||
writeBytes(Name, 16);
|
||||
writeWithPadding(Name, 16);
|
||||
if (is64Bit()) {
|
||||
write64(VMAddr); // vmaddr
|
||||
write64(VMSize); // vmsize
|
||||
write64(SectionDataStartOffset); // file offset
|
||||
write64(SectionDataSize); // file size
|
||||
W.write<uint64_t>(VMAddr); // vmaddr
|
||||
W.write<uint64_t>(VMSize); // vmsize
|
||||
W.write<uint64_t>(SectionDataStartOffset); // file offset
|
||||
W.write<uint64_t>(SectionDataSize); // file size
|
||||
} else {
|
||||
write32(VMAddr); // vmaddr
|
||||
write32(VMSize); // vmsize
|
||||
write32(SectionDataStartOffset); // file offset
|
||||
write32(SectionDataSize); // file size
|
||||
W.write<uint32_t>(VMAddr); // vmaddr
|
||||
W.write<uint32_t>(VMSize); // vmsize
|
||||
W.write<uint32_t>(SectionDataStartOffset); // file offset
|
||||
W.write<uint32_t>(SectionDataSize); // file size
|
||||
}
|
||||
// maxprot
|
||||
write32(MaxProt);
|
||||
W.write<uint32_t>(MaxProt);
|
||||
// initprot
|
||||
write32(InitProt);
|
||||
write32(NumSections);
|
||||
write32(0); // flags
|
||||
W.write<uint32_t>(InitProt);
|
||||
W.write<uint32_t>(NumSections);
|
||||
W.write<uint32_t>(0); // flags
|
||||
|
||||
assert(getStream().tell() - Start == SegmentLoadCommandSize);
|
||||
assert(W.OS.tell() - Start == SegmentLoadCommandSize);
|
||||
}
|
||||
|
||||
void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
|
||||
|
@ -223,31 +227,31 @@ void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
|
|||
// struct section (68 bytes) or
|
||||
// struct section_64 (80 bytes)
|
||||
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
writeBytes(Section.getSectionName(), 16);
|
||||
writeBytes(Section.getSegmentName(), 16);
|
||||
writeWithPadding(Section.getSectionName(), 16);
|
||||
writeWithPadding(Section.getSegmentName(), 16);
|
||||
if (is64Bit()) {
|
||||
write64(VMAddr); // address
|
||||
write64(SectionSize); // size
|
||||
W.write<uint64_t>(VMAddr); // address
|
||||
W.write<uint64_t>(SectionSize); // size
|
||||
} else {
|
||||
write32(VMAddr); // address
|
||||
write32(SectionSize); // size
|
||||
W.write<uint32_t>(VMAddr); // address
|
||||
W.write<uint32_t>(SectionSize); // size
|
||||
}
|
||||
write32(FileOffset);
|
||||
W.write<uint32_t>(FileOffset);
|
||||
|
||||
assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
|
||||
write32(Log2_32(Section.getAlignment()));
|
||||
write32(NumRelocations ? RelocationsStart : 0);
|
||||
write32(NumRelocations);
|
||||
write32(Flags);
|
||||
write32(IndirectSymBase.lookup(&Sec)); // reserved1
|
||||
write32(Section.getStubSize()); // reserved2
|
||||
W.write<uint32_t>(Log2_32(Section.getAlignment()));
|
||||
W.write<uint32_t>(NumRelocations ? RelocationsStart : 0);
|
||||
W.write<uint32_t>(NumRelocations);
|
||||
W.write<uint32_t>(Flags);
|
||||
W.write<uint32_t>(IndirectSymBase.lookup(&Sec)); // reserved1
|
||||
W.write<uint32_t>(Section.getStubSize()); // reserved2
|
||||
if (is64Bit())
|
||||
write32(0); // reserved3
|
||||
W.write<uint32_t>(0); // reserved3
|
||||
|
||||
assert(getStream().tell() - Start ==
|
||||
assert(W.OS.tell() - Start ==
|
||||
(is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section)));
|
||||
}
|
||||
|
||||
|
@ -257,17 +261,17 @@ void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset,
|
|||
uint32_t StringTableSize) {
|
||||
// struct symtab_command (24 bytes)
|
||||
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
write32(MachO::LC_SYMTAB);
|
||||
write32(sizeof(MachO::symtab_command));
|
||||
write32(SymbolOffset);
|
||||
write32(NumSymbols);
|
||||
write32(StringTableOffset);
|
||||
write32(StringTableSize);
|
||||
W.write<uint32_t>(MachO::LC_SYMTAB);
|
||||
W.write<uint32_t>(sizeof(MachO::symtab_command));
|
||||
W.write<uint32_t>(SymbolOffset);
|
||||
W.write<uint32_t>(NumSymbols);
|
||||
W.write<uint32_t>(StringTableOffset);
|
||||
W.write<uint32_t>(StringTableSize);
|
||||
|
||||
assert(getStream().tell() - Start == sizeof(MachO::symtab_command));
|
||||
assert(W.OS.tell() - Start == sizeof(MachO::symtab_command));
|
||||
}
|
||||
|
||||
void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
|
||||
|
@ -280,31 +284,31 @@ void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
|
|||
uint32_t NumIndirectSymbols) {
|
||||
// struct dysymtab_command (80 bytes)
|
||||
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
write32(MachO::LC_DYSYMTAB);
|
||||
write32(sizeof(MachO::dysymtab_command));
|
||||
write32(FirstLocalSymbol);
|
||||
write32(NumLocalSymbols);
|
||||
write32(FirstExternalSymbol);
|
||||
write32(NumExternalSymbols);
|
||||
write32(FirstUndefinedSymbol);
|
||||
write32(NumUndefinedSymbols);
|
||||
write32(0); // tocoff
|
||||
write32(0); // ntoc
|
||||
write32(0); // modtaboff
|
||||
write32(0); // nmodtab
|
||||
write32(0); // extrefsymoff
|
||||
write32(0); // nextrefsyms
|
||||
write32(IndirectSymbolOffset);
|
||||
write32(NumIndirectSymbols);
|
||||
write32(0); // extreloff
|
||||
write32(0); // nextrel
|
||||
write32(0); // locreloff
|
||||
write32(0); // nlocrel
|
||||
W.write<uint32_t>(MachO::LC_DYSYMTAB);
|
||||
W.write<uint32_t>(sizeof(MachO::dysymtab_command));
|
||||
W.write<uint32_t>(FirstLocalSymbol);
|
||||
W.write<uint32_t>(NumLocalSymbols);
|
||||
W.write<uint32_t>(FirstExternalSymbol);
|
||||
W.write<uint32_t>(NumExternalSymbols);
|
||||
W.write<uint32_t>(FirstUndefinedSymbol);
|
||||
W.write<uint32_t>(NumUndefinedSymbols);
|
||||
W.write<uint32_t>(0); // tocoff
|
||||
W.write<uint32_t>(0); // ntoc
|
||||
W.write<uint32_t>(0); // modtaboff
|
||||
W.write<uint32_t>(0); // nmodtab
|
||||
W.write<uint32_t>(0); // extrefsymoff
|
||||
W.write<uint32_t>(0); // nextrefsyms
|
||||
W.write<uint32_t>(IndirectSymbolOffset);
|
||||
W.write<uint32_t>(NumIndirectSymbols);
|
||||
W.write<uint32_t>(0); // extreloff
|
||||
W.write<uint32_t>(0); // nextrel
|
||||
W.write<uint32_t>(0); // locreloff
|
||||
W.write<uint32_t>(0); // nlocrel
|
||||
|
||||
assert(getStream().tell() - Start == sizeof(MachO::dysymtab_command));
|
||||
assert(W.OS.tell() - Start == sizeof(MachO::dysymtab_command));
|
||||
}
|
||||
|
||||
MachObjectWriter::MachSymbolData *
|
||||
|
@ -384,33 +388,33 @@ void MachObjectWriter::writeNlist(MachSymbolData &MSD,
|
|||
|
||||
// struct nlist (12 bytes)
|
||||
|
||||
write32(MSD.StringIndex);
|
||||
write8(Type);
|
||||
write8(SectionIndex);
|
||||
W.write<uint32_t>(MSD.StringIndex);
|
||||
W.OS << char(Type);
|
||||
W.OS << char(SectionIndex);
|
||||
|
||||
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
|
||||
// value.
|
||||
bool EncodeAsAltEntry =
|
||||
IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
|
||||
write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
|
||||
W.write<uint16_t>(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
|
||||
if (is64Bit())
|
||||
write64(Address);
|
||||
W.write<uint64_t>(Address);
|
||||
else
|
||||
write32(Address);
|
||||
W.write<uint32_t>(Address);
|
||||
}
|
||||
|
||||
void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type,
|
||||
uint32_t DataOffset,
|
||||
uint32_t DataSize) {
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
write32(Type);
|
||||
write32(sizeof(MachO::linkedit_data_command));
|
||||
write32(DataOffset);
|
||||
write32(DataSize);
|
||||
W.write<uint32_t>(Type);
|
||||
W.write<uint32_t>(sizeof(MachO::linkedit_data_command));
|
||||
W.write<uint32_t>(DataOffset);
|
||||
W.write<uint32_t>(DataSize);
|
||||
|
||||
assert(getStream().tell() - Start == sizeof(MachO::linkedit_data_command));
|
||||
assert(W.OS.tell() - Start == sizeof(MachO::linkedit_data_command));
|
||||
}
|
||||
|
||||
static unsigned ComputeLinkerOptionsLoadCommandSize(
|
||||
|
@ -426,23 +430,23 @@ void MachObjectWriter::writeLinkerOptionsLoadCommand(
|
|||
const std::vector<std::string> &Options)
|
||||
{
|
||||
unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
|
||||
uint64_t Start = getStream().tell();
|
||||
uint64_t Start = W.OS.tell();
|
||||
(void) Start;
|
||||
|
||||
write32(MachO::LC_LINKER_OPTION);
|
||||
write32(Size);
|
||||
write32(Options.size());
|
||||
W.write<uint32_t>(MachO::LC_LINKER_OPTION);
|
||||
W.write<uint32_t>(Size);
|
||||
W.write<uint32_t>(Options.size());
|
||||
uint64_t BytesWritten = sizeof(MachO::linker_option_command);
|
||||
for (const std::string &Option : Options) {
|
||||
// Write each string, including the null byte.
|
||||
writeBytes(Option, Option.size() + 1);
|
||||
W.OS << Option << '\0';
|
||||
BytesWritten += Option.size() + 1;
|
||||
}
|
||||
|
||||
// Pad to a multiple of the pointer size.
|
||||
writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
|
||||
W.OS.write_zeros(OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
|
||||
|
||||
assert(getStream().tell() - Start == Size);
|
||||
assert(W.OS.tell() - Start == Size);
|
||||
}
|
||||
|
||||
void MachObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||
|
@ -611,7 +615,7 @@ void MachObjectWriter::computeSymbolTable(
|
|||
// Set the Index and the IsExtern bit.
|
||||
unsigned Index = Rel.Sym->getIndex();
|
||||
assert(isInt<24>(Index));
|
||||
if (IsLittleEndian)
|
||||
if (W.Endian == support::little)
|
||||
Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
|
||||
else
|
||||
Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
|
||||
|
@ -847,19 +851,19 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
(VersionInfo.Major << 16);
|
||||
if (VersionInfo.EmitBuildVersion) {
|
||||
// FIXME: Currently empty tools. Add clang version in the future.
|
||||
write32(MachO::LC_BUILD_VERSION);
|
||||
write32(sizeof(MachO::build_version_command));
|
||||
write32(VersionInfo.TypeOrPlatform.Platform);
|
||||
write32(EncodedVersion);
|
||||
write32(0); // SDK version.
|
||||
write32(0); // Empty tools list.
|
||||
W.write<uint32_t>(MachO::LC_BUILD_VERSION);
|
||||
W.write<uint32_t>(sizeof(MachO::build_version_command));
|
||||
W.write<uint32_t>(VersionInfo.TypeOrPlatform.Platform);
|
||||
W.write<uint32_t>(EncodedVersion);
|
||||
W.write<uint32_t>(0); // SDK version.
|
||||
W.write<uint32_t>(0); // Empty tools list.
|
||||
} else {
|
||||
MachO::LoadCommandType LCType
|
||||
= getLCFromMCVM(VersionInfo.TypeOrPlatform.Type);
|
||||
write32(LCType);
|
||||
write32(sizeof(MachO::version_min_command));
|
||||
write32(EncodedVersion);
|
||||
write32(0); // reserved.
|
||||
W.write<uint32_t>(LCType);
|
||||
W.write<uint32_t>(sizeof(MachO::version_min_command));
|
||||
W.write<uint32_t>(EncodedVersion);
|
||||
W.write<uint32_t>(0); // reserved.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -919,14 +923,14 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
|
||||
// Write the actual section data.
|
||||
for (const MCSection &Sec : Asm) {
|
||||
Asm.writeSectionData(getStream(), &Sec, Layout);
|
||||
Asm.writeSectionData(W.OS, &Sec, Layout);
|
||||
|
||||
uint64_t Pad = getPaddingSize(&Sec, Layout);
|
||||
WriteZeros(Pad);
|
||||
W.OS.write_zeros(Pad);
|
||||
}
|
||||
|
||||
// Write the extra padding.
|
||||
WriteZeros(SectionDataPadding);
|
||||
W.OS.write_zeros(SectionDataPadding);
|
||||
|
||||
// Write the relocation entries.
|
||||
for (const MCSection &Sec : Asm) {
|
||||
|
@ -934,8 +938,8 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
// (approximately, the exact algorithm is more complicated than this).
|
||||
std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
|
||||
for (const RelAndSymbol &Rel : make_range(Relocs.rbegin(), Relocs.rend())) {
|
||||
write32(Rel.MRE.r_word0);
|
||||
write32(Rel.MRE.r_word1);
|
||||
W.write<uint32_t>(Rel.MRE.r_word0);
|
||||
W.write<uint32_t>(Rel.MRE.r_word1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,20 +960,20 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
<< ")"
|
||||
<< " end: " << End << "(" << Data->End->getName() << ")"
|
||||
<< " size: " << End - Start << "\n");
|
||||
write32(Start);
|
||||
write16(End - Start);
|
||||
write16(Data->Kind);
|
||||
W.write<uint32_t>(Start);
|
||||
W.write<uint16_t>(End - Start);
|
||||
W.write<uint16_t>(Data->Kind);
|
||||
}
|
||||
|
||||
// Write out the loh commands, if there is one.
|
||||
if (LOHSize) {
|
||||
#ifndef NDEBUG
|
||||
unsigned Start = getStream().tell();
|
||||
unsigned Start = W.OS.tell();
|
||||
#endif
|
||||
Asm.getLOHContainer().emit(*this, Layout);
|
||||
// Pad to a multiple of the pointer size.
|
||||
writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
|
||||
assert(getStream().tell() - Start == LOHSize);
|
||||
W.OS.write_zeros(OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
|
||||
assert(W.OS.tell() - Start == LOHSize);
|
||||
}
|
||||
|
||||
// Write the symbol table data, if used.
|
||||
|
@ -988,12 +992,12 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
|
||||
if (it->Symbol->isAbsolute())
|
||||
Flags |= MachO::INDIRECT_SYMBOL_ABS;
|
||||
write32(Flags);
|
||||
W.write<uint32_t>(Flags);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
write32(it->Symbol->getIndex());
|
||||
W.write<uint32_t>(it->Symbol->getIndex());
|
||||
}
|
||||
|
||||
// FIXME: Check that offsets match computed ones.
|
||||
|
@ -1005,7 +1009,7 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
|
|||
writeNlist(Entry, Layout);
|
||||
|
||||
// Write the string table.
|
||||
StringTable.write(getStream());
|
||||
StringTable.write(W.OS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,6 +196,8 @@ raw_ostream &operator<<(raw_ostream &OS, const WasmRelocationEntry &Rel) {
|
|||
#endif
|
||||
|
||||
class WasmObjectWriter : public MCObjectWriter {
|
||||
support::endian::Writer W;
|
||||
|
||||
/// The target specific Wasm writer instance.
|
||||
std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
|
||||
|
||||
|
@ -250,7 +252,7 @@ class WasmObjectWriter : public MCObjectWriter {
|
|||
public:
|
||||
WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
|
||||
raw_pwrite_stream &OS)
|
||||
: MCObjectWriter(OS, /*IsLittleEndian=*/true),
|
||||
: MCObjectWriter(OS, /*IsLittleEndian=*/true), W(OS, support::little),
|
||||
TargetObjectWriter(std::move(MOTW)) {}
|
||||
|
||||
~WasmObjectWriter() override;
|
||||
|
@ -286,12 +288,12 @@ private:
|
|||
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
|
||||
|
||||
void writeString(const StringRef Str) {
|
||||
encodeULEB128(Str.size(), getStream());
|
||||
writeBytes(Str);
|
||||
encodeULEB128(Str.size(), W.OS);
|
||||
W.OS << Str;
|
||||
}
|
||||
|
||||
void writeValueType(wasm::ValType Ty) {
|
||||
write8(static_cast<uint8_t>(Ty));
|
||||
W.OS << static_cast<char>(Ty);
|
||||
}
|
||||
|
||||
void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
|
||||
|
@ -333,17 +335,17 @@ WasmObjectWriter::~WasmObjectWriter() {}
|
|||
void WasmObjectWriter::startSection(SectionBookkeeping &Section,
|
||||
unsigned SectionId) {
|
||||
LLVM_DEBUG(dbgs() << "startSection " << SectionId << "\n");
|
||||
write8(SectionId);
|
||||
W.OS << char(SectionId);
|
||||
|
||||
Section.SizeOffset = getStream().tell();
|
||||
Section.SizeOffset = W.OS.tell();
|
||||
|
||||
// The section size. We don't know the size yet, so reserve enough space
|
||||
// for any 32-bit value; we'll patch it later.
|
||||
encodeULEB128(UINT32_MAX, getStream());
|
||||
encodeULEB128(UINT32_MAX, W.OS);
|
||||
|
||||
// The position where the section starts, for measuring its size.
|
||||
Section.ContentsOffset = getStream().tell();
|
||||
Section.PayloadOffset = getStream().tell();
|
||||
Section.ContentsOffset = W.OS.tell();
|
||||
Section.PayloadOffset = W.OS.tell();
|
||||
Section.Index = SectionCount++;
|
||||
}
|
||||
|
||||
|
@ -353,19 +355,19 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section,
|
|||
startSection(Section, wasm::WASM_SEC_CUSTOM);
|
||||
|
||||
// The position where the section header ends, for measuring its size.
|
||||
Section.PayloadOffset = getStream().tell();
|
||||
Section.PayloadOffset = W.OS.tell();
|
||||
|
||||
// Custom sections in wasm also have a string identifier.
|
||||
writeString(Name);
|
||||
|
||||
// The position where the custom section starts.
|
||||
Section.ContentsOffset = getStream().tell();
|
||||
Section.ContentsOffset = W.OS.tell();
|
||||
}
|
||||
|
||||
// Now that the section is complete and we know how big it is, patch up the
|
||||
// section size field at the start of the section.
|
||||
void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
|
||||
uint64_t Size = getStream().tell() - Section.PayloadOffset;
|
||||
uint64_t Size = W.OS.tell() - Section.PayloadOffset;
|
||||
if (uint32_t(Size) != Size)
|
||||
report_fatal_error("section size does not fit in a uint32_t");
|
||||
|
||||
|
@ -376,13 +378,14 @@ void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
|
|||
uint8_t Buffer[16];
|
||||
unsigned SizeLen = encodeULEB128(Size, Buffer, 5);
|
||||
assert(SizeLen == 5);
|
||||
getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset);
|
||||
static_cast<raw_pwrite_stream &>(W.OS).pwrite((char *)Buffer, SizeLen,
|
||||
Section.SizeOffset);
|
||||
}
|
||||
|
||||
// Emit the Wasm header.
|
||||
void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
|
||||
writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic)));
|
||||
writeLE32(wasm::WasmVersion);
|
||||
W.OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
|
||||
W.write<uint32_t>(wasm::WasmVersion);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
|
||||
|
@ -662,7 +665,7 @@ WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
|
|||
// directly.
|
||||
void WasmObjectWriter::applyRelocations(
|
||||
ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset) {
|
||||
raw_pwrite_stream &Stream = getStream();
|
||||
auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
|
||||
for (const WasmRelocationEntry &RelEntry : Relocations) {
|
||||
uint64_t Offset = ContentsOffset +
|
||||
RelEntry.FixupSection->getSectionOffset() +
|
||||
|
@ -702,14 +705,14 @@ void WasmObjectWriter::writeTypeSection(
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_TYPE);
|
||||
|
||||
encodeULEB128(FunctionTypes.size(), getStream());
|
||||
encodeULEB128(FunctionTypes.size(), W.OS);
|
||||
|
||||
for (const WasmFunctionType &FuncTy : FunctionTypes) {
|
||||
write8(wasm::WASM_TYPE_FUNC);
|
||||
encodeULEB128(FuncTy.Params.size(), getStream());
|
||||
W.OS << char(wasm::WASM_TYPE_FUNC);
|
||||
encodeULEB128(FuncTy.Params.size(), W.OS);
|
||||
for (wasm::ValType Ty : FuncTy.Params)
|
||||
writeValueType(Ty);
|
||||
encodeULEB128(FuncTy.Returns.size(), getStream());
|
||||
encodeULEB128(FuncTy.Returns.size(), W.OS);
|
||||
for (wasm::ValType Ty : FuncTy.Returns)
|
||||
writeValueType(Ty);
|
||||
}
|
||||
|
@ -728,28 +731,28 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_IMPORT);
|
||||
|
||||
encodeULEB128(Imports.size(), getStream());
|
||||
encodeULEB128(Imports.size(), W.OS);
|
||||
for (const wasm::WasmImport &Import : Imports) {
|
||||
writeString(Import.Module);
|
||||
writeString(Import.Field);
|
||||
write8(Import.Kind);
|
||||
W.OS << char(Import.Kind);
|
||||
|
||||
switch (Import.Kind) {
|
||||
case wasm::WASM_EXTERNAL_FUNCTION:
|
||||
encodeULEB128(Import.SigIndex, getStream());
|
||||
encodeULEB128(Import.SigIndex, W.OS);
|
||||
break;
|
||||
case wasm::WASM_EXTERNAL_GLOBAL:
|
||||
write8(Import.Global.Type);
|
||||
write8(Import.Global.Mutable ? 1 : 0);
|
||||
W.OS << char(Import.Global.Type);
|
||||
W.OS << char(Import.Global.Mutable ? 1 : 0);
|
||||
break;
|
||||
case wasm::WASM_EXTERNAL_MEMORY:
|
||||
encodeULEB128(0, getStream()); // flags
|
||||
encodeULEB128(NumPages, getStream()); // initial
|
||||
encodeULEB128(0, W.OS); // flags
|
||||
encodeULEB128(NumPages, W.OS); // initial
|
||||
break;
|
||||
case wasm::WASM_EXTERNAL_TABLE:
|
||||
write8(Import.Table.ElemType);
|
||||
encodeULEB128(0, getStream()); // flags
|
||||
encodeULEB128(NumElements, getStream()); // initial
|
||||
W.OS << char(Import.Table.ElemType);
|
||||
encodeULEB128(0, W.OS); // flags
|
||||
encodeULEB128(NumElements, W.OS); // initial
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unsupported import kind");
|
||||
|
@ -766,9 +769,9 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_FUNCTION);
|
||||
|
||||
encodeULEB128(Functions.size(), getStream());
|
||||
encodeULEB128(Functions.size(), W.OS);
|
||||
for (const WasmFunction &Func : Functions)
|
||||
encodeULEB128(Func.Type, getStream());
|
||||
encodeULEB128(Func.Type, W.OS);
|
||||
|
||||
endSection(Section);
|
||||
}
|
||||
|
@ -780,14 +783,14 @@ void WasmObjectWriter::writeGlobalSection() {
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_GLOBAL);
|
||||
|
||||
encodeULEB128(Globals.size(), getStream());
|
||||
encodeULEB128(Globals.size(), W.OS);
|
||||
for (const WasmGlobal &Global : Globals) {
|
||||
writeValueType(static_cast<wasm::ValType>(Global.Type.Type));
|
||||
write8(Global.Type.Mutable);
|
||||
W.OS << char(Global.Type.Mutable);
|
||||
|
||||
write8(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(Global.InitialValue, getStream());
|
||||
write8(wasm::WASM_OPCODE_END);
|
||||
W.OS << char(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(Global.InitialValue, W.OS);
|
||||
W.OS << char(wasm::WASM_OPCODE_END);
|
||||
}
|
||||
|
||||
endSection(Section);
|
||||
|
@ -800,11 +803,11 @@ void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_EXPORT);
|
||||
|
||||
encodeULEB128(Exports.size(), getStream());
|
||||
encodeULEB128(Exports.size(), W.OS);
|
||||
for (const wasm::WasmExport &Export : Exports) {
|
||||
writeString(Export.Name);
|
||||
write8(Export.Kind);
|
||||
encodeULEB128(Export.Index, getStream());
|
||||
W.OS << char(Export.Kind);
|
||||
encodeULEB128(Export.Index, W.OS);
|
||||
}
|
||||
|
||||
endSection(Section);
|
||||
|
@ -817,17 +820,17 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) {
|
|||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_ELEM);
|
||||
|
||||
encodeULEB128(1, getStream()); // number of "segments"
|
||||
encodeULEB128(0, getStream()); // the table index
|
||||
encodeULEB128(1, W.OS); // number of "segments"
|
||||
encodeULEB128(0, W.OS); // the table index
|
||||
|
||||
// init expr for starting offset
|
||||
write8(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(kInitialTableOffset, getStream());
|
||||
write8(wasm::WASM_OPCODE_END);
|
||||
W.OS << char(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(kInitialTableOffset, W.OS);
|
||||
W.OS << char(wasm::WASM_OPCODE_END);
|
||||
|
||||
encodeULEB128(TableElems.size(), getStream());
|
||||
encodeULEB128(TableElems.size(), W.OS);
|
||||
for (uint32_t Elem : TableElems)
|
||||
encodeULEB128(Elem, getStream());
|
||||
encodeULEB128(Elem, W.OS);
|
||||
|
||||
endSection(Section);
|
||||
}
|
||||
|
@ -842,7 +845,7 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
|
|||
startSection(Section, wasm::WASM_SEC_CODE);
|
||||
CodeSectionIndex = Section.Index;
|
||||
|
||||
encodeULEB128(Functions.size(), getStream());
|
||||
encodeULEB128(Functions.size(), W.OS);
|
||||
|
||||
for (const WasmFunction &Func : Functions) {
|
||||
auto &FuncSection = static_cast<MCSectionWasm &>(Func.Sym->getSection());
|
||||
|
@ -851,9 +854,9 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
|
|||
if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
|
||||
report_fatal_error(".size expression must be evaluatable");
|
||||
|
||||
encodeULEB128(Size, getStream());
|
||||
FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(getStream(), &FuncSection, Layout);
|
||||
encodeULEB128(Size, W.OS);
|
||||
FuncSection.setSectionOffset(W.OS.tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(W.OS, &FuncSection, Layout);
|
||||
}
|
||||
|
||||
// Apply fixups.
|
||||
|
@ -870,16 +873,16 @@ void WasmObjectWriter::writeDataSection() {
|
|||
startSection(Section, wasm::WASM_SEC_DATA);
|
||||
DataSectionIndex = Section.Index;
|
||||
|
||||
encodeULEB128(DataSegments.size(), getStream()); // count
|
||||
encodeULEB128(DataSegments.size(), W.OS); // count
|
||||
|
||||
for (const WasmDataSegment &Segment : DataSegments) {
|
||||
encodeULEB128(0, getStream()); // memory index
|
||||
write8(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(Segment.Offset, getStream()); // offset
|
||||
write8(wasm::WASM_OPCODE_END);
|
||||
encodeULEB128(Segment.Data.size(), getStream()); // size
|
||||
Segment.Section->setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
writeBytes(Segment.Data); // data
|
||||
encodeULEB128(0, W.OS); // memory index
|
||||
W.OS << char(wasm::WASM_OPCODE_I32_CONST);
|
||||
encodeSLEB128(Segment.Offset, W.OS); // offset
|
||||
W.OS << char(wasm::WASM_OPCODE_END);
|
||||
encodeULEB128(Segment.Data.size(), W.OS); // size
|
||||
Segment.Section->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
|
||||
W.OS << Segment.Data; // data
|
||||
}
|
||||
|
||||
// Apply fixups.
|
||||
|
@ -900,20 +903,18 @@ void WasmObjectWriter::writeRelocSection(
|
|||
SectionBookkeeping Section;
|
||||
startCustomSection(Section, std::string("reloc.") + Name.str());
|
||||
|
||||
raw_pwrite_stream &Stream = getStream();
|
||||
|
||||
encodeULEB128(SectionIndex, Stream);
|
||||
encodeULEB128(Relocations.size(), Stream);
|
||||
encodeULEB128(SectionIndex, W.OS);
|
||||
encodeULEB128(Relocations.size(), W.OS);
|
||||
for (const WasmRelocationEntry& RelEntry : Relocations) {
|
||||
uint64_t Offset = RelEntry.Offset +
|
||||
RelEntry.FixupSection->getSectionOffset();
|
||||
uint32_t Index = getRelocationIndexValue(RelEntry);
|
||||
|
||||
write8(RelEntry.Type);
|
||||
encodeULEB128(Offset, Stream);
|
||||
encodeULEB128(Index, Stream);
|
||||
W.OS << char(RelEntry.Type);
|
||||
encodeULEB128(Offset, W.OS);
|
||||
encodeULEB128(Index, W.OS);
|
||||
if (RelEntry.hasAddend())
|
||||
encodeSLEB128(RelEntry.Addend, Stream);
|
||||
encodeSLEB128(RelEntry.Addend, W.OS);
|
||||
}
|
||||
|
||||
endSection(Section);
|
||||
|
@ -932,34 +933,34 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
|||
const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats) {
|
||||
SectionBookkeeping Section;
|
||||
startCustomSection(Section, "linking");
|
||||
encodeULEB128(wasm::WasmMetadataVersion, getStream());
|
||||
encodeULEB128(wasm::WasmMetadataVersion, W.OS);
|
||||
|
||||
SectionBookkeeping SubSection;
|
||||
if (SymbolInfos.size() != 0) {
|
||||
startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
|
||||
encodeULEB128(SymbolInfos.size(), getStream());
|
||||
encodeULEB128(SymbolInfos.size(), W.OS);
|
||||
for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
|
||||
encodeULEB128(Sym.Kind, getStream());
|
||||
encodeULEB128(Sym.Flags, getStream());
|
||||
encodeULEB128(Sym.Kind, W.OS);
|
||||
encodeULEB128(Sym.Flags, W.OS);
|
||||
switch (Sym.Kind) {
|
||||
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
|
||||
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
|
||||
encodeULEB128(Sym.ElementIndex, getStream());
|
||||
encodeULEB128(Sym.ElementIndex, W.OS);
|
||||
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
|
||||
writeString(Sym.Name);
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_DATA:
|
||||
writeString(Sym.Name);
|
||||
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
|
||||
encodeULEB128(Sym.DataRef.Segment, getStream());
|
||||
encodeULEB128(Sym.DataRef.Offset, getStream());
|
||||
encodeULEB128(Sym.DataRef.Size, getStream());
|
||||
encodeULEB128(Sym.DataRef.Segment, W.OS);
|
||||
encodeULEB128(Sym.DataRef.Offset, W.OS);
|
||||
encodeULEB128(Sym.DataRef.Size, W.OS);
|
||||
}
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION: {
|
||||
const uint32_t SectionIndex =
|
||||
CustomSections[Sym.ElementIndex].OutputIndex;
|
||||
encodeULEB128(SectionIndex, getStream());
|
||||
encodeULEB128(SectionIndex, W.OS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -971,35 +972,35 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
|||
|
||||
if (DataSegments.size()) {
|
||||
startSection(SubSection, wasm::WASM_SEGMENT_INFO);
|
||||
encodeULEB128(DataSegments.size(), getStream());
|
||||
encodeULEB128(DataSegments.size(), W.OS);
|
||||
for (const WasmDataSegment &Segment : DataSegments) {
|
||||
writeString(Segment.Name);
|
||||
encodeULEB128(Segment.Alignment, getStream());
|
||||
encodeULEB128(Segment.Flags, getStream());
|
||||
encodeULEB128(Segment.Alignment, W.OS);
|
||||
encodeULEB128(Segment.Flags, W.OS);
|
||||
}
|
||||
endSection(SubSection);
|
||||
}
|
||||
|
||||
if (!InitFuncs.empty()) {
|
||||
startSection(SubSection, wasm::WASM_INIT_FUNCS);
|
||||
encodeULEB128(InitFuncs.size(), getStream());
|
||||
encodeULEB128(InitFuncs.size(), W.OS);
|
||||
for (auto &StartFunc : InitFuncs) {
|
||||
encodeULEB128(StartFunc.first, getStream()); // priority
|
||||
encodeULEB128(StartFunc.second, getStream()); // function index
|
||||
encodeULEB128(StartFunc.first, W.OS); // priority
|
||||
encodeULEB128(StartFunc.second, W.OS); // function index
|
||||
}
|
||||
endSection(SubSection);
|
||||
}
|
||||
|
||||
if (Comdats.size()) {
|
||||
startSection(SubSection, wasm::WASM_COMDAT_INFO);
|
||||
encodeULEB128(Comdats.size(), getStream());
|
||||
encodeULEB128(Comdats.size(), W.OS);
|
||||
for (const auto &C : Comdats) {
|
||||
writeString(C.first);
|
||||
encodeULEB128(0, getStream()); // flags for future use
|
||||
encodeULEB128(C.second.size(), getStream());
|
||||
encodeULEB128(0, W.OS); // flags for future use
|
||||
encodeULEB128(C.second.size(), W.OS);
|
||||
for (const WasmComdatEntry &Entry : C.second) {
|
||||
encodeULEB128(Entry.Kind, getStream());
|
||||
encodeULEB128(Entry.Index, getStream());
|
||||
encodeULEB128(Entry.Kind, W.OS);
|
||||
encodeULEB128(Entry.Index, W.OS);
|
||||
}
|
||||
}
|
||||
endSection(SubSection);
|
||||
|
@ -1015,8 +1016,8 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
|
|||
auto *Sec = CustomSection.Section;
|
||||
startCustomSection(Section, CustomSection.Name);
|
||||
|
||||
Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(getStream(), Sec, Layout);
|
||||
Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(W.OS, Sec, Layout);
|
||||
|
||||
CustomSection.OutputContentsOffset = Section.ContentsOffset;
|
||||
CustomSection.OutputIndex = Section.Index;
|
||||
|
|
|
@ -125,6 +125,8 @@ public:
|
|||
|
||||
class WinCOFFObjectWriter : public MCObjectWriter {
|
||||
public:
|
||||
support::endian::Writer W;
|
||||
|
||||
using symbols = std::vector<std::unique_ptr<COFFSymbol>>;
|
||||
using sections = std::vector<std::unique_ptr<COFFSection>>;
|
||||
|
||||
|
@ -225,7 +227,8 @@ void COFFSymbol::set_name_offset(uint32_t Offset) {
|
|||
|
||||
WinCOFFObjectWriter::WinCOFFObjectWriter(
|
||||
std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
|
||||
: MCObjectWriter(OS, true), TargetObjectWriter(std::move(MOTW)) {
|
||||
: MCObjectWriter(OS, true), W(OS, support::little),
|
||||
TargetObjectWriter(std::move(MOTW)) {
|
||||
Header.Machine = TargetObjectWriter->getMachine();
|
||||
}
|
||||
|
||||
|
@ -472,40 +475,40 @@ bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
|
|||
|
||||
void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
|
||||
if (UseBigObj) {
|
||||
writeLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
writeLE16(0xFFFF);
|
||||
writeLE16(COFF::BigObjHeader::MinBigObjectVersion);
|
||||
writeLE16(Header.Machine);
|
||||
writeLE32(Header.TimeDateStamp);
|
||||
writeBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)));
|
||||
writeLE32(0);
|
||||
writeLE32(0);
|
||||
writeLE32(0);
|
||||
writeLE32(0);
|
||||
writeLE32(Header.NumberOfSections);
|
||||
writeLE32(Header.PointerToSymbolTable);
|
||||
writeLE32(Header.NumberOfSymbols);
|
||||
W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
W.write<uint16_t>(0xFFFF);
|
||||
W.write<uint16_t>(COFF::BigObjHeader::MinBigObjectVersion);
|
||||
W.write<uint16_t>(Header.Machine);
|
||||
W.write<uint32_t>(Header.TimeDateStamp);
|
||||
W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
|
||||
W.write<uint32_t>(0);
|
||||
W.write<uint32_t>(0);
|
||||
W.write<uint32_t>(0);
|
||||
W.write<uint32_t>(0);
|
||||
W.write<uint32_t>(Header.NumberOfSections);
|
||||
W.write<uint32_t>(Header.PointerToSymbolTable);
|
||||
W.write<uint32_t>(Header.NumberOfSymbols);
|
||||
} else {
|
||||
writeLE16(Header.Machine);
|
||||
writeLE16(static_cast<int16_t>(Header.NumberOfSections));
|
||||
writeLE32(Header.TimeDateStamp);
|
||||
writeLE32(Header.PointerToSymbolTable);
|
||||
writeLE32(Header.NumberOfSymbols);
|
||||
writeLE16(Header.SizeOfOptionalHeader);
|
||||
writeLE16(Header.Characteristics);
|
||||
W.write<uint16_t>(Header.Machine);
|
||||
W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
|
||||
W.write<uint32_t>(Header.TimeDateStamp);
|
||||
W.write<uint32_t>(Header.PointerToSymbolTable);
|
||||
W.write<uint32_t>(Header.NumberOfSymbols);
|
||||
W.write<uint16_t>(Header.SizeOfOptionalHeader);
|
||||
W.write<uint16_t>(Header.Characteristics);
|
||||
}
|
||||
}
|
||||
|
||||
void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
|
||||
writeBytes(StringRef(S.Data.Name, COFF::NameSize));
|
||||
writeLE32(S.Data.Value);
|
||||
W.OS.write(S.Data.Name, COFF::NameSize);
|
||||
W.write<uint32_t>(S.Data.Value);
|
||||
if (UseBigObj)
|
||||
writeLE32(S.Data.SectionNumber);
|
||||
W.write<uint32_t>(S.Data.SectionNumber);
|
||||
else
|
||||
writeLE16(static_cast<int16_t>(S.Data.SectionNumber));
|
||||
writeLE16(S.Data.Type);
|
||||
write8(S.Data.StorageClass);
|
||||
write8(S.Data.NumberOfAuxSymbols);
|
||||
W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
|
||||
W.write<uint16_t>(S.Data.Type);
|
||||
W.OS << char(S.Data.StorageClass);
|
||||
W.OS << char(S.Data.NumberOfAuxSymbols);
|
||||
WriteAuxiliarySymbols(S.Aux);
|
||||
}
|
||||
|
||||
|
@ -514,46 +517,45 @@ void WinCOFFObjectWriter::WriteAuxiliarySymbols(
|
|||
for (const AuxSymbol &i : S) {
|
||||
switch (i.AuxType) {
|
||||
case ATFunctionDefinition:
|
||||
writeLE32(i.Aux.FunctionDefinition.TagIndex);
|
||||
writeLE32(i.Aux.FunctionDefinition.TotalSize);
|
||||
writeLE32(i.Aux.FunctionDefinition.PointerToLinenumber);
|
||||
writeLE32(i.Aux.FunctionDefinition.PointerToNextFunction);
|
||||
WriteZeros(sizeof(i.Aux.FunctionDefinition.unused));
|
||||
W.write<uint32_t>(i.Aux.FunctionDefinition.TagIndex);
|
||||
W.write<uint32_t>(i.Aux.FunctionDefinition.TotalSize);
|
||||
W.write<uint32_t>(i.Aux.FunctionDefinition.PointerToLinenumber);
|
||||
W.write<uint32_t>(i.Aux.FunctionDefinition.PointerToNextFunction);
|
||||
W.OS.write_zeros(sizeof(i.Aux.FunctionDefinition.unused));
|
||||
if (UseBigObj)
|
||||
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
break;
|
||||
case ATbfAndefSymbol:
|
||||
WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused1));
|
||||
writeLE16(i.Aux.bfAndefSymbol.Linenumber);
|
||||
WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused2));
|
||||
writeLE32(i.Aux.bfAndefSymbol.PointerToNextFunction);
|
||||
WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused3));
|
||||
W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused1));
|
||||
W.write<uint16_t>(i.Aux.bfAndefSymbol.Linenumber);
|
||||
W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused2));
|
||||
W.write<uint32_t>(i.Aux.bfAndefSymbol.PointerToNextFunction);
|
||||
W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused3));
|
||||
if (UseBigObj)
|
||||
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
break;
|
||||
case ATWeakExternal:
|
||||
writeLE32(i.Aux.WeakExternal.TagIndex);
|
||||
writeLE32(i.Aux.WeakExternal.Characteristics);
|
||||
WriteZeros(sizeof(i.Aux.WeakExternal.unused));
|
||||
W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
|
||||
W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
|
||||
W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
|
||||
if (UseBigObj)
|
||||
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
break;
|
||||
case ATFile:
|
||||
writeBytes(
|
||||
StringRef(reinterpret_cast<const char *>(&i.Aux),
|
||||
UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
|
||||
W.OS.write(reinterpret_cast<const char *>(&i.Aux),
|
||||
UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size);
|
||||
break;
|
||||
case ATSectionDefinition:
|
||||
writeLE32(i.Aux.SectionDefinition.Length);
|
||||
writeLE16(i.Aux.SectionDefinition.NumberOfRelocations);
|
||||
writeLE16(i.Aux.SectionDefinition.NumberOfLinenumbers);
|
||||
writeLE32(i.Aux.SectionDefinition.CheckSum);
|
||||
writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
|
||||
write8(i.Aux.SectionDefinition.Selection);
|
||||
WriteZeros(sizeof(i.Aux.SectionDefinition.unused));
|
||||
writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
|
||||
W.write<uint32_t>(i.Aux.SectionDefinition.Length);
|
||||
W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
|
||||
W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
|
||||
W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
|
||||
W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
|
||||
W.OS << char(i.Aux.SectionDefinition.Selection);
|
||||
W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
|
||||
W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
|
||||
if (UseBigObj)
|
||||
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -579,23 +581,23 @@ void WinCOFFObjectWriter::writeSectionHeaders() {
|
|||
COFF::section &S = Section->Header;
|
||||
if (Section->Relocations.size() >= 0xffff)
|
||||
S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
|
||||
writeBytes(StringRef(S.Name, COFF::NameSize));
|
||||
writeLE32(S.VirtualSize);
|
||||
writeLE32(S.VirtualAddress);
|
||||
writeLE32(S.SizeOfRawData);
|
||||
writeLE32(S.PointerToRawData);
|
||||
writeLE32(S.PointerToRelocations);
|
||||
writeLE32(S.PointerToLineNumbers);
|
||||
writeLE16(S.NumberOfRelocations);
|
||||
writeLE16(S.NumberOfLineNumbers);
|
||||
writeLE32(S.Characteristics);
|
||||
W.OS.write(S.Name, COFF::NameSize);
|
||||
W.write<uint32_t>(S.VirtualSize);
|
||||
W.write<uint32_t>(S.VirtualAddress);
|
||||
W.write<uint32_t>(S.SizeOfRawData);
|
||||
W.write<uint32_t>(S.PointerToRawData);
|
||||
W.write<uint32_t>(S.PointerToRelocations);
|
||||
W.write<uint32_t>(S.PointerToLineNumbers);
|
||||
W.write<uint16_t>(S.NumberOfRelocations);
|
||||
W.write<uint16_t>(S.NumberOfLineNumbers);
|
||||
W.write<uint32_t>(S.Characteristics);
|
||||
}
|
||||
}
|
||||
|
||||
void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
|
||||
writeLE32(R.VirtualAddress);
|
||||
writeLE32(R.SymbolTableIndex);
|
||||
writeLE16(R.Type);
|
||||
W.write<uint32_t>(R.VirtualAddress);
|
||||
W.write<uint32_t>(R.SymbolTableIndex);
|
||||
W.write<uint16_t>(R.Type);
|
||||
}
|
||||
|
||||
// Write MCSec's contents. What this function does is essentially
|
||||
|
@ -611,7 +613,7 @@ uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
|
|||
Asm.writeSectionData(VecOS, &MCSec, Layout);
|
||||
|
||||
// Write the section contents to the object file.
|
||||
getStream() << Buf;
|
||||
W.OS << Buf;
|
||||
|
||||
// Calculate our CRC with an initial value of '0', this is not how
|
||||
// JamCRC is specified but it aligns with the expected output.
|
||||
|
@ -629,13 +631,13 @@ void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
|
|||
|
||||
// Write the section contents.
|
||||
if (Sec.Header.PointerToRawData != 0) {
|
||||
assert(getStream().tell() <= Sec.Header.PointerToRawData &&
|
||||
assert(W.OS.tell() <= Sec.Header.PointerToRawData &&
|
||||
"Section::PointerToRawData is insane!");
|
||||
|
||||
unsigned PaddingSize = Sec.Header.PointerToRawData - getStream().tell();
|
||||
unsigned PaddingSize = Sec.Header.PointerToRawData - W.OS.tell();
|
||||
assert(PaddingSize < 4 &&
|
||||
"Should only need at most three bytes of padding!");
|
||||
WriteZeros(PaddingSize);
|
||||
W.OS.write_zeros(PaddingSize);
|
||||
|
||||
uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
|
||||
|
||||
|
@ -654,7 +656,7 @@ void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
|
|||
return;
|
||||
}
|
||||
|
||||
assert(getStream().tell() == Sec.Header.PointerToRelocations &&
|
||||
assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
|
||||
"Section::PointerToRelocations is insane!");
|
||||
|
||||
if (Sec.Relocations.size() >= 0xffff) {
|
||||
|
@ -900,7 +902,7 @@ void WinCOFFObjectWriter::assignSectionNumbers() {
|
|||
// Assign file offsets to COFF object file structures.
|
||||
void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout) {
|
||||
unsigned Offset = getInitialOffset();
|
||||
unsigned Offset = W.OS.tell();
|
||||
|
||||
Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
|
||||
Offset += COFF::SectionSize * Header.NumberOfSections;
|
||||
|
@ -1058,7 +1060,7 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
for (; I != IE && J != JE; ++I, ++J)
|
||||
writeSection(Asm, Layout, **I, *J);
|
||||
|
||||
assert(getStream().tell() == Header.PointerToSymbolTable &&
|
||||
assert(W.OS.tell() == Header.PointerToSymbolTable &&
|
||||
"Header::PointerToSymbolTable is insane!");
|
||||
|
||||
// Write a symbol table.
|
||||
|
@ -1067,7 +1069,7 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
|
|||
WriteSymbol(*Symbol);
|
||||
|
||||
// Write a string table, which completes the entire COFF file.
|
||||
Strings.write(getStream());
|
||||
Strings.write(W.OS);
|
||||
}
|
||||
|
||||
MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
|
||||
|
|
|
@ -225,7 +225,7 @@ getSection(const object::MachOObjectFile &Obj,
|
|||
template <typename SegmentTy>
|
||||
static void transferSegmentAndSections(
|
||||
const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment,
|
||||
const object::MachOObjectFile &Obj, MCObjectWriter &Writer,
|
||||
const object::MachOObjectFile &Obj, MachObjectWriter &Writer,
|
||||
uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t DwarfSegmentSize,
|
||||
uint64_t &GapForDwarf, uint64_t &EndAddress) {
|
||||
if (StringRef("__DWARF") == Segment.segname)
|
||||
|
@ -255,14 +255,13 @@ static void transferSegmentAndSections(
|
|||
unsigned nsects = Segment.nsects;
|
||||
if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
|
||||
MachO::swapStruct(Segment);
|
||||
Writer.writeBytes(
|
||||
StringRef(reinterpret_cast<char *>(&Segment), sizeof(Segment)));
|
||||
Writer.W.OS.write(reinterpret_cast<char *>(&Segment), sizeof(Segment));
|
||||
for (unsigned i = 0; i < nsects; ++i) {
|
||||
auto Sect = getSection(Obj, Segment, LCI, i);
|
||||
Sect.offset = Sect.reloff = Sect.nreloc = 0;
|
||||
if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
|
||||
MachO::swapStruct(Sect);
|
||||
Writer.writeBytes(StringRef(reinterpret_cast<char *>(&Sect), sizeof(Sect)));
|
||||
Writer.W.OS.write(reinterpret_cast<char *>(&Sect), sizeof(Sect));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,10 +428,9 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS,
|
|||
// Write the load commands.
|
||||
assert(OutFile.tell() == HeaderSize);
|
||||
if (UUIDCmd.cmd != 0) {
|
||||
Writer.write32(UUIDCmd.cmd);
|
||||
Writer.write32(UUIDCmd.cmdsize);
|
||||
Writer.writeBytes(
|
||||
StringRef(reinterpret_cast<const char *>(UUIDCmd.uuid), 16));
|
||||
Writer.W.write<uint32_t>(UUIDCmd.cmd);
|
||||
Writer.W.write<uint32_t>(UUIDCmd.cmdsize);
|
||||
OutFile.write(reinterpret_cast<const char *>(UUIDCmd.uuid), 16);
|
||||
assert(OutFile.tell() == HeaderSize + sizeof(UUIDCmd));
|
||||
}
|
||||
|
||||
|
@ -479,12 +477,12 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS,
|
|||
NumDwarfSections, Layout, Writer);
|
||||
|
||||
assert(OutFile.tell() == LoadCommandSize + HeaderSize);
|
||||
Writer.WriteZeros(SymtabStart - (LoadCommandSize + HeaderSize));
|
||||
OutFile.write_zeros(SymtabStart - (LoadCommandSize + HeaderSize));
|
||||
assert(OutFile.tell() == SymtabStart);
|
||||
|
||||
// Transfer symbols.
|
||||
if (ShouldEmitSymtab) {
|
||||
Writer.writeBytes(NewSymtab.str());
|
||||
OutFile << NewSymtab.str();
|
||||
assert(OutFile.tell() == StringStart);
|
||||
|
||||
// Transfer string table.
|
||||
|
@ -492,21 +490,20 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS,
|
|||
// dsymutil-classic starts the reconstructed string table with 2 of these.
|
||||
// Reproduce that behavior for now (there is corresponding code in
|
||||
// transferSymbol).
|
||||
Writer.WriteZeros(1);
|
||||
OutFile << '\0';
|
||||
std::vector<DwarfStringPoolEntryRef> Strings = NewStrings.getEntries();
|
||||
for (auto EntryRef : Strings) {
|
||||
if (EntryRef.getIndex() == -1U)
|
||||
break;
|
||||
StringRef ZeroTerminated(EntryRef.getString().data(),
|
||||
EntryRef.getString().size() + 1);
|
||||
Writer.writeBytes(ZeroTerminated);
|
||||
OutFile.write(EntryRef.getString().data(),
|
||||
EntryRef.getString().size() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
assert(OutFile.tell() == StringStart + NewStringsSize);
|
||||
|
||||
// Pad till the Dwarf segment start.
|
||||
Writer.WriteZeros(DwarfSegmentStart - (StringStart + NewStringsSize));
|
||||
OutFile.write_zeros(DwarfSegmentStart - (StringStart + NewStringsSize));
|
||||
assert(OutFile.tell() == DwarfSegmentStart);
|
||||
|
||||
// Emit the Dwarf sections contents.
|
||||
|
@ -515,7 +512,7 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS,
|
|||
continue;
|
||||
|
||||
uint64_t Pos = OutFile.tell();
|
||||
Writer.WriteZeros(alignTo(Pos, Sec.getAlignment()) - Pos);
|
||||
OutFile.write_zeros(alignTo(Pos, Sec.getAlignment()) - Pos);
|
||||
MCAsm.writeSectionData(OutFile, &Sec, Layout);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue