Coverage Report

Created: 2019-01-18 03:29

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/Writer.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Writer.cpp ---------------------------------------------------------===//
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
#include "Writer.h"
11
#include "Config.h"
12
#include "InputChunks.h"
13
#include "InputEvent.h"
14
#include "InputGlobal.h"
15
#include "OutputSections.h"
16
#include "OutputSegment.h"
17
#include "SymbolTable.h"
18
#include "WriterUtils.h"
19
#include "lld/Common/ErrorHandler.h"
20
#include "lld/Common/Memory.h"
21
#include "lld/Common/Strings.h"
22
#include "lld/Common/Threads.h"
23
#include "llvm/ADT/DenseSet.h"
24
#include "llvm/ADT/SmallVector.h"
25
#include "llvm/ADT/StringMap.h"
26
#include "llvm/BinaryFormat/Wasm.h"
27
#include "llvm/Object/WasmTraits.h"
28
#include "llvm/Support/FileOutputBuffer.h"
29
#include "llvm/Support/Format.h"
30
#include "llvm/Support/FormatVariadic.h"
31
#include "llvm/Support/LEB128.h"
32
33
#include <cstdarg>
34
#include <map>
35
36
#define DEBUG_TYPE "lld"
37
38
using namespace llvm;
39
using namespace llvm::wasm;
40
using namespace lld;
41
using namespace lld::wasm;
42
43
static constexpr int kStackAlignment = 16;
44
static constexpr const char *kFunctionTableName = "__indirect_function_table";
45
46
namespace {
47
48
// An init entry to be written to either the synthetic init func or the
49
// linking metadata.
50
struct WasmInitEntry {
51
  const FunctionSymbol *Sym;
52
  uint32_t Priority;
53
};
54
55
// The writer writes a SymbolTable result to a file.
56
class Writer {
57
public:
58
  void run();
59
60
private:
61
  void openFile();
62
63
  uint32_t lookupType(const WasmSignature &Sig);
64
  uint32_t registerType(const WasmSignature &Sig);
65
66
  void createCtorFunction();
67
  void calculateInitFunctions();
68
  void assignIndexes();
69
  void calculateImports();
70
  void calculateExports();
71
  void calculateCustomSections();
72
  void assignSymtab();
73
  void calculateTypes();
74
  void createOutputSegments();
75
  void layoutMemory();
76
  void createHeader();
77
  void createSections();
78
  SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = "");
79
80
  // Builtin sections
81
  void createTypeSection();
82
  void createFunctionSection();
83
  void createTableSection();
84
  void createGlobalSection();
85
  void createEventSection();
86
  void createExportSection();
87
  void createImportSection();
88
  void createMemorySection();
89
  void createElemSection();
90
  void createCodeSection();
91
  void createDataSection();
92
  void createCustomSections();
93
94
  // Custom sections
95
  void createDylinkSection();
96
  void createRelocSections();
97
  void createLinkingSection();
98
  void createNameSection();
99
  void createProducersSection();
100
101
  void writeHeader();
102
  void writeSections();
103
104
  uint64_t FileSize = 0;
105
  uint32_t TableBase = 0;
106
  uint32_t NumMemoryPages = 0;
107
  uint32_t MaxMemoryPages = 0;
108
  // Memory size and aligment. Written to the "dylink" section
109
  // when build with -shared or -pie.
110
  uint32_t MemAlign = 0;
111
  uint32_t MemSize = 0;
112
113
  std::vector<const WasmSignature *> Types;
114
  DenseMap<WasmSignature, int32_t> TypeIndices;
115
  std::vector<const Symbol *> ImportedSymbols;
116
  unsigned NumImportedFunctions = 0;
117
  unsigned NumImportedGlobals = 0;
118
  unsigned NumImportedEvents = 0;
119
  std::vector<WasmExport> Exports;
120
  std::vector<const DefinedData *> DefinedFakeGlobals;
121
  std::vector<InputGlobal *> InputGlobals;
122
  std::vector<InputFunction *> InputFunctions;
123
  std::vector<InputEvent *> InputEvents;
124
  std::vector<const FunctionSymbol *> IndirectFunctions;
125
  std::vector<const Symbol *> SymtabEntries;
126
  std::vector<WasmInitEntry> InitFunctions;
127
128
  llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;
129
  llvm::StringMap<SectionSymbol *> CustomSectionSymbols;
130
131
  // Elements that are used to construct the final output
132
  std::string Header;
133
  std::vector<OutputSection *> OutputSections;
134
135
  std::unique_ptr<FileOutputBuffer> Buffer;
136
137
  std::vector<OutputSegment *> Segments;
138
  llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
139
};
140
141
} // anonymous namespace
142
143
106
void Writer::createImportSection() {
144
106
  uint32_t NumImports = ImportedSymbols.size();
145
106
  if (Config->ImportMemory)
146
3
    ++NumImports;
147
106
  if (Config->ImportTable)
148
2
    ++NumImports;
149
106
150
106
  if (NumImports == 0)
151
86
    return;
152
20
153
20
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT);
154
20
  raw_ostream &OS = Section->getStream();
155
20
156
20
  writeUleb128(OS, NumImports, "import count");
157
20
158
20
  if (Config->ImportMemory) {
159
3
    WasmImport Import;
160
3
    Import.Module = "env";
161
3
    Import.Field = "memory";
162
3
    Import.Kind = WASM_EXTERNAL_MEMORY;
163
3
    Import.Memory.Flags = 0;
164
3
    Import.Memory.Initial = NumMemoryPages;
165
3
    if (MaxMemoryPages != 0) {
166
2
      Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
167
2
      Import.Memory.Maximum = MaxMemoryPages;
168
2
    }
169
3
    if (Config->SharedMemory)
170
1
      Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
171
3
    writeImport(OS, Import);
172
3
  }
173
20
174
20
  if (Config->ImportTable) {
175
2
    uint32_t TableSize = TableBase + IndirectFunctions.size();
176
2
    WasmImport Import;
177
2
    Import.Module = "env";
178
2
    Import.Field = kFunctionTableName;
179
2
    Import.Kind = WASM_EXTERNAL_TABLE;
180
2
    Import.Table.ElemType = WASM_TYPE_FUNCREF;
181
2
    Import.Table.Limits = {0, TableSize, 0};
182
2
    writeImport(OS, Import);
183
2
  }
