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 //===----------------------------------------------------------------------===// 8 9 #include "OutputSegment.h" 10 #include "InputChunks.h" 11 #include "lld/Common/Memory.h" 12 13 #define DEBUG_TYPE "lld" 14 15 using namespace llvm; 16 using namespace llvm::wasm; 17 18 namespace lld { 19 20 namespace wasm { 21 22 void OutputSegment::addInputSegment(InputSegment *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(); 32 } 33 34 // This function scans over the input segments. 35 // 36 // It removes MergeInputSegments 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<SyntheticMergedDataSegment *> mergedSegments; 43 std::vector<InputSegment *> newSegments; 44 for (InputSegment *s : inputSegments) { 45 MergeInputSegment *ms = dyn_cast<MergeInputSegment>(s); 46 if (!ms) { 47 newSegments.push_back(s); 48 continue; 49 } 50 51 // A segment should not make it here unless its alive 52 assert(ms->live); 53 54 auto i = 55 llvm::find_if(mergedSegments, [=](SyntheticMergedDataSegment *seg) { 56 return seg->flags == ms->flags && seg->alignment == ms->alignment; 57 }); 58 if (i == mergedSegments.end()) { 59 LLVM_DEBUG(llvm::dbgs() << "new merge section: " << name 60 << " alignment=" << ms->alignment << "\n"); 61 SyntheticMergedDataSegment *syn = 62 make<SyntheticMergedDataSegment>(name, ms->alignment, ms->flags); 63 syn->outputSeg = this; 64 mergedSegments.push_back(syn); 65 i = std::prev(mergedSegments.end()); 66 newSegments.push_back(syn); 67 } else { 68 LLVM_DEBUG(llvm::dbgs() << "adding to merge section: " << name << "\n"); 69 } 70 (*i)->addMergeSegment(ms); 71 } 72 73 for (auto *ms : mergedSegments) 74 ms->finalizeContents(); 75 76 inputSegments = newSegments; 77 size = 0; 78 for (InputSegment *seg : inputSegments) { 79 size = llvm::alignTo(size, 1ULL << seg->alignment); 80 LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg->getName() 81 << " -> " << size << "\n"); 82 seg->outputSegmentOffset = size; 83 size += seg->getSize(); 84 } 85 } 86 87 } // namespace wasm 88 } // namespace lld 89