summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/wasm/CMakeLists.txt2
-rw-r--r--lld/wasm/InputChunks.cpp (renamed from lld/wasm/InputSegment.cpp)12
-rw-r--r--lld/wasm/InputChunks.h125
-rw-r--r--lld/wasm/InputFiles.cpp21
-rw-r--r--lld/wasm/InputFiles.h2
-rw-r--r--lld/wasm/InputFunction.h57
-rw-r--r--lld/wasm/InputSegment.h76
-rw-r--r--lld/wasm/OutputSections.cpp41
-rw-r--r--lld/wasm/OutputSections.h3
-rw-r--r--lld/wasm/OutputSegment.h2
-rw-r--r--lld/wasm/SymbolTable.cpp2
-rw-r--r--lld/wasm/Symbols.cpp3
-rw-r--r--lld/wasm/Writer.cpp2
13 files changed, 165 insertions, 183 deletions
diff --git a/lld/wasm/CMakeLists.txt b/lld/wasm/CMakeLists.txt
index 19b0d168437..927c9c57ff4 100644
--- a/lld/wasm/CMakeLists.txt
+++ b/lld/wasm/CMakeLists.txt
@@ -4,8 +4,8 @@ add_public_tablegen_target(WasmOptionsTableGen)
add_lld_library(lldWasm
Driver.cpp
+ InputChunks.cpp
InputFiles.cpp
- InputSegment.cpp
OutputSections.cpp
SymbolTable.cpp
Symbols.cpp
diff --git a/lld/wasm/InputSegment.cpp b/lld/wasm/InputChunks.cpp
index 65091438625..3c856714b28 100644
--- a/lld/wasm/InputSegment.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "InputSegment.h"
+#include "InputChunks.h"
#include "OutputSegment.h"
#include "lld/Common/LLVM.h"
@@ -18,8 +18,16 @@ using namespace lld::wasm;
uint32_t InputSegment::translateVA(uint32_t Address) const {
assert(Address >= startVA() && Address < endVA());
- int32_t Delta = OutputSeg->StartVA + OutputSegmentOffset - startVA();
+ int32_t Delta = OutputSeg->StartVA + OutputOffset - startVA();
DEBUG(dbgs() << "translateVA: " << getName() << " Delta=" << Delta
<< " Address=" << Address << "\n");
return Address + Delta;
}
+
+void InputChunk::copyRelocations(const WasmSection &Section) {
+ size_t Start = getInputSectionOffset();
+ size_t Size = getSize();
+ for (const WasmRelocation &R : Section.Relocations)
+ if (R.Offset >= Start && R.Offset < Start + Size)
+ Relocations.push_back(R);
+}
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
new file mode 100644
index 00000000000..6f60daac51a
--- /dev/null
+++ b/lld/wasm/InputChunks.h
@@ -0,0 +1,125 @@
+//===- InputChunks.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An input chunk represents an indivisible blocks of code or data from an input
+// file. i.e. a single wasm data segment or a single wasm function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_WASM_INPUT_CHUNKS_H
+#define LLD_WASM_INPUT_CHUNKS_H
+
+#include "InputFiles.h"
+#include "WriterUtils.h"
+#include "lld/Common/ErrorHandler.h"
+#include "llvm/Object/Wasm.h"
+
+using llvm::object::WasmSegment;
+using llvm::wasm::WasmFunction;
+using llvm::wasm::WasmRelocation;
+using llvm::wasm::WasmSignature;
+using llvm::object::WasmSection;
+
+namespace lld {
+namespace wasm {
+
+class ObjFile;
+class OutputSegment;
+
+class InputChunk {
+public:
+ InputChunk(const ObjFile &F) : File(F) {}
+ virtual ~InputChunk() = default;
+ void copyRelocations(const WasmSection &Section);
+
+ virtual const uint8_t *getData() const = 0;
+ virtual uint32_t getSize() const = 0;
+ virtual uint32_t getInputSectionOffset() const = 0;
+
+ int32_t OutputOffset = 0;
+ std::vector<WasmRelocation> Relocations;
+ std::vector<OutputRelocation> OutRelocations;
+ const ObjFile &File;
+};
+
+// Represents a WebAssembly data segment which can be included as part of
+// an output data segments. Note that in WebAssembly, unlike ELF and other
+// formats, used the term "data segment" to refer to the continous regions of
+// memory that make on the data section. See:
+// https://webassembly.github.io/spec/syntax/modules.html#syntax-data
+//
+// For example, by default, clang will produce a separate data section for
+// each global variable.
+class InputSegment : public InputChunk {
+public:
+ InputSegment(const WasmSegment &Seg, const ObjFile &F)
+ : InputChunk(F), Segment(Seg) {}
+
+ // Translate an offset in the input segment to an offset in the output
+ // segment.
+ uint32_t translateVA(uint32_t Address) const;
+
+ const OutputSegment *getOutputSegment() const { return OutputSeg; }
+
+ void setOutputSegment(const OutputSegment *Segment, uint32_t Offset) {
+ OutputSeg = Segment;
+ OutputOffset = Offset;
+ }
+
+ const uint8_t *getData() const override {
+ return Segment.Data.Content.data();
+ }
+ uint32_t getSize() const override { return Segment.Data.Content.size(); }
+ uint32_t getInputSectionOffset() const override {
+ return Segment.SectionOffset;
+ }
+ uint32_t getAlignment() const { return Segment.Data.Alignment; }
+ uint32_t startVA() const { return Segment.Data.Offset.Value.Int32; }
+ uint32_t endVA() const { return startVA() + getSize(); }
+ StringRef getName() const { return Segment.Data.Name; }
+
+protected:
+ const WasmSegment &Segment;
+ const OutputSegment *OutputSeg = nullptr;
+};
+
+// Represents a single wasm function within and input file. These are
+// combined to create the final output CODE section.
+class InputFunction : public InputChunk {
+public:
+ InputFunction(const WasmSignature &S, const WasmFunction &Func,
+ const ObjFile &F)
+ : InputChunk(F), Signature(S), Function(Func) {}
+
+ uint32_t getSize() const override { return Function.Size; }
+ const uint8_t *getData() const override {
+ return File.CodeSection->Content.data() + Function.CodeSectionOffset;
+ }
+ uint32_t getInputSectionOffset() const override {
+ return Function.CodeSectionOffset;
+ };
+
+ uint32_t getOutputIndex() const { return OutputIndex.getValue(); };
+ bool hasOutputIndex() const { return OutputIndex.hasValue(); };
+ void setOutputIndex(uint32_t Index) {
+ assert(!hasOutputIndex());
+ OutputIndex = Index;
+ };
+
+ const WasmSignature &Signature;
+
+protected:
+ const WasmFunction &Function;
+ llvm::Optional<uint32_t> OutputIndex;
+};
+
+} // namespace wasm
+} // namespace lld
+
+#endif // LLD_WASM_INPUT_CHUNKS_H
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 62fa8f43692..36a609e21bc 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -10,8 +10,7 @@
#include "InputFiles.h"
#include "Config.h"
-#include "InputFunction.h"
-#include "InputSegment.h"
+#include "InputChunks.h"
#include "SymbolTable.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
@@ -126,14 +125,6 @@ InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) const {
return nullptr;
}
-static void copyRelocationsRange(std::vector<WasmRelocation> &To,
- ArrayRef<WasmRelocation> From, size_t Start,
- size_t Size) {
- for (const WasmRelocation &R : From)
- if (R.Offset >= Start && R.Offset < Start + Size)
- To.push_back(R);
-}
-
// Get the value stored in the wasm global represented by this symbol.
// This represents the virtual address of the symbol in the input file.
uint32_t ObjFile::getGlobalValue(const WasmSymbol &Sym) const {
@@ -175,8 +166,7 @@ void ObjFile::initializeSymbols() {
for (const WasmSegment &S : WasmObj->dataSegments()) {
InputSegment *Seg = make<InputSegment>(S, *this);
- copyRelocationsRange(Seg->Relocations, DataSection->Relocations,
- Seg->getInputSectionOffset(), Seg->getSize());
+ Seg->copyRelocations(*DataSection);
Segments.emplace_back(Seg);
}
@@ -186,10 +176,9 @@ void ObjFile::initializeSymbols() {
for (size_t I = 0; I < Funcs.size(); ++I) {
const WasmFunction &Func = Funcs[I];
const WasmSignature &Sig = Types[FuncTypes[I]];
- InputFunction *Function = make<InputFunction>(Sig, Func, *this);
- copyRelocationsRange(Function->Relocations, CodeSection->Relocations,
- Func.CodeSectionOffset, Func.Size);
- Functions.emplace_back(Function);
+ InputFunction *F = make<InputFunction>(Sig, Func, *this);
+ F->copyRelocations(*CodeSection);
+ Functions.emplace_back(F);
}
// Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols
diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h
index 921fc231483..11d10f6846c 100644
--- a/lld/wasm/InputFiles.h
+++ b/lld/wasm/InputFiles.h
@@ -98,6 +98,7 @@ public:
uint32_t getRelocatedAddress(uint32_t Index) const;
const WasmSection *CodeSection = nullptr;
+ const WasmSection *DataSection = nullptr;
std::vector<uint32_t> TypeMap;
std::vector<InputSegment *> Segments;
@@ -131,7 +132,6 @@ private:
// List of all indirect symbols indexed by table index space.
std::vector<Symbol *> TableSymbols;
- const WasmSection *DataSection = nullptr;
uint32_t NumGlobalImports = 0;
uint32_t NumFunctionImports = 0;
std::unique_ptr<WasmObjectFile> WasmObj;
diff --git a/lld/wasm/InputFunction.h b/lld/wasm/InputFunction.h
deleted file mode 100644
index a660d62bb69..00000000000
--- a/lld/wasm/InputFunction.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//===- InpuFunction.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Represents a WebAssembly function in an input file which could also be
-// assigned a function index in the output.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_WASM_INPUT_FUNCTION_H
-#define LLD_WASM_INPUT_FUNCTION_H
-
-#include "WriterUtils.h"
-#include "llvm/Object/Wasm.h"
-
-using llvm::wasm::WasmRelocation;
-using llvm::wasm::WasmFunction;
-
-namespace lld {
-namespace wasm {
-
-class ObjFile;
-
-class InputFunction {
-public:
- InputFunction(const WasmSignature &S, const WasmFunction &Func,
- const ObjFile &F)
- : Signature(S), Function(Func), File(F) {}
-
- uint32_t getOutputIndex() const { return OutputIndex.getValue(); };
- bool hasOutputIndex() const { return OutputIndex.hasValue(); };
-
- void setOutputIndex(uint32_t Index) {
- assert(!hasOutputIndex());
- OutputIndex = Index;
- };
-
- const WasmSignature &Signature;
- const WasmFunction &Function;
- int32_t OutputOffset = 0;
- std::vector<WasmRelocation> Relocations;
- std::vector<OutputRelocation> OutRelocations;
- const ObjFile &File;
-
-protected:
- llvm::Optional<uint32_t> OutputIndex;
-};
-
-} // namespace wasm
-} // namespace lld
-
-#endif // LLD_WASM_INPUT_FUNCTION_H
diff --git a/lld/wasm/InputSegment.h b/lld/wasm/InputSegment.h
deleted file mode 100644
index 10ca8413d2c..00000000000
--- a/lld/wasm/InputSegment.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===- InputSegment.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Represents a WebAssembly data segment which can be included as part of
-// an output data segments. Note that in WebAssembly, unlike ELF and other
-// formats, used the term "data segment" to refer to the continous regions of
-// memory that make on the data section. See:
-// https://webassembly.github.io/spec/syntax/modules.html#syntax-data
-//
-// For example, by default, clang will produce a separate data section for
-// each global variable.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_WASM_INPUT_SEGMENT_H
-#define LLD_WASM_INPUT_SEGMENT_H
-
-#include "WriterUtils.h"
-#include "lld/Common/ErrorHandler.h"
-#include "llvm/Object/Wasm.h"
-
-using llvm::object::WasmSegment;
-using llvm::wasm::WasmRelocation;
-
-namespace lld {
-namespace wasm {
-
-class ObjFile;
-class OutputSegment;
-
-class InputSegment {
-public:
- InputSegment(const WasmSegment &Seg, const ObjFile &F)
- : Segment(Seg), File(F) {}
-
- // Translate an offset in the input segment to an offset in the output
- // segment.
- uint32_t translateVA(uint32_t Address) const;
-
- const OutputSegment *getOutputSegment() const { return OutputSeg; }
-
- uint32_t getOutputSegmentOffset() const { return OutputSegmentOffset; }
-
- uint32_t getInputSectionOffset() const { return Segment.SectionOffset; }
-
- void setOutputSegment(const OutputSegment *Segment, uint32_t Offset) {
- OutputSeg = Segment;
- OutputSegmentOffset = Offset;
- }
-
- uint32_t getSize() const { return Segment.Data.Content.size(); }
- uint32_t getAlignment() const { return Segment.Data.Alignment; }
- uint32_t startVA() const { return Segment.Data.Offset.Value.Int32; }
- uint32_t endVA() const { return startVA() + getSize(); }
- StringRef getName() const { return Segment.Data.Name; }
-
- const WasmSegment &Segment;
- const ObjFile &File;
- std::vector<WasmRelocation> Relocations;
- std::vector<OutputRelocation> OutRelocations;
-
-protected:
- const OutputSegment *OutputSeg = nullptr;
- uint32_t OutputSegmentOffset = 0;
-};
-
-} // namespace wasm
-} // namespace lld
-
-#endif // LLD_WASM_INPUT_SEGMENT_H
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index 150d47a72f3..473b9dc79d5 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -10,8 +10,8 @@
#include "OutputSections.h"
#include "Config.h"
+#include "InputChunks.h"
#include "InputFiles.h"
-#include "InputFunction.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
#include "lld/Common/ErrorHandler.h"
@@ -202,11 +202,11 @@ CodeSection::CodeSection(ArrayRef<InputFunction *> Functions)
OS.flush();
BodySize = CodeSectionHeader.size();
- for (InputFunction *Func : Functions) {
+ for (InputChunk *Func : Functions) {
Func->OutputOffset = BodySize;
calcRelocations(Func->File, Func->Relocations, Func->OutRelocations,
- Func->OutputOffset - Func->Function.CodeSectionOffset);
- BodySize += Func->Function.Size;
+ Func->OutputOffset - Func->getInputSectionOffset());
+ BodySize += Func->getSize();
}
createHeader(BodySize);
@@ -230,24 +230,22 @@ void CodeSection::writeTo(uint8_t *Buf) {
Buf += CodeSectionHeader.size();
// Write code section bodies
- parallelForEach(Functions, [ContentsStart](InputFunction *Func) {
- ArrayRef<uint8_t> Content(Func->File.CodeSection->Content);
- memcpy(ContentsStart + Func->OutputOffset,
- Content.data() + Func->Function.CodeSectionOffset,
- Func->Function.Size);
+ parallelForEach(Functions, [ContentsStart](InputChunk *Func) {
+ memcpy(ContentsStart + Func->OutputOffset, Func->getData(),
+ Func->getSize());
applyRelocations(ContentsStart, Func->OutRelocations);
});
}
uint32_t CodeSection::numRelocations() const {
uint32_t Count = 0;
- for (const InputFunction *Func : Functions)
+ for (const InputChunk *Func : Functions)
Count += Func->OutRelocations.size();
return Count;
}
void CodeSection::writeRelocations(raw_ostream &OS) const {
- for (const InputFunction *Func : Functions)
+ for (const InputChunk *Func : Functions)
for (const OutputRelocation &Reloc : Func->OutRelocations)
writeReloc(OS, Reloc);
}
@@ -271,13 +269,12 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments)
Segment->setSectionOffset(BodySize);
BodySize += Segment->Header.size();
log("Data segment: size=" + Twine(Segment->Size));
- for (InputSegment *InputSeg : Segment->InputSegments) {
- uint32_t InputOffset = InputSeg->getInputSectionOffset();
+ for (InputChunk *InputSeg : Segment->InputSegments) {
uint32_t OutputOffset = Segment->getSectionOffset() +
- Segment->Header.size() +
- InputSeg->getOutputSegmentOffset();
+ Segment->Header.size() + InputSeg->OutputOffset;
calcRelocations(InputSeg->File, InputSeg->Relocations,
- InputSeg->OutRelocations, OutputOffset - InputOffset);
+ InputSeg->OutRelocations,
+ OutputOffset - InputSeg->getInputSectionOffset());
}
BodySize += Segment->Size;
}
@@ -305,11 +302,9 @@ void DataSection::writeTo(uint8_t *Buf) {
memcpy(SegStart, Segment->Header.data(), Segment->Header.size());
// Write segment data payload
- for (const InputSegment *Input : Segment->InputSegments) {
- ArrayRef<uint8_t> Content(Input->Segment.Data.Content);
- memcpy(SegStart + Segment->Header.size() +
- Input->getOutputSegmentOffset(),
- Content.data(), Content.size());
+ for (const InputChunk *Input : Segment->InputSegments) {
+ memcpy(SegStart + Segment->Header.size() + Input->OutputOffset,
+ Input->getData(), Input->getSize());
applyRelocations(ContentsStart, Input->OutRelocations);
}
});
@@ -318,14 +313,14 @@ void DataSection::writeTo(uint8_t *Buf) {
uint32_t DataSection::numRelocations() const {
uint32_t Count = 0;
for (const OutputSegment *Seg : Segments)
- for (const InputSegment *InputSeg : Seg->InputSegments)
+ for (const InputChunk *InputSeg : Seg->InputSegments)
Count += InputSeg->OutRelocations.size();
return Count;
}
void DataSection::writeRelocations(raw_ostream &OS) const {
for (const OutputSegment *Seg : Segments)
- for (const InputSegment *InputSeg : Seg->InputSegments)
+ for (const InputChunk *InputSeg : Seg->InputSegments)
for (const OutputRelocation &Reloc : InputSeg->OutRelocations)
writeReloc(OS, Reloc);
}
diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h
index 5ba7b38f760..7a303612070 100644
--- a/lld/wasm/OutputSections.h
+++ b/lld/wasm/OutputSections.h
@@ -10,7 +10,7 @@
#ifndef LLD_WASM_OUTPUT_SECTIONS_H
#define LLD_WASM_OUTPUT_SECTIONS_H
-#include "InputSegment.h"
+#include "InputChunks.h"
#include "WriterUtils.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/DenseMap.h"
@@ -28,7 +28,6 @@ std::string toString(const wasm::OutputSection &Section);
namespace wasm {
class OutputSegment;
-class InputFunction;
class OutputSection {
public:
diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h
index a22c8023442..9825ce8e697 100644
--- a/lld/wasm/OutputSegment.h
+++ b/lld/wasm/OutputSegment.h
@@ -10,7 +10,7 @@
#ifndef LLD_WASM_OUTPUT_SEGMENT_H
#define LLD_WASM_OUTPUT_SEGMENT_H
-#include "InputSegment.h"
+#include "InputChunks.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/Wasm.h"
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 573739adef6..8706698df74 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -10,7 +10,7 @@
#include "SymbolTable.h"
#include "Config.h"
-#include "InputFunction.h"
+#include "InputChunks.h"
#include "WriterUtils.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index a466a6cddd3..0e1391f0b10 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -10,9 +10,8 @@
#include "Symbols.h"
#include "Config.h"
+#include "InputChunks.h"
#include "InputFiles.h"
-#include "InputFunction.h"
-#include "InputSegment.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Strings.h"
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 828bd53bf5a..6fbc75477d9 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -10,7 +10,7 @@
#include "Writer.h"
#include "Config.h"
-#include "InputFunction.h"
+#include "InputChunks.h"
#include "OutputSections.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
OpenPOWER on IntegriCloud