Chromium Code Reviews| 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()); |