diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-06-06 03:56:29 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-06-06 03:56:29 +0000 |
commit | f5b0c5a1c735dd2a6027edcca83cddc6d755bdc2 (patch) | |
tree | 755bfc73de0021d29c7e3d686398969a636d78df /lib/CodeGen/ELFWriter.cpp | |
parent | 556929a84bb8842cb07bebf4df67810d17be096e (diff) | |
download | external_llvm-f5b0c5a1c735dd2a6027edcca83cddc6d755bdc2.zip external_llvm-f5b0c5a1c735dd2a6027edcca83cddc6d755bdc2.tar.gz external_llvm-f5b0c5a1c735dd2a6027edcca83cddc6d755bdc2.tar.bz2 |
Remove elf specific info from ELFWriter.h to Elf.h. Code cleanup and more comments added
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72982 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ELFWriter.cpp')
-rw-r--r-- | lib/CodeGen/ELFWriter.cpp | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index be8edce..24f12a3 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -33,6 +33,7 @@ #include "ELFWriter.h" #include "ELFCodeEmitter.h" +#include "ELF.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/DerivedTypes.h" @@ -67,7 +68,8 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM, ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm) : MachineFunctionPass(&ID), O(o), TM(tm) { - e_flags = 0; // e_flags defaults to 0, no flags. + e_flags = 0; // e_flags defaults to 0, no flags. + e_machine = TM.getELFWriterInfo()->getEMachine(); is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64; isLittleEndian = TM.getTargetData()->isLittleEndian(); @@ -90,24 +92,39 @@ bool ELFWriter::doInitialization(Module &M) { std::vector<unsigned char> &FH = FileHeader; OutputBuffer FHOut(FH, is64Bit, isLittleEndian); - FHOut.outbyte(0x7F); // EI_MAG0 - FHOut.outbyte('E'); // EI_MAG1 - FHOut.outbyte('L'); // EI_MAG2 - FHOut.outbyte('F'); // EI_MAG3 - FHOut.outbyte(is64Bit ? 2 : 1); // EI_CLASS - FHOut.outbyte(isLittleEndian ? 1 : 2); // EI_DATA - FHOut.outbyte(1); // EI_VERSION - FH.resize(16); // EI_PAD up to 16 bytes. - - // This should change for shared objects. - FHOut.outhalf(1); // e_type = ET_REL - FHOut.outhalf(TM.getELFWriterInfo()->getEMachine()); // target-defined - FHOut.outword(1); // e_version = 1 - FHOut.outaddr(0); // e_entry = 0 -> no entry point in .o file - FHOut.outaddr(0); // e_phoff = 0 -> no program header for .o - - ELFHeader_e_shoff_Offset = FH.size(); - FHOut.outaddr(0); // e_shoff + unsigned ElfClass = is64Bit ? ELFCLASS64 : ELFCLASS32; + unsigned ElfEndian = isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB; + + // ELF Header + // ---------- + // Fields e_shnum e_shstrndx are only known after all section have + // been emitted. They locations in the ouput buffer are recorded so + // to be patched up later. + // + // Note + // ---- + // FHOut.outaddr method behaves differently for ELF32 and ELF64 writing + // 4 bytes in the former and 8 in the last for *_off and *_addr elf types + + FHOut.outbyte(0x7f); // e_ident[EI_MAG0] + FHOut.outbyte('E'); // e_ident[EI_MAG1] + FHOut.outbyte('L'); // e_ident[EI_MAG2] + FHOut.outbyte('F'); // e_ident[EI_MAG3] + + FHOut.outbyte(ElfClass); // e_ident[EI_CLASS] + FHOut.outbyte(ElfEndian); // e_ident[EI_DATA] + FHOut.outbyte(EV_CURRENT); // e_ident[EI_VERSION] + + FH.resize(16); // e_ident[EI_NIDENT-EI_PAD] + + FHOut.outhalf(ET_REL); // e_type + FHOut.outhalf(e_machine); // e_machine = target + FHOut.outword(EV_CURRENT); // e_version + FHOut.outaddr(0); // e_entry = 0 -> no entry point in .o file + FHOut.outaddr(0); // e_phoff = 0 -> no program header for .o + + ELFHdr_e_shoff_Offset = FH.size(); + FHOut.outaddr(0); // e_shoff = sec hdr table off in bytes FHOut.outword(e_flags); // e_flags = whatever the target wants FHOut.outhalf(is64Bit ? 64 : 52); // e_ehsize = ELF header size @@ -115,14 +132,16 @@ bool ELFWriter::doInitialization(Module &M) { FHOut.outhalf(0); // e_phnum = # prog header entries = 0 FHOut.outhalf(is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size + // e_shnum = # of section header ents + ELFHdr_e_shnum_Offset = FH.size(); + FHOut.outhalf(0); - ELFHeader_e_shnum_Offset = FH.size(); - FHOut.outhalf(0); // e_shnum = # of section header ents - ELFHeader_e_shstrndx_Offset = FH.size(); - FHOut.outhalf(0); // e_shstrndx = Section # of '.shstrtab' + // e_shstrndx = Section # of '.shstrtab' + ELFHdr_e_shstrndx_Offset = FH.size(); + FHOut.outhalf(0); // Add the null section, which is required to be first in the file. - getSection("", 0, 0); + getSection("", ELFSection::SHT_NULL, 0); // Start up the symbol table. The first entry in the symtab is the null // entry. @@ -334,7 +353,7 @@ void ELFWriter::EmitSectionTableStringTable() { // Now that we know which section number is the .shstrtab section, update the // e_shstrndx entry in the ELF header. OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian); - FHOut.fixhalf(SHStrTab.SectionIdx, ELFHeader_e_shstrndx_Offset); + FHOut.fixhalf(SHStrTab.SectionIdx, ELFHdr_e_shstrndx_Offset); // Set the NameIdx of each section in the string table and emit the bytes for // the string table. @@ -386,11 +405,11 @@ void ELFWriter::OutputSectionsAndSectionTable() { // Now that we know where all of the sections will be emitted, set the e_shnum // entry in the ELF header. OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian); - FHOut.fixhalf(NumSections, ELFHeader_e_shnum_Offset); + FHOut.fixhalf(NumSections, ELFHdr_e_shnum_Offset); // Now that we know the offset in the file of the section table, update the // e_shoff address in the ELF header. - FHOut.fixaddr(FileOff, ELFHeader_e_shoff_Offset); + FHOut.fixaddr(FileOff, ELFHdr_e_shoff_Offset); // Now that we know all of the data in the file header, emit it and all of the // sections! |