184
20
185
28
  for (const Symbol *Sym : ImportedSymbols) {
186
28
    WasmImport Import;
187
28
    Import.Module = "env";
188
28
    Import.Field = Sym->getName();
189
28
    if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
190
18
      Import.Kind = WASM_EXTERNAL_FUNCTION;
191
18
      Import.SigIndex = lookupType(*FunctionSym->Signature);
192
18
    } else 
if (auto *10
GlobalSym10
= dyn_cast<GlobalSymbol>(Sym)) {
193
10
      Import.Kind = WASM_EXTERNAL_GLOBAL;
194
10
      Import.Global = *GlobalSym->getGlobalType();
195
10
    } else {
196
0
      auto *EventSym = cast<EventSymbol>(Sym);
197
0
      Import.Kind = WASM_EXTERNAL_EVENT;
198
0
      Import.Event.Attribute = EventSym->getEventType()->Attribute;
199
0
      Import.Event.SigIndex = lookupType(*EventSym->Signature);
200
0
    }
201
28
    writeImport(OS, Import);
202
28
  }
203
20
}
204
205
106
void Writer::createTypeSection() {
206
106
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE);
207
106
  raw_ostream &OS = Section->getStream();
208
106
  writeUleb128(OS, Types.size(), "type count");
209
106
  for (const WasmSignature *Sig : Types)
210
176
    writeSig(OS, *Sig);
211
106
}
212
213
106
void Writer::createFunctionSection() {
214
106
  if (InputFunctions.empty())
215
1
    return;
216
105
217
105
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION);
218
105
  raw_ostream &OS = Section->getStream();
219
105
220
105
  writeUleb128(OS, InputFunctions.size(), "function count");
221
105
  for (const InputFunction *Func : InputFunctions)
222
494
    writeUleb128(OS, lookupType(Func->Signature), "sig index");
223
105
}
224
225
106
void Writer::createMemorySection() {
226
106
  if (Config->ImportMemory)
227
3
    return;
228
103
229
103
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY);
230
103
  raw_ostream &OS = Section->getStream();
231
103
232
103
  bool HasMax = MaxMemoryPages != 0;
233
103
  writeUleb128(OS, 1, "memory count");
234
103
  unsigned Flags = 0;
235
103
  if (HasMax)
236
2
    Flags |= WASM_LIMITS_FLAG_HAS_MAX;
237
103
  if (Config->SharedMemory)
238
1
    Flags |= WASM_LIMITS_FLAG_IS_SHARED;
239
103
  writeUleb128(OS, Flags, "memory limits flags");
240
103
  writeUleb128(OS, NumMemoryPages, "initial pages");
241
103
  if (HasMax)
242
2
    writeUleb128(OS, MaxMemoryPages, "max pages");
243
103
}
244
245
106
void Writer::createGlobalSection() {
246
106
  unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
247
106
  if (NumGlobals == 0)
248
17
    return;
249
89
250
89
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
251
89
  raw_ostream &OS = Section->getStream();
252
89
253
89
  writeUleb128(OS, NumGlobals, "global count");
254
89
  for (const InputGlobal *G : InputGlobals)
255
91
    writeGlobal(OS, G->Global);
256
186
  for (const DefinedData *Sym : DefinedFakeGlobals) {
257
186
    WasmGlobal Global;
258
186
    Global.Type = {WASM_TYPE_I32, false};
259
186
    Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
260
186
    Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
261
186
    writeGlobal(OS, Global);
262
186
  }
263
89
}
264
265
// The event section contains a list of declared wasm events associated with the
266
// module. Currently the only supported event kind is exceptions. A single event
267
// entry represents a single event with an event tag. All C++ exceptions are
268
// represented by a single event. An event entry in this section contains
269
// information on what kind of event it is (e.g. exception) and the type of
270
// values contained in a single event object. (In wasm, an event can contain
271
// multiple values of primitive types. But for C++ exceptions, we just throw a
272
// pointer which is an i32 value (for wasm32 architecture), so the signature of
273
// C++ exception is (i32)->(void), because all event types are assumed to have
274
// void return type to share WasmSignature with functions.)
275
106
void Writer::createEventSection() {
276
106
  unsigned NumEvents = InputEvents.size();
277
106
  if (NumEvents == 0)
278
105
    return;
279
1
280
1
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_EVENT);
281
1
  raw_ostream &OS = Section->getStream();
282
1
283
1
  writeUleb128(OS, NumEvents, "event count");
284
1
  for (InputEvent *E : InputEvents) {
285
1
    E->Event.Type.SigIndex = lookupType(E->Signature);
286
1
    writeEvent(OS, E->Event);
287
1
  }
