blob: 1fcb5723df9807c7edffb03ab3d45346d25731f5 [file] [log] [blame]
Sam Cleggc94d3932017-11-17 18:14:09 +00001//===- OutputSections.h -----------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Sam Cleggc94d3932017-11-17 18:14:09 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_WASM_OUTPUT_SECTIONS_H
10#define LLD_WASM_OUTPUT_SECTIONS_H
11
Sam Clegg5fa274b2018-01-10 01:13:34 +000012#include "InputChunks.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000013#include "WriterUtils.h"
14#include "lld/Common/ErrorHandler.h"
Sam Clegg45218f42018-11-27 01:08:16 +000015#include "lld/Common/LLVM.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000016#include "llvm/ADT/DenseMap.h"
17
Sam Cleggc94d3932017-11-17 18:14:09 +000018namespace lld {
19
20namespace wasm {
21class OutputSection;
22}
Rui Ueyama136d27a2019-07-11 05:40:30 +000023std::string toString(const wasm::OutputSection &section);
Sam Cleggc94d3932017-11-17 18:14:09 +000024
25namespace wasm {
26
27class OutputSegment;
Sam Cleggc94d3932017-11-17 18:14:09 +000028
29class OutputSection {
30public:
Rui Ueyama136d27a2019-07-11 05:40:30 +000031 OutputSection(uint32_t type, std::string name = "")
32 : type(type), name(name) {}
Sam Cleggc94d3932017-11-17 18:14:09 +000033 virtual ~OutputSection() = default;
34
Rui Ueyama22c8f332018-02-28 17:33:04 +000035 StringRef getSectionName() const;
Rui Ueyama136d27a2019-07-11 05:40:30 +000036 void setOffset(size_t newOffset) {
37 log("setOffset: " + toString(*this) + ": " + Twine(newOffset));
38 offset = newOffset;
Sam Cleggc94d3932017-11-17 18:14:09 +000039 }
Rui Ueyama136d27a2019-07-11 05:40:30 +000040 void createHeader(size_t bodySize);
Sam Clegg8fcf0122019-05-21 09:13:09 +000041 virtual bool isNeeded() const { return true; }
Sam Cleggc94d3932017-11-17 18:14:09 +000042 virtual size_t getSize() const = 0;
Rui Ueyama136d27a2019-07-11 05:40:30 +000043 virtual void writeTo(uint8_t *buf) = 0;
Sam Cleggd029bf02019-05-16 21:36:06 +000044 virtual void finalizeContents() = 0;
Rui Ueyama7e296ad2019-07-10 09:10:01 +000045 virtual uint32_t getNumRelocations() const { return 0; }
Rui Ueyama136d27a2019-07-11 05:40:30 +000046 virtual void writeRelocations(raw_ostream &os) const {}
Sam Cleggc94d3932017-11-17 18:14:09 +000047
Rui Ueyama136d27a2019-07-11 05:40:30 +000048 std::string header;
49 uint32_t type;
50 uint32_t sectionIndex = UINT32_MAX;
51 std::string name;
52 OutputSectionSymbol *sectionSym = nullptr;
Sam Cleggc94d3932017-11-17 18:14:09 +000053
Sam Cleggc94d3932017-11-17 18:14:09 +000054protected:
Rui Ueyama136d27a2019-07-11 05:40:30 +000055 size_t offset = 0;
Sam Cleggc94d3932017-11-17 18:14:09 +000056};
57
Sam Cleggc94d3932017-11-17 18:14:09 +000058class CodeSection : public OutputSection {
59public:
Rui Ueyama136d27a2019-07-11 05:40:30 +000060 explicit CodeSection(ArrayRef<InputFunction *> functions)
61 : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {}
Sam Cleggd029bf02019-05-16 21:36:06 +000062
Rui Ueyama136d27a2019-07-11 05:40:30 +000063 size_t getSize() const override { return header.size() + bodySize; }
64 void writeTo(uint8_t *buf) override;
Rui Ueyama7e296ad2019-07-10 09:10:01 +000065 uint32_t getNumRelocations() const override;
Rui Ueyama136d27a2019-07-11 05:40:30 +000066 void writeRelocations(raw_ostream &os) const override;
67 bool isNeeded() const override { return functions.size() > 0; }
Sam Cleggd029bf02019-05-16 21:36:06 +000068 void finalizeContents() override;
Sam Cleggc94d3932017-11-17 18:14:09 +000069
70protected:
Rui Ueyama136d27a2019-07-11 05:40:30 +000071 ArrayRef<InputFunction *> functions;
72 std::string codeSectionHeader;
73 size_t bodySize = 0;
Sam Cleggc94d3932017-11-17 18:14:09 +000074};
75
76class DataSection : public OutputSection {
77public:
Rui Ueyama136d27a2019-07-11 05:40:30 +000078 explicit DataSection(ArrayRef<OutputSegment *> segments)
79 : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {}
Sam Cleggd029bf02019-05-16 21:36:06 +000080
Rui Ueyama136d27a2019-07-11 05:40:30 +000081 size_t getSize() const override { return header.size() + bodySize; }
82 void writeTo(uint8_t *buf) override;
Rui Ueyama7e296ad2019-07-10 09:10:01 +000083 uint32_t getNumRelocations() const override;
Rui Ueyama136d27a2019-07-11 05:40:30 +000084 void writeRelocations(raw_ostream &os) const override;
Thomas Lively190dacc2019-10-15 19:05:11 +000085 bool isNeeded() const override;
Sam Cleggd029bf02019-05-16 21:36:06 +000086 void finalizeContents() override;
Sam Cleggc94d3932017-11-17 18:14:09 +000087
88protected:
Rui Ueyama136d27a2019-07-11 05:40:30 +000089 ArrayRef<OutputSegment *> segments;
90 std::string dataSectionHeader;
91 size_t bodySize = 0;
Sam Cleggc94d3932017-11-17 18:14:09 +000092};
93
Heejin Ahn4821ebf2018-08-29 21:03:16 +000094// Represents a custom section in the output file. Wasm custom sections are
Sam Clegg80ba4382018-04-10 16:12:49 +000095// used for storing user-defined metadata. Unlike the core sections types
96// they are identified by their string name.
97// The linker combines custom sections that have the same name by simply
98// concatenating them.
99// Note that some custom sections such as "name" and "linking" are handled
100// separately and are instead synthesized by the linker.
101class CustomSection : public OutputSection {
102public:
Rui Ueyama136d27a2019-07-11 05:40:30 +0000103 CustomSection(std::string name, ArrayRef<InputSection *> inputSections)
104 : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name),
105 inputSections(inputSections) {}
Sam Clegg80ba4382018-04-10 16:12:49 +0000106 size_t getSize() const override {
Rui Ueyama136d27a2019-07-11 05:40:30 +0000107 return header.size() + nameData.size() + payloadSize;
Sam Clegg80ba4382018-04-10 16:12:49 +0000108 }
Rui Ueyama136d27a2019-07-11 05:40:30 +0000109 void writeTo(uint8_t *buf) override;
Rui Ueyama7e296ad2019-07-10 09:10:01 +0000110 uint32_t getNumRelocations() const override;
Rui Ueyama136d27a2019-07-11 05:40:30 +0000111 void writeRelocations(raw_ostream &os) const override;
Sam Cleggd029bf02019-05-16 21:36:06 +0000112 void finalizeContents() override;
Sam Clegg80ba4382018-04-10 16:12:49 +0000113
114protected:
Rui Ueyama136d27a2019-07-11 05:40:30 +0000115 size_t payloadSize = 0;
116 ArrayRef<InputSection *> inputSections;
117 std::string nameData;
Sam Clegg80ba4382018-04-10 16:12:49 +0000118};
119
Sam Cleggc94d3932017-11-17 18:14:09 +0000120} // namespace wasm
121} // namespace lld
122
123#endif // LLD_WASM_OUTPUT_SECTIONS_H