blob: ce6bff32228fec6f8a12c404a44cf60fddd868a4 [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"
Rafael Espindola8c022ca2017-07-27 19:22:43 +000015#include "LinkerScript.h"
Simon Atanasyan41325112016-06-19 21:39:37 +000016#include "Relocations.h"
Rui Ueyama3f851702017-10-02 21:00:41 +000017#include "lld/Common/LLVM.h"
Rui Ueyamaa0752a52016-03-13 20:28:29 +000018#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;
Rui Ueyamaf52496e2017-11-03 21:21:47 +000025class Symbol;
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;
Rui Ueyama709fb2bb12017-07-26 22:13:32 +000032template <class ELFT> class ObjFile;
Peter Collingbourne21a12fc2016-04-27 20:22:31 +000033template <class ELFT> class SharedFile;
Rui Ueyama4076fa12017-02-26 23:35:34 +000034class SharedSymbol;
Peter Collingbournee9a9e0a2017-11-06 04:35:31 +000035class Defined;
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 Espindola8c022ca2017-07-27 19:22:43 +000041class OutputSection final : public BaseCommand, 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 }
Rui Ueyama5908c2f2017-10-11 02:28:28 +000048
Rafael Espindola8c022ca2017-07-27 19:22:43 +000049 static bool classof(const BaseCommand *C);
Rafael Espindola5616adf2017-03-08 22:36:28 +000050
Rafael Espindola48798642018-01-25 19:02:08 +000051 uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; }
Rafael Espindolae08e78d2016-11-09 23:23:45 +000052 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000053
Rui Ueyama2317d0d2015-10-15 20:55:22 +000054 unsigned SectionIndex;
Rafael Espindola52101412017-05-12 14:52:22 +000055 unsigned SortRank;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000056
Rafael Espindola0b113672016-07-27 14:10:56 +000057 uint32_t getPhdrFlags() const;
Rui Ueyama3b04d832016-07-14 05:46:24 +000058
George Rimar582ede82017-09-07 10:53:07 +000059 // Pointer to the PT_LOAD segment, which this section resides in. This field
60 // is used to correctly compute file offset of a section. When two sections
61 // share the same load segment, difference between their file offsets should
62 // be equal to difference between their virtual addresses. To compute some
63 // section offset we use the following formula: Off = Off_first + VA -
64 // VA_first, where Off_first and VA_first is file offset and VA of first
65 // section in PT_LOAD.
66 PhdrEntry *PtLoad = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000067
George Rimar990c9cb2017-06-07 09:20:35 +000068 // Pointer to a relocation section for this section. Usually nullptr because
69 // we consume relocations, but if --emit-relocs is specified (which is rare),
70 // it may have a non-null value.
71 OutputSection *RelocationSection = nullptr;
72
James Henderson8d0efdd2017-12-12 11:51:13 +000073 // Initially this field is the number of InputSections that have been added to
74 // the OutputSection so far. Later on, after a call to assignAddresses, it
75 // corresponds to the Elf_Shdr member.
Rafael Espindolae08e78d2016-11-09 23:23:45 +000076 uint64_t Size = 0;
James Henderson8d0efdd2017-12-12 11:51:13 +000077
78 // The following fields correspond to Elf_Shdr members.
Rafael Espindolae08e78d2016-11-09 23:23:45 +000079 uint64_t Offset = 0;
Rafael Espindolae08e78d2016-11-09 23:23:45 +000080 uint64_t Addr = 0;
Rafael Espindola04a2e342016-11-09 01:42:41 +000081 uint32_t ShName = 0;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000082
Rui Ueyama0e2bfb12017-10-07 00:43:31 +000083 void addSection(InputSection *IS);
Eugene Leviant84569e62016-11-29 08:05:44 +000084
85 // Location in the output buffer.
86 uint8_t *Loc = nullptr;
Rafael Espindola8c022ca2017-07-27 19:22:43 +000087
88 // The following members are normally only used in linker scripts.
89 MemoryRegion *MemRegion = nullptr;
Rafael Espindola567175f2018-01-25 01:36:36 +000090 MemoryRegion *LMARegion = nullptr;
Rafael Espindola8c022ca2017-07-27 19:22:43 +000091 Expr AddrExpr;
92 Expr AlignExpr;
93 Expr LMAExpr;
94 Expr SubalignExpr;
Rui Ueyama6b394ca2017-10-11 01:50:56 +000095 std::vector<BaseCommand *> SectionCommands;
Rafael Espindola8c022ca2017-07-27 19:22:43 +000096 std::vector<StringRef> Phdrs;
97 llvm::Optional<uint32_t> Filler;
98 ConstraintKind Constraint = ConstraintKind::NoConstraint;
99 std::string Location;
100 std::string MemoryRegionName;
George Rimar5d01a8b2018-01-12 09:07:35 +0000101 std::string LMARegionName;
George Rimar1c08e9f2018-02-16 10:42:58 +0000102 bool NonAlloc = false;
Rafael Espindola8c022ca2017-07-27 19:22:43 +0000103 bool Noload = false;
George Rimarc4df6702018-03-01 12:27:04 +0000104 bool ExpressionsUseSymbols = false;
Rafael Espindola8c022ca2017-07-27 19:22:43 +0000105
106 template <class ELFT> void finalize();
107 template <class ELFT> void writeTo(uint8_t *Buf);
108 template <class ELFT> void maybeCompress();
Rafael Espindola8c022ca2017-07-27 19:22:43 +0000109
110 void sort(std::function<int(InputSectionBase *S)> Order);
111 void sortInitFini();
112 void sortCtorsDtors();
Rui Ueyama40bd97a2017-10-06 21:42:37 +0000113
114private:
115 // Used for implementation of --compress-debug-sections option.
Rafael Espindola10bcc1c2017-12-12 17:37:01 +0000116 std::vector<uint8_t> ZDebugHeader;
117 llvm::SmallVector<char, 1> CompressedData;
118
119 uint32_t getFiller();
120};
121
Rafael Espindola8c022ca2017-07-27 19:22:43 +0000122int getPriority(StringRef S);
123
George Rimar563e4f22018-02-22 09:55:28 +0000124std::vector<InputSection *> getInputSections(OutputSection* OS);
125
Rui Ueyama9d1bacb12017-02-27 02:31:26 +0000126// All output sections that are handled by the linker specially are
Rui Ueyama15ef5e12015-10-07 19:18:16 +0000127// globally accessible. Writer initializes them, so don't use them
128// until Writer is initialized.
Rui Ueyama9d1bacb12017-02-27 02:31:26 +0000129struct Out {
Rui Ueyamacfadbd92016-11-01 23:12:51 +0000130 static uint8_t First;
Rafael Espindola24e6f362017-02-24 15:07:30 +0000131 static OutputSection *Opd;
Hal Finkeldaedc122015-10-12 23:16:53 +0000132 static uint8_t *OpdBuf;
Rafael Espindola17cb7c02016-12-19 17:01:01 +0000133 static PhdrEntry *TlsPhdr;
Rafael Espindola24e6f362017-02-24 15:07:30 +0000134 static OutputSection *DebugInfo;
135 static OutputSection *ElfHeader;
136 static OutputSection *ProgramHeaders;
137 static OutputSection *PreinitArray;
138 static OutputSection *InitArray;
139 static OutputSection *FiniArray;
Rui Ueyama15ef5e12015-10-07 19:18:16 +0000140};
Rui Ueyamad888d102015-10-09 19:34:55 +0000141
George Rimar67c60722017-07-18 11:55:35 +0000142} // namespace elf
143} // namespace lld
Rui Ueyama40bd97a2017-10-06 21:42:37 +0000144
Rafael Espindola63866282017-02-16 19:23:15 +0000145namespace lld {
146namespace elf {
George Rimar6892afa2016-07-12 09:49:43 +0000147
George Rimar78aa2702017-03-13 14:40:58 +0000148uint64_t getHeaderSize();
Rafael Espindola0d4b6d52016-09-22 16:47:21 +0000149
Rafael Espindolaf51c8052017-06-13 23:26:31 +0000150extern std::vector<OutputSection *> OutputSections;
Rafael Espindolae0df00b2016-02-28 00:25:54 +0000151} // namespace elf
Eugene Zelenko6e43b492015-11-04 02:11:57 +0000152} // namespace lld
153
George Rimar6892afa2016-07-12 09:49:43 +0000154#endif