288
1
}
289
290
106
void Writer::createTableSection() {
291
106
  if (Config->ImportTable)
292
2
    return;
293
104
294
104
  // Always output a table section (or table import), even if there are no
295
104
  // indirect calls.  There are two reasons for this:
296
104
  //  1. For executables it is useful to have an empty table slot at 0
297
104
  //     which can be filled with a null function call handler.
298
104
  //  2. If we don't do this, any program that contains a call_indirect but
299
104
  //     no address-taken function will fail at validation time since it is
300
104
  //     a validation error to include a call_indirect instruction if there
301
104
  //     is not table.
302
104
  uint32_t TableSize = TableBase + IndirectFunctions.size();
303
104
304
104
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
305
104
  raw_ostream &OS = Section->getStream();
306
104
307
104
  writeUleb128(OS, 1, "table count");
308
104
  WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
309
104
  writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
310
104
}
311
312
106
void Writer::createExportSection() {
313
106
  if (!Exports.size())
314
17
    return;
315
89
316
89
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
317
89
  raw_ostream &OS = Section->getStream();
318
89
319
89
  writeUleb128(OS, Exports.size(), "export count");
320
89
  for (const WasmExport &Export : Exports)
321
417
    writeExport(OS, Export);
322
89
}
323
324
106
void Writer::calculateCustomSections() {
325
106
  log("calculateCustomSections");
326
106
  bool StripDebug = Config->StripDebug || 
Config->StripAll102
;
327
173
  for (ObjFile *File : Symtab->ObjectFiles) {
328
306
    for (InputSection *Section : File->CustomSections) {
329
306
      StringRef Name = Section->getName();
330
306
      // These custom sections are known the linker and synthesized rather than
331
306
      // blindly copied
332
306
      if (Name == "linking" || 
Name == "name"133
||
Name == "producers"133
||
333
306
          
Name.startswith("reloc.")130
)
334
280
        continue;
335
26
      // .. or it is a debug section
336
26
      if (StripDebug && 
Name.startswith(".debug_")0
)
337
0
        continue;
338
26
      CustomSectionMapping[Name].push_back(Section);
339
26
    }
340
173
  }
341
106
}
342
343
106
void Writer::createCustomSections() {
344
106
  log("createCustomSections");
345
106
  for (auto &Pair : CustomSectionMapping) {
346
18
    StringRef Name = Pair.first();
347
18
348
18
    auto P = CustomSectionSymbols.find(Name);
349
18
    if (P != CustomSectionSymbols.end()) {
350
0
      uint32_t SectionIndex = OutputSections.size();
351
0
      P->second->setOutputSectionIndex(SectionIndex);
352
0
    }
353
18
354
18
    LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");
355
18
    OutputSections.push_back(make<CustomSection>(Name, Pair.second));
356
18
  }
357
106
}
358
359
106
void Writer::createElemSection() {
360
106
  if (IndirectFunctions.empty())
361
91
    return;
362
15
363
15
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM);
364
15
  raw_ostream &OS = Section->getStream();
365
15
366
15
  writeUleb128(OS, 1, "segment count");
367
15
  writeUleb128(OS, 0, "table index");
368
15
  WasmInitExpr InitExpr;
369
15
  if (Config->Pic) {
370
1
    InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
371
1
    InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
372
14
  } else {
373
14
    InitExpr.Opcode = WASM_OPCODE_I32_CONST;
374
14
    InitExpr.Value.Int32 = TableBase;
375
14
  }
376
15
  writeInitExpr(OS, InitExpr);
377
15
  writeUleb128(OS, IndirectFunctions.size(), "elem count");
378
15
379
15
  uint32_t TableIndex = TableBase;
380
43
  for (const FunctionSymbol *Sym : IndirectFunctions) {
381
43
    assert(Sym->getTableIndex() == TableIndex);
382
43
    writeUleb128(OS, Sym->getFunctionIndex(), "function index");
383
43
    ++TableIndex;
384
43
  }
385
15
}
386
387
106
void Writer::createCodeSection() {
388
106
  if (InputFunctions.empty())
389
1
    return;
390
105
391
105
  log("createCodeSection");
392
105
393
105
  auto Section = make<CodeSection>(InputFunctions);
394
105
  OutputSections.push_back(Section);
395
105
}
396
397
106
void Writer::createDataSection() {
398
106
  if (!Segments.size())
399
83
    return;
400
23
401
23
  log("createDataSection");
402
23
  auto Section = make<DataSection>(Segments);
403
23
  OutputSections.push_back(Section);
404
23
}
405
406
// Create relocations sections in the final output.
407
// These are only created when relocatable output is requested.
408
17
void Writer::createRelocSections() {
409
17
  log("createRelocSections");
410
17
  // Don't use iterator here since we are adding to OutputSection
411
17
  size_t OrigSize = OutputSections.size();
412
135
  for (size_t I = 0; I < OrigSize; 
I++118
) {
413
118
    OutputSection *OSec = OutputSections[I];
414
118
    uint32_t Count = OSec->numRelocations();
415
118
    if (!Count)
416
106
      continue;
417
12
418
12
    StringRef Name;
419
12
    if (OSec->Type == WASM_SEC_DATA)
420
3
      Name = "reloc.DATA";
421
9
    else if (OSec->Type == WASM_SEC_CODE)
422
9
      Name = "reloc.CODE";
423
0
    else if (OSec->Type == WASM_SEC_CUSTOM)
424
0
      Name = Saver.save("reloc." + OSec->Name);
425
0
    else
426
0
      llvm_unreachable(
427
12
          "relocations only supported for code, data, or custom sections");
428
12
429
12
    SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name);
430
12
    raw_ostream &OS = Section->getStream();
431
12
    writeUleb128(OS, I, "reloc section");
432
12
    writeUleb128(OS, Count, "reloc count");
433
12
    OSec->writeRelocations(OS);
434
12
  }
