[JITLink] Add support of R_X86_64_32S relocation
[llvm-project.git] / lld / wasm / OutputSegment.cpp
blobc09d5c30a0f6b79e5ce071b4c12620a2c205f90c
1 //===- OutputSegment.h -----------------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "OutputSegment.h"
10 #include "InputChunks.h"
11 #include "lld/Common/Memory.h"
13 #define DEBUG_TYPE "lld"
15 using namespace llvm;
16 using namespace llvm::wasm;
18 namespace lld {
20 namespace wasm {
22 void OutputSegment::addInputSegment(InputChunk *inSeg) {
23 alignment = std::max(alignment, inSeg->alignment);
24 inputSegments.push_back(inSeg);
25 size = llvm::alignTo(size, 1ULL << inSeg->alignment);
26 LLVM_DEBUG(dbgs() << "addInputSegment: " << inSeg->getName()
27 << " oname=" << name << " size=" << inSeg->getSize()
28 << " align=" << inSeg->alignment << " at:" << size << "\n");
29 inSeg->outputSeg = this;
30 inSeg->outputSegmentOffset = size;
31 size += inSeg->getSize();
34 // This function scans over the input segments.
36 // It removes MergeInputChunks from the input section array and adds
37 // new synthetic sections at the location of the first input section
38 // that it replaces. It then finalizes each synthetic section in order
39 // to compute an output offset for each piece of each input section.
40 void OutputSegment::finalizeInputSegments() {
41 LLVM_DEBUG(llvm::dbgs() << "finalizeInputSegments: " << name << "\n");
42 std::vector<SyntheticMergedChunk *> mergedSegments;
43 std::vector<InputChunk *> newSegments;
44 for (InputChunk *s : inputSegments) {
45 MergeInputChunk *ms = dyn_cast<MergeInputChunk>(s);
46 if (!ms) {
47 newSegments.push_back(s);
48 continue;
51 // A segment should not make it here unless its alive
52 assert(ms->live);
54 auto i = llvm::find_if(mergedSegments, [=](SyntheticMergedChunk *seg) {
55 return seg->flags == ms->flags && seg->alignment == ms->alignment;
56 });
57 if (i == mergedSegments.end()) {
58 LLVM_DEBUG(llvm::dbgs() << "new merge segment: " << name
59 << " alignment=" << ms->alignment << "\n");
60 auto *syn = make<SyntheticMergedChunk>(name, ms->alignment, ms->flags);
61 syn->outputSeg = this;
62 mergedSegments.push_back(syn);
63 i = std::prev(mergedSegments.end());
64 newSegments.push_back(syn);
65 } else {
66 LLVM_DEBUG(llvm::dbgs() << "adding to merge segment: " << name << "\n");
68 (*i)->addMergeChunk(ms);
71 for (auto *ms : mergedSegments)
72 ms->finalizeContents();
74 inputSegments = newSegments;
75 size = 0;
76 for (InputChunk *seg : inputSegments) {
77 size = llvm::alignTo(size, 1ULL << seg->alignment);
78 LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg->getName()
79 << " -> " << size << "\n");
80 seg->outputSegmentOffset = size;
81 size += seg->getSize();
85 } // namespace wasm
86 } // namespace lld