IceELFObjectWriter.h revision 08c3bcd66dc0101720da78c1d5f49230f4521c75
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>
11908c3bcd66dc0101720da78c1d5f49230f4521c75Jan Voung  void writeELFHeaderInternal(uint64_t 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