435
17
}
436
437
233
static uint32_t getWasmFlags(const Symbol *Sym) {
438
233
  uint32_t Flags = 0;
439
233
  if (Sym->isLocal())
440
20
    Flags |= WASM_SYMBOL_BINDING_LOCAL;
441
233
  if (Sym->isWeak())
442
6
    Flags |= WASM_SYMBOL_BINDING_WEAK;
443
233
  if (Sym->isHidden())
444
25
    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
445
233
  if (Sym->isUndefined())
446
13
    Flags |= WASM_SYMBOL_UNDEFINED;
447
233
  return Flags;
448
233
}
449
450
// Some synthetic sections (e.g. "name" and "linking") have subsections.
451
// Just like the synthetic sections themselves these need to be created before
452
// they can be written out (since they are preceded by their length). This
453
// class is used to create subsections and then write them into the stream
454
// of the parent section.
455
class SubSection {
456
public:
457
123
  explicit SubSection(uint32_t Type) : Type(Type) {}
458
459
123
  void writeTo(raw_ostream &To) {
460
123
    OS.flush();
461
123
    writeUleb128(To, Type, "subsection type");
462
123
    writeUleb128(To, Body.size(), "subsection size");
463
123
    To.write(Body.data(), Body.size());
464
123
  }
465
466
private:
467
  uint32_t Type;
468
  std::string Body;
469
470
public:
471
  raw_string_ostream OS{Body};
472
};
473
474
// Create the custom "dylink" section containing information for the dynamic
475
// linker.
476
// See
477
// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
478
1
void Writer::createDylinkSection() {
479
1
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink");
480
1
  raw_ostream &OS = Section->getStream();
481
1
482
1
  writeUleb128(OS, MemSize, "MemSize");
483
1
  writeUleb128(OS, MemAlign, "MemAlign");
484
1
  writeUleb128(OS, IndirectFunctions.size(), "TableSize");
485
1
  writeUleb128(OS, 0, "TableAlign");
486
1
  writeUleb128(OS, 0, "Needed");  // TODO: Support "needed" shared libraries
487
1
}
488
489
// Create the custom "linking" section containing linker metadata.
490
// This is only created when relocatable output is requested.
491
17
void Writer::createLinkingSection() {
492
17
  SyntheticSection *Section =
493
17
      createSyntheticSection(WASM_SEC_CUSTOM, "linking");
494
17
  raw_ostream &OS = Section->getStream();
495
17
496
17
  writeUleb128(OS, WasmMetadataVersion, "Version");
497
17
498
17
  if (!SymtabEntries.empty()) {
499
17
    SubSection Sub(WASM_SYMBOL_TABLE);
500
17
    writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols");
501
17
502
233
    for (const Symbol *Sym : SymtabEntries) {
503
233
      assert(Sym->isDefined() || Sym->isUndefined());
504
233
      WasmSymbolType Kind = Sym->getWasmType();
505
233
      uint32_t Flags = getWasmFlags(Sym);
506
233
507
233
      writeU8(Sub.OS, Kind, "sym kind");
508
233
      writeUleb128(Sub.OS, Flags, "sym flags");
509
233
510
233
      if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
511
205
        writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
512
205
        if (Sym->isDefined())
513
198
          writeStr(Sub.OS, Sym->getName(), "sym name");
514
205
      } else 
if (auto *28
G28
= dyn_cast<GlobalSymbol>(Sym)) {
515
4
        writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
516
4
        if (Sym->isDefined())
517
0
          writeStr(Sub.OS, Sym->getName(), "sym name");
518
24
      } else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
519
0
        writeUleb128(Sub.OS, E->getEventIndex(), "index");
520
0
        if (Sym->isDefined())
521
0
          writeStr(Sub.OS, Sym->getName(), "sym name");
522
24
      } else if (isa<DataSymbol>(Sym)) {
523
24
        writeStr(Sub.OS, Sym->getName(), "sym name");
524
24
        if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
525
22
          writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index");
526
22
          writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(),
527
22
                       "data offset");
528
22
          writeUleb128(Sub.OS, DataSym->getSize(), "data size");
529
22
        }
530
24
      } else {
531
0
        auto *S = cast<SectionSymbol>(Sym);
532
0
        writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index");
533
0
      }
534
233
    }
535
17
536
17
    Sub.writeTo(OS);
537
17
  }
538
17
539
17
  if (Segments.size()) {
540
5
    SubSection Sub(WASM_SEGMENT_INFO);
541
5
    writeUleb128(Sub.OS, Segments.size(), "num data segments");
542
19
    for (const OutputSegment *S : Segments) {
543
19
      writeStr(Sub.OS, S->Name, "segment name");
544
19
      writeUleb128(Sub.OS, S->Alignment, "alignment");
545
19
      writeUleb128(Sub.OS, 0, "flags");
546
19
    }
547
5
    Sub.writeTo(OS);
548
5
  }
549
17
550
17
  if (!InitFunctions.empty()) {
551
1
    SubSection Sub(WASM_INIT_FUNCS);
552
1
    writeUleb128(Sub.OS, InitFunctions.size(), "num init functions");
553
13
    for (const WasmInitEntry &F : InitFunctions) {
554
13
      writeUleb128(Sub.OS, F.Priority, "priority");
555
13
      writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index");
556
13
    }
557
1
    Sub.writeTo(OS);
558
1
  }
559
17
560
17
  struct ComdatEntry {
561
17
    unsigned Kind;
562
17
    uint32_t Index;
563
17
  };
564
17
  std::map<StringRef, std::vector<ComdatEntry>> Comdats;
565
17
566
197
  for (const InputFunction *F : InputFunctions) {
567
197
    StringRef Comdat = F->getComdatName();
568
197
    if (!Comdat.empty())
569
1
      Comdats[Comdat].emplace_back(
570
1
          ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()});
571
197
  }
572
36
  for (uint32_t I = 0; I < Segments.size(); 
++I19
) {
573
19
    const auto &InputSegments = Segments[I]->InputSegments;
574
19
    if (InputSegments.empty())
575
0
      continue;
576
19
    StringRef Comdat = InputSegments[0]->getComdatName();
577
#ifndef NDEBUG
578
    for (const InputSegment *IS : InputSegments)
579
      assert(IS->getComdatName() == Comdat);
580
#endif
581
19
    if (!Comdat.empty())
582
1
      Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});
583
19
  }
584
17
585
17
  if (!Comdats.empty()) {
586
1
    SubSection Sub(WASM_COMDAT_INFO);
587
1
    writeUleb128(Sub.OS, Comdats.size(), "num comdats");
588
1
    for (const auto &C : Comdats) {
589
1
      writeStr(Sub.OS, C.first, "comdat name");
590
1
      writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use
591
1
      writeUleb128(Sub.OS, C.second.size(), "num entries");
592
2
      for (const ComdatEntry &Entry : C.second) {
593
2
        writeU8(Sub.OS, Entry.Kind, "entry kind");
594
2
        writeUleb128(Sub.OS, Entry.Index, "entry index");
595
2
      }
596
1
    }
597
1
    Sub.writeTo(OS);
598
1
  }
