IceELFObjectWriter.h revision a601cc5f89701e1f117ab61bfa3669d1aed48846
108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung//===- subzero/src/IceELFObjectWriter.h - ELF object writer -----*- C++ -*-===// 208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// The Subzero Code Generator 408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// This file is distributed under the University of Illinois Open Source 608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// License. See LICENSE.TXT for details. 708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung//===----------------------------------------------------------------------===// 908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 1008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// Abstraction for a writer that is responsible for writing an ELF file. 1108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 1208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung//===----------------------------------------------------------------------===// 1308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 1408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#ifndef SUBZERO_SRC_ICEELFOBJECTWRITER_H 1508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#define SUBZERO_SRC_ICEELFOBJECTWRITER_H 1608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 1708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#include "IceDefs.h" 1808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#include "IceELFSection.h" 1908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#include "IceELFStreamer.h" 2008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 2108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voungusing namespace llvm::ELF; 2208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 2308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voungnamespace Ice { 2408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 2508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// Higher level ELF object writer. Manages section information and writes 2608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// the final ELF object. The object writer will write to file the code 2708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// and data as it is being defined (rather than keep a copy). 2808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// After all definitions are written out, it will finalize the bookkeeping 2908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// sections and write them out. Expected usage: 3008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// 3108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// (1) writeInitialELFHeader 3208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// (2) writeDataInitializer* 3308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// (3) writeFunctionCode* 3408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung// (4) writeNonUserSections 3508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voungclass ELFObjectWriter { 3608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFObjectWriter(const ELFObjectWriter &) = delete; 3708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFObjectWriter &operator=(const ELFObjectWriter &) = delete; 3808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 3908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voungpublic: 4008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out); 4108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 4208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Write the initial ELF header. This is just to reserve space in the ELF 4308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // file. Reserving space allows the other functions to write text 4408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // and data directly to the file and get the right file offsets. 4508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void writeInitialELFHeader(); 4608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 4708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Copy data of a function's text section to file and note the offset of the 4808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // symbol's definition in the symbol table. 4908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // TODO(jvoung): This also needs the relocations to adjust the 5008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // section-relative offsets and hook them up to the symbol table references. 5108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void writeFunctionCode(const IceString &FuncName, bool IsInternal, 5208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung const llvm::StringRef Data); 5308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 5408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Copy initializer data for a global to file and note the offset and 5508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // size of the global's definition in the symbol table. 5608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // TODO(jvoung): This needs to know which section. This also needs the 5708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // relocations to hook them up to the symbol table references. Also 5808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // TODO is handling BSS (which just needs to note the size). 5908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void writeDataInitializer(const IceString &VarName, 6008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung const llvm::StringRef Data); 6108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 6208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Do final layout and write out the rest of the object file, then 6308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // patch up the initial ELF header with the final info. 6408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void writeNonUserSections(); 6508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 6608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voungprivate: 6708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung GlobalContext &Ctx; 6808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFStreamer &Str; 6908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung bool SectionNumbersAssigned; 7008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 7108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // All created sections, separated into different pools. 7208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung typedef std::vector<ELFSection *> SectionList; 7308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung typedef std::vector<ELFTextSection *> TextSectionList; 7408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung typedef std::vector<ELFDataSection *> DataSectionList; 7508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung typedef std::vector<ELFRelocationSectionBase *> RelSectionList; 7608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung TextSectionList TextSections; 7708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung RelSectionList RelTextSections; 7808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung DataSectionList DataSections; 7908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung RelSectionList RelDataSections; 8008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung DataSectionList RoDataSections; 8108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung RelSectionList RelRoDataSections; 8208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 8308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Handles to special sections that need incremental bookkeeping. 8408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFSection *NullSection; 8508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFStringTableSection *ShStrTab; 8608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFSymbolTableSection *SymTab; 8708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung ELFStringTableSection *StrTab; 8808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 8908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung template <typename T> 9008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung T *createSection(const IceString &Name, Elf64_Word ShType, 9108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 9208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung Elf64_Xword ShEntsize); 9308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 9408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Align the file position before writing out a section's data, 9508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // and return the position of the file. 9608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung Elf64_Off alignFileOffset(Elf64_Xword Align); 9708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 9808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Assign an ordering / section numbers to each section. 9908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Fill in other information that is only known near the end 10008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // (such as the size, if it wasn't already incrementally updated). 10108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // This then collects all sections in the decided order, into one vector, 10208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // for conveniently writing out all of the section headers. 10308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void assignSectionNumbersInfo(SectionList &AllSections); 10408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 10508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // This function assigns .foo and .rel.foo consecutive section numbers. 10608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // It also sets the relocation section's sh_info field to the related 10708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // section's number. 10808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung template <typename UserSectionList> 10908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void assignRelSectionNumInPairs(SizeT &CurSectionNumber, 11008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung UserSectionList &UserSections, 11108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung RelSectionList &RelSections, 11208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung SectionList &AllSections); 11308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 11408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Link the relocation sections to the symbol table. 11508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections); 11608c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 11708c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung // Write the ELF file header with the given information about sections. 11808c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung template <bool IsELF64> 119a601cc5f89701e1f117ab61bfa3669d1aed48846Jan Voung void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, 12008c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung SizeT SectHeaderStrIndex, SizeT NumSections); 12108c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung}; 12208c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 12308c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung} // end of namespace Ice 12408c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung 12508c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung#endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H 126