blob: 68ee066a13dafe16823585d62c4de01226d0265b [file] [log] [blame]
Rafael Espindola5805c4f2015-09-21 21:38:08 +00001//===- OutputSections.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_OUTPUT_SECTIONS_H
11#define LLD_ELF_OUTPUT_SECTIONS_H
12
Davide Italiano85121bb2015-09-25 03:56:11 +000013#include "Config.h"
Rafael Espindola5616adf2017-03-08 22:36:28 +000014#include "InputSection.h"
Simon Atanasyan41325112016-06-19 21:39:37 +000015#include "Relocations.h"
Davide Italiano85121bb2015-09-25 03:56:11 +000016
Rui Ueyamaa0752a52016-03-13 20:28:29 +000017#include "lld/Core/LLVM.h"
18#include "llvm/MC/StringTableBuilder.h"
19#include "llvm/Object/ELF.h"
Rafael Espindola5805c4f2015-09-21 21:38:08 +000020
21namespace lld {
Rafael Espindolae0df00b2016-02-28 00:25:54 +000022namespace elf {
Rafael Espindola5805c4f2015-09-21 21:38:08 +000023
Rafael Espindola17cb7c02016-12-19 17:01:01 +000024struct PhdrEntry;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000025class SymbolBody;
Rafael Espindola2deeb602016-07-21 20:18:30 +000026struct EhSectionPiece;
Rafael Espindola5c02b742017-03-06 21:17:18 +000027class EhInputSection;
Rafael Espindola774ea7d2017-02-23 16:49:07 +000028class InputSection;
Rafael Espindolab4c9b812017-02-23 02:28:28 +000029class InputSectionBase;
Rafael Espindola6119b862017-03-06 20:23:56 +000030class MergeInputSection;
Rafael Espindola24e6f362017-02-24 15:07:30 +000031class OutputSection;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000032template <class ELFT> class ObjectFile;
Peter Collingbourne21a12fc2016-04-27 20:22:31 +000033template <class ELFT> class SharedFile;
Rui Ueyama4076fa12017-02-26 23:35:34 +000034class SharedSymbol;
Rui Ueyama80474a22017-02-28 19:29:55 +000035class DefinedRegular;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000036
Rafael Espindola71675852015-09-22 00:16:19 +000037// This represents a section in an output file.
Rafael Espindola24e6f362017-02-24 15:07:30 +000038// It is composed of multiple InputSections.
Rafael Espindola71675852015-09-22 00:16:19 +000039// The writer creates multiple OutputSections and assign them unique,
Rafael Espindola5805c4f2015-09-21 21:38:08 +000040// non-overlapping file offsets and VAs.
Rafael Espindola5616adf2017-03-08 22:36:28 +000041class OutputSection final : public SectionBase {
Rafael Espindola5805c4f2015-09-21 21:38:08 +000042public:
Rafael Espindola24e6f362017-02-24 15:07:30 +000043 OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000044
Rafael Espindola5616adf2017-03-08 22:36:28 +000045 static bool classof(const SectionBase *S) {
46 return S->kind() == SectionBase::Output;
47 }
48
Rafael Espindolae08e78d2016-11-09 23:23:45 +000049 uint64_t getLMA() const { return Addr + LMAOffset; }
50 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000051
Rui Ueyama2317d0d2015-10-15 20:55:22 +000052 unsigned SectionIndex;
Rafael Espindola52101412017-05-12 14:52:22 +000053 unsigned SortRank;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000054
Rafael Espindola0b113672016-07-27 14:10:56 +000055 uint32_t getPhdrFlags() const;
Rui Ueyama3b04d832016-07-14 05:46:24 +000056
Rafael Espindola8bb40872017-03-07 15:51:09 +000057 void updateAlignment(uint32_t Val) {
Rafael Espindola37707632017-03-07 14:55:52 +000058 if (Val > Alignment)
59 Alignment = Val;
Rafael Espindola115f0f32015-11-03 14:13:40 +000060 }
Rafael Espindola5805c4f2015-09-21 21:38:08 +000061
Eugene Leviant3d9abec2016-09-29 09:20:33 +000062 // Pointer to the first section in PT_LOAD segment, which this section
63 // also resides in. This field is used to correctly compute file offset
64 // of a section. When two sections share the same load segment, difference
65 // between their file offsets should be equal to difference between their
66 // virtual addresses. To compute some section offset we use the following
67 // formula: Off = Off_first + VA - VA_first.
Rafael Espindola24e6f362017-02-24 15:07:30 +000068 OutputSection *FirstInPtLoad = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000069
George Rimar990c9cb2017-06-07 09:20:35 +000070 // Pointer to a relocation section for this section. Usually nullptr because
71 // we consume relocations, but if --emit-relocs is specified (which is rare),
72 // it may have a non-null value.
73 OutputSection *RelocationSection = nullptr;
74
Rafael Espindola04a2e342016-11-09 01:42:41 +000075 // The following fields correspond to Elf_Shdr members.
Rafael Espindolae08e78d2016-11-09 23:23:45 +000076 uint64_t Size = 0;
Rafael Espindolae08e78d2016-11-09 23:23:45 +000077 uint64_t Offset = 0;
Rafael Espindolae08e78d2016-11-09 23:23:45 +000078 uint64_t LMAOffset = 0;
79 uint64_t Addr = 0;
Rafael Espindola04a2e342016-11-09 01:42:41 +000080 uint32_t ShName = 0;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000081
Rafael Espindoladc8eb812017-04-07 01:40:21 +000082 void addSection(InputSection *S);
Rafael Espindola774ea7d2017-02-23 16:49:07 +000083 std::vector<InputSection *> Sections;
Eugene Leviant84569e62016-11-29 08:05:44 +000084
George Rimardbf93392017-04-17 08:58:12 +000085 // Used for implementation of --compress-debug-sections option.
Rui Ueyama07c62c12017-04-19 11:32:13 +000086 std::vector<uint8_t> ZDebugHeader;
George Rimardbf93392017-04-17 08:58:12 +000087 llvm::SmallVector<char, 1> CompressedData;
George Rimardbf93392017-04-17 08:58:12 +000088
Eugene Leviant84569e62016-11-29 08:05:44 +000089 // Location in the output buffer.
90 uint8_t *Loc = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000091};
92
Rui Ueyama9d1bacb12017-02-27 02:31:26 +000093// All output sections that are handled by the linker specially are
Rui Ueyama15ef5e12015-10-07 19:18:16 +000094// globally accessible. Writer initializes them, so don't use them
95// until Writer is initialized.
Rui Ueyama9d1bacb12017-02-27 02:31:26 +000096struct Out {
Rui Ueyamacfadbd92016-11-01 23:12:51 +000097 static uint8_t First;
Rafael Espindola24e6f362017-02-24 15:07:30 +000098 static OutputSection *Opd;
Hal Finkeldaedc122015-10-12 23:16:53 +000099 static uint8_t *OpdBuf;
Rafael Espindola17cb7c02016-12-19 17:01:01 +0000100 static PhdrEntry *TlsPhdr;
Rafael Espindola24e6f362017-02-24 15:07:30 +0000101 static OutputSection *DebugInfo;
102 static OutputSection *ElfHeader;
103 static OutputSection *ProgramHeaders;
104 static OutputSection *PreinitArray;
105 static OutputSection *InitArray;
106 static OutputSection *FiniArray;
Rui Ueyama15ef5e12015-10-07 19:18:16 +0000107};
Rui Ueyamad888d102015-10-09 19:34:55 +0000108
Rafael Espindola72447082017-01-05 14:35:41 +0000109struct SectionKey {
George Rimar6892afa2016-07-12 09:49:43 +0000110 StringRef Name;
Rafael Espindola72447082017-01-05 14:35:41 +0000111 uint64_t Flags;
Rafael Espindolafcd208f2017-03-08 19:35:29 +0000112 uint32_t Alignment;
George Rimar6892afa2016-07-12 09:49:43 +0000113};
Rafael Espindola63866282017-02-16 19:23:15 +0000114}
115}
116namespace llvm {
117template <> struct DenseMapInfo<lld::elf::SectionKey> {
118 static lld::elf::SectionKey getEmptyKey();
119 static lld::elf::SectionKey getTombstoneKey();
120 static unsigned getHashValue(const lld::elf::SectionKey &Val);
121 static bool isEqual(const lld::elf::SectionKey &LHS,
122 const lld::elf::SectionKey &RHS);
123};
124}
125namespace lld {
126namespace elf {
George Rimar6892afa2016-07-12 09:49:43 +0000127
128// This class knows how to create an output section for a given
129// input section. Output section type is determined by various
130// factors, including input section's sh_flags, sh_type and
131// linker scripts.
Rui Ueyama02a036f2017-02-27 02:31:48 +0000132class OutputSectionFactory {
George Rimar6892afa2016-07-12 09:49:43 +0000133public:
Rafael Espindola05531242017-07-06 16:40:44 +0000134 OutputSectionFactory();
Rafael Espindolabd3ab092017-01-05 14:52:46 +0000135 ~OutputSectionFactory();
Rui Ueyama02a036f2017-02-27 02:31:48 +0000136
Rafael Espindolab4c9b812017-02-23 02:28:28 +0000137 void addInputSec(InputSectionBase *IS, StringRef OutsecName);
Rafael Espindola4f013bb2017-04-26 22:30:15 +0000138 void addInputSec(InputSectionBase *IS, StringRef OutsecName,
139 OutputSection *&Sec);
Rafael Espindola82902742017-02-16 17:32:26 +0000140
George Rimar6892afa2016-07-12 09:49:43 +0000141private:
Rafael Espindola24e6f362017-02-24 15:07:30 +0000142 llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
George Rimar6892afa2016-07-12 09:49:43 +0000143};
144
George Rimar78aa2702017-03-13 14:40:58 +0000145uint64_t getHeaderSize();
Rafael Espindolae39709b2017-05-30 20:40:03 +0000146void reportDiscarded(InputSectionBase *IS);
Rafael Espindola0d4b6d52016-09-22 16:47:21 +0000147
Rafael Espindolaf51c8052017-06-13 23:26:31 +0000148extern std::vector<OutputSection *> OutputSections;
149extern std::vector<OutputSectionCommand *> OutputSectionCommands;
Rafael Espindolae0df00b2016-02-28 00:25:54 +0000150} // namespace elf
Eugene Zelenko6e43b492015-11-04 02:11:57 +0000151} // namespace lld
152
George Rimar6892afa2016-07-12 09:49:43 +0000153
154#endif