599
17
}
600
601
// Create the custom "name" section containing debug symbol names.
602
100
void Writer::createNameSection() {
603
100
  unsigned NumNames = NumImportedFunctions;
604
100
  for (const InputFunction *F : InputFunctions)
605
477
    if (!F->getName().empty() || 
!F->getDebugName().empty()0
)
606
477
      ++NumNames;
607
100
608
100
  if (NumNames == 0)
609
1
    return;
610
99
611
99
  SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name");
612
99
613
99
  SubSection Sub(WASM_NAMES_FUNCTION);
614
99
  writeUleb128(Sub.OS, NumNames, "name count");
615
99
616
99
  // Names must appear in function index order.  As it happens ImportedSymbols
617
99
  // and InputFunctions are numbered in order with imported functions coming
618
99
  // first.
619
99
  for (const Symbol *S : ImportedSymbols) {
620
28
    if (auto *F = dyn_cast<FunctionSymbol>(S)) {
621
18
      writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
622
18
      writeStr(Sub.OS, toString(*S), "symbol name");
623
18
    }
624
28
  }
625
477
  for (const InputFunction *F : InputFunctions) {
626
477
    if (!F->getName().empty()) {
627
477
      writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
628
477
      if (!F->getDebugName().empty()) {
629
5
        writeStr(Sub.OS, F->getDebugName(), "symbol name");
630
472
      } else {
631
472
        writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name");
632
472
      }
633
477
    }
634
477
  }
635
99
636
99
  Sub.writeTo(Section->getStream());
637
99
}
638
639
104
void Writer::createProducersSection() {
640
104
  SmallVector<std::pair<std::string, std::string>, 8> Languages;
641
104
  SmallVector<std::pair<std::string, std::string>, 8> Tools;
642
104
  SmallVector<std::pair<std::string, std::string>, 8> SDKs;
643
171
  for (ObjFile *File : Symtab->ObjectFiles) {
644
171
    const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
645
171
    for (auto &Producers : {std::make_pair(&Info.Languages, &Languages),
646
171
                            std::make_pair(&Info.Tools, &Tools),
647
171
                            std::make_pair(&Info.SDKs, &SDKs)})
648
513
      for (auto &Producer : *Producers.first)
649
6
        if (Producers.second->end() ==
650
6
            std::find_if(Producers.second->begin(), Producers.second->end(),
651
6
                         [&](std::pair<std::string, std::string> Seen) {
652
2
                           return Seen.first == Producer.first;
653
2
                         }))
654
4
          Producers.second->push_back(Producer);
655
171
  }
656
104
  int FieldCount =
657
104
      int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty());
658
104
  if (FieldCount == 0)
659
102
    return;
660
2
  SyntheticSection *Section =
661
2
      createSyntheticSection(WASM_SEC_CUSTOM, "producers");
662
2
  auto &OS = Section->getStream();
663
2
  writeUleb128(OS, FieldCount, "field count");
664
2
  for (auto &Field :
665
2
       {std::make_pair("language", Languages),
666
6
        std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) {
667
6
    if (Field.second.empty())
668
2
      continue;
669
4
    writeStr(OS, Field.first, "field name");
670
4
    writeUleb128(OS, Field.second.size(), "number of entries");
671
4
    for (auto &Entry : Field.second) {
672
4
      writeStr(OS, Entry.first, "producer name");
673
4
      writeStr(OS, Entry.second, "producer version");
674
4
    }
675
4
  }
676
2
}
677
678
105
void Writer::writeHeader() {
679
105
  memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
680
105
}
681
682
void Writer::writeSections() {
683
  uint8_t *Buf = Buffer->getBufferStart();
684
901
  parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); });
685
}
686
687
// Fix the memory layout of the output binary.  This assigns memory offsets
688
// to each of the input data sections as well as the explicit stack region.
689
// The default memory layout is as follows, from low to high.
690
//
691
//  - initialized data (starting at Config->GlobalBase)
692
//  - BSS data (not currently implemented in llvm)
693
//  - explicit stack (Config->ZStackSize)
694
//  - heap start / unallocated
695
//
696
// The --stack-first option means that stack is placed before any static data.
697
// This can be useful since it means that stack overflow traps immediately
698
// rather than overwriting global data, but also increases code size since all
699
// static data loads and stores requires larger offsets.
700
106
void Writer::layoutMemory() {
701
106
  createOutputSegments();
702
106
703
106
  uint32_t MemoryPtr = 0;
704
106
705
106
  auto PlaceStack = [&]() {
706
105
    if (Config->Relocatable || 
Config->Shared88
)
707
17
      return;
708
88
    MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
709
88
    if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
710
1
      error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
711
88
    log("mem: stack size  = " + Twine(Config->ZStackSize));
712
88
    log("mem: stack base  = " + Twine(MemoryPtr));
713
88
    MemoryPtr += Config->ZStackSize;
714
88
    auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
715
88
    SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
716
88
    log("mem: stack top   = " + Twine(MemoryPtr));
717
88
  };
718
106
719
106
  if (Config->StackFirst) {
720
1
    PlaceStack();
721
105
  } else {
722
105
    MemoryPtr = Config->GlobalBase;
723
105
    log("mem: global base = " + Twine(Config->GlobalBase));
724
105
  }
725
106
726
106
  uint32_t DataStart = MemoryPtr;
727
106
728
106
  // Arbitrarily set __dso_handle handle to point to the start of the data
729
106
  // segments.
730
106
  if (WasmSym::DsoHandle)
731
89
    WasmSym::DsoHandle->setVirtualAddress(DataStart);
732
106
733
106
  MemAlign = 0;
734
106
  for (OutputSegment *Seg : Segments) {
735
49
    MemAlign = std::max(MemAlign, Seg->Alignment);
736
49
    MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
737
49
    Seg->StartVA = MemoryPtr;
738
49
    log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
739
49
                MemoryPtr, Seg->Size, Seg->Alignment));
740
49
    MemoryPtr += Seg->Size;
741
49
  }
742
106
743
106
  // TODO: Add .bss space here.
744
106
  if (WasmSym::DataEnd)
745
88
    WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
746
106
747
106
  log("mem: static data = " + Twine(MemoryPtr - DataStart));
748
106
749
106
  if (Config->Shared) {
750
1
    MemSize = MemoryPtr;
751
1
    return;
752
1
  }
753
105
754
105
  if (!Config->StackFirst)
755
104
    PlaceStack();
756
105
757
105
  // Set `__heap_base` to directly follow the end of the stack or global data.
758
105
  // The fact that this comes last means that a malloc/brk implementation
759
105
  // can grow the heap at runtime.
