blob: f5ae7b8b581a8110eed38c0da53a13bccd86e9b9 [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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
11/// Abstraction for a writer that is responsible for writing an ELF file.
12///
Jan Voung08c3bcd2014-12-01 17:55:16 -080013//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEELFOBJECTWRITER_H
16#define SUBZERO_SRC_ICEELFOBJECTWRITER_H
17
18#include "IceDefs.h"
19#include "IceELFSection.h"
20#include "IceELFStreamer.h"
Jan Voung91a3e2c2015-01-09 13:01:42 -080021#include "IceTypes.h"
Jan Voung08c3bcd2014-12-01 17:55:16 -080022
23using namespace llvm::ELF;
24
25namespace Ice {
26
Andrew Scull9612d322015-07-06 14:53:25 -070027/// Higher level ELF object writer. Manages section information and writes
28/// the final ELF object. The object writer will write to file the code
29/// and data as it is being defined (rather than keep a copy).
30/// After all definitions are written out, it will finalize the bookkeeping
31/// sections and write them out. Expected usage:
32///
33/// (1) writeInitialELFHeader (invoke once)
34/// (2) writeDataSection (may be invoked multiple times, as long as
35/// SectionSuffix is unique)
36/// (3) writeFunctionCode (must invoke once per function)
37/// (4) writeConstantPool (must invoke once per pooled primitive type)
38/// (5) setUndefinedSyms (invoke once)
39/// (6) writeNonUserSections (invoke once)
40///
41/// The requirement for writeDataSection to be invoked only once can
42/// be relaxed if using -fdata-sections. The requirement to invoke only once
43/// without -fdata-sections is so that variables that belong to each possible
44/// SectionType are contiguous in the file. With -fdata-sections, each global
45/// variable is in a separate section and therefore the sections will be
46/// trivially contiguous.
Jan Voung08c3bcd2014-12-01 17:55:16 -080047class ELFObjectWriter {
Jim Stichnothc6ead202015-02-24 09:30:30 -080048 ELFObjectWriter() = delete;
Jan Voung08c3bcd2014-12-01 17:55:16 -080049 ELFObjectWriter(const ELFObjectWriter &) = delete;
50 ELFObjectWriter &operator=(const ELFObjectWriter &) = delete;
51
52public:
53 ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out);
54
Andrew Scull9612d322015-07-06 14:53:25 -070055 /// Write the initial ELF header. This is just to reserve space in the ELF
56 /// file. Reserving space allows the other functions to write text
57 /// and data directly to the file and get the right file offsets.
Jan Voung08c3bcd2014-12-01 17:55:16 -080058 void writeInitialELFHeader();
59
Andrew Scull9612d322015-07-06 14:53:25 -070060 /// Copy initializer data for globals to file and note the offset and size
61 /// of each global's definition in the symbol table.
62 /// Use the given target's RelocationKind for any relocations.
Jan Voung72984d82015-01-29 14:42:38 -080063 void writeDataSection(const VariableDeclarationList &Vars,
John Porto8b1a7052015-06-17 13:20:08 -070064 FixupKind RelocationKind,
65 const IceString &SectionSuffix);
Jan Voung72984d82015-01-29 14:42:38 -080066
Andrew Scull9612d322015-07-06 14:53:25 -070067 /// Copy data of a function's text section to file and note the offset of the
68 /// symbol's definition in the symbol table.
69 /// Copy the text fixups for use after all functions are written.
70 /// The text buffer and fixups are extracted from the Assembler object.
Jan Voung08c3bcd2014-12-01 17:55:16 -080071 void writeFunctionCode(const IceString &FuncName, bool IsInternal,
Jan Voungec270732015-01-12 17:00:22 -080072 const Assembler *Asm);
Jan Voung08c3bcd2014-12-01 17:55:16 -080073
Andrew Scull9612d322015-07-06 14:53:25 -070074 /// Queries the GlobalContext for constant pools of the given type
75 /// and writes out read-only data sections for those constants. This also
76 /// fills the symbol table with labels for each constant pool entry.
Jan Voung91a3e2c2015-01-09 13:01:42 -080077 template <typename ConstType> void writeConstantPool(Type Ty);
78
Andrew Scull86df4e92015-07-30 13:54:44 -070079 /// Write a jump table and register fixups for the target addresses.
80 void writeJumpTable(const JumpTableData &JT, FixupKind RelocationKind);
81
Andrew Scull9612d322015-07-06 14:53:25 -070082 /// Populate the symbol table with a list of external/undefined symbols.
Jan Voung261cae32015-02-01 10:31:03 -080083 void setUndefinedSyms(const ConstantList &UndefSyms);
84
Andrew Scull9612d322015-07-06 14:53:25 -070085 /// Do final layout and write out the rest of the object file.
86 /// Finally, patch up the initial ELF header with the final info.
Jan Voung08c3bcd2014-12-01 17:55:16 -080087 void writeNonUserSections();
88
Andrew Scull9612d322015-07-06 14:53:25 -070089 /// Which type of ELF section a global variable initializer belongs to.
90 /// This is used as an array index so should start at 0 and be contiguous.
Jan Voung72984d82015-01-29 14:42:38 -080091 enum SectionType { ROData = 0, Data, BSS, NumSectionTypes };
92
Jan Voung08c3bcd2014-12-01 17:55:16 -080093private:
94 GlobalContext &Ctx;
95 ELFStreamer &Str;
Jim Stichnotheafb56c2015-06-22 10:35:22 -070096 bool SectionNumbersAssigned = false;
Jan Voung1f47ad02015-03-20 15:01:26 -070097 bool ELF64;
Jan Voung08c3bcd2014-12-01 17:55:16 -080098
99 // All created sections, separated into different pools.
100 typedef std::vector<ELFSection *> SectionList;
101 typedef std::vector<ELFTextSection *> TextSectionList;
102 typedef std::vector<ELFDataSection *> DataSectionList;
Jan Voungec270732015-01-12 17:00:22 -0800103 typedef std::vector<ELFRelocationSection *> RelSectionList;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800104 TextSectionList TextSections;
105 RelSectionList RelTextSections;
106 DataSectionList DataSections;
107 RelSectionList RelDataSections;
Jan Voung72984d82015-01-29 14:42:38 -0800108 DataSectionList RODataSections;
109 RelSectionList RelRODataSections;
110 DataSectionList BSSSections;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800111
112 // Handles to special sections that need incremental bookkeeping.
113 ELFSection *NullSection;
114 ELFStringTableSection *ShStrTab;
115 ELFSymbolTableSection *SymTab;
116 ELFStringTableSection *StrTab;
117
118 template <typename T>
119 T *createSection(const IceString &Name, Elf64_Word ShType,
120 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
121 Elf64_Xword ShEntsize);
122
Andrew Scull9612d322015-07-06 14:53:25 -0700123 /// Create a relocation section, given the related section
124 /// (e.g., .text, .data., .rodata).
Jan Voung72984d82015-01-29 14:42:38 -0800125 ELFRelocationSection *
Jan Voung1f47ad02015-03-20 15:01:26 -0700126 createRelocationSection(const ELFSection *RelatedSection);
Jan Voung72984d82015-01-29 14:42:38 -0800127
Andrew Scull9612d322015-07-06 14:53:25 -0700128 /// Align the file position before writing out a section's data,
129 /// and return the position of the file.
Jan Voung08c3bcd2014-12-01 17:55:16 -0800130 Elf64_Off alignFileOffset(Elf64_Xword Align);
131
Andrew Scull9612d322015-07-06 14:53:25 -0700132 /// Assign an ordering / section numbers to each section.
133 /// Fill in other information that is only known near the end
134 /// (such as the size, if it wasn't already incrementally updated).
135 /// This then collects all sections in the decided order, into one vector,
136 /// for conveniently writing out all of the section headers.
Jan Voung08c3bcd2014-12-01 17:55:16 -0800137 void assignSectionNumbersInfo(SectionList &AllSections);
138
Andrew Scull9612d322015-07-06 14:53:25 -0700139 /// This function assigns .foo and .rel.foo consecutive section numbers.
140 /// It also sets the relocation section's sh_info field to the related
141 /// section's number.
Jan Voung08c3bcd2014-12-01 17:55:16 -0800142 template <typename UserSectionList>
143 void assignRelSectionNumInPairs(SizeT &CurSectionNumber,
144 UserSectionList &UserSections,
145 RelSectionList &RelSections,
146 SectionList &AllSections);
147
Andrew Scull9612d322015-07-06 14:53:25 -0700148 /// Link the relocation sections to the symbol table.
Jan Voung08c3bcd2014-12-01 17:55:16 -0800149 void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections);
150
Andrew Scull9612d322015-07-06 14:53:25 -0700151 /// Helper function for writeDataSection. Writes a data section of type
Andrew Scull87f80c12015-07-20 10:19:16 -0700152 /// SectionType, given the global variables Vars belonging to that
153 /// SectionType.
Jan Voung72984d82015-01-29 14:42:38 -0800154 void writeDataOfType(SectionType SectionType,
155 const VariableDeclarationList &Vars,
John Porto8b1a7052015-06-17 13:20:08 -0700156 FixupKind RelocationKind,
157 const IceString &SectionSuffix);
Jan Voung72984d82015-01-29 14:42:38 -0800158
Andrew Scull9612d322015-07-06 14:53:25 -0700159 /// Write the final relocation sections given the final symbol table.
160 /// May also be able to seek around the file and resolve function calls
161 /// that are for functions within the same section.
Jan Voung1f47ad02015-03-20 15:01:26 -0700162 void writeAllRelocationSections();
163 void writeRelocationSections(RelSectionList &RelSections);
Jan Voungec270732015-01-12 17:00:22 -0800164
Andrew Scull9612d322015-07-06 14:53:25 -0700165 /// Write the ELF file header with the given information about sections.
Jan Voung08c3bcd2014-12-01 17:55:16 -0800166 template <bool IsELF64>
Jan Vounga601cc52014-12-03 15:51:22 -0800167 void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset,
Jan Voung08c3bcd2014-12-01 17:55:16 -0800168 SizeT SectHeaderStrIndex, SizeT NumSections);
169};
170
171} // end of namespace Ice
172
173#endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H