Index: src/IceELFObjectWriter.cpp |
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp |
index 3ac8a55fec660c736161cb5db134459d9fb82beb..257252711ed510c2e9a28783ae5860d94fae6140 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,56 @@ 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.size() == 0) { |
Jim Stichnoth
2015/01/09 19:23:45
Pool.empty()
jvoung (off chromium)
2015/01/09 19:52:16
Done.
|
+ return; |
+ } |
+ SizeT Align = typeAlignInBytes(Ty); |
+ SizeT EntSize = typeWidthInBytes(Ty); |
+ // Assume that writing EntSize bytes at a time allows us to avoid aligning |
+ // between entries. |
+ assert(EntSize % Align == 0); |
+ assert(EntSize == sizeof(typename ConstType::PrimType)); |
+ const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
+ std::string SecBuffer; |
+ llvm::raw_string_ostream SecStrBuf(SecBuffer); |
+ SecStrBuf << ".rodata.cst" << EntSize; |
+ ELFDataSection *Section = createSection<ELFDataSection>( |
+ SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, EntSize); |
+ 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) { |
+ ConstType *Const = llvm::cast<ConstType>(C); |
Jim Stichnoth
2015/01/09 19:23:45
Could use "auto Const" here.
jvoung (off chromium)
2015/01/09 19:52:16
Done.
|
+ 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(); |
+ char Buf[20]; |
+ assert(EntSize < llvm::array_lengthof(Buf)); |
+ memcpy(Buf, &Value, EntSize); |
Jim Stichnoth
2015/01/09 19:23:45
Can you make this safer in the NDEBUG build by usi
jvoung (off chromium)
2015/01/09 19:52:16
Done.
|
+ Str.writeBytes(llvm::StringRef(Buf, EntSize)); |
+ OffsetInSection += EntSize; |
+ } |
+ 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. |
jvoung (off chromium)
2015/01/09 02:05:50
Wasn't sure of a better way =/
I think on ARM we'
Jim Stichnoth
2015/01/09 19:23:45
I think this is the usual way...
jvoung (off chromium)
2015/01/09 19:52:16
Done.
|
+template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
+ |
+template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
+ |
void ELFObjectWriter::writeNonUserSections() { |
bool IsELF64 = isELF64(Ctx.getTargetArch()); |