760
105
  if (!Config->Relocatable) {
761
88
    WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
762
88
    log("mem: heap base   = " + Twine(MemoryPtr));
763
88
  }
764
105
765
105
  if (Config->InitialMemory != 0) {
766
5
    if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
767
0
      error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
768
5
    if (MemoryPtr > Config->InitialMemory)
769
0
      error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
770
5
    else
771
5
      MemoryPtr = Config->InitialMemory;
772
5
  }
773
105
  MemSize = MemoryPtr;
774
105
  NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
775
105
  log("mem: total pages = " + Twine(NumMemoryPages));
776
105
777
105
  if (Config->MaxMemory != 0) {
778
4
    if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
779
0
      error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
780
4
    if (MemoryPtr > Config->MaxMemory)
781
0
      error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
782
4
    MaxMemoryPages = Config->MaxMemory / WasmPageSize;
783
4
    log("mem: max pages   = " + Twine(MaxMemoryPages));
784
4
  }
785
105
}
786
787
SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
788
763
                                                 StringRef Name) {
789
763
  auto Sec = make<SyntheticSection>(Type, Name);
790
763
  log("createSection: " + toString(*Sec));
791
763
  OutputSections.push_back(Sec);
792
763
  return Sec;
793
763
}
794
795
void Writer::createSections() {
796
  // Known sections
797
  if (Config->Pic)
798
    createDylinkSection();
799
  createTypeSection();
800
  createImportSection();
801
  createFunctionSection();
802
  createTableSection();
803
  createMemorySection();
804
  createGlobalSection();
805
  createEventSection();
806
  createExportSection();
807
  createElemSection();
808
  createCodeSection();
809
  createDataSection();
810
  createCustomSections();
811
812
  // Custom sections
813
  if (Config->Relocatable) {
814
    createLinkingSection();
815
    createRelocSections();
816
  }
817
818
  if (!Config->StripDebug && !Config->StripAll)
819
    createNameSection();
820
821
  if (!Config->StripAll)
822
    createProducersSection();
823
824
  for (OutputSection *S : OutputSections) {
825
    S->setOffset(FileSize);
826
    S->finalizeContents();
827
    FileSize += S->getSize();
828
  }
829
}
830
831
106
void Writer::calculateImports() {
832
949
  for (Symbol *Sym : Symtab->getSymbols()) {
833
949
    if (!Sym->isUndefined())
834
911
      continue;
835
38
    if (isa<DataSymbol>(Sym))
836
4
      continue;
837
34
    if (Sym->isWeak() && 
!Config->Relocatable1
)
838
0
      continue;
839
34
    if (!Sym->isLive())
840
6
      continue;
841
28
    if (!Sym->IsUsedInRegularObj)
842
0
      continue;
843
28
844
28
    LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
845
28
    ImportedSymbols.emplace_back(Sym);
846
28
    if (auto *F = dyn_cast<FunctionSymbol>(Sym))
847
18
      F->setFunctionIndex(NumImportedFunctions++);
848
10
    else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
849
10
      G->setGlobalIndex(NumImportedGlobals++);
850
0
    else
851
0
      cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
852
28
  }
853
106
}
854
855
106
void Writer::calculateExports() {
856
106
  if (Config->Relocatable)
857
17
    return;
858
89
859
89
  if (!Config->Relocatable && !Config->ImportMemory)
860
86
    Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
861
89
862
89
  if (!Config->Relocatable && Config->ExportTable)
863
1
    Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
864
89
865
89
  unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
866
89
867
733
  for (Symbol *Sym : Symtab->getSymbols()) {
868
733
    if (!Sym->isExported())
869
401
      continue;
870
332
    if (!Sym->isLive())
871
0
      continue;
872
332
873
332
    StringRef Name = Sym->getName();
874
332
    WasmExport Export;
875
332
    if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
876
144
      Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
877
188
    } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
878
2
      // TODO(sbc): Remove this check once to mutable global proposal is
879
2
      // implement in all major browsers.
880
2
      // See: https://github.com/WebAssembly/mutable-global
881
2
      if (G->getGlobalType()->Mutable) {
882
2
        // Only the __stack_pointer should ever be create as mutable.
883
2
        assert(G == WasmSym::StackPointer);
884
2
        continue;
885
2
      }
886
0
      Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
887
186
    } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
888
0
      Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
889
186
    } else {
890
186
      auto *D = cast<DefinedData>(Sym);
891
186
      DefinedFakeGlobals.emplace_back(D);
892
186
      Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
893
186
    }
894
332
895
332
    
LLVM_DEBUG330
(dbgs() << "Export: " << Name << "\n");
896
330
    Exports.push_back(Export);
897
330
  }
898
89
}
899
900
106
void Writer::assignSymtab() {
901
106
  if (!Config->Relocatable)
902
89
    return;
903
17
904
17
  StringMap<uint32_t> SectionSymbolIndices;
905
17
906
17
  unsigned SymbolIndex = SymtabEntries.size();
907
34
  for (ObjFile *File : Symtab->ObjectFiles) {
908
34
    LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
909
240
    for (Symbol *Sym : File->getSymbols()) {
910
240
      if (Sym->getFile() != File)
911
7
        continue;
912
233
913
233
      if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
914
0
        StringRef Name = S->getName();
915
0
        if (CustomSectionMapping.count(Name) == 0)
916
0
          continue;
917
0
918
0
        auto SSI = SectionSymbolIndices.find(Name);
919
0
        if (SSI != SectionSymbolIndices.end()) {
920
0
          Sym->setOutputSymbolIndex(SSI->second);
921
0
          continue;
922
0
        }
923
0
924
0
        SectionSymbolIndices[Name] = SymbolIndex;
925
0
        CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
926
0
927
0
        Sym->markLive();
928
0
      }
929
233
930
233
      // (Since this is relocatable output, GC is not performed so symbols must
931
233
      // be live.)
932
233
      assert(Sym->isLive());
933
233
      Sym->setOutputSymbolIndex(SymbolIndex++);
934
233
      SymtabEntries.emplace_back(Sym);
935
233
    }
936
34
  }
937
17
938
17
  // For the moment, relocatable output doesn't contain any synthetic functions,
