blob: 9356ee32a948636dcd26dc72252c6ff070ca0341 [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)
John Porto8b1a7052015-06-17 13:20:08 -070033// (2) writeDataSection (may be invoked multiple times, as long as
34// SectionSuffix is unique)
35// (3) writeFunctionCode (must invoke once per function)
36// (4) writeConstantPool (must invoke once per pooled primitive type)
37// (5) setUndefinedSyms (invoke once)
38// (6) writeNonUserSections (invoke once)
Jan Voung72984d82015-01-29 14:42:38 -080039//
40// The requirement for writeDataSection to be invoked only once can
41// be relaxed if using -fdata-sections. The requirement to invoke only once
42// without -fdata-sections is so that variables that belong to each possible
43// SectionType are contiguous in the file. With -fdata-sections, each global
44// variable is in a separate section and therefore the sections will be
45// trivially contiguous.
Jan Voung08c3bcd2014-12-01 17:55:16 -080046class ELFObjectWriter {
Jim Stichnothc6ead202015-02-24 09:30:30 -080047 ELFObjectWriter() = delete;
Jan Voung08c3bcd2014-12-01 17:55:16 -080048 ELFObjectWriter(const ELFObjectWriter &) = delete;
49 ELFObjectWriter &operator=(const ELFObjectWriter &) = delete;
50
51public:
52 ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out);
53
54 // Write the initial ELF header. This is just to reserve space in the ELF
55 // file. Reserving space allows the other functions to write text
56 // and data directly to the file and get the right file offsets.
57 void writeInitialELFHeader();
58
Jan Voung72984d82015-01-29 14:42:38 -080059 // Copy initializer data for globals to file and note the offset and size
60 // of each global's definition in the symbol table.
61 // Use the given target's RelocationKind for any relocations.
62 void writeDataSection(const VariableDeclarationList &Vars,
John Porto8b1a7052015-06-17 13:20:08 -070063 FixupKind RelocationKind,
64 const IceString &SectionSuffix);
Jan Voung72984d82015-01-29 14:42:38 -080065
Jan Voung08c3bcd2014-12-01 17:55:16 -080066 // Copy data of a function's text section to file and note the offset of the
67 // symbol's definition in the symbol table.
Jan Voungec270732015-01-12 17:00:22 -080068 // Copy the text fixups for use after all functions are written.
Jan Voung72984d82015-01-29 14:42:38 -080069 // The text buffer and fixups are extracted from the Assembler object.
Jan Voung08c3bcd2014-12-01 17:55:16 -080070 void writeFunctionCode(const IceString &FuncName, bool IsInternal,
Jan Voungec270732015-01-12 17:00:22 -080071 const Assembler *Asm);
Jan Voung08c3bcd2014-12-01 17:55:16 -080072
Jan Voung72984d82015-01-29 14:42:38 -080073 // Queries the GlobalContext for constant pools of the given type
74 // and writes out read-only data sections for those constants. This also
75 // fills the symbol table with labels for each constant pool entry.
Jan Voung91a3e2c2015-01-09 13:01:42 -080076 template <typename ConstType> void writeConstantPool(Type Ty);
77
Jan Voung261cae32015-02-01 10:31:03 -080078 // Populate the symbol table with a list of external/undefined symbols.
79 void setUndefinedSyms(const ConstantList &UndefSyms);
80
Jan Voung72984d82015-01-29 14:42:38 -080081 // Do final layout and write out the rest of the object file.
82 // Finally, patch up the initial ELF header with the final info.
Jan Voung08c3bcd2014-12-01 17:55:16 -080083 void writeNonUserSections();
84
Jan Voung72984d82015-01-29 14:42:38 -080085 // Which type of ELF section a global variable initializer belongs to.
86 // This is used as an array index so should start at 0 and be contiguous.
87 enum SectionType { ROData = 0, Data, BSS, NumSectionTypes };
88
Jan Voung08c3bcd2014-12-01 17:55:16 -080089private:
90 GlobalContext &Ctx;
91 ELFStreamer &Str;
Jim Stichnotheafb56c2015-06-22 10:35:22 -070092 bool SectionNumbersAssigned = false;
Jan Voung1f47ad02015-03-20 15:01:26 -070093 bool ELF64;
Jan Voung08c3bcd2014-12-01 17:55:16 -080094
95 // All created sections, separated into different pools.
96 typedef std::vector<ELFSection *> SectionList;
97 typedef std::vector<ELFTextSection *> TextSectionList;
98 typedef std::vector<ELFDataSection *> DataSectionList;
Jan Voungec270732015-01-12 17:00:22 -080099 typedef std::vector<ELFRelocationSection *> RelSectionList;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800100 TextSectionList TextSections;
101 RelSectionList RelTextSections;
102 DataSectionList DataSections;
103 RelSectionList RelDataSections;
Jan Voung72984d82015-01-29 14:42:38 -0800104 DataSectionList RODataSections;
105 RelSectionList RelRODataSections;
106 DataSectionList BSSSections;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800107
108 // Handles to special sections that need incremental bookkeeping.
109 ELFSection *NullSection;
110 ELFStringTableSection *ShStrTab;
111 ELFSymbolTableSection *SymTab;
112 ELFStringTableSection *StrTab;
113
114 template <typename T>
115 T *createSection(const IceString &Name, Elf64_Word ShType,
116 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
117 Elf64_Xword ShEntsize);
118
Jan Voung72984d82015-01-29 14:42:38 -0800119 // Create a relocation section, given the related section
120 // (e.g., .text, .data., .rodata).
121 ELFRelocationSection *
Jan Voung1f47ad02015-03-20 15:01:26 -0700122 createRelocationSection(const ELFSection *RelatedSection);
Jan Voung72984d82015-01-29 14:42:38 -0800123
Jan Voung08c3bcd2014-12-01 17:55:16 -0800124 // Align the file position before writing out a section's data,
125 // and return the position of the file.
126 Elf64_Off alignFileOffset(Elf64_Xword Align);
127
128 // Assign an ordering / section numbers to each section.
129 // Fill in other information that is only known near the end
130 // (such as the size, if it wasn't already incrementally updated).
131 // This then collects all sections in the decided order, into one vector,
132 // for conveniently writing out all of the section headers.
133 void assignSectionNumbersInfo(SectionList &AllSections);
134
135 // This function assigns .foo and .rel.foo consecutive section numbers.
136 // It also sets the relocation section's sh_info field to the related
137 // section's number.
138 template <typename UserSectionList>
139 void assignRelSectionNumInPairs(SizeT &CurSectionNumber,
140 UserSectionList &UserSections,
141 RelSectionList &RelSections,
142 SectionList &AllSections);
143
144 // Link the relocation sections to the symbol table.
145 void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections);
146
Jan Voung72984d82015-01-29 14:42:38 -0800147 // Helper function for writeDataSection. Writes a data section of type
148 // SectionType, given the global variables Vars belonging to that SectionType.
149 void writeDataOfType(SectionType SectionType,
150 const VariableDeclarationList &Vars,
John Porto8b1a7052015-06-17 13:20:08 -0700151 FixupKind RelocationKind,
152 const IceString &SectionSuffix);
Jan Voung72984d82015-01-29 14:42:38 -0800153
Jan Voungec270732015-01-12 17:00:22 -0800154 // Write the final relocation sections given the final symbol table.
155 // May also be able to seek around the file and resolve function calls
156 // that are for functions within the same section.
Jan Voung1f47ad02015-03-20 15:01:26 -0700157 void writeAllRelocationSections();
158 void writeRelocationSections(RelSectionList &RelSections);
Jan Voungec270732015-01-12 17:00:22 -0800159
Jan Voung08c3bcd2014-12-01 17:55:16 -0800160 // Write the ELF file header with the given information about sections.
161 template <bool IsELF64>
Jan Vounga601cc52014-12-03 15:51:22 -0800162 void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset,
Jan Voung08c3bcd2014-12-01 17:55:16 -0800163 SizeT SectHeaderStrIndex, SizeT NumSections);
164};
165
166} // end of namespace Ice
167
168#endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H