unsigned StringTableIndex;
// This holds the .symtab section index.
unsigned SymbolTableIndex;
- // This holds the .symtab_shndx section index.
- unsigned SymtabShndxSectionIndex = 0;
// Sections in the order they are to be output in the section table.
std::vector<const MCSectionELF *> SectionTable;
Renames.clear();
Relocations.clear();
StrTabBuilder.clear();
- SymtabShndxSectionIndex = 0;
SectionTable.clear();
MCObjectWriter::reset();
}
template <typename T> void write(T Val) {
if (IsLittleEndian)
- support::endian::Writer<support::little>(OS).write(Val);
+ support::endian::Writer<support::little>(getStream()).write(Val);
else
- support::endian::Writer<support::big>(OS).write(Val);
+ support::endian::Writer<support::big>(getStream()).write(Val);
}
void writeHeader(const MCAssembler &Asm);
uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
const MCSectionELF &Section);
};
-} // namespace
+}
void ELFObjectWriter::align(unsigned Alignment) {
- uint64_t Padding = OffsetToAlignment(OS.tell(), Alignment);
+ uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
WriteZeros(Padding);
}
SymbolTableIndex = addToSectionTable(SymtabSection);
align(SymtabSection->getAlignment());
- uint64_t SecStart = OS.tell();
+ uint64_t SecStart = getStream().tell();
// The first entry is the undefined symbol entry.
Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
// seems that this information is not easily accessible from the
// ELFObjectWriter.
StringRef Name = Symbol.getName();
+ SmallString<32> Buf;
if (!Name.startswith("?") && !Name.startswith("@?") &&
!Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
// This symbol isn't following the MSVC C++ name mangling convention. We
// can thus safely interpret the @@@ in symbol names as specifying symbol
// versioning.
- SmallString<32> Buf;
size_t Pos = Name.find("@@@");
if (Pos != StringRef::npos) {
Buf += Name.substr(0, Pos);
ExternalSymbolData.push_back(MSD);
}
+ // This holds the .symtab_shndx section index.
+ unsigned SymtabShndxSectionIndex = 0;
+
if (HasLargeSectionIndex) {
MCSectionELF *SymtabShndxSection =
Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
unsigned Index = FileNames.size() + 1;
for (ELFSymbolData &MSD : LocalSymbolData) {
- unsigned StringIndex;
- if (MSD.Symbol->getType() == ELF::STT_SECTION || MSD.Name.empty())
- StringIndex = 0;
- else
- StringIndex = StrTabBuilder.getOffset(MSD.Name);
+ unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
+ ? 0
+ : StrTabBuilder.getOffset(MSD.Name);
MSD.Symbol->setIndex(Index++);
writeSymbol(Writer, StringIndex, MSD, Layout);
}
assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
}
- uint64_t SecEnd = OS.tell();
+ uint64_t SecEnd = getStream().tell();
SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
}
assert(SymtabShndxSectionIndex != 0);
- SecStart = OS.tell();
+ SecStart = getStream().tell();
const MCSectionELF *SymtabShndxSection =
SectionTable[SymtabShndxSectionIndex - 1];
for (uint32_t Index : ShndxIndexes)
write(Index);
- SecEnd = OS.tell();
+ SecEnd = getStream().tell();
SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
}
return RelaSection;
}
-static SmallVector<char, 128>
-getUncompressedData(const MCAsmLayout &Layout,
- const MCSection::FragmentListType &Fragments) {
- SmallVector<char, 128> UncompressedData;
- for (const MCFragment &F : Fragments) {
- const SmallVectorImpl<char> *Contents;
- switch (F.getKind()) {
- case MCFragment::FT_Data:
- Contents = &cast<MCDataFragment>(F).getContents();
- break;
- case MCFragment::FT_Dwarf:
- Contents = &cast<MCDwarfLineAddrFragment>(F).getContents();
- break;
- case MCFragment::FT_DwarfFrame:
- Contents = &cast<MCDwarfCallFrameFragment>(F).getContents();
- break;
- default:
- llvm_unreachable(
- "Not expecting any other fragment types in a debug_* section");
- }
- UncompressedData.append(Contents->begin(), Contents->end());
- }
- return UncompressedData;
-}
-
// Include the debug info compression header:
// "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
// useful for consumers to preallocate a buffer to decompress into.
return;
}
- // Gather the uncompressed data from all the fragments.
- const MCSection::FragmentListType &Fragments = Section.getFragmentList();
- SmallVector<char, 128> UncompressedData =
- getUncompressedData(Layout, Fragments);
+ SmallVector<char, 128> UncompressedData;
+ raw_svector_ostream VecOS(UncompressedData);
+ raw_pwrite_stream &OldStream = getStream();
+ setStream(VecOS);
+ Asm.writeSectionData(&Section, Layout);
+ setStream(OldStream);
SmallVector<char, 128> CompressedContents;
zlib::Status Success = zlib::compress(
StringRef(UncompressedData.data(), UncompressedData.size()),
CompressedContents);
if (Success != zlib::StatusOK) {
- Asm.writeSectionData(&Section, Layout);
+ getStream() << UncompressedData;
return;
}
if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) {
- Asm.writeSectionData(&Section, Layout);
+ getStream() << UncompressedData;
return;
}
Asm.getContext().renameELFSection(&Section,
(".z" + SectionName.drop_front(1)).str());
- OS << CompressedContents;
+ getStream() << CompressedContents;
}
void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
- OS << StrTabBuilder.data();
+ getStream() << StrTabBuilder.data();
return StrtabSection;
}
align(Section.getAlignment());
// Remember the offset into the file for this section.
- uint64_t SecStart = OS.tell();
+ uint64_t SecStart = getStream().tell();
const MCSymbolELF *SignatureSymbol = Section.getGroup();
writeSectionData(Asm, Section, Layout);
- uint64_t SecEnd = OS.tell();
+ uint64_t SecEnd = getStream().tell();
SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
align(Group->getAlignment());
// Remember the offset into the file for this section.
- uint64_t SecStart = OS.tell();
+ uint64_t SecStart = getStream().tell();
const MCSymbol *SignatureSymbol = Group->getGroup();
assert(SignatureSymbol);
write(SecIndex);
}
- uint64_t SecEnd = OS.tell();
+ uint64_t SecEnd = getStream().tell();
SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
}
align(RelSection->getAlignment());
// Remember the offset into the file for this section.
- uint64_t SecStart = OS.tell();
+ uint64_t SecStart = getStream().tell();
writeRelocations(Asm, *RelSection->getAssociatedSection());
- uint64_t SecEnd = OS.tell();
+ uint64_t SecEnd = getStream().tell();
SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
}
{
- uint64_t SecStart = OS.tell();
+ uint64_t SecStart = getStream().tell();
const MCSectionELF *Sec = createStringTable(Ctx);
- uint64_t SecEnd = OS.tell();
+ uint64_t SecEnd = getStream().tell();
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
}
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
align(NaturalAlignment);
- const unsigned SectionHeaderOffset = OS.tell();
+ const unsigned SectionHeaderOffset = getStream().tell();
// ... then the section header table ...
writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
uint64_t Val = SectionHeaderOffset;
if (sys::IsLittleEndianHost != IsLittleEndian)
sys::swapByteOrder(Val);
- OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
- offsetof(ELF::Elf64_Ehdr, e_shoff));
+ getStream().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);
- OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
- offsetof(ELF::Elf32_Ehdr, e_shoff));
+ getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
+ offsetof(ELF::Elf32_Ehdr, e_shoff));
NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
}
- OS.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
- NumSectionsOffset);
+ getStream().pwrite(reinterpret_cast<char *>(&NumSections),
+ sizeof(NumSections), NumSectionsOffset);
}
bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(