939
17
  // so no need to look through the Symtab for symbols not referenced by
940
17
  // Symtab->ObjectFiles.
941
17
}
942
943
513
uint32_t Writer::lookupType(const WasmSignature &Sig) {
944
513
  auto It = TypeIndices.find(Sig);
945
513
  if (It == TypeIndices.end()) {
946
0
    error("type not found: " + toString(Sig));
947
0
    return 0;
948
0
  }
949
513
  return It->second;
950
513
}
951
952
535
uint32_t Writer::registerType(const WasmSignature &Sig) {
953
535
  auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
954
535
  if (Pair.second) {
955
176
    LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n");
956
176
    Types.push_back(&Sig);
957
176
  }
958
535
  return Pair.first->second;
959
535
}
960
961
106
void Writer::calculateTypes() {
962
106
  // The output type section is the union of the following sets:
963
106
  // 1. Any signature used in the TYPE relocation
964
106
  // 2. The signatures of all imported functions
965
106
  // 3. The signatures of all defined functions
966
106
  // 4. The signatures of all imported events
967
106
  // 5. The signatures of all defined events
968
106
969
173
  for (ObjFile *File : Symtab->ObjectFiles) {
970
173
    ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
971
399
    for (uint32_t I = 0; I < Types.size(); 
I++226
)
972
226
      if (File->TypeIsUsed[I])
973
11
        File->TypeMap[I] = registerType(Types[I]);
974
173
  }
975
106
976
106
  for (const Symbol *Sym : ImportedSymbols) {
977
28
    if (auto *F = dyn_cast<FunctionSymbol>(Sym))
978
18
      registerType(*F->Signature);
979
10
    else if (auto *E = dyn_cast<EventSymbol>(Sym))
980
0
      registerType(*E->Signature);
981
28
  }
982
106
983
106
  for (const InputFunction *F : InputFunctions)
984
494
    registerType(F->Signature);
985
106
986
106
  for (const InputEvent *E : InputEvents)
987
1
    registerType(E->Signature);
988
106
}
989
990
106
void Writer::assignIndexes() {
991
106
  assert(InputFunctions.empty());
992
106
  uint32_t FunctionIndex = NumImportedFunctions;
993
513
  auto AddDefinedFunction = [&](InputFunction *Func) {
994
513
    if (!Func->Live)
995
19
      return;
996
494
    InputFunctions.emplace_back(Func);
997
494
    Func->setFunctionIndex(FunctionIndex++);
998
494
  };
999
106
1000
106
  for (InputFunction *Func : Symtab->SyntheticFunctions)
1001
96
    AddDefinedFunction(Func);
1002
106
1003
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1004
173
    LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
1005
173
    for (InputFunction *Func : File->Functions)
1006
417
      AddDefinedFunction(Func);
1007
173
  }
1008
106
1009
106
  uint32_t TableIndex = TableBase;
1010
811
  auto HandleRelocs = [&](InputChunk *Chunk) {
1011
811
    if (!Chunk->Live)
1012
239
      return;
1013
572
    ObjFile *File = Chunk->File;
1014
572
    ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
1015
572
    for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
1016
384
      if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
1017
384
          
Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB370
) {
1018
51
        FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
1019
51
        if (Sym->hasTableIndex() || 
!Sym->hasFunctionIndex()43
)
1020
8
          continue;
1021
43
        Sym->setTableIndex(TableIndex++);
1022
43
        IndirectFunctions.emplace_back(Sym);
1023
333
      } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
1024
11
        // Mark target type as live
1025
11
        File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
1026
11
        File->TypeIsUsed[Reloc.Index] = true;
1027
11
      }
1028
384
    }
1029
572
  };
1030
106
1031
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1032
173
    LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
1033
173
    for (InputChunk *Chunk : File->Functions)
1034
417
      HandleRelocs(Chunk);
1035
173
    for (InputChunk *Chunk : File->Segments)
1036
88
      HandleRelocs(Chunk);
1037
173
    for (auto &P : File->CustomSections)
1038
306
      HandleRelocs(P);
1039
173
  }
1040
106
1041
106
  assert(InputGlobals.empty());
1042
106
  uint32_t GlobalIndex = NumImportedGlobals;
1043
106
  auto AddDefinedGlobal = [&](InputGlobal *Global) {
1044
92
    if (Global->Live) {
1045
91
      LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
1046
91
      Global->setGlobalIndex(GlobalIndex++);
1047
91
      InputGlobals.push_back(Global);
1048
91
    }
1049
92
  };
1050
106
1051
106
  for (InputGlobal *Global : Symtab->SyntheticGlobals)
1052
88
    AddDefinedGlobal(Global);
1053
106
1054
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1055
173
    LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
1056
173
    for (InputGlobal *Global : File->Globals)
1057
4
      AddDefinedGlobal(Global);
1058
173
  }
1059
106
1060
106
  assert(InputEvents.empty());
1061
106
  uint32_t EventIndex = NumImportedEvents;
1062
106
  auto AddDefinedEvent = [&](InputEvent *Event) {
1063
2
    if (Event->Live) {
1064
1
      LLVM_DEBUG(dbgs() << "AddDefinedEvent: " << EventIndex << "\n");
1065
1
      Event->setEventIndex(EventIndex++);
1066
1
      InputEvents.push_back(Event);
1067
1
    }
1068
2
  };
1069
106
1070
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1071
173
    LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
1072
173
    for (InputEvent *Event : File->Events)
1073
2
      AddDefinedEvent(Event);
1074
173
  }
