blob: 11038455616eab6a33b44ea83a8c67c58fd53bd1 [file] [log] [blame]
Jan Voung08c3bcd2014-12-01 17:55:16 -08001//===- subzero/src/IceELFObjectWriter.h - ELF object writer -----*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Abstraction for a writer that is responsible for writing an ELF file.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef SUBZERO_SRC_ICEELFOBJECTWRITER_H
15#define SUBZERO_SRC_ICEELFOBJECTWRITER_H
16
17#include "IceDefs.h"
18#include "IceELFSection.h"
19#include "IceELFStreamer.h"
Jan Voung91a3e2c2015-01-09 13:01:42 -080020#include "IceTypes.h"
Jan Voung08c3bcd2014-12-01 17:55:16 -080021
22using namespace llvm::ELF;
23
24namespace Ice {
25
26// Higher level ELF object writer. Manages section information and writes
27// the final ELF object. The object writer will write to file the code
28// and data as it is being defined (rather than keep a copy).
29// After all definitions are written out, it will finalize the bookkeeping
30// sections and write them out. Expected usage:
31//
Jan Voung72984d82015-01-29 14:42:38 -080032// (1) writeInitialELFHeader (invoke once)
33// (2) writeDataSection (invoke once)
34// (3) writeFunctionCode (must invoke once per function)
35// (4) writeConstantPool (must invoke once per pooled primitive type)
Jan Voung261cae32015-02-01 10:31:03 -080036// (5) setUndefinedSyms (invoke once)
37// (6) writeNonUserSections (invoke once)
Jan Voung72984d82015-01-29 14:42:38 -080038//
39// The requirement for writeDataSection to be invoked only once can
40// be relaxed if using -fdata-sections. The requirement to invoke only once
41// without -fdata-sections is so that variables that belong to each possible
42// SectionType are contiguous in the file. With -fdata-sections, each global
43// variable is in a separate section and therefore the sections will be
44// trivially contiguous.
45//
46// The motivation for requiring that writeFunctionCode happen after
47// writeDataSection: to keep the .text and .data sections contiguous in the
48// file. Having both -fdata-sections and -ffunction-sections does allow
49// relaxing this requirement.
Jan Voung08c3bcd2014-12-01 17:55:16 -080050class ELFObjectWriter {
Jim Stichnothc6ead202015-02-24 09:30:30 -080051 ELFObjectWriter() = delete;
Jan Voung08c3bcd2014-12-01 17:55:16 -080052 ELFObjectWriter(const ELFObjectWriter &) = delete;
53 ELFObjectWriter &operator=(const ELFObjectWriter &) = delete;
54
55public:
56 ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out);
57
58 // Write the initial ELF header. This is just to reserve space in the ELF
59 // file. Reserving space allows the other functions to write text
60 // and data directly to the file and get the right file offsets.
61 void writeInitialELFHeader();
62
Jan Voung72984d82015-01-29 14:42:38 -080063 // Copy initializer data for globals to file and note the offset and size
64 // of each global's definition in the symbol table.
65 // Use the given target's RelocationKind for any relocations.
66 void writeDataSection(const VariableDeclarationList &Vars,
67 FixupKind RelocationKind);
68
Jan Voung08c3bcd2014-12-01 17:55:16 -080069 // Copy data of a function's text section to file and note the offset of the
70 // symbol's definition in the symbol table.
Jan Voungec270732015-01-12 17:00:22 -080071 // Copy the text fixups for use after all functions are written.
Jan Voung72984d82015-01-29 14:42:38 -080072 // The text buffer and fixups are extracted from the Assembler object.
Jan Voung08c3bcd2014-12-01 17:55:16 -080073 void writeFunctionCode(const IceString &FuncName, bool IsInternal,
Jan Voungec270732015-01-12 17:00:22 -080074 const Assembler *Asm);
Jan Voung08c3bcd2014-12-01 17:55:16 -080075
Jan Voung72984d82015-01-29 14:42:38 -080076 // Queries the GlobalContext for constant pools of the given type
77 // and writes out read-only data sections for those constants. This also
78 // fills the symbol table with labels for each constant pool entry.
Jan Voung91a3e2c2015-01-09 13:01:42 -080079 template <typename ConstType> void writeConstantPool(Type Ty);
80
Jan Voung261cae32015-02-01 10:31:03 -080081 // Populate the symbol table with a list of external/undefined symbols.
82 void setUndefinedSyms(const ConstantList &UndefSyms);
83
Jan Voung72984d82015-01-29 14:42:38 -080084 // Do final layout and write out the rest of the object file.
85 // Finally, patch up the initial ELF header with the final info.
Jan Voung08c3bcd2014-12-01 17:55:16 -080086 void writeNonUserSections();
87
Jan Voung72984d82015-01-29 14:42:38 -080088 // Which type of ELF section a global variable initializer belongs to.
89 // This is used as an array index so should start at 0 and be contiguous.
90 enum SectionType { ROData = 0, Data, BSS, NumSectionTypes };
91
Jan Voung08c3bcd2014-12-01 17:55:16 -080092private:
93 GlobalContext &Ctx;
94 ELFStreamer &Str;
95 bool SectionNumbersAssigned;
Jan Voung1f47ad02015-03-20 15:01:26 -070096 bool ELF64;
Jan Voung08c3bcd2014-12-01 17:55:16 -080097
98 // All created sections, separated into different pools.
99 typedef std::vector<ELFSection *> SectionList;
100 typedef std::vector<ELFTextSection *> TextSectionList;
101 typedef std::vector<ELFDataSection *> DataSectionList;
Jan Voungec270732015-01-12 17:00:22 -0800102 typedef std::vector<ELFRelocationSection *> RelSectionList;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800103 TextSectionList TextSections;
104 RelSectionList RelTextSections;
105 DataSectionList DataSections;
106 RelSectionList RelDataSections;
Jan Voung72984d82015-01-29 14:42:38 -0800107 DataSectionList RODataSections;
108 RelSectionList RelRODataSections;
109 DataSectionList BSSSections;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800110
111 // Handles to special sections that need incremental bookkeeping.
112 ELFSection *NullSection;
113 ELFStringTableSection *ShStrTab;
114 ELFSymbolTableSection *SymTab;
115 ELFStringTableSection *StrTab;
116
117 template <typename T>
118 T *createSection(const IceString &Name, Elf64_Word ShType,
119 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
120 Elf64_Xword ShEntsize);
121
Jan Voung72984d82015-01-29 14:42:38 -0800122 // Create a relocation section, given the related section
123 // (e.g., .text, .data., .rodata).
124 ELFRelocationSection *
Jan Voung1f47ad02015-03-20 15:01:26 -0700125 createRelocationSection(const ELFSection *RelatedSection);
Jan Voung72984d82015-01-29 14:42:38 -0800126
Jan Voung08c3bcd2014-12-01 17:55:16 -0800127 // Align the file position before writing out a section's data,
128 // and return the position of the file.
129 Elf64_Off alignFileOffset(Elf64_Xword Align);
130
131 // Assign an ordering / section numbers to each section.
132 // Fill in other information that is only known near the end
133 // (such as the size, if it wasn't already incrementally updated).
134 // This then collects all sections in the decided order, into one vector,
135 // for conveniently writing out all of the section headers.
136 void assignSectionNumbersInfo(SectionList &AllSections);
137
138 // This function assigns .foo and .rel.foo consecutive section numbers.
139 // It also sets the relocation section's sh_info field to the related
140 // section's number.
141 template <typename UserSectionList>
142 void assignRelSectionNumInPairs(SizeT &CurSectionNumber,
143 UserSectionList &UserSections,
144 RelSectionList &RelSections,
145 SectionList &AllSections);
146
147 // Link the relocation sections to the symbol table.
148 void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections);
149
Jan Voung72984d82015-01-29 14:42:38 -0800150 // Helper function for writeDataSection. Writes a data section of type
151 // SectionType, given the global variables Vars belonging to that SectionType.
152 void writeDataOfType(SectionType SectionType,
153 const VariableDeclarationList &Vars,
Jan Voung1f47ad02015-03-20 15:01:26 -0700154 FixupKind RelocationKind);
Jan Voung72984d82015-01-29 14:42:38 -0800155
Jan Voungec270732015-01-12 17:00:22 -0800156 // Write the final relocation sections given the final symbol table.
157 // May also be able to seek around the file and resolve function calls
158 // that are for functions within the same section.
Jan Voung1f47ad02015-03-20 15:01:26 -0700159 void writeAllRelocationSections();
160 void writeRelocationSections(RelSectionList &RelSections);
Jan Voungec270732015-01-12 17:00:22 -0800161
Jan Voung08c3bcd2014-12-01 17:55:16 -0800162 // Write the ELF file header with the given information about sections.
163 template <bool IsELF64>
Jan Vounga601cc52014-12-03 15:51:22 -0800164 void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset,
Jan Voung08c3bcd2014-12-01 17:55:16 -0800165 SizeT SectHeaderStrIndex, SizeT NumSections);
166};
167
168} // end of namespace Ice
169
170#endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H