Coverage Report

Created: 2019-05-19 14:56

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