Index: src/IceELFObjectWriter.cpp |
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp |
index 3ac8a55fec660c736161cb5db134459d9fb82beb..4a31a99b8e365029199346b91af0a093423e2819 100644 |
--- a/src/IceELFObjectWriter.cpp |
+++ b/src/IceELFObjectWriter.cpp |
@@ -17,6 +17,7 @@ |
#include "IceELFStreamer.h" |
#include "IceGlobalContext.h" |
#include "IceGlobalInits.h" |
+#include "IceOperand.h" |
using namespace llvm::ELF; |
@@ -291,6 +292,61 @@ void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, |
Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx |
} |
+template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { |
+ ConstantList Pool = Ctx.getConstantPool(Ty); |
+ if (Pool.empty()) { |
+ return; |
+ } |
+ SizeT Align = typeAlignInBytes(Ty); |
+ size_t EntSize = typeWidthInBytes(Ty); |
+ char Buf[20]; |
+ SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); |
+ assert(WriteAmt == EntSize); |
+ // Assume that writing WriteAmt bytes at a time allows us to avoid aligning |
+ // between entries. |
+ assert(WriteAmt % Align == 0); |
+ // Check that we write the full PrimType. |
+ assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
+ const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
+ std::string SecBuffer; |
+ llvm::raw_string_ostream SecStrBuf(SecBuffer); |
+ SecStrBuf << ".rodata.cst" << WriteAmt; |
+ ELFDataSection *Section = createSection<ELFDataSection>( |
+ SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
+ RoDataSections.push_back(Section); |
+ SizeT OffsetInSection = 0; |
+ // The symbol table entry doesn't need to know the defined symbol's |
+ // size since this is in a section with a fixed Entry Size. |
+ const SizeT SymbolSize = 0; |
+ Section->setFileOffset(alignFileOffset(Align)); |
+ |
+ // Write the data. |
+ for (Constant *C : Pool) { |
+ auto Const = llvm::cast<ConstType>(C); |
+ std::string SymBuffer; |
+ llvm::raw_string_ostream SymStrBuf(SymBuffer); |
+ SymStrBuf << ".L$" << Ty << "$" << Const->getPoolEntryID(); |
+ std::string &SymName = SymStrBuf.str(); |
+ SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, |
+ OffsetInSection, SymbolSize); |
+ StrTab->add(SymName); |
+ typename ConstType::PrimType Value = Const->getValue(); |
+ memcpy(Buf, &Value, WriteAmt); |
+ Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); |
+ OffsetInSection += WriteAmt; |
+ } |
+ Section->setSize(OffsetInSection); |
+} |
+ |
+// Instantiate known needed versions of the template, since we are |
+// defining the function in the .cpp file instead of the .h file. |
+// We may need to instantiate constant pools for integers as well |
+// if we do constant-pooling of large integers to remove them |
+// from the instruction stream (fewer bytes controlled by an attacker). |
+template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
+ |
+template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
+ |
void ELFObjectWriter::writeNonUserSections() { |
bool IsELF64 = isELF64(Ctx.getTargetArch()); |