blob: e45e91e028e623acdd93f16bd94b5dc286b62c80 [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"
Simon Atanasyan41325112016-06-19 21:39:37 +000014#include "Relocations.h"
Davide Italiano85121bb2015-09-25 03:56:11 +000015
Rui Ueyamaa0752a52016-03-13 20:28:29 +000016#include "lld/Core/LLVM.h"
17#include "llvm/MC/StringTableBuilder.h"
18#include "llvm/Object/ELF.h"
Rafael Espindola5805c4f2015-09-21 21:38:08 +000019
20namespace lld {
Rafael Espindolae0df00b2016-02-28 00:25:54 +000021namespace elf {
Rafael Espindola5805c4f2015-09-21 21:38:08 +000022
Rafael Espindola17cb7c02016-12-19 17:01:01 +000023struct PhdrEntry;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000024class SymbolBody;
Rafael Espindola2deeb602016-07-21 20:18:30 +000025struct EhSectionPiece;
Rui Ueyama0b9a9032016-05-24 04:19:20 +000026template <class ELFT> class EhInputSection;
Rafael Espindola774ea7d2017-02-23 16:49:07 +000027class InputSection;
Rafael Espindolab4c9b812017-02-23 02:28:28 +000028class InputSectionBase;
Rafael Espindolac159c962015-10-19 21:00:02 +000029template <class ELFT> class MergeInputSection;
Rafael Espindola24e6f362017-02-24 15:07:30 +000030class OutputSection;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000031template <class ELFT> class ObjectFile;
Peter Collingbourne21a12fc2016-04-27 20:22:31 +000032template <class ELFT> class SharedFile;
Rui Ueyama4076fa12017-02-26 23:35:34 +000033class SharedSymbol;
Rui Ueyama80474a22017-02-28 19:29:55 +000034class DefinedRegular;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000035
Rafael Espindola71675852015-09-22 00:16:19 +000036// This represents a section in an output file.
Rafael Espindola24e6f362017-02-24 15:07:30 +000037// It is composed of multiple InputSections.
Rafael Espindola71675852015-09-22 00:16:19 +000038// The writer creates multiple OutputSections and assign them unique,
Rafael Espindola5805c4f2015-09-21 21:38:08 +000039// non-overlapping file offsets and VAs.
Rafael Espindola24e6f362017-02-24 15:07:30 +000040class OutputSection final {
Rafael Espindola5805c4f2015-09-21 21:38:08 +000041public:
Rafael Espindola24e6f362017-02-24 15:07:30 +000042 OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000043
Rafael Espindolae08e78d2016-11-09 23:23:45 +000044 uint64_t getLMA() const { return Addr + LMAOffset; }
45 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000046
Rui Ueyama2317d0d2015-10-15 20:55:22 +000047 unsigned SectionIndex;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000048
Rafael Espindola0b113672016-07-27 14:10:56 +000049 uint32_t getPhdrFlags() const;
Rui Ueyama3b04d832016-07-14 05:46:24 +000050
Rafael Espindolae08e78d2016-11-09 23:23:45 +000051 void updateAlignment(uint64_t Alignment) {
Rafael Espindola04a2e342016-11-09 01:42:41 +000052 if (Alignment > Addralign)
53 Addralign = Alignment;
Rafael Espindola115f0f32015-11-03 14:13:40 +000054 }
Rafael Espindola5805c4f2015-09-21 21:38:08 +000055
Rui Ueyama47091902016-03-30 19:41:51 +000056 // If true, this section will be page aligned on disk.
57 // Typically the first section of each PT_LOAD segment has this flag.
58 bool PageAlign = false;
59
Eugene Leviant3d9abec2016-09-29 09:20:33 +000060 // Pointer to the first section in PT_LOAD segment, which this section
61 // also resides in. This field is used to correctly compute file offset
62 // of a section. When two sections share the same load segment, difference
63 // between their file offsets should be equal to difference between their
64 // virtual addresses. To compute some section offset we use the following
65 // formula: Off = Off_first + VA - VA_first.
Rafael Espindola24e6f362017-02-24 15:07:30 +000066 OutputSection *FirstInPtLoad = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000067
Rafael Espindola5805c4f2015-09-21 21:38:08 +000068 StringRef Name;
Rafael Espindola04a2e342016-11-09 01:42:41 +000069
70 // The following fields correspond to Elf_Shdr members.
Rafael Espindolae08e78d2016-11-09 23:23:45 +000071 uint64_t Size = 0;
72 uint64_t Entsize = 0;
73 uint64_t Addralign = 0;
74 uint64_t Offset = 0;
75 uint64_t Flags = 0;
76 uint64_t LMAOffset = 0;
77 uint64_t Addr = 0;
Rafael Espindola04a2e342016-11-09 01:42:41 +000078 uint32_t ShName = 0;
79 uint32_t Type = 0;
80 uint32_t Info = 0;
81 uint32_t Link = 0;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000082
Rafael Espindola24e6f362017-02-24 15:07:30 +000083 void addSection(InputSectionBase *C);
Rafael Espindolac404d502017-02-23 02:32:18 +000084 void sort(std::function<int(InputSectionBase *S)> Order);
Rui Ueyama5af83682016-02-11 23:41:38 +000085 void sortInitFini();
86 void sortCtorsDtors();
Rafael Espindola24e6f362017-02-24 15:07:30 +000087 template <class ELFT> void writeTo(uint8_t *Buf);
88 template <class ELFT> void finalize();
89 template <class ELFT> void assignOffsets();
Rafael Espindola774ea7d2017-02-23 16:49:07 +000090 std::vector<InputSection *> Sections;
Eugene Leviant84569e62016-11-29 08:05:44 +000091
92 // Location in the output buffer.
93 uint8_t *Loc = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000094};
95
Rui Ueyama9d1bacb12017-02-27 02:31:26 +000096// All output sections that are handled by the linker specially are
Rui Ueyama15ef5e12015-10-07 19:18:16 +000097// globally accessible. Writer initializes them, so don't use them
98// until Writer is initialized.
Rui Ueyama9d1bacb12017-02-27 02:31:26 +000099struct Out {
Rui Ueyamacfadbd92016-11-01 23:12:51 +0000100 static uint8_t First;
Rafael Espindola24e6f362017-02-24 15:07:30 +0000101 static OutputSection *Bss;
102 static OutputSection *BssRelRo;
103 static OutputSection *Opd;
Hal Finkeldaedc122015-10-12 23:16:53 +0000104 static uint8_t *OpdBuf;
Rafael Espindola17cb7c02016-12-19 17:01:01 +0000105 static PhdrEntry *TlsPhdr;
Rafael Espindola24e6f362017-02-24 15:07:30 +0000106 static OutputSection *DebugInfo;
107 static OutputSection *ElfHeader;
108 static OutputSection *ProgramHeaders;
109 static OutputSection *PreinitArray;
110 static OutputSection *InitArray;
111 static OutputSection *FiniArray;
Rui Ueyama15ef5e12015-10-07 19:18:16 +0000112};
Rui Ueyamad888d102015-10-09 19:34:55 +0000113
Rafael Espindola72447082017-01-05 14:35:41 +0000114struct SectionKey {
George Rimar6892afa2016-07-12 09:49:43 +0000115 StringRef Name;
Rafael Espindola72447082017-01-05 14:35:41 +0000116 uint64_t Flags;
117 uint64_t Alignment;
George Rimar6892afa2016-07-12 09:49:43 +0000118};
Rafael Espindola63866282017-02-16 19:23:15 +0000119}
120}
121namespace llvm {
122template <> struct DenseMapInfo<lld::elf::SectionKey> {
123 static lld::elf::SectionKey getEmptyKey();
124 static lld::elf::SectionKey getTombstoneKey();
125 static unsigned getHashValue(const lld::elf::SectionKey &Val);
126 static bool isEqual(const lld::elf::SectionKey &LHS,
127 const lld::elf::SectionKey &RHS);
128};
129}
130namespace lld {
131namespace elf {
George Rimar6892afa2016-07-12 09:49:43 +0000132
133// This class knows how to create an output section for a given
134// input section. Output section type is determined by various
135// factors, including input section's sh_flags, sh_type and
136// linker scripts.
Rui Ueyama02a036f2017-02-27 02:31:48 +0000137class OutputSectionFactory {
George Rimar6892afa2016-07-12 09:49:43 +0000138public:
Rafael Espindola24e6f362017-02-24 15:07:30 +0000139 OutputSectionFactory(std::vector<OutputSection *> &OutputSections);
Rafael Espindolabd3ab092017-01-05 14:52:46 +0000140 ~OutputSectionFactory();
Rui Ueyama02a036f2017-02-27 02:31:48 +0000141
142 template <class ELFT>
Rafael Espindolab4c9b812017-02-23 02:28:28 +0000143 void addInputSec(InputSectionBase *IS, StringRef OutsecName);
Rafael Espindola82902742017-02-16 17:32:26 +0000144
George Rimar6892afa2016-07-12 09:49:43 +0000145private:
Rafael Espindola24e6f362017-02-24 15:07:30 +0000146 llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
147 std::vector<OutputSection *> &OutputSections;
George Rimar6892afa2016-07-12 09:49:43 +0000148};
149
Rafael Espindola0d4b6d52016-09-22 16:47:21 +0000150template <class ELFT> uint64_t getHeaderSize() {
151 if (Config->OFormatBinary)
152 return 0;
Rui Ueyama9d1bacb12017-02-27 02:31:26 +0000153 return Out::ElfHeader->Size + Out::ProgramHeaders->Size;
Rafael Espindola0d4b6d52016-09-22 16:47:21 +0000154}
155
Rafael Espindolae0df00b2016-02-28 00:25:54 +0000156} // namespace elf
Eugene Zelenko6e43b492015-11-04 02:11:57 +0000157} // namespace lld
158
George Rimar6892afa2016-07-12 09:49:43 +0000159
160#endif