1075
106
}
1076
1077
78
static StringRef getOutputDataSegmentName(StringRef Name) {
1078
78
  // With PIC code we currently only support a single data segment since
1079
78
  // we only have a single __memory_base to use as our base address.
1080
78
  if (Config->Pic)
1081
2
    return "data";
1082
76
  if (!Config->MergeDataSegments)
1083
28
    return Name;
1084
48
  if (Name.startswith(".text."))
1085
0
    return ".text";
1086
48
  if (Name.startswith(".data."))
1087
33
    return ".data";
1088
15
  if (Name.startswith(".bss."))
1089
9
    return ".bss";
1090
6
  if (Name.startswith(".rodata."))
1091
6
    return ".rodata";
1092
0
  return Name;
1093
0
}
1094
1095
106
void Writer::createOutputSegments() {
1096
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1097
173
    for (InputSegment *Segment : File->Segments) {
1098
88
      if (!Segment->Live)
1099
10
        continue;
1100
78
      StringRef Name = getOutputDataSegmentName(Segment->getName());
1101
78
      OutputSegment *&S = SegmentMap[Name];
1102
78
      if (S == nullptr) {
1103
49
        LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
1104
49
        S = make<OutputSegment>(Name, Segments.size());
1105
49
        Segments.push_back(S);
1106
49
      }
1107
78
      S->addInputSegment(Segment);
1108
78
      LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
1109
78
    }
1110
173
  }
1111
106
}
1112
1113
static const int OPCODE_CALL = 0x10;
1114
static const int OPCODE_END = 0xb;
1115
1116
// Create synthetic "__wasm_call_ctors" function based on ctor functions
1117
// in input object.
1118
89
void Writer::createCtorFunction() {
1119
89
  // First write the body's contents to a string.
1120
89
  std::string BodyContent;
1121
89
  {
1122
89
    raw_string_ostream OS(BodyContent);
1123
89
    writeUleb128(OS, 0, "num locals");
1124
89
    for (const WasmInitEntry &F : InitFunctions) {
1125
13
      writeU8(OS, OPCODE_CALL, "CALL");
1126
13
      writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
1127
13
    }
1128
89
    writeU8(OS, OPCODE_END, "END");
1129
89
  }
1130
89
1131
89
  // Once we know the size of the body we can create the final function body
1132
89
  std::string FunctionBody;
1133
89
  {
1134
89
    raw_string_ostream OS(FunctionBody);
1135
89
    writeUleb128(OS, BodyContent.size(), "function size");
1136
89
    OS << BodyContent;
1137
89
  }
1138
89
1139
89
  ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
1140
89
  cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
1141
89
}
1142
1143
// Populate InitFunctions vector with init functions from all input objects.
1144
// This is then used either when creating the output linking section or to
1145
// synthesize the "__wasm_call_ctors" function.
1146
106
void Writer::calculateInitFunctions() {
1147
173
  for (ObjFile *File : Symtab->ObjectFiles) {
1148
173
    const WasmLinkingData &L = File->getWasmObj()->linkingData();
1149
173
    for (const WasmInitFunc &F : L.InitFunctions) {
1150
26
      FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
1151
26
      if (*Sym->Signature != WasmSignature{{}, {}})
1152
0
        error("invalid signature for init func: " + toString(*Sym));
1153
26
      InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
1154
26
    }
1155
173
  }
1156
106
1157
106
  // Sort in order of priority (lowest first) so that they are called
1158
106
  // in the correct order.
1159
106
  std::stable_sort(InitFunctions.begin(), InitFunctions.end(),
1160
106
                   [](const WasmInitEntry &L, const WasmInitEntry &R) {
1161
64
                     return L.Priority < R.Priority;
1162
64
                   });
1163
106
}
1164
1165
void Writer::run() {
1166
  if (Config->Relocatable || Config->Pic)
1167
    Config->GlobalBase = 0;
1168
1169
  // For PIC code the table base is assigned dynamically by the loader.
1170
  // For non-PIC, we start at 1 so that accessing table index 0 always traps.
1171
  if (!Config->Pic)
1172
    TableBase = 1;
1173
1174
  log("-- calculateImports");
1175
  calculateImports();
1176
  log("-- assignIndexes");
1177
  assignIndexes();
1178
  log("-- calculateInitFunctions");
1179
  calculateInitFunctions();
1180
  if (!Config->Relocatable)
1181
    createCtorFunction();
1182
  log("-- calculateTypes");
1183
  calculateTypes();
1184
  log("-- layoutMemory");
1185
  layoutMemory();
1186
  log("-- calculateExports");
1187
  calculateExports();
1188
  log("-- calculateCustomSections");
1189
  calculateCustomSections();
1190
  log("-- assignSymtab");
1191
  assignSymtab();
1192
1193
  if (errorHandler().Verbose) {
1194
    log("Defined Functions: " + Twine(InputFunctions.size()));
1195
    log("Defined Globals  : " + Twine(InputGlobals.size()));
1196
    log("Defined Events   : " + Twine(InputEvents.size()));
1197
    log("Function Imports : " + Twine(NumImportedFunctions));
1198
    log("Global Imports   : " + Twine(NumImportedGlobals));
1199
    log("Event Imports    : " + Twine(NumImportedEvents));
1200
    for (ObjFile *File : Symtab->ObjectFiles)
1201
      File->dumpInfo();
1202
  }
1203
1204
  createHeader();
1205
  log("-- createSections");
1206
  createSections();
1207
1208
  log("-- openFile");
1209
  openFile();
1210
  if (errorCount())
1211
    return;
1212
1213
  writeHeader();
1214
1215
  log("-- writeSections");
1216
  writeSections();
1217
  if (errorCount())
1218
    return;
1219
1220
  if (Error E = Buffer->commit())
1221
    fatal("failed to write the output file: " + toString(std::move(E)));
1222
}
1223
1224
// Open a result file.
1225
106
void Writer::openFile() {
1226
106
  log("writing: " + Config->OutputFile);
1227
106
1228
106
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
1229
106
      FileOutputBuffer::create(Config->OutputFile, FileSize,
1230
106
                               FileOutputBuffer::F_executable);
1231
106
1232
106
  if (!BufferOrErr)
1233
0
    error("failed to open " + Config->OutputFile + ": " +
1234
0
          toString(BufferOrErr.takeError()));
1235
106
  else
1236
106
    Buffer = std::move(*BufferOrErr);
1237
106
}
1238
1239
106
void Writer::createHeader() {
1240
106
  raw_string_ostream OS(Header);
1241
106
  writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
1242
106
  writeU32(OS, WasmVersion, "wasm version");
1243
106
  OS.flush();
1244
106
  FileSize += Header.size();
1245
106
}
1246
1247
106
void lld::wasm::writeResult() { Writer().run(); }