diff options
Diffstat (limited to 'lld/wasm')
-rw-r--r-- | lld/wasm/Config.h | 84 | ||||
-rw-r--r-- | lld/wasm/Driver.cpp | 690 | ||||
-rw-r--r-- | lld/wasm/InputChunks.cpp | 290 | ||||
-rw-r--r-- | lld/wasm/InputChunks.h | 154 | ||||
-rw-r--r-- | lld/wasm/InputEvent.h | 30 | ||||
-rw-r--r-- | lld/wasm/InputFiles.cpp | 562 | ||||
-rw-r--r-- | lld/wasm/InputFiles.h | 120 | ||||
-rw-r--r-- | lld/wasm/InputGlobal.h | 28 | ||||
-rw-r--r-- | lld/wasm/LTO.cpp | 148 | ||||
-rw-r--r-- | lld/wasm/LTO.h | 8 | ||||
-rw-r--r-- | lld/wasm/MarkLive.cpp | 122 | ||||
-rw-r--r-- | lld/wasm/OutputSections.cpp | 230 | ||||
-rw-r--r-- | lld/wasm/OutputSections.h | 84 | ||||
-rw-r--r-- | lld/wasm/OutputSegment.h | 36 | ||||
-rw-r--r-- | lld/wasm/Relocations.cpp | 68 | ||||
-rw-r--r-- | lld/wasm/Relocations.h | 2 | ||||
-rw-r--r-- | lld/wasm/SymbolTable.cpp | 750 | ||||
-rw-r--r-- | lld/wasm/SymbolTable.h | 98 | ||||
-rw-r--r-- | lld/wasm/Symbols.cpp | 302 | ||||
-rw-r--r-- | lld/wasm/Symbols.h | 334 | ||||
-rw-r--r-- | lld/wasm/SyntheticSections.cpp | 690 | ||||
-rw-r--r-- | lld/wasm/SyntheticSections.h | 206 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 804 | ||||
-rw-r--r-- | lld/wasm/WriterUtils.cpp | 198 | ||||
-rw-r--r-- | lld/wasm/WriterUtils.h | 48 |
25 files changed, 3043 insertions, 3043 deletions
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index b63044852d5..e502b2f17cd 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -22,58 +22,58 @@ namespace wasm { // and such fields have the same name as the corresponding options. // Most fields are initialized by the driver. struct Configuration { - bool AllowUndefined; - bool CheckFeatures; - bool CompressRelocations; - bool Demangle; - bool DisableVerify; - bool EmitRelocs; - bool ExportAll; - bool ExportDynamic; - bool ExportTable; - bool GcSections; - bool ImportMemory; - bool SharedMemory; - bool PassiveSegments; - bool ImportTable; - bool MergeDataSegments; - bool Pie; - bool PrintGcSections; - bool Relocatable; - bool SaveTemps; - bool Shared; - bool StripAll; - bool StripDebug; - bool StackFirst; - bool Trace; - uint32_t GlobalBase; - uint32_t InitialMemory; - uint32_t MaxMemory; - uint32_t ZStackSize; - unsigned LTOPartitions; - unsigned LTOO; - unsigned Optimize; - unsigned ThinLTOJobs; + bool allowUndefined; + bool checkFeatures; + bool compressRelocations; + bool demangle; + bool disableVerify; + bool emitRelocs; + bool exportAll; + bool exportDynamic; + bool exportTable; + bool gcSections; + bool importMemory; + bool sharedMemory; + bool passiveSegments; + bool importTable; + bool mergeDataSegments; + bool pie; + bool printGcSections; + bool relocatable; + bool saveTemps; + bool shared; + bool stripAll; + bool stripDebug; + bool stackFirst; + bool trace; + uint32_t globalBase; + uint32_t initialMemory; + uint32_t maxMemory; + uint32_t zStackSize; + unsigned ltoPartitions; + unsigned ltoo; + unsigned optimize; + unsigned thinLTOJobs; - llvm::StringRef Entry; - llvm::StringRef OutputFile; - llvm::StringRef ThinLTOCacheDir; + llvm::StringRef entry; + llvm::StringRef outputFile; + llvm::StringRef thinLTOCacheDir; - llvm::StringSet<> AllowUndefinedSymbols; - llvm::StringSet<> ExportedSymbols; - std::vector<llvm::StringRef> SearchPaths; - llvm::CachePruningPolicy ThinLTOCachePolicy; - llvm::Optional<std::vector<std::string>> Features; + llvm::StringSet<> allowUndefinedSymbols; + llvm::StringSet<> exportedSymbols; + std::vector<llvm::StringRef> searchPaths; + llvm::CachePruningPolicy thinLTOCachePolicy; + llvm::Optional<std::vector<std::string>> features; // The following config options do not directly correspond to any // particualr command line options. // True if we are creating position-independent code. - bool Pic; + bool isPic; }; // The only instance of Configuration struct. -extern Configuration *Config; +extern Configuration *config; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index a3852d47b60..d190dba7eac 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -40,7 +40,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -Configuration *lld::wasm::Config; +Configuration *lld::wasm::config; namespace { @@ -65,39 +65,39 @@ static void initLLVM() { class LinkerDriver { public: - void link(ArrayRef<const char *> ArgsArr); + void link(ArrayRef<const char *> argsArr); private: - void createFiles(opt::InputArgList &Args); - void addFile(StringRef Path); - void addLibrary(StringRef Name); + void createFiles(opt::InputArgList &args); + void addFile(StringRef path); + void addLibrary(StringRef name); // True if we are in --whole-archive and --no-whole-archive. - bool InWholeArchive = false; + bool inWholeArchive = false; - std::vector<InputFile *> Files; + std::vector<InputFile *> files; }; } // anonymous namespace -bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, - raw_ostream &Error) { - errorHandler().LogName = args::getFilenameWithoutExe(Args[0]); - errorHandler().ErrorOS = &Error; - errorHandler().ColorDiagnostics = Error.has_colors(); - errorHandler().ErrorLimitExceededMsg = +bool lld::wasm::link(ArrayRef<const char *> args, bool canExitEarly, + raw_ostream &error) { + errorHandler().logName = args::getFilenameWithoutExe(args[0]); + errorHandler().errorOS = &error; + errorHandler().colorDiagnostics = error.has_colors(); + errorHandler().errorLimitExceededMsg = "too many errors emitted, stopping now (use " "-error-limit=0 to see all errors)"; - Config = make<Configuration>(); - Symtab = make<SymbolTable>(); + config = make<Configuration>(); + symtab = make<SymbolTable>(); initLLVM(); - LinkerDriver().link(Args); + LinkerDriver().link(args); // Exit immediately if we don't need to return to the caller. // This saves time because the overhead of calling destructors // for all globally-allocated objects is not negligible. - if (CanExitEarly) + if (canExitEarly) exitLld(errorCount() ? 1 : 0); freeArena(); @@ -110,7 +110,7 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, #undef PREFIX // Create table mapping all options defined in Options.td -static const opt::OptTable::Info OptInfo[] = { +static const opt::OptTable::Info optInfo[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, @@ -121,57 +121,57 @@ static const opt::OptTable::Info OptInfo[] = { namespace { class WasmOptTable : public llvm::opt::OptTable { public: - WasmOptTable() : OptTable(OptInfo) {} - opt::InputArgList parse(ArrayRef<const char *> Argv); + WasmOptTable() : OptTable(optInfo) {} + opt::InputArgList parse(ArrayRef<const char *> argv); }; } // namespace // Set color diagnostics according to -color-diagnostics={auto,always,never} // or -no-color-diagnostics flags. -static void handleColorDiagnostics(opt::InputArgList &Args) { - auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, +static void handleColorDiagnostics(opt::InputArgList &args) { + auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, OPT_no_color_diagnostics); - if (!Arg) + if (!arg) return; - if (Arg->getOption().getID() == OPT_color_diagnostics) { - errorHandler().ColorDiagnostics = true; - } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { - errorHandler().ColorDiagnostics = false; + if (arg->getOption().getID() == OPT_color_diagnostics) { + errorHandler().colorDiagnostics = true; + } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { + errorHandler().colorDiagnostics = false; } else { - StringRef S = Arg->getValue(); - if (S == "always") - errorHandler().ColorDiagnostics = true; - else if (S == "never") - errorHandler().ColorDiagnostics = false; - else if (S != "auto") - error("unknown option: --color-diagnostics=" + S); + StringRef s = arg->getValue(); + if (s == "always") + errorHandler().colorDiagnostics = true; + else if (s == "never") + errorHandler().colorDiagnostics = false; + else if (s != "auto") + error("unknown option: --color-diagnostics=" + s); } } // Find a file by concatenating given paths. -static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { - SmallString<128> S; - path::append(S, Path1, Path2); - if (fs::exists(S)) - return S.str().str(); +static Optional<std::string> findFile(StringRef path1, const Twine &path2) { + SmallString<128> s; + path::append(s, path1, path2); + if (fs::exists(s)) + return s.str().str(); return None; } -opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { - SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); +opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) { + SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size()); - unsigned MissingIndex; - unsigned MissingCount; + unsigned missingIndex; + unsigned missingCount; // Expand response files (arguments in the form of @<filename>) - cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec); + cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, vec); - opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); + opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount); - handleColorDiagnostics(Args); - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) - error("unknown argument: " + Arg->getAsString(Args)); - return Args; + handleColorDiagnostics(args); + for (auto *arg : args.filtered(OPT_UNKNOWN)) + error("unknown argument: " + arg->getAsString(args)); + return args; } // Currently we allow a ".imports" to live alongside a library. This can @@ -181,189 +181,189 @@ opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { // In the long run this information would be better stored as a symbol // attribute/flag in the object file itself. // See: https://github.com/WebAssembly/tool-conventions/issues/35 -static void readImportFile(StringRef Filename) { - if (Optional<MemoryBufferRef> Buf = readFile(Filename)) - for (StringRef Sym : args::getLines(*Buf)) - Config->AllowUndefinedSymbols.insert(Sym); +static void readImportFile(StringRef filename) { + if (Optional<MemoryBufferRef> buf = readFile(filename)) + for (StringRef sym : args::getLines(*buf)) + config->allowUndefinedSymbols.insert(sym); } // Returns slices of MB by parsing MB as an archive file. // Each slice consists of a member file in the archive. -std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) { - std::unique_ptr<Archive> File = - CHECK(Archive::create(MB), - MB.getBufferIdentifier() + ": failed to parse archive"); - - std::vector<MemoryBufferRef> V; - Error Err = Error::success(); - for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) { - Archive::Child C = - CHECK(COrErr, MB.getBufferIdentifier() + +std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef mb) { + std::unique_ptr<Archive> file = + CHECK(Archive::create(mb), + mb.getBufferIdentifier() + ": failed to parse archive"); + + std::vector<MemoryBufferRef> v; + Error err = Error::success(); + for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) { + Archive::Child c = + CHECK(cOrErr, mb.getBufferIdentifier() + ": could not get the child of the archive"); - MemoryBufferRef MBRef = - CHECK(C.getMemoryBufferRef(), - MB.getBufferIdentifier() + + MemoryBufferRef mbref = + CHECK(c.getMemoryBufferRef(), + mb.getBufferIdentifier() + ": could not get the buffer for a child of the archive"); - V.push_back(MBRef); + v.push_back(mbref); } - if (Err) - fatal(MB.getBufferIdentifier() + - ": Archive::children failed: " + toString(std::move(Err))); + if (err) + fatal(mb.getBufferIdentifier() + + ": Archive::children failed: " + toString(std::move(err))); // Take ownership of memory buffers created for members of thin archives. - for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers()) - make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); + for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers()) + make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); - return V; + return v; } -void LinkerDriver::addFile(StringRef Path) { - Optional<MemoryBufferRef> Buffer = readFile(Path); - if (!Buffer.hasValue()) +void LinkerDriver::addFile(StringRef path) { + Optional<MemoryBufferRef> buffer = readFile(path); + if (!buffer.hasValue()) return; - MemoryBufferRef MBRef = *Buffer; + MemoryBufferRef mbref = *buffer; - switch (identify_magic(MBRef.getBuffer())) { + switch (identify_magic(mbref.getBuffer())) { case file_magic::archive: { - SmallString<128> ImportFile = Path; - path::replace_extension(ImportFile, ".imports"); - if (fs::exists(ImportFile)) - readImportFile(ImportFile.str()); + SmallString<128> importFile = path; + path::replace_extension(importFile, ".imports"); + if (fs::exists(importFile)) + readImportFile(importFile.str()); // Handle -whole-archive. - if (InWholeArchive) { - for (MemoryBufferRef &M : getArchiveMembers(MBRef)) - Files.push_back(createObjectFile(M, Path)); + if (inWholeArchive) { + for (MemoryBufferRef &m : getArchiveMembers(mbref)) + files.push_back(createObjectFile(m, path)); return; } - std::unique_ptr<Archive> File = - CHECK(Archive::create(MBRef), Path + ": failed to parse archive"); + std::unique_ptr<Archive> file = + CHECK(Archive::create(mbref), path + ": failed to parse archive"); - if (!File->isEmpty() && !File->hasSymbolTable()) { - error(MBRef.getBufferIdentifier() + + if (!file->isEmpty() && !file->hasSymbolTable()) { + error(mbref.getBufferIdentifier() + ": archive has no index; run ranlib to add one"); } - Files.push_back(make<ArchiveFile>(MBRef)); + files.push_back(make<ArchiveFile>(mbref)); return; } case file_magic::bitcode: case file_magic::wasm_object: - Files.push_back(createObjectFile(MBRef)); + files.push_back(createObjectFile(mbref)); break; default: - error("unknown file type: " + MBRef.getBufferIdentifier()); + error("unknown file type: " + mbref.getBufferIdentifier()); } } // Add a given library by searching it from input search paths. -void LinkerDriver::addLibrary(StringRef Name) { - for (StringRef Dir : Config->SearchPaths) { - if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) { - addFile(*S); +void LinkerDriver::addLibrary(StringRef name) { + for (StringRef dir : config->searchPaths) { + if (Optional<std::string> s = findFile(dir, "lib" + name + ".a")) { + addFile(*s); return; } } - error("unable to find library -l" + Name); + error("unable to find library -l" + name); } -void LinkerDriver::createFiles(opt::InputArgList &Args) { - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { +void LinkerDriver::createFiles(opt::InputArgList &args) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_l: - addLibrary(Arg->getValue()); + addLibrary(arg->getValue()); break; case OPT_INPUT: - addFile(Arg->getValue()); + addFile(arg->getValue()); break; case OPT_whole_archive: - InWholeArchive = true; + inWholeArchive = true; break; case OPT_no_whole_archive: - InWholeArchive = false; + inWholeArchive = false; break; } } } -static StringRef getEntry(opt::InputArgList &Args) { - auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); - if (!Arg) { - if (Args.hasArg(OPT_relocatable)) +static StringRef getEntry(opt::InputArgList &args) { + auto *arg = args.getLastArg(OPT_entry, OPT_no_entry); + if (!arg) { + if (args.hasArg(OPT_relocatable)) return ""; - if (Args.hasArg(OPT_shared)) + if (args.hasArg(OPT_shared)) return "__wasm_call_ctors"; return "_start"; } - if (Arg->getOption().getID() == OPT_no_entry) + if (arg->getOption().getID() == OPT_no_entry) return ""; - return Arg->getValue(); + return arg->getValue(); } // Initializes Config members by the command line options. -static void readConfigs(opt::InputArgList &Args) { - Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); - Config->CheckFeatures = - Args.hasFlag(OPT_check_features, OPT_no_check_features, true); - Config->CompressRelocations = Args.hasArg(OPT_compress_relocations); - Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); - Config->DisableVerify = Args.hasArg(OPT_disable_verify); - Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); - Config->Entry = getEntry(Args); - Config->ExportAll = Args.hasArg(OPT_export_all); - Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic, +static void readConfigs(opt::InputArgList &args) { + config->allowUndefined = args.hasArg(OPT_allow_undefined); + config->checkFeatures = + args.hasFlag(OPT_check_features, OPT_no_check_features, true); + config->compressRelocations = args.hasArg(OPT_compress_relocations); + config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true); + config->disableVerify = args.hasArg(OPT_disable_verify); + config->emitRelocs = args.hasArg(OPT_emit_relocs); + config->entry = getEntry(args); + config->exportAll = args.hasArg(OPT_export_all); + config->exportDynamic = args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); - Config->ExportTable = Args.hasArg(OPT_export_table); - errorHandler().FatalWarnings = - Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); - Config->ImportMemory = Args.hasArg(OPT_import_memory); - Config->SharedMemory = Args.hasArg(OPT_shared_memory); + config->exportTable = args.hasArg(OPT_export_table); + errorHandler().fatalWarnings = + args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); + config->importMemory = args.hasArg(OPT_import_memory); + config->sharedMemory = args.hasArg(OPT_shared_memory); // TODO: Make passive segments the default with shared memory - Config->PassiveSegments = - Args.hasFlag(OPT_passive_segments, OPT_active_segments, false); - Config->ImportTable = Args.hasArg(OPT_import_table); - Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); - Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); - Config->Optimize = args::getInteger(Args, OPT_O, 0); - Config->OutputFile = Args.getLastArgValue(OPT_o); - Config->Relocatable = Args.hasArg(OPT_relocatable); - Config->GcSections = - Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable); - Config->MergeDataSegments = - Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, - !Config->Relocatable); - Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false); - Config->PrintGcSections = - Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); - Config->SaveTemps = Args.hasArg(OPT_save_temps); - Config->SearchPaths = args::getStrings(Args, OPT_L); - Config->Shared = Args.hasArg(OPT_shared); - Config->StripAll = Args.hasArg(OPT_strip_all); - Config->StripDebug = Args.hasArg(OPT_strip_debug); - Config->StackFirst = Args.hasArg(OPT_stack_first); - Config->Trace = Args.hasArg(OPT_trace); - Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); - Config->ThinLTOCachePolicy = CHECK( - parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), + config->passiveSegments = + args.hasFlag(OPT_passive_segments, OPT_active_segments, false); + config->importTable = args.hasArg(OPT_import_table); + config->ltoo = args::getInteger(args, OPT_lto_O, 2); + config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); + config->optimize = args::getInteger(args, OPT_O, 0); + config->outputFile = args.getLastArgValue(OPT_o); + config->relocatable = args.hasArg(OPT_relocatable); + config->gcSections = + args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable); + config->mergeDataSegments = + args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, + !config->relocatable); + config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false); + config->printGcSections = + args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); + config->saveTemps = args.hasArg(OPT_save_temps); + config->searchPaths = args::getStrings(args, OPT_L); + config->shared = args.hasArg(OPT_shared); + config->stripAll = args.hasArg(OPT_strip_all); + config->stripDebug = args.hasArg(OPT_strip_debug); + config->stackFirst = args.hasArg(OPT_stack_first); + config->trace = args.hasArg(OPT_trace); + config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir); + config->thinLTOCachePolicy = CHECK( + parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)), "--thinlto-cache-policy: invalid cache policy"); - Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); - errorHandler().Verbose = Args.hasArg(OPT_verbose); - LLVM_DEBUG(errorHandler().Verbose = true); - ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); - - Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); - Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); - Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0); - Config->ZStackSize = - args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); - - if (auto *Arg = Args.getLastArg(OPT_features)) { - Config->Features = + config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u); + errorHandler().verbose = args.hasArg(OPT_verbose); + LLVM_DEBUG(errorHandler().verbose = true); + threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true); + + config->initialMemory = args::getInteger(args, OPT_initial_memory, 0); + config->globalBase = args::getInteger(args, OPT_global_base, 1024); + config->maxMemory = args::getInteger(args, OPT_max_memory, 0); + config->zStackSize = + args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize); + + if (auto *arg = args.getLastArg(OPT_features)) { + config->features = llvm::Optional<std::vector<std::string>>(std::vector<std::string>()); - for (StringRef S : Arg->getValues()) - Config->Features->push_back(S); + for (StringRef s : arg->getValues()) + config->features->push_back(s); } } @@ -372,183 +372,183 @@ static void readConfigs(opt::InputArgList &Args) { // This function initialize such members. See Config.h for the details // of these values. static void setConfigs() { - Config->Pic = Config->Pie || Config->Shared; + config->isPic = config->pie || config->shared; - if (Config->Pic) { - if (Config->ExportTable) + if (config->isPic) { + if (config->exportTable) error("-shared/-pie is incompatible with --export-table"); - Config->ImportTable = true; + config->importTable = true; } - if (Config->Shared) { - Config->ImportMemory = true; - Config->ExportDynamic = true; - Config->AllowUndefined = true; + if (config->shared) { + config->importMemory = true; + config->exportDynamic = true; + config->allowUndefined = true; } } // Some command line options or some combinations of them are not allowed. // This function checks for such errors. -static void checkOptions(opt::InputArgList &Args) { - if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations) +static void checkOptions(opt::InputArgList &args) { + if (!config->stripDebug && !config->stripAll && config->compressRelocations) error("--compress-relocations is incompatible with output debug" " information. Please pass --strip-debug or --strip-all"); - if (Config->LTOO > 3) - error("invalid optimization level for LTO: " + Twine(Config->LTOO)); - if (Config->LTOPartitions == 0) + if (config->ltoo > 3) + error("invalid optimization level for LTO: " + Twine(config->ltoo)); + if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); - if (Config->ThinLTOJobs == 0) + if (config->thinLTOJobs == 0) error("--thinlto-jobs: number of threads must be > 0"); - if (Config->Pie && Config->Shared) + if (config->pie && config->shared) error("-shared and -pie may not be used together"); - if (Config->OutputFile.empty()) + if (config->outputFile.empty()) error("no output file specified"); - if (Config->ImportTable && Config->ExportTable) + if (config->importTable && config->exportTable) error("--import-table and --export-table may not be used together"); - if (Config->Relocatable) { - if (!Config->Entry.empty()) + if (config->relocatable) { + if (!config->entry.empty()) error("entry point specified for relocatable output file"); - if (Config->GcSections) + if (config->gcSections) error("-r and --gc-sections may not be used together"); - if (Config->CompressRelocations) + if (config->compressRelocations) error("-r -and --compress-relocations may not be used together"); - if (Args.hasArg(OPT_undefined)) + if (args.hasArg(OPT_undefined)) error("-r -and --undefined may not be used together"); - if (Config->Pie) + if (config->pie) error("-r and -pie may not be used together"); } } // Force Sym to be entered in the output. Used for -u or equivalent. -static Symbol *handleUndefined(StringRef Name) { - Symbol *Sym = Symtab->find(Name); - if (!Sym) +static Symbol *handleUndefined(StringRef name) { + Symbol *sym = symtab->find(name); + if (!sym) return nullptr; // Since symbol S may not be used inside the program, LTO may // eliminate it. Mark the symbol as "used" to prevent it. - Sym->IsUsedInRegularObj = true; + sym->isUsedInRegularObj = true; - if (auto *LazySym = dyn_cast<LazySymbol>(Sym)) - LazySym->fetch(); + if (auto *lazySym = dyn_cast<LazySymbol>(sym)) + lazySym->fetch(); - return Sym; + return sym; } static UndefinedGlobal * -createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) { - auto *Sym = - cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, Name, - DefaultModule, 0, - nullptr, Type)); - Config->AllowUndefinedSymbols.insert(Sym->getName()); - Sym->IsUsedInRegularObj = true; - return Sym; +createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) { + auto *sym = + cast<UndefinedGlobal>(symtab->addUndefinedGlobal(name, name, + defaultModule, 0, + nullptr, type)); + config->allowUndefinedSymbols.insert(sym->getName()); + sym->isUsedInRegularObj = true; + return sym; } // Create ABI-defined synthetic symbols static void createSyntheticSymbols() { - static WasmSignature NullSignature = {{}, {}}; - static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false}; - static llvm::wasm::WasmGlobalType MutableGlobalTypeI32 = {WASM_TYPE_I32, + static WasmSignature nullSignature = {{}, {}}; + static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false}; + static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32, true}; - if (!Config->Relocatable) { - WasmSym::CallCtors = Symtab->addSyntheticFunction( + if (!config->relocatable) { + WasmSym::callCtors = symtab->addSyntheticFunction( "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, - make<SyntheticFunction>(NullSignature, "__wasm_call_ctors")); + make<SyntheticFunction>(nullSignature, "__wasm_call_ctors")); - if (Config->PassiveSegments) { + if (config->passiveSegments) { // Passive segments are used to avoid memory being reinitialized on each // thread's instantiation. These passive segments are initialized and // dropped in __wasm_init_memory, which is the first function called from // __wasm_call_ctors. - WasmSym::InitMemory = Symtab->addSyntheticFunction( + WasmSym::initMemory = symtab->addSyntheticFunction( "__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN, - make<SyntheticFunction>(NullSignature, "__wasm_init_memory")); + make<SyntheticFunction>(nullSignature, "__wasm_init_memory")); } - if (Config->Pic) { + if (config->isPic) { // For PIC code we create a synthetic function __wasm_apply_relocs which // is called from __wasm_call_ctors before the user-level constructors. - WasmSym::ApplyRelocs = Symtab->addSyntheticFunction( + WasmSym::applyRelocs = symtab->addSyntheticFunction( "__wasm_apply_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, - make<SyntheticFunction>(NullSignature, "__wasm_apply_relocs")); + make<SyntheticFunction>(nullSignature, "__wasm_apply_relocs")); } } // The __stack_pointer is imported in the shared library case, and exported // in the non-shared (executable) case. - if (Config->Shared) { - WasmSym::StackPointer = - createUndefinedGlobal("__stack_pointer", &MutableGlobalTypeI32); + if (config->shared) { + WasmSym::stackPointer = + createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32); } else { - llvm::wasm::WasmGlobal Global; - Global.Type = {WASM_TYPE_I32, true}; - Global.InitExpr.Value.Int32 = 0; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.SymbolName = "__stack_pointer"; - auto *StackPointer = make<InputGlobal>(Global, nullptr); - StackPointer->Live = true; + llvm::wasm::WasmGlobal global; + global.Type = {WASM_TYPE_I32, true}; + global.InitExpr.Value.Int32 = 0; + global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + global.SymbolName = "__stack_pointer"; + auto *stackPointer = make<InputGlobal>(global, nullptr); + stackPointer->live = true; // For non-PIC code // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global // spec proposal is implemented in all major browsers. // See: https://github.com/WebAssembly/mutable-global - WasmSym::StackPointer = Symtab->addSyntheticGlobal( - "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); - WasmSym::DataEnd = Symtab->addOptionalDataSymbol("__data_end"); - WasmSym::GlobalBase = Symtab->addOptionalDataSymbol("__global_base"); - WasmSym::HeapBase = Symtab->addOptionalDataSymbol("__heap_base"); + WasmSym::stackPointer = symtab->addSyntheticGlobal( + "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, stackPointer); + WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end"); + WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base"); + WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base"); } - if (Config->Pic) { + if (config->isPic) { // For PIC code, we import two global variables (__memory_base and // __table_base) from the environment and use these as the offset at // which to load our static data and function table. // See: // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md - WasmSym::MemoryBase = - createUndefinedGlobal("__memory_base", &GlobalTypeI32); - WasmSym::TableBase = createUndefinedGlobal("__table_base", &GlobalTypeI32); - WasmSym::MemoryBase->markLive(); - WasmSym::TableBase->markLive(); + WasmSym::memoryBase = + createUndefinedGlobal("__memory_base", &globalTypeI32); + WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32); + WasmSym::memoryBase->markLive(); + WasmSym::tableBase->markLive(); } - WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol( + WasmSym::dsoHandle = symtab->addSyntheticDataSymbol( "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN); } // Reconstructs command line arguments so that so that you can re-run // the same command with the same inputs. This is for --reproduce. -static std::string createResponseFile(const opt::InputArgList &Args) { - SmallString<0> Data; - raw_svector_ostream OS(Data); +static std::string createResponseFile(const opt::InputArgList &args) { + SmallString<0> data; + raw_svector_ostream os(data); // Copy the command line to the output while rewriting paths. - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { + for (auto *arg : args) { + switch (arg->getOption().getID()) { case OPT_reproduce: break; case OPT_INPUT: - OS << quote(relativeToRoot(Arg->getValue())) << "\n"; + os << quote(relativeToRoot(arg->getValue())) << "\n"; break; case OPT_o: // If -o path contains directories, "lld @response.txt" will likely // fail because the archive we are creating doesn't contain empty // directories for the output path (-o doesn't create directories). // Strip directories to prevent the issue. - OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n"; + os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n"; break; default: - OS << toString(*Arg) << "\n"; + os << toString(*arg) << "\n"; } } - return Data.str(); + return data.str(); } // The --wrap option is a feature to rename symbols so that you can write @@ -560,13 +560,13 @@ static std::string createResponseFile(const opt::InputArgList &Args) { // // This data structure is instantiated for each -wrap option. struct WrappedSymbol { - Symbol *Sym; - Symbol *Real; - Symbol *Wrap; + Symbol *sym; + Symbol *real; + Symbol *wrap; }; -static Symbol *addUndefined(StringRef Name) { - return Symtab->addUndefinedFunction(Name, "", "", 0, nullptr, nullptr, false); +static Symbol *addUndefined(StringRef name) { + return symtab->addUndefinedFunction(name, "", "", 0, nullptr, nullptr, false); } // Handles -wrap option. @@ -574,34 +574,34 @@ static Symbol *addUndefined(StringRef Name) { // This function instantiates wrapper symbols. At this point, they seem // like they are not being used at all, so we explicitly set some flags so // that LTO won't eliminate them. -static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) { - std::vector<WrappedSymbol> V; - DenseSet<StringRef> Seen; +static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) { + std::vector<WrappedSymbol> v; + DenseSet<StringRef> seen; - for (auto *Arg : Args.filtered(OPT_wrap)) { - StringRef Name = Arg->getValue(); - if (!Seen.insert(Name).second) + for (auto *arg : args.filtered(OPT_wrap)) { + StringRef name = arg->getValue(); + if (!seen.insert(name).second) continue; - Symbol *Sym = Symtab->find(Name); - if (!Sym) + Symbol *sym = symtab->find(name); + if (!sym) continue; - Symbol *Real = addUndefined(Saver.save("__real_" + Name)); - Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name)); - V.push_back({Sym, Real, Wrap}); + Symbol *real = addUndefined(saver.save("__real_" + name)); + Symbol *wrap = addUndefined(saver.save("__wrap_" + name)); + v.push_back({sym, real, wrap}); // We want to tell LTO not to inline symbols to be overwritten // because LTO doesn't know the final symbol contents after renaming. - Real->CanInline = false; - Sym->CanInline = false; + real->canInline = false; + sym->canInline = false; // Tell LTO not to eliminate these symbols. - Sym->IsUsedInRegularObj = true; - Wrap->IsUsedInRegularObj = true; - Real->IsUsedInRegularObj = false; + sym->isUsedInRegularObj = true; + wrap->isUsedInRegularObj = true; + real->isUsedInRegularObj = false; } - return V; + return v; } // Do renaming for -wrap by updating pointers to symbols. @@ -609,158 +609,158 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) { // When this function is executed, only InputFiles and symbol table // contain pointers to symbol objects. We visit them to replace pointers, // so that wrapped symbols are swapped as instructed by the command line. -static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) { - DenseMap<Symbol *, Symbol *> Map; - for (const WrappedSymbol &W : Wrapped) { - Map[W.Sym] = W.Wrap; - Map[W.Real] = W.Sym; +static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) { + DenseMap<Symbol *, Symbol *> map; + for (const WrappedSymbol &w : wrapped) { + map[w.sym] = w.wrap; + map[w.real] = w.sym; } // Update pointers in input files. - parallelForEach(Symtab->ObjectFiles, [&](InputFile *File) { - MutableArrayRef<Symbol *> Syms = File->getMutableSymbols(); - for (size_t I = 0, E = Syms.size(); I != E; ++I) - if (Symbol *S = Map.lookup(Syms[I])) - Syms[I] = S; + parallelForEach(symtab->objectFiles, [&](InputFile *file) { + MutableArrayRef<Symbol *> syms = file->getMutableSymbols(); + for (size_t i = 0, e = syms.size(); i != e; ++i) + if (Symbol *s = map.lookup(syms[i])) + syms[i] = s; }); // Update pointers in the symbol table. - for (const WrappedSymbol &W : Wrapped) - Symtab->wrap(W.Sym, W.Real, W.Wrap); + for (const WrappedSymbol &w : wrapped) + symtab->wrap(w.sym, w.real, w.wrap); } -void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { - WasmOptTable Parser; - opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); +void LinkerDriver::link(ArrayRef<const char *> argsArr) { + WasmOptTable parser; + opt::InputArgList args = parser.parse(argsArr.slice(1)); // Handle --help - if (Args.hasArg(OPT_help)) { - Parser.PrintHelp(outs(), - (std::string(ArgsArr[0]) + " [options] file...").c_str(), + if (args.hasArg(OPT_help)) { + parser.PrintHelp(outs(), + (std::string(argsArr[0]) + " [options] file...").c_str(), "LLVM Linker", false); return; } // Handle --version - if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) { + if (args.hasArg(OPT_version) || args.hasArg(OPT_v)) { outs() << getLLDVersion() << "\n"; return; } // Handle --reproduce - if (auto *Arg = Args.getLastArg(OPT_reproduce)) { - StringRef Path = Arg->getValue(); - Expected<std::unique_ptr<TarWriter>> ErrOrWriter = - TarWriter::create(Path, path::stem(Path)); - if (ErrOrWriter) { - Tar = std::move(*ErrOrWriter); - Tar->append("response.txt", createResponseFile(Args)); - Tar->append("version.txt", getLLDVersion() + "\n"); + if (auto *arg = args.getLastArg(OPT_reproduce)) { + StringRef path = arg->getValue(); + Expected<std::unique_ptr<TarWriter>> errOrWriter = + TarWriter::create(path, path::stem(path)); + if (errOrWriter) { + tar = std::move(*errOrWriter); + tar->append("response.txt", createResponseFile(args)); + tar->append("version.txt", getLLDVersion() + "\n"); } else { - error("--reproduce: " + toString(ErrOrWriter.takeError())); + error("--reproduce: " + toString(errOrWriter.takeError())); } } // Parse and evaluate -mllvm options. - std::vector<const char *> V; - V.push_back("wasm-ld (LLVM option parsing)"); - for (auto *Arg : Args.filtered(OPT_mllvm)) - V.push_back(Arg->getValue()); - cl::ParseCommandLineOptions(V.size(), V.data()); + std::vector<const char *> v; + v.push_back("wasm-ld (LLVM option parsing)"); + for (auto *arg : args.filtered(OPT_mllvm)) + v.push_back(arg->getValue()); + cl::ParseCommandLineOptions(v.size(), v.data()); - errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); + errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20); - readConfigs(Args); + readConfigs(args); setConfigs(); - checkOptions(Args); + checkOptions(args); - if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) - readImportFile(Arg->getValue()); + if (auto *arg = args.getLastArg(OPT_allow_undefined_file)) + readImportFile(arg->getValue()); - if (!Args.hasArg(OPT_INPUT)) { + if (!args.hasArg(OPT_INPUT)) { error("no input files"); return; } // Handle --trace-symbol. - for (auto *Arg : Args.filtered(OPT_trace_symbol)) - Symtab->trace(Arg->getValue()); + for (auto *arg : args.filtered(OPT_trace_symbol)) + symtab->trace(arg->getValue()); - for (auto *Arg : Args.filtered(OPT_export)) - Config->ExportedSymbols.insert(Arg->getValue()); + for (auto *arg : args.filtered(OPT_export)) + config->exportedSymbols.insert(arg->getValue()); - if (!Config->Relocatable) + if (!config->relocatable) createSyntheticSymbols(); - createFiles(Args); + createFiles(args); if (errorCount()) return; // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. - for (InputFile *F : Files) - Symtab->addFile(F); + for (InputFile *f : files) + symtab->addFile(f); if (errorCount()) return; // Handle the `--undefined <sym>` options. - for (auto *Arg : Args.filtered(OPT_undefined)) - handleUndefined(Arg->getValue()); + for (auto *arg : args.filtered(OPT_undefined)) + handleUndefined(arg->getValue()); // Handle the `--export <sym>` options // This works like --undefined but also exports the symbol if its found - for (auto *Arg : Args.filtered(OPT_export)) - handleUndefined(Arg->getValue()); - - Symbol *EntrySym = nullptr; - if (!Config->Relocatable && !Config->Entry.empty()) { - EntrySym = handleUndefined(Config->Entry); - if (EntrySym && EntrySym->isDefined()) - EntrySym->ForceExport = true; + for (auto *arg : args.filtered(OPT_export)) + handleUndefined(arg->getValue()); + + Symbol *entrySym = nullptr; + if (!config->relocatable && !config->entry.empty()) { + entrySym = handleUndefined(config->entry); + if (entrySym && entrySym->isDefined()) + entrySym->forceExport = true; else error("entry symbol not defined (pass --no-entry to supress): " + - Config->Entry); + config->entry); } if (errorCount()) return; // Create wrapped symbols for -wrap option. - std::vector<WrappedSymbol> Wrapped = addWrappedSymbols(Args); + std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args); // Do link-time optimization if given files are LLVM bitcode files. // This compiles bitcode files into real object files. - Symtab->addCombinedLTOObject(); + symtab->addCombinedLTOObject(); if (errorCount()) return; // Resolve any variant symbols that were created due to signature // mismatchs. - Symtab->handleSymbolVariants(); + symtab->handleSymbolVariants(); if (errorCount()) return; // Apply symbol renames for -wrap. - if (!Wrapped.empty()) - wrapSymbols(Wrapped); - - for (auto *Arg : Args.filtered(OPT_export)) { - Symbol *Sym = Symtab->find(Arg->getValue()); - if (Sym && Sym->isDefined()) - Sym->ForceExport = true; - else if (!Config->AllowUndefined) + if (!wrapped.empty()) + wrapSymbols(wrapped); + + for (auto *arg : args.filtered(OPT_export)) { + Symbol *sym = symtab->find(arg->getValue()); + if (sym && sym->isDefined()) + sym->forceExport = true; + else if (!config->allowUndefined) error(Twine("symbol exported via --export not found: ") + - Arg->getValue()); + arg->getValue()); } - if (!Config->Relocatable) { + if (!config->relocatable) { // Add synthetic dummies for weak undefined functions. Must happen // after LTO otherwise functions may not yet have signatures. - Symtab->handleWeakUndefines(); + symtab->handleWeakUndefines(); } - if (EntrySym) - EntrySym->setHidden(false); + if (entrySym) + entrySym->setHidden(false); if (errorCount()) return; diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index cb62f96c35b..d37b58a5dee 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -22,8 +22,8 @@ using namespace llvm::support::endian; using namespace lld; using namespace lld::wasm; -StringRef lld::relocTypeToString(uint8_t RelocType) { - switch (RelocType) { +StringRef lld::relocTypeToString(uint8_t relocType) { + switch (relocType) { #define WASM_RELOC(NAME, REL) \ case REL: \ return #NAME; @@ -33,67 +33,67 @@ StringRef lld::relocTypeToString(uint8_t RelocType) { llvm_unreachable("unknown reloc type"); } -std::string lld::toString(const InputChunk *C) { - return (toString(C->File) + ":(" + C->getName() + ")").str(); +std::string lld::toString(const InputChunk *c) { + return (toString(c->file) + ":(" + c->getName() + ")").str(); } StringRef InputChunk::getComdatName() const { - uint32_t Index = getComdat(); - if (Index == UINT32_MAX) + uint32_t index = getComdat(); + if (index == UINT32_MAX) return StringRef(); - return File->getWasmObj()->linkingData().Comdats[Index]; + return file->getWasmObj()->linkingData().Comdats[index]; } void InputChunk::verifyRelocTargets() const { - for (const WasmRelocation &Rel : Relocations) { - uint32_t ExistingValue; - unsigned BytesRead = 0; - uint32_t Offset = Rel.Offset - getInputSectionOffset(); - const uint8_t *Loc = data().data() + Offset; - switch (Rel.Type) { + for (const WasmRelocation &rel : relocations) { + uint32_t existingValue; + unsigned bytesRead = 0; + uint32_t offset = rel.Offset - getInputSectionOffset(); + const uint8_t *loc = data().data() + offset; + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - ExistingValue = decodeULEB128(Loc, &BytesRead); + existingValue = decodeULEB128(loc, &bytesRead); break; case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc, &BytesRead)); + existingValue = static_cast<uint32_t>(decodeSLEB128(loc, &bytesRead)); break; case R_WASM_TABLE_INDEX_I32: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: case R_WASM_SECTION_OFFSET_I32: - ExistingValue = static_cast<uint32_t>(read32le(Loc)); + existingValue = static_cast<uint32_t>(read32le(loc)); break; default: llvm_unreachable("unknown relocation type"); } - if (BytesRead && BytesRead != 5) + if (bytesRead && bytesRead != 5) warn("expected LEB at relocation site be 5-byte padded"); - if (Rel.Type != R_WASM_GLOBAL_INDEX_LEB) { - uint32_t ExpectedValue = File->calcExpectedValue(Rel); - if (ExpectedValue != ExistingValue) - warn("unexpected existing value for " + relocTypeToString(Rel.Type) + - ": existing=" + Twine(ExistingValue) + - " expected=" + Twine(ExpectedValue)); + if (rel.Type != R_WASM_GLOBAL_INDEX_LEB) { + uint32_t expectedValue = file->calcExpectedValue(rel); + if (expectedValue != existingValue) + warn("unexpected existing value for " + relocTypeToString(rel.Type) + + ": existing=" + Twine(existingValue) + + " expected=" + Twine(expectedValue)); } } } // Copy this input chunk to an mmap'ed output file and apply relocations. -void InputChunk::writeTo(uint8_t *Buf) const { +void InputChunk::writeTo(uint8_t *buf) const { // Copy contents - memcpy(Buf + OutputOffset, data().data(), data().size()); + memcpy(buf + outputOffset, data().data(), data().size()); // Apply relocations - if (Relocations.empty()) + if (relocations.empty()) return; #ifndef NDEBUG @@ -101,38 +101,38 @@ void InputChunk::writeTo(uint8_t *Buf) const { #endif LLVM_DEBUG(dbgs() << "applying relocations: " << getName() - << " count=" << Relocations.size() << "\n"); - int32_t Off = OutputOffset - getInputSectionOffset(); - - for (const WasmRelocation &Rel : Relocations) { - uint8_t *Loc = Buf + Rel.Offset + Off; - uint32_t Value = File->calcNewValue(Rel); - LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(Rel.Type)); - if (Rel.Type != R_WASM_TYPE_INDEX_LEB) - LLVM_DEBUG(dbgs() << " sym=" << File->getSymbols()[Rel.Index]->getName()); - LLVM_DEBUG(dbgs() << " addend=" << Rel.Addend << " index=" << Rel.Index - << " value=" << Value << " offset=" << Rel.Offset + << " count=" << relocations.size() << "\n"); + int32_t off = outputOffset - getInputSectionOffset(); + + for (const WasmRelocation &rel : relocations) { + uint8_t *loc = buf + rel.Offset + off; + uint32_t value = file->calcNewValue(rel); + LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(rel.Type)); + if (rel.Type != R_WASM_TYPE_INDEX_LEB) + LLVM_DEBUG(dbgs() << " sym=" << file->getSymbols()[rel.Index]->getName()); + LLVM_DEBUG(dbgs() << " addend=" << rel.Addend << " index=" << rel.Index + << " value=" << value << " offset=" << rel.Offset << "\n"); - switch (Rel.Type) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - encodeULEB128(Value, Loc, 5); + encodeULEB128(value, loc, 5); break; case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - encodeSLEB128(static_cast<int32_t>(Value), Loc, 5); + encodeSLEB128(static_cast<int32_t>(value), loc, 5); break; case R_WASM_TABLE_INDEX_I32: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: case R_WASM_SECTION_OFFSET_I32: - write32le(Loc, Value); + write32le(loc, value); break; default: llvm_unreachable("unknown relocation type"); @@ -143,59 +143,59 @@ void InputChunk::writeTo(uint8_t *Buf) const { // Copy relocation entries to a given output stream. // This function is used only when a user passes "-r". For a regular link, // we consume relocations instead of copying them to an output file. -void InputChunk::writeRelocations(raw_ostream &OS) const { - if (Relocations.empty()) +void InputChunk::writeRelocations(raw_ostream &os) const { + if (relocations.empty()) return; - int32_t Off = OutputOffset - getInputSectionOffset(); - LLVM_DEBUG(dbgs() << "writeRelocations: " << File->getName() - << " offset=" << Twine(Off) << "\n"); + int32_t off = outputOffset - getInputSectionOffset(); + LLVM_DEBUG(dbgs() << "writeRelocations: " << file->getName() + << " offset=" << Twine(off) << "\n"); - for (const WasmRelocation &Rel : Relocations) { - writeUleb128(OS, Rel.Type, "reloc type"); - writeUleb128(OS, Rel.Offset + Off, "reloc offset"); - writeUleb128(OS, File->calcNewIndex(Rel), "reloc index"); + for (const WasmRelocation &rel : relocations) { + writeUleb128(os, rel.Type, "reloc type"); + writeUleb128(os, rel.Offset + off, "reloc offset"); + writeUleb128(os, file->calcNewIndex(rel), "reloc index"); - if (relocTypeHasAddend(Rel.Type)) - writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend"); + if (relocTypeHasAddend(rel.Type)) + writeSleb128(os, file->calcNewAddend(rel), "reloc addend"); } } -void InputFunction::setFunctionIndex(uint32_t Index) { +void InputFunction::setFunctionIndex(uint32_t index) { LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName() - << " -> " << Index << "\n"); + << " -> " << index << "\n"); assert(!hasFunctionIndex()); - FunctionIndex = Index; + functionIndex = index; } -void InputFunction::setTableIndex(uint32_t Index) { +void InputFunction::setTableIndex(uint32_t index) { LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> " - << Index << "\n"); + << index << "\n"); assert(!hasTableIndex()); - TableIndex = Index; + tableIndex = index; } // Write a relocation value without padding and return the number of bytes // witten. -static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel, - uint32_t Value) { - switch (Rel.Type) { +static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel, + uint32_t value) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: - return encodeULEB128(Value, Buf); + return encodeULEB128(value, buf); case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: - return encodeSLEB128(static_cast<int32_t>(Value), Buf); + return encodeSLEB128(static_cast<int32_t>(value), buf); default: llvm_unreachable("unexpected relocation type"); } } -static unsigned getRelocWidthPadded(const WasmRelocation &Rel) { - switch (Rel.Type) { +static unsigned getRelocWidthPadded(const WasmRelocation &rel) { + switch (rel.Type) { case R_WASM_TYPE_INDEX_LEB: case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: @@ -209,9 +209,9 @@ static unsigned getRelocWidthPadded(const WasmRelocation &Rel) { } } -static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) { - uint8_t Buf[5]; - return writeCompressedReloc(Buf, Rel, Value); +static unsigned getRelocWidth(const WasmRelocation &rel, uint32_t value) { + uint8_t buf[5]; + return writeCompressedReloc(buf, rel, value); } // Relocations of type LEB and SLEB in the code section are padded to 5 bytes @@ -225,124 +225,124 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) { // This function only computes the final output size. It must be called // before getSize() is used to calculate of layout of the code section. void InputFunction::calculateSize() { - if (!File || !Config->CompressRelocations) + if (!file || !config->compressRelocations) return; LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n"); - const uint8_t *SecStart = File->CodeSection->Content.data(); - const uint8_t *FuncStart = SecStart + getInputSectionOffset(); - uint32_t FunctionSizeLength; - decodeULEB128(FuncStart, &FunctionSizeLength); + const uint8_t *secStart = file->codeSection->Content.data(); + const uint8_t *funcStart = secStart + getInputSectionOffset(); + uint32_t functionSizeLength; + decodeULEB128(funcStart, &functionSizeLength); - uint32_t Start = getInputSectionOffset(); - uint32_t End = Start + Function->Size; + uint32_t start = getInputSectionOffset(); + uint32_t end = start + function->Size; - uint32_t LastRelocEnd = Start + FunctionSizeLength; - for (const WasmRelocation &Rel : Relocations) { - LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n"); - CompressedFuncSize += Rel.Offset - LastRelocEnd; - CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel)); - LastRelocEnd = Rel.Offset + getRelocWidthPadded(Rel); + uint32_t lastRelocEnd = start + functionSizeLength; + for (const WasmRelocation &rel : relocations) { + LLVM_DEBUG(dbgs() << " region: " << (rel.Offset - lastRelocEnd) << "\n"); + compressedFuncSize += rel.Offset - lastRelocEnd; + compressedFuncSize += getRelocWidth(rel, file->calcNewValue(rel)); + lastRelocEnd = rel.Offset + getRelocWidthPadded(rel); } - LLVM_DEBUG(dbgs() << " final region: " << (End - LastRelocEnd) << "\n"); - CompressedFuncSize += End - LastRelocEnd; + LLVM_DEBUG(dbgs() << " final region: " << (end - lastRelocEnd) << "\n"); + compressedFuncSize += end - lastRelocEnd; // Now we know how long the resulting function is we can add the encoding // of its length - uint8_t Buf[5]; - CompressedSize = CompressedFuncSize + encodeULEB128(CompressedFuncSize, Buf); + uint8_t buf[5]; + compressedSize = compressedFuncSize + encodeULEB128(compressedFuncSize, buf); - LLVM_DEBUG(dbgs() << " calculateSize orig: " << Function->Size << "\n"); - LLVM_DEBUG(dbgs() << " calculateSize new: " << CompressedSize << "\n"); + LLVM_DEBUG(dbgs() << " calculateSize orig: " << function->Size << "\n"); + LLVM_DEBUG(dbgs() << " calculateSize new: " << compressedSize << "\n"); } // Override the default writeTo method so that we can (optionally) write the // compressed version of the function. -void InputFunction::writeTo(uint8_t *Buf) const { - if (!File || !Config->CompressRelocations) - return InputChunk::writeTo(Buf); +void InputFunction::writeTo(uint8_t *buf) const { + if (!file || !config->compressRelocations) + return InputChunk::writeTo(buf); - Buf += OutputOffset; - uint8_t *Orig = Buf; - (void)Orig; + buf += outputOffset; + uint8_t *orig = buf; + (void)orig; - const uint8_t *SecStart = File->CodeSection->Content.data(); - const uint8_t *FuncStart = SecStart + getInputSectionOffset(); - const uint8_t *End = FuncStart + Function->Size; - uint32_t Count; - decodeULEB128(FuncStart, &Count); - FuncStart += Count; + const uint8_t *secStart = file->codeSection->Content.data(); + const uint8_t *funcStart = secStart + getInputSectionOffset(); + const uint8_t *end = funcStart + function->Size; + uint32_t count; + decodeULEB128(funcStart, &count); + funcStart += count; LLVM_DEBUG(dbgs() << "write func: " << getName() << "\n"); - Buf += encodeULEB128(CompressedFuncSize, Buf); - const uint8_t *LastRelocEnd = FuncStart; - for (const WasmRelocation &Rel : Relocations) { - unsigned ChunkSize = (SecStart + Rel.Offset) - LastRelocEnd; - LLVM_DEBUG(dbgs() << " write chunk: " << ChunkSize << "\n"); - memcpy(Buf, LastRelocEnd, ChunkSize); - Buf += ChunkSize; - Buf += writeCompressedReloc(Buf, Rel, File->calcNewValue(Rel)); - LastRelocEnd = SecStart + Rel.Offset + getRelocWidthPadded(Rel); + buf += encodeULEB128(compressedFuncSize, buf); + const uint8_t *lastRelocEnd = funcStart; + for (const WasmRelocation &rel : relocations) { + unsigned chunkSize = (secStart + rel.Offset) - lastRelocEnd; + LLVM_DEBUG(dbgs() << " write chunk: " << chunkSize << "\n"); + memcpy(buf, lastRelocEnd, chunkSize); + buf += chunkSize; + buf += writeCompressedReloc(buf, rel, file->calcNewValue(rel)); + lastRelocEnd = secStart + rel.Offset + getRelocWidthPadded(rel); } - unsigned ChunkSize = End - LastRelocEnd; - LLVM_DEBUG(dbgs() << " write final chunk: " << ChunkSize << "\n"); - memcpy(Buf, LastRelocEnd, ChunkSize); - LLVM_DEBUG(dbgs() << " total: " << (Buf + ChunkSize - Orig) << "\n"); + unsigned chunkSize = end - lastRelocEnd; + LLVM_DEBUG(dbgs() << " write final chunk: " << chunkSize << "\n"); + memcpy(buf, lastRelocEnd, chunkSize); + LLVM_DEBUG(dbgs() << " total: " << (buf + chunkSize - orig) << "\n"); } // Generate code to apply relocations to the data section at runtime. // This is only called when generating shared libaries (PIC) where address are // not known at static link time. -void InputSegment::generateRelocationCode(raw_ostream &OS) const { +void InputSegment::generateRelocationCode(raw_ostream &os) const { LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName() - << " count=" << Relocations.size() << "\n"); + << " count=" << relocations.size() << "\n"); // TODO(sbc): Encode the relocations in the data section and write a loop // here to apply them. - uint32_t SegmentVA = OutputSeg->StartVA + OutputSegmentOffset; - for (const WasmRelocation &Rel : Relocations) { - uint32_t Offset = Rel.Offset - getInputSectionOffset(); - uint32_t OutputOffset = SegmentVA + Offset; + uint32_t segmentVA = outputSeg->startVA + outputSegmentOffset; + for (const WasmRelocation &rel : relocations) { + uint32_t offset = rel.Offset - getInputSectionOffset(); + uint32_t outputOffset = segmentVA + offset; - LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(Rel.Type) - << " addend=" << Rel.Addend << " index=" << Rel.Index - << " output offset=" << OutputOffset << "\n"); + LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type) + << " addend=" << rel.Addend << " index=" << rel.Index + << " output offset=" << outputOffset << "\n"); // Get __memory_base - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, WasmSym::MemoryBase->getGlobalIndex(), "memory_base"); + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base"); // Add the offset of the relocation - writeU8(OS, WASM_OPCODE_I32_CONST, "I32_CONST"); - writeSleb128(OS, OutputOffset, "offset"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + writeU8(os, WASM_OPCODE_I32_CONST, "I32_CONST"); + writeSleb128(os, outputOffset, "offset"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); - Symbol *Sym = File->getSymbol(Rel); + Symbol *sym = file->getSymbol(rel); // Now figure out what we want to store - if (Sym->hasGOTIndex()) { - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, Sym->getGOTIndex(), "global index"); - if (Rel.Addend) { - writeU8(OS, WASM_OPCODE_I32_CONST, "CONST"); - writeSleb128(OS, Rel.Addend, "addend"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + if (sym->hasGOTIndex()) { + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, sym->getGOTIndex(), "global index"); + if (rel.Addend) { + writeU8(os, WASM_OPCODE_I32_CONST, "CONST"); + writeSleb128(os, rel.Addend, "addend"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); } } else { - const GlobalSymbol* BaseSymbol = WasmSym::MemoryBase; - if (Rel.Type == R_WASM_TABLE_INDEX_I32) - BaseSymbol = WasmSym::TableBase; - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, BaseSymbol->getGlobalIndex(), "base"); - writeU8(OS, WASM_OPCODE_I32_CONST, "CONST"); - writeSleb128(OS, File->calcNewValue(Rel), "offset"); - writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + const GlobalSymbol* baseSymbol = WasmSym::memoryBase; + if (rel.Type == R_WASM_TABLE_INDEX_I32) + baseSymbol = WasmSym::tableBase; + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(os, baseSymbol->getGlobalIndex(), "base"); + writeU8(os, WASM_OPCODE_I32_CONST, "CONST"); + writeSleb128(os, file->calcNewValue(rel), "offset"); + writeU8(os, WASM_OPCODE_I32_ADD, "ADD"); } // Store that value at the virtual address - writeU8(OS, WASM_OPCODE_I32_STORE, "I32_STORE"); - writeUleb128(OS, 2, "align"); - writeUleb128(OS, 0, "offset"); + writeU8(os, WASM_OPCODE_I32_STORE, "I32_STORE"); + writeUleb128(os, 2, "align"); + writeUleb128(os, 0, "offset"); } } diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h index b8e4c327323..2d3eb40f807 100644 --- a/lld/wasm/InputChunks.h +++ b/lld/wasm/InputChunks.h @@ -37,15 +37,15 @@ class InputChunk { public: enum Kind { DataSegment, Function, SyntheticFunction, Section }; - Kind kind() const { return SectionKind; } + Kind kind() const { return sectionKind; } virtual uint32_t getSize() const { return data().size(); } virtual uint32_t getInputSize() const { return getSize(); }; - virtual void writeTo(uint8_t *SectionStart) const; + virtual void writeTo(uint8_t *sectionStart) const; - ArrayRef<WasmRelocation> getRelocations() const { return Relocations; } - void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; } + ArrayRef<WasmRelocation> getRelocations() const { return relocations; } + void setRelocations(ArrayRef<WasmRelocation> rs) { relocations = rs; } virtual StringRef getName() const = 0; virtual StringRef getDebugName() const = 0; @@ -53,23 +53,23 @@ public: StringRef getComdatName() const; virtual uint32_t getInputSectionOffset() const = 0; - size_t getNumRelocations() const { return Relocations.size(); } - void writeRelocations(llvm::raw_ostream &OS) const; + size_t getNumRelocations() const { return relocations.size(); } + void writeRelocations(llvm::raw_ostream &os) const; - ObjFile *File; - int32_t OutputOffset = 0; + ObjFile *file; + int32_t outputOffset = 0; // Signals that the section is part of the output. The garbage collector, // and COMDAT handling can set a sections' Live bit. // If GC is disabled, all sections start out as live by default. - unsigned Live : 1; + unsigned live : 1; // Signals the chunk was discarded by COMDAT handling. - unsigned Discarded : 1; + unsigned discarded : 1; protected: - InputChunk(ObjFile *F, Kind K) - : File(F), Live(!Config->GcSections), Discarded(false), SectionKind(K) {} + InputChunk(ObjFile *f, Kind k) + : file(f), live(!config->gcSections), discarded(false), sectionKind(k) {} virtual ~InputChunk() = default; virtual ArrayRef<uint8_t> data() const = 0; @@ -77,8 +77,8 @@ protected: // This is performed only debug builds as an extra sanity check. void verifyRelocTargets() const; - ArrayRef<WasmRelocation> Relocations; - Kind SectionKind; + ArrayRef<WasmRelocation> relocations; + Kind sectionKind; }; // Represents a WebAssembly data segment which can be included as part of @@ -91,65 +91,65 @@ protected: // each global variable. class InputSegment : public InputChunk { public: - InputSegment(const WasmSegment &Seg, ObjFile *F) - : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {} + InputSegment(const WasmSegment &seg, ObjFile *f) + : InputChunk(f, InputChunk::DataSegment), segment(seg) {} - static bool classof(const InputChunk *C) { return C->kind() == DataSegment; } + static bool classof(const InputChunk *c) { return c->kind() == DataSegment; } - void generateRelocationCode(raw_ostream &OS) const; + void generateRelocationCode(raw_ostream &os) const; - uint32_t getAlignment() const { return Segment.Data.Alignment; } - StringRef getName() const override { return Segment.Data.Name; } + uint32_t getAlignment() const { return segment.Data.Alignment; } + StringRef getName() const override { return segment.Data.Name; } StringRef getDebugName() const override { return StringRef(); } - uint32_t getComdat() const override { return Segment.Data.Comdat; } + uint32_t getComdat() const override { return segment.Data.Comdat; } uint32_t getInputSectionOffset() const override { - return Segment.SectionOffset; + return segment.SectionOffset; } - const OutputSegment *OutputSeg = nullptr; - int32_t OutputSegmentOffset = 0; + const OutputSegment *outputSeg = nullptr; + int32_t outputSegmentOffset = 0; protected: - ArrayRef<uint8_t> data() const override { return Segment.Data.Content; } + ArrayRef<uint8_t> data() const override { return segment.Data.Content; } - const WasmSegment &Segment; + const WasmSegment &segment; }; // Represents a single wasm function within and input file. These are // combined to create the final output CODE section. class InputFunction : public InputChunk { public: - InputFunction(const WasmSignature &S, const WasmFunction *Func, ObjFile *F) - : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} + InputFunction(const WasmSignature &s, const WasmFunction *func, ObjFile *f) + : InputChunk(f, InputChunk::Function), signature(s), function(func) {} - static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::Function || - C->kind() == InputChunk::SyntheticFunction; + static bool classof(const InputChunk *c) { + return c->kind() == InputChunk::Function || + c->kind() == InputChunk::SyntheticFunction; } - void writeTo(uint8_t *SectionStart) const override; - StringRef getName() const override { return Function->SymbolName; } - StringRef getDebugName() const override { return Function->DebugName; } - uint32_t getComdat() const override { return Function->Comdat; } + void writeTo(uint8_t *sectionStart) const override; + StringRef getName() const override { return function->SymbolName; } + StringRef getDebugName() const override { return function->DebugName; } + uint32_t getComdat() const override { return function->Comdat; } uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); } - uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; } + uint32_t getFunctionCodeOffset() const { return function->CodeOffset; } uint32_t getSize() const override { - if (Config->CompressRelocations && File) { - assert(CompressedSize); - return CompressedSize; + if (config->compressRelocations && file) { + assert(compressedSize); + return compressedSize; } return data().size(); } - uint32_t getInputSize() const override { return Function->Size; } - uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); } - bool hasFunctionIndex() const { return FunctionIndex.hasValue(); } - void setFunctionIndex(uint32_t Index); + uint32_t getInputSize() const override { return function->Size; } + uint32_t getFunctionIndex() const { return functionIndex.getValue(); } + bool hasFunctionIndex() const { return functionIndex.hasValue(); } + void setFunctionIndex(uint32_t index); uint32_t getInputSectionOffset() const override { - return Function->CodeSectionOffset; + return function->CodeSectionOffset; } - uint32_t getTableIndex() const { return TableIndex.getValue(); } - bool hasTableIndex() const { return TableIndex.hasValue(); } - void setTableIndex(uint32_t Index); + uint32_t getTableIndex() const { return tableIndex.getValue(); } + bool hasTableIndex() const { return tableIndex.hasValue(); } + void setTableIndex(uint32_t index); // The size of a given input function can depend on the values of the // LEB relocations within it. This finalizeContents method is called after @@ -157,76 +157,76 @@ public: // called. void calculateSize(); - const WasmSignature &Signature; + const WasmSignature &signature; protected: ArrayRef<uint8_t> data() const override { - assert(!Config->CompressRelocations); - return File->CodeSection->Content.slice(getInputSectionOffset(), - Function->Size); + assert(!config->compressRelocations); + return file->codeSection->Content.slice(getInputSectionOffset(), + function->Size); } - const WasmFunction *Function; - llvm::Optional<uint32_t> FunctionIndex; - llvm::Optional<uint32_t> TableIndex; - uint32_t CompressedFuncSize = 0; - uint32_t CompressedSize = 0; + const WasmFunction *function; + llvm::Optional<uint32_t> functionIndex; + llvm::Optional<uint32_t> tableIndex; + uint32_t compressedFuncSize = 0; + uint32_t compressedSize = 0; }; class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, StringRef Name, - StringRef DebugName = {}) - : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) { - SectionKind = InputChunk::SyntheticFunction; + SyntheticFunction(const WasmSignature &s, StringRef name, + StringRef debugName = {}) + : InputFunction(s, nullptr, nullptr), name(name), debugName(debugName) { + sectionKind = InputChunk::SyntheticFunction; } - static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::SyntheticFunction; + static bool classof(const InputChunk *c) { + return c->kind() == InputChunk::SyntheticFunction; } - StringRef getName() const override { return Name; } - StringRef getDebugName() const override { return DebugName; } + StringRef getName() const override { return name; } + StringRef getDebugName() const override { return debugName; } uint32_t getComdat() const override { return UINT32_MAX; } - void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; } + void setBody(ArrayRef<uint8_t> body_) { body = body_; } protected: - ArrayRef<uint8_t> data() const override { return Body; } + ArrayRef<uint8_t> data() const override { return body; } - StringRef Name; - StringRef DebugName; - ArrayRef<uint8_t> Body; + StringRef name; + StringRef debugName; + ArrayRef<uint8_t> body; }; // Represents a single Wasm Section within an input file. class InputSection : public InputChunk { public: - InputSection(const WasmSection &S, ObjFile *F) - : InputChunk(F, InputChunk::Section), Section(S) { - assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM); + InputSection(const WasmSection &s, ObjFile *f) + : InputChunk(f, InputChunk::Section), section(s) { + assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM); } - StringRef getName() const override { return Section.Name; } + StringRef getName() const override { return section.Name; } StringRef getDebugName() const override { return StringRef(); } uint32_t getComdat() const override { return UINT32_MAX; } - OutputSection *OutputSec = nullptr; + OutputSection *outputSec = nullptr; protected: - ArrayRef<uint8_t> data() const override { return Section.Content; } + ArrayRef<uint8_t> data() const override { return section.Content; } // Offset within the input section. This is only zero since this chunk // type represents an entire input section, not part of one. uint32_t getInputSectionOffset() const override { return 0; } - const WasmSection &Section; + const WasmSection §ion; }; } // namespace wasm std::string toString(const wasm::InputChunk *); -StringRef relocTypeToString(uint8_t RelocType); +StringRef relocTypeToString(uint8_t relocType); } // namespace lld diff --git a/lld/wasm/InputEvent.h b/lld/wasm/InputEvent.h index 52afc930f70..98cfdf7bfc7 100644 --- a/lld/wasm/InputEvent.h +++ b/lld/wasm/InputEvent.h @@ -28,33 +28,33 @@ namespace wasm { // form the final EVENTS section. class InputEvent { public: - InputEvent(const WasmSignature &S, const WasmEvent &E, ObjFile *F) - : File(F), Event(E), Signature(S), Live(!Config->GcSections) {} + InputEvent(const WasmSignature &s, const WasmEvent &e, ObjFile *f) + : file(f), event(e), signature(s), live(!config->gcSections) {} - StringRef getName() const { return Event.SymbolName; } - const WasmEventType &getType() const { return Event.Type; } + StringRef getName() const { return event.SymbolName; } + const WasmEventType &getType() const { return event.Type; } - uint32_t getEventIndex() const { return EventIndex.getValue(); } - bool hasEventIndex() const { return EventIndex.hasValue(); } - void setEventIndex(uint32_t Index) { + uint32_t getEventIndex() const { return eventIndex.getValue(); } + bool hasEventIndex() const { return eventIndex.hasValue(); } + void setEventIndex(uint32_t index) { assert(!hasEventIndex()); - EventIndex = Index; + eventIndex = index; } - ObjFile *File; - WasmEvent Event; - const WasmSignature &Signature; + ObjFile *file; + WasmEvent event; + const WasmSignature &signature; - bool Live = false; + bool live = false; protected: - llvm::Optional<uint32_t> EventIndex; + llvm::Optional<uint32_t> eventIndex; }; } // namespace wasm -inline std::string toString(const wasm::InputEvent *E) { - return (toString(E->File) + ":(" + E->getName() + ")").str(); +inline std::string toString(const wasm::InputEvent *e) { + return (toString(e->file) + ":(" + e->getName() + ")").str(); } } // namespace lld diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index b3e41a41b5f..b5233cf09ed 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -29,77 +29,77 @@ using namespace llvm; using namespace llvm::object; using namespace llvm::wasm; -std::unique_ptr<llvm::TarWriter> lld::wasm::Tar; +std::unique_ptr<llvm::TarWriter> lld::wasm::tar; -Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) { - log("Loading: " + Path); +Optional<MemoryBufferRef> lld::wasm::readFile(StringRef path) { + log("Loading: " + path); - auto MBOrErr = MemoryBuffer::getFile(Path); - if (auto EC = MBOrErr.getError()) { - error("cannot open " + Path + ": " + EC.message()); + auto mbOrErr = MemoryBuffer::getFile(path); + if (auto ec = mbOrErr.getError()) { + error("cannot open " + path + ": " + ec.message()); return None; } - std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; - MemoryBufferRef MBRef = MB->getMemBufferRef(); - make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership + std::unique_ptr<MemoryBuffer> &mb = *mbOrErr; + MemoryBufferRef mbref = mb->getMemBufferRef(); + make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take MB ownership - if (Tar) - Tar->append(relativeToRoot(Path), MBRef.getBuffer()); - return MBRef; + if (tar) + tar->append(relativeToRoot(path), mbref.getBuffer()); + return mbref; } -InputFile *lld::wasm::createObjectFile(MemoryBufferRef MB, - StringRef ArchiveName) { - file_magic Magic = identify_magic(MB.getBuffer()); - if (Magic == file_magic::wasm_object) { - std::unique_ptr<Binary> Bin = - CHECK(createBinary(MB), MB.getBufferIdentifier()); - auto *Obj = cast<WasmObjectFile>(Bin.get()); - if (Obj->isSharedObject()) - return make<SharedFile>(MB); - return make<ObjFile>(MB, ArchiveName); +InputFile *lld::wasm::createObjectFile(MemoryBufferRef mb, + StringRef archiveName) { + file_magic magic = identify_magic(mb.getBuffer()); + if (magic == file_magic::wasm_object) { + std::unique_ptr<Binary> bin = + CHECK(createBinary(mb), mb.getBufferIdentifier()); + auto *obj = cast<WasmObjectFile>(bin.get()); + if (obj->isSharedObject()) + return make<SharedFile>(mb); + return make<ObjFile>(mb, archiveName); } - if (Magic == file_magic::bitcode) - return make<BitcodeFile>(MB, ArchiveName); + if (magic == file_magic::bitcode) + return make<BitcodeFile>(mb, archiveName); - fatal("unknown file type: " + MB.getBufferIdentifier()); + fatal("unknown file type: " + mb.getBufferIdentifier()); } void ObjFile::dumpInfo() const { log("info for: " + toString(this) + - "\n Symbols : " + Twine(Symbols.size()) + - "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) + - "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()) + - "\n Event Imports : " + Twine(WasmObj->getNumImportedEvents())); + "\n Symbols : " + Twine(symbols.size()) + + "\n Function Imports : " + Twine(wasmObj->getNumImportedFunctions()) + + "\n Global Imports : " + Twine(wasmObj->getNumImportedGlobals()) + + "\n Event Imports : " + Twine(wasmObj->getNumImportedEvents())); } // Relocations contain either symbol or type indices. This function takes a // relocation and returns relocated index (i.e. translates from the input // symbol/type space to the output symbol/type space). -uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { - assert(TypeIsUsed[Reloc.Index]); - return TypeMap[Reloc.Index]; +uint32_t ObjFile::calcNewIndex(const WasmRelocation &reloc) const { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) { + assert(typeIsUsed[reloc.Index]); + return typeMap[reloc.Index]; } - const Symbol *Sym = Symbols[Reloc.Index]; - if (auto *SS = dyn_cast<SectionSymbol>(Sym)) - Sym = SS->getOutputSectionSymbol(); - return Sym->getOutputSymbolIndex(); + const Symbol *sym = symbols[reloc.Index]; + if (auto *ss = dyn_cast<SectionSymbol>(sym)) + sym = ss->getOutputSectionSymbol(); + return sym->getOutputSymbolIndex(); } // Relocations can contain addend for combined sections. This function takes a // relocation and returns updated addend by offset in the output section. -uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const { - switch (Reloc.Type) { +uint32_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const { + switch (reloc.Type) { case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_REL_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_FUNCTION_OFFSET_I32: - return Reloc.Addend; + return reloc.Addend; case R_WASM_SECTION_OFFSET_I32: - return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; + return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend; default: llvm_unreachable("unexpected relocation type"); } @@ -108,42 +108,42 @@ uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const { // Calculate the value we expect to find at the relocation location. // This is used as a sanity check before applying a relocation to a given // location. It is useful for catching bugs in the compiler and linker. -uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { - switch (Reloc.Type) { +uint32_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - return TableEntries[Sym.Info.ElementIndex]; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + return tableEntries[sym.Info.ElementIndex]; } case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_REL_SLEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - if (Sym.isUndefined()) + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + if (sym.isUndefined()) return 0; - const WasmSegment &Segment = - WasmObj->dataSegments()[Sym.Info.DataRef.Segment]; - return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset + - Reloc.Addend; + const WasmSegment &segment = + wasmObj->dataSegments()[sym.Info.DataRef.Segment]; + return segment.Data.Offset.Value.Int32 + sym.Info.DataRef.Offset + + reloc.Addend; } case R_WASM_FUNCTION_OFFSET_I32: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - InputFunction *F = - Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()]; - return F->getFunctionInputOffset() + F->getFunctionCodeOffset() + - Reloc.Addend; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + InputFunction *f = + functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()]; + return f->getFunctionInputOffset() + f->getFunctionCodeOffset() + + reloc.Addend; } case R_WASM_SECTION_OFFSET_I32: - return Reloc.Addend; + return reloc.Addend; case R_WASM_TYPE_INDEX_LEB: - return Reloc.Index; + return reloc.Index; case R_WASM_FUNCTION_INDEX_LEB: case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: { - const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; - return Sym.Info.ElementIndex; + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + return sym.Info.ElementIndex; } default: llvm_unreachable("unknown relocation type"); @@ -151,115 +151,115 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { } // Translate from the relocation's index into the final linked output value. -uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const { - const Symbol* Sym = nullptr; - if (Reloc.Type != R_WASM_TYPE_INDEX_LEB) { - Sym = Symbols[Reloc.Index]; +uint32_t ObjFile::calcNewValue(const WasmRelocation &reloc) const { + const Symbol* sym = nullptr; + if (reloc.Type != R_WASM_TYPE_INDEX_LEB) { + sym = symbols[reloc.Index]; // We can end up with relocations against non-live symbols. For example // in debug sections. - if ((isa<FunctionSymbol>(Sym) || isa<DataSymbol>(Sym)) && !Sym->isLive()) + if ((isa<FunctionSymbol>(sym) || isa<DataSymbol>(sym)) && !sym->isLive()) return 0; } - switch (Reloc.Type) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: - if (Config->Pic && !getFunctionSymbol(Reloc.Index)->hasTableIndex()) + if (config->isPic && !getFunctionSymbol(reloc.Index)->hasTableIndex()) return 0; - return getFunctionSymbol(Reloc.Index)->getTableIndex(); + return getFunctionSymbol(reloc.Index)->getTableIndex(); case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: case R_WASM_MEMORY_ADDR_REL_SLEB: - if (isa<UndefinedData>(Sym)) + if (isa<UndefinedData>(sym)) return 0; - return cast<DefinedData>(Sym)->getVirtualAddress() + Reloc.Addend; + return cast<DefinedData>(sym)->getVirtualAddress() + reloc.Addend; case R_WASM_TYPE_INDEX_LEB: - return TypeMap[Reloc.Index]; + return typeMap[reloc.Index]; case R_WASM_FUNCTION_INDEX_LEB: - return getFunctionSymbol(Reloc.Index)->getFunctionIndex(); + return getFunctionSymbol(reloc.Index)->getFunctionIndex(); case R_WASM_GLOBAL_INDEX_LEB: - if (auto GS = dyn_cast<GlobalSymbol>(Sym)) - return GS->getGlobalIndex(); - return Sym->getGOTIndex(); + if (auto gs = dyn_cast<GlobalSymbol>(sym)) + return gs->getGlobalIndex(); + return sym->getGOTIndex(); case R_WASM_EVENT_INDEX_LEB: - return getEventSymbol(Reloc.Index)->getEventIndex(); + return getEventSymbol(reloc.Index)->getEventIndex(); case R_WASM_FUNCTION_OFFSET_I32: { - auto *F = cast<DefinedFunction>(Sym); - return F->Function->OutputOffset + F->Function->getFunctionCodeOffset() + - Reloc.Addend; + auto *f = cast<DefinedFunction>(sym); + return f->function->outputOffset + f->function->getFunctionCodeOffset() + + reloc.Addend; } case R_WASM_SECTION_OFFSET_I32: - return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; + return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend; default: llvm_unreachable("unknown relocation type"); } } template <class T> -static void setRelocs(const std::vector<T *> &Chunks, - const WasmSection *Section) { - if (!Section) +static void setRelocs(const std::vector<T *> &chunks, + const WasmSection *section) { + if (!section) return; - ArrayRef<WasmRelocation> Relocs = Section->Relocations; - assert(std::is_sorted(Relocs.begin(), Relocs.end(), - [](const WasmRelocation &R1, const WasmRelocation &R2) { - return R1.Offset < R2.Offset; + ArrayRef<WasmRelocation> relocs = section->Relocations; + assert(std::is_sorted(relocs.begin(), relocs.end(), + [](const WasmRelocation &r1, const WasmRelocation &r2) { + return r1.Offset < r2.Offset; })); assert(std::is_sorted( - Chunks.begin(), Chunks.end(), [](InputChunk *C1, InputChunk *C2) { - return C1->getInputSectionOffset() < C2->getInputSectionOffset(); + chunks.begin(), chunks.end(), [](InputChunk *c1, InputChunk *c2) { + return c1->getInputSectionOffset() < c2->getInputSectionOffset(); })); - auto RelocsNext = Relocs.begin(); - auto RelocsEnd = Relocs.end(); - auto RelocLess = [](const WasmRelocation &R, uint32_t Val) { - return R.Offset < Val; + auto relocsNext = relocs.begin(); + auto relocsEnd = relocs.end(); + auto relocLess = [](const WasmRelocation &r, uint32_t val) { + return r.Offset < val; }; - for (InputChunk *C : Chunks) { - auto RelocsStart = std::lower_bound(RelocsNext, RelocsEnd, - C->getInputSectionOffset(), RelocLess); - RelocsNext = std::lower_bound( - RelocsStart, RelocsEnd, C->getInputSectionOffset() + C->getInputSize(), - RelocLess); - C->setRelocations(ArrayRef<WasmRelocation>(RelocsStart, RelocsNext)); + for (InputChunk *c : chunks) { + auto relocsStart = std::lower_bound(relocsNext, relocsEnd, + c->getInputSectionOffset(), relocLess); + relocsNext = std::lower_bound( + relocsStart, relocsEnd, c->getInputSectionOffset() + c->getInputSize(), + relocLess); + c->setRelocations(ArrayRef<WasmRelocation>(relocsStart, relocsNext)); } } -void ObjFile::parse(bool IgnoreComdats) { +void ObjFile::parse(bool ignoreComdats) { // Parse a memory buffer as a wasm file. LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); - std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this)); + std::unique_ptr<Binary> bin = CHECK(createBinary(mb), toString(this)); - auto *Obj = dyn_cast<WasmObjectFile>(Bin.get()); - if (!Obj) + auto *obj = dyn_cast<WasmObjectFile>(bin.get()); + if (!obj) fatal(toString(this) + ": not a wasm file"); - if (!Obj->isRelocatableObject()) + if (!obj->isRelocatableObject()) fatal(toString(this) + ": not a relocatable wasm file"); - Bin.release(); - WasmObj.reset(Obj); + bin.release(); + wasmObj.reset(obj); // Build up a map of function indices to table indices for use when // verifying the existing table index relocations - uint32_t TotalFunctions = - WasmObj->getNumImportedFunctions() + WasmObj->functions().size(); - TableEntries.resize(TotalFunctions); - for (const WasmElemSegment &Seg : WasmObj->elements()) { - if (Seg.Offset.Opcode != WASM_OPCODE_I32_CONST) + uint32_t totalFunctions = + wasmObj->getNumImportedFunctions() + wasmObj->functions().size(); + tableEntries.resize(totalFunctions); + for (const WasmElemSegment &seg : wasmObj->elements()) { + if (seg.Offset.Opcode != WASM_OPCODE_I32_CONST) fatal(toString(this) + ": invalid table elements"); - uint32_t Offset = Seg.Offset.Value.Int32; - for (uint32_t Index = 0; Index < Seg.Functions.size(); Index++) { + uint32_t offset = seg.Offset.Value.Int32; + for (uint32_t index = 0; index < seg.Functions.size(); index++) { - uint32_t FunctionIndex = Seg.Functions[Index]; - TableEntries[FunctionIndex] = Offset + Index; + uint32_t functionIndex = seg.Functions[index]; + tableEntries[functionIndex] = offset + index; } } - uint32_t SectionIndex = 0; + uint32_t sectionIndex = 0; // Bool for each symbol, true if called directly. This allows us to implement // a weaker form of signature checking where undefined functions that are not @@ -267,185 +267,185 @@ void ObjFile::parse(bool IgnoreComdats) { // function's signature. We cannot do this for directly called functions // because those signatures are checked at validation times. // See https://bugs.llvm.org/show_bug.cgi?id=40412 - std::vector<bool> IsCalledDirectly(WasmObj->getNumberOfSymbols(), false); - for (const SectionRef &Sec : WasmObj->sections()) { - const WasmSection &Section = WasmObj->getWasmSection(Sec); + std::vector<bool> isCalledDirectly(wasmObj->getNumberOfSymbols(), false); + for (const SectionRef &sec : wasmObj->sections()) { + const WasmSection §ion = wasmObj->getWasmSection(sec); // Wasm objects can have at most one code and one data section. - if (Section.Type == WASM_SEC_CODE) { - assert(!CodeSection); - CodeSection = &Section; - } else if (Section.Type == WASM_SEC_DATA) { - assert(!DataSection); - DataSection = &Section; - } else if (Section.Type == WASM_SEC_CUSTOM) { - CustomSections.emplace_back(make<InputSection>(Section, this)); - CustomSections.back()->setRelocations(Section.Relocations); - CustomSectionsByIndex[SectionIndex] = CustomSections.back(); + if (section.Type == WASM_SEC_CODE) { + assert(!codeSection); + codeSection = §ion; + } else if (section.Type == WASM_SEC_DATA) { + assert(!dataSection); + dataSection = §ion; + } else if (section.Type == WASM_SEC_CUSTOM) { + customSections.emplace_back(make<InputSection>(section, this)); + customSections.back()->setRelocations(section.Relocations); + customSectionsByIndex[sectionIndex] = customSections.back(); } - SectionIndex++; + sectionIndex++; // Scans relocations to dermine determine if a function symbol is called // directly - for (const WasmRelocation &Reloc : Section.Relocations) - if (Reloc.Type == R_WASM_FUNCTION_INDEX_LEB) - IsCalledDirectly[Reloc.Index] = true; + for (const WasmRelocation &reloc : section.Relocations) + if (reloc.Type == R_WASM_FUNCTION_INDEX_LEB) + isCalledDirectly[reloc.Index] = true; } - TypeMap.resize(getWasmObj()->types().size()); - TypeIsUsed.resize(getWasmObj()->types().size(), false); + typeMap.resize(getWasmObj()->types().size()); + typeIsUsed.resize(getWasmObj()->types().size(), false); - ArrayRef<StringRef> Comdats = WasmObj->linkingData().Comdats; - for (StringRef Comdat : Comdats) { - bool IsNew = IgnoreComdats || Symtab->addComdat(Comdat); - KeptComdats.push_back(IsNew); + ArrayRef<StringRef> comdats = wasmObj->linkingData().Comdats; + for (StringRef comdat : comdats) { + bool isNew = ignoreComdats || symtab->addComdat(comdat); + keptComdats.push_back(isNew); } // Populate `Segments`. - for (const WasmSegment &S : WasmObj->dataSegments()) { - auto* Seg = make<InputSegment>(S, this); - Seg->Discarded = isExcludedByComdat(Seg); - Segments.emplace_back(Seg); + for (const WasmSegment &s : wasmObj->dataSegments()) { + auto* seg = make<InputSegment>(s, this); + seg->discarded = isExcludedByComdat(seg); + segments.emplace_back(seg); } - setRelocs(Segments, DataSection); + setRelocs(segments, dataSection); // Populate `Functions`. - ArrayRef<WasmFunction> Funcs = WasmObj->functions(); - ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes(); - ArrayRef<WasmSignature> Types = WasmObj->types(); - Functions.reserve(Funcs.size()); - - for (size_t I = 0, E = Funcs.size(); I != E; ++I) { - auto* Func = make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this); - Func->Discarded = isExcludedByComdat(Func); - Functions.emplace_back(Func); + ArrayRef<WasmFunction> funcs = wasmObj->functions(); + ArrayRef<uint32_t> funcTypes = wasmObj->functionTypes(); + ArrayRef<WasmSignature> types = wasmObj->types(); + functions.reserve(funcs.size()); + + for (size_t i = 0, e = funcs.size(); i != e; ++i) { + auto* func = make<InputFunction>(types[funcTypes[i]], &funcs[i], this); + func->discarded = isExcludedByComdat(func); + functions.emplace_back(func); } - setRelocs(Functions, CodeSection); + setRelocs(functions, codeSection); // Populate `Globals`. - for (const WasmGlobal &G : WasmObj->globals()) - Globals.emplace_back(make<InputGlobal>(G, this)); + for (const WasmGlobal &g : wasmObj->globals()) + globals.emplace_back(make<InputGlobal>(g, this)); // Populate `Events`. - for (const WasmEvent &E : WasmObj->events()) - Events.emplace_back(make<InputEvent>(Types[E.Type.SigIndex], E, this)); + for (const WasmEvent &e : wasmObj->events()) + events.emplace_back(make<InputEvent>(types[e.Type.SigIndex], e, this)); // Populate `Symbols` based on the WasmSymbols in the object. - Symbols.reserve(WasmObj->getNumberOfSymbols()); - for (const SymbolRef &Sym : WasmObj->symbols()) { - const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl()); - if (WasmSym.isDefined()) { + symbols.reserve(wasmObj->getNumberOfSymbols()); + for (const SymbolRef &sym : wasmObj->symbols()) { + const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl()); + if (wasmSym.isDefined()) { // createDefined may fail if the symbol is comdat excluded in which case // we fall back to creating an undefined symbol - if (Symbol *D = createDefined(WasmSym)) { - Symbols.push_back(D); + if (Symbol *d = createDefined(wasmSym)) { + symbols.push_back(d); continue; } } - size_t Idx = Symbols.size(); - Symbols.push_back(createUndefined(WasmSym, IsCalledDirectly[Idx])); + size_t idx = symbols.size(); + symbols.push_back(createUndefined(wasmSym, isCalledDirectly[idx])); } } -bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const { - uint32_t C = Chunk->getComdat(); - if (C == UINT32_MAX) +bool ObjFile::isExcludedByComdat(InputChunk *chunk) const { + uint32_t c = chunk->getComdat(); + if (c == UINT32_MAX) return false; - return !KeptComdats[C]; + return !keptComdats[c]; } -FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const { - return cast<FunctionSymbol>(Symbols[Index]); +FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t index) const { + return cast<FunctionSymbol>(symbols[index]); } -GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const { - return cast<GlobalSymbol>(Symbols[Index]); +GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t index) const { + return cast<GlobalSymbol>(symbols[index]); } -EventSymbol *ObjFile::getEventSymbol(uint32_t Index) const { - return cast<EventSymbol>(Symbols[Index]); +EventSymbol *ObjFile::getEventSymbol(uint32_t index) const { + return cast<EventSymbol>(symbols[index]); } -SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const { - return cast<SectionSymbol>(Symbols[Index]); +SectionSymbol *ObjFile::getSectionSymbol(uint32_t index) const { + return cast<SectionSymbol>(symbols[index]); } -DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const { - return cast<DataSymbol>(Symbols[Index]); +DataSymbol *ObjFile::getDataSymbol(uint32_t index) const { + return cast<DataSymbol>(symbols[index]); } -Symbol *ObjFile::createDefined(const WasmSymbol &Sym) { - StringRef Name = Sym.Info.Name; - uint32_t Flags = Sym.Info.Flags; +Symbol *ObjFile::createDefined(const WasmSymbol &sym) { + StringRef name = sym.Info.Name; + uint32_t flags = sym.Info.Flags; - switch (Sym.Info.Kind) { + switch (sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: { - InputFunction *Func = - Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()]; - if (Func->Discarded) + InputFunction *func = + functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()]; + if (func->discarded) return nullptr; - if (Sym.isBindingLocal()) - return make<DefinedFunction>(Name, Flags, this, Func); - return Symtab->addDefinedFunction(Name, Flags, this, Func); + if (sym.isBindingLocal()) + return make<DefinedFunction>(name, flags, this, func); + return symtab->addDefinedFunction(name, flags, this, func); } case WASM_SYMBOL_TYPE_DATA: { - InputSegment *Seg = Segments[Sym.Info.DataRef.Segment]; - if (Seg->Discarded) + InputSegment *seg = segments[sym.Info.DataRef.Segment]; + if (seg->discarded) return nullptr; - uint32_t Offset = Sym.Info.DataRef.Offset; - uint32_t Size = Sym.Info.DataRef.Size; + uint32_t offset = sym.Info.DataRef.Offset; + uint32_t size = sym.Info.DataRef.Size; - if (Sym.isBindingLocal()) - return make<DefinedData>(Name, Flags, this, Seg, Offset, Size); - return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size); + if (sym.isBindingLocal()) + return make<DefinedData>(name, flags, this, seg, offset, size); + return symtab->addDefinedData(name, flags, this, seg, offset, size); } case WASM_SYMBOL_TYPE_GLOBAL: { - InputGlobal *Global = - Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()]; - if (Sym.isBindingLocal()) - return make<DefinedGlobal>(Name, Flags, this, Global); - return Symtab->addDefinedGlobal(Name, Flags, this, Global); + InputGlobal *global = + globals[sym.Info.ElementIndex - wasmObj->getNumImportedGlobals()]; + if (sym.isBindingLocal()) + return make<DefinedGlobal>(name, flags, this, global); + return symtab->addDefinedGlobal(name, flags, this, global); } case WASM_SYMBOL_TYPE_SECTION: { - InputSection *Section = CustomSectionsByIndex[Sym.Info.ElementIndex]; - assert(Sym.isBindingLocal()); - return make<SectionSymbol>(Flags, Section, this); + InputSection *section = customSectionsByIndex[sym.Info.ElementIndex]; + assert(sym.isBindingLocal()); + return make<SectionSymbol>(flags, section, this); } case WASM_SYMBOL_TYPE_EVENT: { - InputEvent *Event = - Events[Sym.Info.ElementIndex - WasmObj->getNumImportedEvents()]; - if (Sym.isBindingLocal()) - return make<DefinedEvent>(Name, Flags, this, Event); - return Symtab->addDefinedEvent(Name, Flags, this, Event); + InputEvent *event = + events[sym.Info.ElementIndex - wasmObj->getNumImportedEvents()]; + if (sym.isBindingLocal()) + return make<DefinedEvent>(name, flags, this, event); + return symtab->addDefinedEvent(name, flags, this, event); } } llvm_unreachable("unknown symbol kind"); } -Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly) { - StringRef Name = Sym.Info.Name; - uint32_t Flags = Sym.Info.Flags; +Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) { + StringRef name = sym.Info.Name; + uint32_t flags = sym.Info.Flags; - switch (Sym.Info.Kind) { + switch (sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - if (Sym.isBindingLocal()) - return make<UndefinedFunction>(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.Signature, IsCalledDirectly); - return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.Signature, IsCalledDirectly); + if (sym.isBindingLocal()) + return make<UndefinedFunction>(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.Signature, isCalledDirectly); + return symtab->addUndefinedFunction(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.Signature, isCalledDirectly); case WASM_SYMBOL_TYPE_DATA: - if (Sym.isBindingLocal()) - return make<UndefinedData>(Name, Flags, this); - return Symtab->addUndefinedData(Name, Flags, this); + if (sym.isBindingLocal()) + return make<UndefinedData>(name, flags, this); + return symtab->addUndefinedData(name, flags, this); case WASM_SYMBOL_TYPE_GLOBAL: - if (Sym.isBindingLocal()) - return make<UndefinedGlobal>(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.GlobalType); - return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName, - Sym.Info.ImportModule, Flags, this, - Sym.GlobalType); + if (sym.isBindingLocal()) + return make<UndefinedGlobal>(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.GlobalType); + return symtab->addUndefinedGlobal(name, sym.Info.ImportName, + sym.Info.ImportModule, flags, this, + sym.GlobalType); case WASM_SYMBOL_TYPE_SECTION: llvm_unreachable("section symbols cannot be undefined"); } @@ -455,41 +455,41 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly) { void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); - File = CHECK(Archive::create(MB), toString(this)); + file = CHECK(Archive::create(mb), toString(this)); // Read the symbol table to construct Lazy symbols. - int Count = 0; - for (const Archive::Symbol &Sym : File->symbols()) { - Symtab->addLazy(this, &Sym); - ++Count; + int count = 0; + for (const Archive::Symbol &sym : file->symbols()) { + symtab->addLazy(this, &sym); + ++count; } - LLVM_DEBUG(dbgs() << "Read " << Count << " symbols\n"); + LLVM_DEBUG(dbgs() << "Read " << count << " symbols\n"); } -void ArchiveFile::addMember(const Archive::Symbol *Sym) { - const Archive::Child &C = - CHECK(Sym->getMember(), - "could not get the member for symbol " + Sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol *sym) { + const Archive::Child &c = + CHECK(sym->getMember(), + "could not get the member for symbol " + sym->getName()); // Don't try to load the same member twice (this can happen when members // mutually reference each other). - if (!Seen.insert(C.getChildOffset()).second) + if (!seen.insert(c.getChildOffset()).second) return; - LLVM_DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n"); + LLVM_DEBUG(dbgs() << "loading lazy: " << sym->getName() << "\n"); LLVM_DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); - MemoryBufferRef MB = - CHECK(C.getMemoryBufferRef(), + MemoryBufferRef mb = + CHECK(c.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + - Sym->getName()); + sym->getName()); - InputFile *Obj = createObjectFile(MB, getName()); - Symtab->addFile(Obj); + InputFile *obj = createObjectFile(mb, getName()); + symtab->addFile(obj); } -static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { - switch (GvVisibility) { +static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) { + switch (gvVisibility) { case GlobalValue::DefaultVisibility: return WASM_SYMBOL_VISIBILITY_DEFAULT; case GlobalValue::HiddenVisibility: @@ -499,52 +499,52 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { llvm_unreachable("unknown visibility"); } -static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, - const lto::InputFile::Symbol &ObjSym, - BitcodeFile &F) { - StringRef Name = Saver.save(ObjSym.getName()); +static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats, + const lto::InputFile::Symbol &objSym, + BitcodeFile &f) { + StringRef name = saver.save(objSym.getName()); - uint32_t Flags = ObjSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0; - Flags |= mapVisibility(ObjSym.getVisibility()); + uint32_t flags = objSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0; + flags |= mapVisibility(objSym.getVisibility()); - int C = ObjSym.getComdatIndex(); - bool ExcludedByComdat = C != -1 && !KeptComdats[C]; + int c = objSym.getComdatIndex(); + bool excludedByComdat = c != -1 && !keptComdats[c]; - if (ObjSym.isUndefined() || ExcludedByComdat) { - if (ObjSym.isExecutable()) - return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F, + if (objSym.isUndefined() || excludedByComdat) { + if (objSym.isExecutable()) + return symtab->addUndefinedFunction(name, name, defaultModule, flags, &f, nullptr, true); - return Symtab->addUndefinedData(Name, Flags, &F); + return symtab->addUndefinedData(name, flags, &f); } - if (ObjSym.isExecutable()) - return Symtab->addDefinedFunction(Name, Flags, &F, nullptr); - return Symtab->addDefinedData(Name, Flags, &F, nullptr, 0, 0); + if (objSym.isExecutable()) + return symtab->addDefinedFunction(name, flags, &f, nullptr); + return symtab->addDefinedData(name, flags, &f, nullptr, 0, 0); } void BitcodeFile::parse() { - Obj = check(lto::InputFile::create(MemoryBufferRef( - MB.getBuffer(), Saver.save(ArchiveName + MB.getBufferIdentifier())))); - Triple T(Obj->getTargetTriple()); - if (T.getArch() != Triple::wasm32) { - error(toString(MB.getBufferIdentifier()) + ": machine type must be wasm32"); + obj = check(lto::InputFile::create(MemoryBufferRef( + mb.getBuffer(), saver.save(archiveName + mb.getBufferIdentifier())))); + Triple t(obj->getTargetTriple()); + if (t.getArch() != Triple::wasm32) { + error(toString(mb.getBufferIdentifier()) + ": machine type must be wasm32"); return; } - std::vector<bool> KeptComdats; - for (StringRef S : Obj->getComdatTable()) - KeptComdats.push_back(Symtab->addComdat(S)); + std::vector<bool> keptComdats; + for (StringRef s : obj->getComdatTable()) + keptComdats.push_back(symtab->addComdat(s)); - for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) - Symbols.push_back(createBitcodeSymbol(KeptComdats, ObjSym, *this)); + for (const lto::InputFile::Symbol &objSym : obj->symbols()) + symbols.push_back(createBitcodeSymbol(keptComdats, objSym, *this)); } // Returns a string in the format of "foo.o" or "foo.a(bar.o)". -std::string lld::toString(const wasm::InputFile *File) { - if (!File) +std::string lld::toString(const wasm::InputFile *file) { + if (!file) return "<internal>"; - if (File->ArchiveName.empty()) - return File->getName(); + if (file->archiveName.empty()) + return file->getName(); - return (File->ArchiveName + "(" + File->getName() + ")").str(); + return (file->archiveName + "(" + file->getName() + ")").str(); } diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h index 57d36a8dc2a..2b25906f443 100644 --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -35,7 +35,7 @@ class InputSection; // If --reproduce option is given, all input files are written // to this tar archive. -extern std::unique_ptr<llvm::TarWriter> Tar; +extern std::unique_ptr<llvm::TarWriter> tar; class InputFile { public: @@ -49,129 +49,129 @@ public: virtual ~InputFile() {} // Returns the filename. - StringRef getName() const { return MB.getBufferIdentifier(); } + StringRef getName() const { return mb.getBufferIdentifier(); } - Kind kind() const { return FileKind; } + Kind kind() const { return fileKind; } // An archive file name if this file is created from an archive. - StringRef ArchiveName; + StringRef archiveName; - ArrayRef<Symbol *> getSymbols() const { return Symbols; } + ArrayRef<Symbol *> getSymbols() const { return symbols; } - MutableArrayRef<Symbol *> getMutableSymbols() { return Symbols; } + MutableArrayRef<Symbol *> getMutableSymbols() { return symbols; } protected: - InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} - MemoryBufferRef MB; + InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {} + MemoryBufferRef mb; // List of all symbols referenced or defined by this file. - std::vector<Symbol *> Symbols; + std::vector<Symbol *> symbols; private: - const Kind FileKind; + const Kind fileKind; }; // .a file (ar archive) class ArchiveFile : public InputFile { public: - explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } + explicit ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {} + static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; } - void addMember(const llvm::object::Archive::Symbol *Sym); + void addMember(const llvm::object::Archive::Symbol *sym); void parse(); private: - std::unique_ptr<llvm::object::Archive> File; - llvm::DenseSet<uint64_t> Seen; + std::unique_ptr<llvm::object::Archive> file; + llvm::DenseSet<uint64_t> seen; }; // .o file (wasm object file) class ObjFile : public InputFile { public: - explicit ObjFile(MemoryBufferRef M, StringRef ArchiveName) - : InputFile(ObjectKind, M) { - this->ArchiveName = ArchiveName; + explicit ObjFile(MemoryBufferRef m, StringRef archiveName) + : InputFile(ObjectKind, m) { + this->archiveName = archiveName; } - static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } + static bool classof(const InputFile *f) { return f->kind() == ObjectKind; } - void parse(bool IgnoreComdats = false); + void parse(bool ignoreComdats = false); // Returns the underlying wasm file. - const WasmObjectFile *getWasmObj() const { return WasmObj.get(); } + const WasmObjectFile *getWasmObj() const { return wasmObj.get(); } void dumpInfo() const; - uint32_t calcNewIndex(const WasmRelocation &Reloc) const; - uint32_t calcNewValue(const WasmRelocation &Reloc) const; - uint32_t calcNewAddend(const WasmRelocation &Reloc) const; - uint32_t calcExpectedValue(const WasmRelocation &Reloc) const; - Symbol *getSymbol(const WasmRelocation &Reloc) const { - return Symbols[Reloc.Index]; + uint32_t calcNewIndex(const WasmRelocation &reloc) const; + uint32_t calcNewValue(const WasmRelocation &reloc) const; + uint32_t calcNewAddend(const WasmRelocation &reloc) const; + uint32_t calcExpectedValue(const WasmRelocation &reloc) const; + Symbol *getSymbol(const WasmRelocation &reloc) const { + return symbols[reloc.Index]; }; - const WasmSection *CodeSection = nullptr; - const WasmSection *DataSection = nullptr; + const WasmSection *codeSection = nullptr; + const WasmSection *dataSection = nullptr; // Maps input type indices to output type indices - std::vector<uint32_t> TypeMap; - std::vector<bool> TypeIsUsed; + std::vector<uint32_t> typeMap; + std::vector<bool> typeIsUsed; // Maps function indices to table indices - std::vector<uint32_t> TableEntries; - std::vector<bool> KeptComdats; - std::vector<InputSegment *> Segments; - std::vector<InputFunction *> Functions; - std::vector<InputGlobal *> Globals; - std::vector<InputEvent *> Events; - std::vector<InputSection *> CustomSections; - llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex; - - Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; } - FunctionSymbol *getFunctionSymbol(uint32_t Index) const; - DataSymbol *getDataSymbol(uint32_t Index) const; - GlobalSymbol *getGlobalSymbol(uint32_t Index) const; - SectionSymbol *getSectionSymbol(uint32_t Index) const; - EventSymbol *getEventSymbol(uint32_t Index) const; + std::vector<uint32_t> tableEntries; + std::vector<bool> keptComdats; + std::vector<InputSegment *> segments; + std::vector<InputFunction *> functions; + std::vector<InputGlobal *> globals; + std::vector<InputEvent *> events; + std::vector<InputSection *> customSections; + llvm::DenseMap<uint32_t, InputSection *> customSectionsByIndex; + + Symbol *getSymbol(uint32_t index) const { return symbols[index]; } + FunctionSymbol *getFunctionSymbol(uint32_t index) const; + DataSymbol *getDataSymbol(uint32_t index) const; + GlobalSymbol *getGlobalSymbol(uint32_t index) const; + SectionSymbol *getSectionSymbol(uint32_t index) const; + EventSymbol *getEventSymbol(uint32_t index) const; private: - Symbol *createDefined(const WasmSymbol &Sym); - Symbol *createUndefined(const WasmSymbol &Sym, bool IsCalledDirectly); + Symbol *createDefined(const WasmSymbol &sym); + Symbol *createUndefined(const WasmSymbol &sym, bool isCalledDirectly); - bool isExcludedByComdat(InputChunk *Chunk) const; + bool isExcludedByComdat(InputChunk *chunk) const; - std::unique_ptr<WasmObjectFile> WasmObj; + std::unique_ptr<WasmObjectFile> wasmObj; }; // .so file. class SharedFile : public InputFile { public: - explicit SharedFile(MemoryBufferRef M) : InputFile(SharedKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == SharedKind; } + explicit SharedFile(MemoryBufferRef m) : InputFile(SharedKind, m) {} + static bool classof(const InputFile *f) { return f->kind() == SharedKind; } }; // .bc file class BitcodeFile : public InputFile { public: - explicit BitcodeFile(MemoryBufferRef M, StringRef ArchiveName) - : InputFile(BitcodeKind, M) { - this->ArchiveName = ArchiveName; + explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName) + : InputFile(BitcodeKind, m) { + this->archiveName = archiveName; } - static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } + static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } void parse(); - std::unique_ptr<llvm::lto::InputFile> Obj; + std::unique_ptr<llvm::lto::InputFile> obj; }; // Will report a fatal() error if the input buffer is not a valid bitcode // or wasm object file. -InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = ""); +InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = ""); // Opens a given file. -llvm::Optional<MemoryBufferRef> readFile(StringRef Path); +llvm::Optional<MemoryBufferRef> readFile(StringRef path); } // namespace wasm -std::string toString(const wasm::InputFile *File); +std::string toString(const wasm::InputFile *file); } // namespace lld diff --git a/lld/wasm/InputGlobal.h b/lld/wasm/InputGlobal.h index e008d2ecc3f..89cde8423c8 100644 --- a/lld/wasm/InputGlobal.h +++ b/lld/wasm/InputGlobal.h @@ -22,32 +22,32 @@ namespace wasm { // combined to form the final GLOBALS section. class InputGlobal { public: - InputGlobal(const WasmGlobal &G, ObjFile *F) - : File(F), Global(G), Live(!Config->GcSections) {} + InputGlobal(const WasmGlobal &g, ObjFile *f) + : file(f), global(g), live(!config->gcSections) {} - StringRef getName() const { return Global.SymbolName; } - const WasmGlobalType &getType() const { return Global.Type; } + StringRef getName() const { return global.SymbolName; } + const WasmGlobalType &getType() const { return global.Type; } - uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); } - bool hasGlobalIndex() const { return GlobalIndex.hasValue(); } - void setGlobalIndex(uint32_t Index) { + uint32_t getGlobalIndex() const { return globalIndex.getValue(); } + bool hasGlobalIndex() const { return globalIndex.hasValue(); } + void setGlobalIndex(uint32_t index) { assert(!hasGlobalIndex()); - GlobalIndex = Index; + globalIndex = index; } - ObjFile *File; - WasmGlobal Global; + ObjFile *file; + WasmGlobal global; - bool Live = false; + bool live = false; protected: - llvm::Optional<uint32_t> GlobalIndex; + llvm::Optional<uint32_t> globalIndex; }; } // namespace wasm -inline std::string toString(const wasm::InputGlobal *G) { - return (toString(G->File) + ":(" + G->getName() + ")").str(); +inline std::string toString(const wasm::InputGlobal *g) { + return (toString(g->file) + ":(" + g->getName() + ")").str(); } } // namespace lld diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 0c42e0e2123..fa48f4db7fd 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -40,127 +40,127 @@ using namespace lld; using namespace lld::wasm; static std::unique_ptr<lto::LTO> createLTO() { - lto::Config C; - C.Options = initTargetOptionsFromCodeGenFlags(); + lto::Config c; + c.Options = initTargetOptionsFromCodeGenFlags(); // Always emit a section per function/data with LTO. - C.Options.FunctionSections = true; - C.Options.DataSections = true; - - C.DisableVerify = Config->DisableVerify; - C.DiagHandler = diagnosticHandler; - C.OptLevel = Config->LTOO; - C.MAttrs = getMAttrs(); - C.CGOptLevel = args::getCGOptLevel(Config->LTOO); - - if (Config->Relocatable) - C.RelocModel = None; - else if (Config->Pic) - C.RelocModel = Reloc::PIC_; + c.Options.FunctionSections = true; + c.Options.DataSections = true; + + c.DisableVerify = config->disableVerify; + c.DiagHandler = diagnosticHandler; + c.OptLevel = config->ltoo; + c.MAttrs = getMAttrs(); + c.CGOptLevel = args::getCGOptLevel(config->ltoo); + + if (config->relocatable) + c.RelocModel = None; + else if (config->isPic) + c.RelocModel = Reloc::PIC_; else - C.RelocModel = Reloc::Static; + c.RelocModel = Reloc::Static; - if (Config->SaveTemps) - checkError(C.addSaveTemps(Config->OutputFile.str() + ".", + if (config->saveTemps) + checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath*/ true)); - lto::ThinBackend Backend; - if (Config->ThinLTOJobs != -1U) - Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); - return llvm::make_unique<lto::LTO>(std::move(C), Backend, - Config->LTOPartitions); + lto::ThinBackend backend; + if (config->thinLTOJobs != -1U) + backend = lto::createInProcessThinBackend(config->thinLTOJobs); + return llvm::make_unique<lto::LTO>(std::move(c), backend, + config->ltoPartitions); } -BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} +BitcodeCompiler::BitcodeCompiler() : ltoObj(createLTO()) {} BitcodeCompiler::~BitcodeCompiler() = default; -static void undefine(Symbol *S) { - if (auto F = dyn_cast<DefinedFunction>(S)) - replaceSymbol<UndefinedFunction>(F, F->getName(), F->getName(), - DefaultModule, 0, - F->getFile(), F->Signature); - else if (isa<DefinedData>(S)) - replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile()); +static void undefine(Symbol *s) { + if (auto f = dyn_cast<DefinedFunction>(s)) + replaceSymbol<UndefinedFunction>(f, f->getName(), f->getName(), + defaultModule, 0, + f->getFile(), f->signature); + else if (isa<DefinedData>(s)) + replaceSymbol<UndefinedData>(s, s->getName(), 0, s->getFile()); else llvm_unreachable("unexpected symbol kind"); } -void BitcodeCompiler::add(BitcodeFile &F) { - lto::InputFile &Obj = *F.Obj; - unsigned SymNum = 0; - ArrayRef<Symbol *> Syms = F.getSymbols(); - std::vector<lto::SymbolResolution> Resols(Syms.size()); +void BitcodeCompiler::add(BitcodeFile &f) { + lto::InputFile &obj = *f.obj; + unsigned symNum = 0; + ArrayRef<Symbol *> syms = f.getSymbols(); + std::vector<lto::SymbolResolution> resols(syms.size()); // Provide a resolution to the LTO API for each symbol. - for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { - Symbol *Sym = Syms[SymNum]; - lto::SymbolResolution &R = Resols[SymNum]; - ++SymNum; + for (const lto::InputFile::Symbol &objSym : obj.symbols()) { + Symbol *sym = syms[symNum]; + lto::SymbolResolution &r = resols[symNum]; + ++symNum; // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile // reports two symbols for module ASM defined. Without this check, lld // flags an undefined in IR with a definition in ASM as prevailing. // Once IRObjectFile is fixed to report only one symbol this hack can // be removed. - R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; - R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || - (R.Prevailing && Sym->isExported()); - if (R.Prevailing) - undefine(Sym); + r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f; + r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj || + (r.Prevailing && sym->isExported()); + if (r.Prevailing) + undefine(sym); // We tell LTO to not apply interprocedural optimization for wrapped // (with --wrap) symbols because otherwise LTO would inline them while // their values are still not final. - R.LinkerRedefined = !Sym->CanInline; + r.LinkerRedefined = !sym->canInline; } - checkError(LTOObj->add(std::move(F.Obj), Resols)); + checkError(ltoObj->add(std::move(f.obj), resols)); } // Merge all the bitcode files we have seen, codegen the result // and return the resulting objects. std::vector<StringRef> BitcodeCompiler::compile() { - unsigned MaxTasks = LTOObj->getMaxTasks(); - Buf.resize(MaxTasks); - Files.resize(MaxTasks); + unsigned maxTasks = ltoObj->getMaxTasks(); + buf.resize(maxTasks); + files.resize(maxTasks); // The --thinlto-cache-dir option specifies the path to a directory in which // to cache native object files for ThinLTO incremental builds. If a path was // specified, configure LTO to use it as the cache directory. - lto::NativeObjectCache Cache; - if (!Config->ThinLTOCacheDir.empty()) - Cache = check( - lto::localCache(Config->ThinLTOCacheDir, - [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { - Files[Task] = std::move(MB); + lto::NativeObjectCache cache; + if (!config->thinLTOCacheDir.empty()) + cache = check( + lto::localCache(config->thinLTOCacheDir, + [&](size_t task, std::unique_ptr<MemoryBuffer> mb) { + files[task] = std::move(mb); })); - checkError(LTOObj->run( - [&](size_t Task) { + checkError(ltoObj->run( + [&](size_t task) { return llvm::make_unique<lto::NativeObjectStream>( - llvm::make_unique<raw_svector_ostream>(Buf[Task])); + llvm::make_unique<raw_svector_ostream>(buf[task])); }, - Cache)); + cache)); - if (!Config->ThinLTOCacheDir.empty()) - pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy); + if (!config->thinLTOCacheDir.empty()) + pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy); - std::vector<StringRef> Ret; - for (unsigned I = 0; I != MaxTasks; ++I) { - if (Buf[I].empty()) + std::vector<StringRef> ret; + for (unsigned i = 0; i != maxTasks; ++i) { + if (buf[i].empty()) continue; - if (Config->SaveTemps) { - if (I == 0) - saveBuffer(Buf[I], Config->OutputFile + ".lto.o"); + if (config->saveTemps) { + if (i == 0) + saveBuffer(buf[i], config->outputFile + ".lto.o"); else - saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o"); + saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o"); } - Ret.emplace_back(Buf[I].data(), Buf[I].size()); + ret.emplace_back(buf[i].data(), buf[i].size()); } - for (std::unique_ptr<MemoryBuffer> &File : Files) - if (File) - Ret.push_back(File->getBuffer()); + for (std::unique_ptr<MemoryBuffer> &file : files) + if (file) + ret.push_back(file->getBuffer()); - return Ret; + return ret; } diff --git a/lld/wasm/LTO.h b/lld/wasm/LTO.h index 37fea7ad6ee..9c1e1788ed3 100644 --- a/lld/wasm/LTO.h +++ b/lld/wasm/LTO.h @@ -43,13 +43,13 @@ public: BitcodeCompiler(); ~BitcodeCompiler(); - void add(BitcodeFile &F); + void add(BitcodeFile &f); std::vector<StringRef> compile(); private: - std::unique_ptr<llvm::lto::LTO> LTOObj; - std::vector<SmallString<0>> Buf; - std::vector<std::unique_ptr<MemoryBuffer>> Files; + std::unique_ptr<llvm::lto::LTO> ltoObj; + std::vector<SmallString<0>> buf; + std::vector<std::unique_ptr<MemoryBuffer>> files; }; } // namespace wasm } // namespace lld diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 08264925a7f..703daf27e01 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -32,68 +32,68 @@ using namespace llvm; using namespace llvm::wasm; void lld::wasm::markLive() { - if (!Config->GcSections) + if (!config->gcSections) return; LLVM_DEBUG(dbgs() << "markLive\n"); - SmallVector<InputChunk *, 256> Q; + SmallVector<InputChunk *, 256> q; - std::function<void(Symbol*)> Enqueue = [&](Symbol *Sym) { - if (!Sym || Sym->isLive()) + std::function<void(Symbol*)> enqueue = [&](Symbol *sym) { + if (!sym || sym->isLive()) return; - LLVM_DEBUG(dbgs() << "markLive: " << Sym->getName() << "\n"); - Sym->markLive(); - if (InputChunk *Chunk = Sym->getChunk()) - Q.push_back(Chunk); + LLVM_DEBUG(dbgs() << "markLive: " << sym->getName() << "\n"); + sym->markLive(); + if (InputChunk *chunk = sym->getChunk()) + q.push_back(chunk); // The ctor functions are all referenced by the synthetic CallCtors // function. However, this function does not contain relocations so we // have to manually mark the ctors as live if CallCtors itself is live. - if (Sym == WasmSym::CallCtors) { - if (Config->PassiveSegments) - Enqueue(WasmSym::InitMemory); - if (Config->Pic) - Enqueue(WasmSym::ApplyRelocs); - for (const ObjFile *Obj : Symtab->ObjectFiles) { - const WasmLinkingData &L = Obj->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) { - auto* InitSym = Obj->getFunctionSymbol(F.Symbol); - if (!InitSym->isDiscarded()) - Enqueue(InitSym); + if (sym == WasmSym::callCtors) { + if (config->passiveSegments) + enqueue(WasmSym::initMemory); + if (config->isPic) + enqueue(WasmSym::applyRelocs); + for (const ObjFile *obj : symtab->objectFiles) { + const WasmLinkingData &l = obj->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) { + auto* initSym = obj->getFunctionSymbol(f.Symbol); + if (!initSym->isDiscarded()) + enqueue(initSym); } } } }; // Add GC root symbols. - if (!Config->Entry.empty()) - Enqueue(Symtab->find(Config->Entry)); + if (!config->entry.empty()) + enqueue(symtab->find(config->entry)); // We need to preserve any exported symbol - for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->isExported()) - Enqueue(Sym); + for (Symbol *sym : symtab->getSymbols()) + if (sym->isExported()) + enqueue(sym); // For relocatable output, we need to preserve all the ctor functions - if (Config->Relocatable) { - for (const ObjFile *Obj : Symtab->ObjectFiles) { - const WasmLinkingData &L = Obj->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) - Enqueue(Obj->getFunctionSymbol(F.Symbol)); + if (config->relocatable) { + for (const ObjFile *obj : symtab->objectFiles) { + const WasmLinkingData &l = obj->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) + enqueue(obj->getFunctionSymbol(f.Symbol)); } } - if (Config->Pic) - Enqueue(WasmSym::CallCtors); + if (config->isPic) + enqueue(WasmSym::callCtors); // Follow relocations to mark all reachable chunks. - while (!Q.empty()) { - InputChunk *C = Q.pop_back_val(); + while (!q.empty()) { + InputChunk *c = q.pop_back_val(); - for (const WasmRelocation Reloc : C->getRelocations()) { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) + for (const WasmRelocation reloc : c->getRelocations()) { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) continue; - Symbol *Sym = C->File->getSymbol(Reloc.Index); + Symbol *sym = c->file->getSymbol(reloc.Index); // If the function has been assigned the special index zero in the table, // the relocation doesn't pull in the function body, since the function @@ -102,38 +102,38 @@ void lld::wasm::markLive() { // zero is only reachable via "call", not via "call_indirect". The stub // functions used for weak-undefined symbols have this behaviour (compare // equal to null pointer, only reachable via direct call). - if (Reloc.Type == R_WASM_TABLE_INDEX_SLEB || - Reloc.Type == R_WASM_TABLE_INDEX_I32) { - auto *FuncSym = cast<FunctionSymbol>(Sym); - if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0) + if (reloc.Type == R_WASM_TABLE_INDEX_SLEB || + reloc.Type == R_WASM_TABLE_INDEX_I32) { + auto *funcSym = cast<FunctionSymbol>(sym); + if (funcSym->hasTableIndex() && funcSym->getTableIndex() == 0) continue; } - Enqueue(Sym); + enqueue(sym); } } // Report garbage-collected sections. - if (Config->PrintGcSections) { - for (const ObjFile *Obj : Symtab->ObjectFiles) { - for (InputChunk *C : Obj->Functions) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputChunk *C : Obj->Segments) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputGlobal *G : Obj->Globals) - if (!G->Live) - message("removing unused section " + toString(G)); - for (InputEvent *E : Obj->Events) - if (!E->Live) - message("removing unused section " + toString(E)); + if (config->printGcSections) { + for (const ObjFile *obj : symtab->objectFiles) { + for (InputChunk *c : obj->functions) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputChunk *c : obj->segments) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputGlobal *g : obj->globals) + if (!g->live) + message("removing unused section " + toString(g)); + for (InputEvent *e : obj->events) + if (!e->live) + message("removing unused section " + toString(e)); } - for (InputChunk *C : Symtab->SyntheticFunctions) - if (!C->Live) - message("removing unused section " + toString(C)); - for (InputGlobal *G : Symtab->SyntheticGlobals) - if (!G->Live) - message("removing unused section " + toString(G)); + for (InputChunk *c : symtab->syntheticFunctions) + if (!c->live) + message("removing unused section " + toString(c)); + for (InputGlobal *g : symtab->syntheticGlobals) + if (!g->live) + message("removing unused section " + toString(g)); } } diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index d5434b102cc..c019d89e447 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -23,8 +23,8 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static StringRef sectionTypeToString(uint32_t SectionType) { - switch (SectionType) { +static StringRef sectionTypeToString(uint32_t sectionType) { + switch (sectionType) { case WASM_SEC_CUSTOM: return "CUSTOM"; case WASM_SEC_TYPE: @@ -59,192 +59,192 @@ static StringRef sectionTypeToString(uint32_t SectionType) { } // Returns a string, e.g. "FUNCTION(.text)". -std::string lld::toString(const OutputSection &Sec) { - if (!Sec.Name.empty()) - return (Sec.getSectionName() + "(" + Sec.Name + ")").str(); - return Sec.getSectionName(); +std::string lld::toString(const OutputSection &sec) { + if (!sec.name.empty()) + return (sec.getSectionName() + "(" + sec.name + ")").str(); + return sec.getSectionName(); } StringRef OutputSection::getSectionName() const { - return sectionTypeToString(Type); + return sectionTypeToString(type); } -void OutputSection::createHeader(size_t BodySize) { - raw_string_ostream OS(Header); - debugWrite(OS.tell(), "section type [" + getSectionName() + "]"); - encodeULEB128(Type, OS); - writeUleb128(OS, BodySize, "section size"); - OS.flush(); - log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + +void OutputSection::createHeader(size_t bodySize) { + raw_string_ostream os(header); + debugWrite(os.tell(), "section type [" + getSectionName() + "]"); + encodeULEB128(type, os); + writeUleb128(os, bodySize, "section size"); + os.flush(); + log("createHeader: " + toString(*this) + " body=" + Twine(bodySize) + " total=" + Twine(getSize())); } void CodeSection::finalizeContents() { - raw_string_ostream OS(CodeSectionHeader); - writeUleb128(OS, Functions.size(), "function count"); - OS.flush(); - BodySize = CodeSectionHeader.size(); - - for (InputFunction *Func : Functions) { - Func->OutputOffset = BodySize; - Func->calculateSize(); - BodySize += Func->getSize(); + raw_string_ostream os(codeSectionHeader); + writeUleb128(os, functions.size(), "function count"); + os.flush(); + bodySize = codeSectionHeader.size(); + + for (InputFunction *func : functions) { + func->outputOffset = bodySize; + func->calculateSize(); + bodySize += func->getSize(); } - createHeader(BodySize); + createHeader(bodySize); } -void CodeSection::writeTo(uint8_t *Buf) { +void CodeSection::writeTo(uint8_t *buf) { log("writing " + toString(*this)); log(" size=" + Twine(getSize())); - log(" headersize=" + Twine(Header.size())); - log(" codeheadersize=" + Twine(CodeSectionHeader.size())); - Buf += Offset; + log(" headersize=" + Twine(header.size())); + log(" codeheadersize=" + Twine(codeSectionHeader.size())); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); // Write code section headers - memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); + memcpy(buf, codeSectionHeader.data(), codeSectionHeader.size()); // Write code section bodies - for (const InputChunk *Chunk : Functions) - Chunk->writeTo(Buf); + for (const InputChunk *chunk : functions) + chunk->writeTo(buf); } uint32_t CodeSection::getNumRelocations() const { - uint32_t Count = 0; - for (const InputChunk *Func : Functions) - Count += Func->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const InputChunk *func : functions) + count += func->getNumRelocations(); + return count; } -void CodeSection::writeRelocations(raw_ostream &OS) const { - for (const InputChunk *C : Functions) - C->writeRelocations(OS); +void CodeSection::writeRelocations(raw_ostream &os) const { + for (const InputChunk *c : functions) + c->writeRelocations(os); } void DataSection::finalizeContents() { - raw_string_ostream OS(DataSectionHeader); + raw_string_ostream os(dataSectionHeader); - writeUleb128(OS, Segments.size(), "data segment count"); - OS.flush(); - BodySize = DataSectionHeader.size(); + writeUleb128(os, segments.size(), "data segment count"); + os.flush(); + bodySize = dataSectionHeader.size(); - assert((!Config->Pic || Segments.size() <= 1) && + assert((!config->isPic || segments.size() <= 1) && "Currenly only a single data segment is supported in PIC mode"); - for (OutputSegment *Segment : Segments) { - raw_string_ostream OS(Segment->Header); - writeUleb128(OS, Segment->InitFlags, "init flags"); - if (Segment->InitFlags & WASM_SEGMENT_HAS_MEMINDEX) - writeUleb128(OS, 0, "memory index"); - if ((Segment->InitFlags & WASM_SEGMENT_IS_PASSIVE) == 0) { - WasmInitExpr InitExpr; - if (Config->Pic) { - InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - InitExpr.Value.Global = WasmSym::MemoryBase->getGlobalIndex(); + for (OutputSegment *segment : segments) { + raw_string_ostream os(segment->header); + writeUleb128(os, segment->initFlags, "init flags"); + if (segment->initFlags & WASM_SEGMENT_HAS_MEMINDEX) + writeUleb128(os, 0, "memory index"); + if ((segment->initFlags & WASM_SEGMENT_IS_PASSIVE) == 0) { + WasmInitExpr initExpr; + if (config->isPic) { + initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Value.Global = WasmSym::memoryBase->getGlobalIndex(); } else { - InitExpr.Opcode = WASM_OPCODE_I32_CONST; - InitExpr.Value.Int32 = Segment->StartVA; + initExpr.Opcode = WASM_OPCODE_I32_CONST; + initExpr.Value.Int32 = segment->startVA; } - writeInitExpr(OS, InitExpr); + writeInitExpr(os, initExpr); } - writeUleb128(OS, Segment->Size, "segment size"); - OS.flush(); + writeUleb128(os, segment->size, "segment size"); + os.flush(); - Segment->SectionOffset = BodySize; - BodySize += Segment->Header.size() + Segment->Size; - log("Data segment: size=" + Twine(Segment->Size) + ", startVA=" + - Twine::utohexstr(Segment->StartVA) + ", name=" + Segment->Name); + segment->sectionOffset = bodySize; + bodySize += segment->header.size() + segment->size; + log("Data segment: size=" + Twine(segment->size) + ", startVA=" + + Twine::utohexstr(segment->startVA) + ", name=" + segment->name); - for (InputSegment *InputSeg : Segment->InputSegments) - InputSeg->OutputOffset = Segment->SectionOffset + Segment->Header.size() + - InputSeg->OutputSegmentOffset; + for (InputSegment *inputSeg : segment->inputSegments) + inputSeg->outputOffset = segment->sectionOffset + segment->header.size() + + inputSeg->outputSegmentOffset; } - createHeader(BodySize); + createHeader(bodySize); } -void DataSection::writeTo(uint8_t *Buf) { +void DataSection::writeTo(uint8_t *buf) { log("writing " + toString(*this) + " size=" + Twine(getSize()) + - " body=" + Twine(BodySize)); - Buf += Offset; + " body=" + Twine(bodySize)); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); // Write data section headers - memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); + memcpy(buf, dataSectionHeader.data(), dataSectionHeader.size()); - for (const OutputSegment *Segment : Segments) { + for (const OutputSegment *segment : segments) { // Write data segment header - uint8_t *SegStart = Buf + Segment->SectionOffset; - memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); + uint8_t *segStart = buf + segment->sectionOffset; + memcpy(segStart, segment->header.data(), segment->header.size()); // Write segment data payload - for (const InputChunk *Chunk : Segment->InputSegments) - Chunk->writeTo(Buf); + for (const InputChunk *chunk : segment->inputSegments) + chunk->writeTo(buf); } } uint32_t DataSection::getNumRelocations() const { - uint32_t Count = 0; - for (const OutputSegment *Seg : Segments) - for (const InputChunk *InputSeg : Seg->InputSegments) - Count += InputSeg->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const OutputSegment *seg : segments) + for (const InputChunk *inputSeg : seg->inputSegments) + count += inputSeg->getNumRelocations(); + return count; } -void DataSection::writeRelocations(raw_ostream &OS) const { - for (const OutputSegment *Seg : Segments) - for (const InputChunk *C : Seg->InputSegments) - C->writeRelocations(OS); +void DataSection::writeRelocations(raw_ostream &os) const { + for (const OutputSegment *seg : segments) + for (const InputChunk *c : seg->inputSegments) + c->writeRelocations(os); } void CustomSection::finalizeContents() { - raw_string_ostream OS(NameData); - encodeULEB128(Name.size(), OS); - OS << Name; - OS.flush(); - - for (InputSection *Section : InputSections) { - Section->OutputOffset = PayloadSize; - Section->OutputSec = this; - PayloadSize += Section->getSize(); + raw_string_ostream os(nameData); + encodeULEB128(name.size(), os); + os << name; + os.flush(); + + for (InputSection *section : inputSections) { + section->outputOffset = payloadSize; + section->outputSec = this; + payloadSize += section->getSize(); } - createHeader(PayloadSize + NameData.size()); + createHeader(payloadSize + nameData.size()); } -void CustomSection::writeTo(uint8_t *Buf) { +void CustomSection::writeTo(uint8_t *buf) { log("writing " + toString(*this) + " size=" + Twine(getSize()) + - " chunks=" + Twine(InputSections.size())); + " chunks=" + Twine(inputSections.size())); - assert(Offset); - Buf += Offset; + assert(offset); + buf += offset; // Write section header - memcpy(Buf, Header.data(), Header.size()); - Buf += Header.size(); - memcpy(Buf, NameData.data(), NameData.size()); - Buf += NameData.size(); + memcpy(buf, header.data(), header.size()); + buf += header.size(); + memcpy(buf, nameData.data(), nameData.size()); + buf += nameData.size(); // Write custom sections payload - for (const InputSection *Section : InputSections) - Section->writeTo(Buf); + for (const InputSection *section : inputSections) + section->writeTo(buf); } uint32_t CustomSection::getNumRelocations() const { - uint32_t Count = 0; - for (const InputSection *InputSect : InputSections) - Count += InputSect->getNumRelocations(); - return Count; + uint32_t count = 0; + for (const InputSection *inputSect : inputSections) + count += inputSect->getNumRelocations(); + return count; } -void CustomSection::writeRelocations(raw_ostream &OS) const { - for (const InputSection *S : InputSections) - S->writeRelocations(OS); +void CustomSection::writeRelocations(raw_ostream &os) const { + for (const InputSection *s : inputSections) + s->writeRelocations(os); } diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h index 3045ed7c56b..6b1c2a2eba2 100644 --- a/lld/wasm/OutputSections.h +++ b/lld/wasm/OutputSections.h @@ -20,7 +20,7 @@ namespace lld { namespace wasm { class OutputSection; } -std::string toString(const wasm::OutputSection &Section); +std::string toString(const wasm::OutputSection §ion); namespace wasm { @@ -28,67 +28,67 @@ class OutputSegment; class OutputSection { public: - OutputSection(uint32_t Type, std::string Name = "") - : Type(Type), Name(Name) {} + OutputSection(uint32_t type, std::string name = "") + : type(type), name(name) {} virtual ~OutputSection() = default; StringRef getSectionName() const; - void setOffset(size_t NewOffset) { - log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); - Offset = NewOffset; + void setOffset(size_t newOffset) { + log("setOffset: " + toString(*this) + ": " + Twine(newOffset)); + offset = newOffset; } - void createHeader(size_t BodySize); + void createHeader(size_t bodySize); virtual bool isNeeded() const { return true; } virtual size_t getSize() const = 0; - virtual void writeTo(uint8_t *Buf) = 0; + virtual void writeTo(uint8_t *buf) = 0; virtual void finalizeContents() = 0; virtual uint32_t getNumRelocations() const { return 0; } - virtual void writeRelocations(raw_ostream &OS) const {} + virtual void writeRelocations(raw_ostream &os) const {} - std::string Header; - uint32_t Type; - uint32_t SectionIndex = UINT32_MAX; - std::string Name; - OutputSectionSymbol *SectionSym = nullptr; + std::string header; + uint32_t type; + uint32_t sectionIndex = UINT32_MAX; + std::string name; + OutputSectionSymbol *sectionSym = nullptr; protected: - size_t Offset = 0; + size_t offset = 0; }; class CodeSection : public OutputSection { public: - explicit CodeSection(ArrayRef<InputFunction *> Functions) - : OutputSection(llvm::wasm::WASM_SEC_CODE), Functions(Functions) {} + explicit CodeSection(ArrayRef<InputFunction *> functions) + : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {} - size_t getSize() const override { return Header.size() + BodySize; } - void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return header.size() + bodySize; } + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; - bool isNeeded() const override { return Functions.size() > 0; } + void writeRelocations(raw_ostream &os) const override; + bool isNeeded() const override { return functions.size() > 0; } void finalizeContents() override; protected: - ArrayRef<InputFunction *> Functions; - std::string CodeSectionHeader; - size_t BodySize = 0; + ArrayRef<InputFunction *> functions; + std::string codeSectionHeader; + size_t bodySize = 0; }; class DataSection : public OutputSection { public: - explicit DataSection(ArrayRef<OutputSegment *> Segments) - : OutputSection(llvm::wasm::WASM_SEC_DATA), Segments(Segments) {} + explicit DataSection(ArrayRef<OutputSegment *> segments) + : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {} - size_t getSize() const override { return Header.size() + BodySize; } - void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return header.size() + bodySize; } + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; - bool isNeeded() const override { return Segments.size() > 0; } + void writeRelocations(raw_ostream &os) const override; + bool isNeeded() const override { return segments.size() > 0; } void finalizeContents() override; protected: - ArrayRef<OutputSegment *> Segments; - std::string DataSectionHeader; - size_t BodySize = 0; + ArrayRef<OutputSegment *> segments; + std::string dataSectionHeader; + size_t bodySize = 0; }; // Represents a custom section in the output file. Wasm custom sections are @@ -100,21 +100,21 @@ protected: // separately and are instead synthesized by the linker. class CustomSection : public OutputSection { public: - CustomSection(std::string Name, ArrayRef<InputSection *> InputSections) - : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, Name), - InputSections(InputSections) {} + CustomSection(std::string name, ArrayRef<InputSection *> inputSections) + : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name), + inputSections(inputSections) {} size_t getSize() const override { - return Header.size() + NameData.size() + PayloadSize; + return header.size() + nameData.size() + payloadSize; } - void writeTo(uint8_t *Buf) override; + void writeTo(uint8_t *buf) override; uint32_t getNumRelocations() const override; - void writeRelocations(raw_ostream &OS) const override; + void writeRelocations(raw_ostream &os) const override; void finalizeContents() override; protected: - size_t PayloadSize = 0; - ArrayRef<InputSection *> InputSections; - std::string NameData; + size_t payloadSize = 0; + ArrayRef<InputSection *> inputSections; + std::string nameData; }; } // namespace wasm diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h index a9679c1d675..14142fbd44f 100644 --- a/lld/wasm/OutputSegment.h +++ b/lld/wasm/OutputSegment.h @@ -20,30 +20,30 @@ class InputSegment; class OutputSegment { public: - OutputSegment(StringRef N, uint32_t Index) : Name(N), Index(Index) {} - - void addInputSegment(InputSegment *InSeg) { - Alignment = std::max(Alignment, InSeg->getAlignment()); - InputSegments.push_back(InSeg); - Size = llvm::alignTo(Size, 1ULL << InSeg->getAlignment()); - InSeg->OutputSeg = this; - InSeg->OutputSegmentOffset = Size; - Size += InSeg->getSize(); + OutputSegment(StringRef n, uint32_t index) : name(n), index(index) {} + + void addInputSegment(InputSegment *inSeg) { + alignment = std::max(alignment, inSeg->getAlignment()); + inputSegments.push_back(inSeg); + size = llvm::alignTo(size, 1ULL << inSeg->getAlignment()); + inSeg->outputSeg = this; + inSeg->outputSegmentOffset = size; + size += inSeg->getSize(); } - StringRef Name; - const uint32_t Index; - uint32_t InitFlags = 0; - uint32_t SectionOffset = 0; - uint32_t Alignment = 0; - uint32_t StartVA = 0; - std::vector<InputSegment *> InputSegments; + StringRef name; + const uint32_t index; + uint32_t initFlags = 0; + uint32_t sectionOffset = 0; + uint32_t alignment = 0; + uint32_t startVA = 0; + std::vector<InputSegment *> inputSegments; // Sum of the size of the all the input segments - uint32_t Size = 0; + uint32_t size = 0; // Segment header - std::string Header; + std::string header; }; } // namespace wasm diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp index faedd000329..e39f6987a42 100644 --- a/lld/wasm/Relocations.cpp +++ b/lld/wasm/Relocations.cpp @@ -17,69 +17,69 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static bool requiresGOTAccess(const Symbol *Sym) { - return Config->Pic && !Sym->isHidden() && !Sym->isLocal(); +static bool requiresGOTAccess(const Symbol *sym) { + return config->isPic && !sym->isHidden() && !sym->isLocal(); } -static bool allowUndefined(const Symbol* Sym) { +static bool allowUndefined(const Symbol* sym) { // Historically --allow-undefined doesn't work for data symbols since we don't // have any way to represent these as imports in the final binary. The idea // behind allowing undefined symbols is to allow importing these symbols from // the embedder and we can't do this for data symbols (at least not without // compiling with -fPIC) - if (isa<DataSymbol>(Sym)) + if (isa<DataSymbol>(sym)) return false; - return (Config->AllowUndefined || - Config->AllowUndefinedSymbols.count(Sym->getName()) != 0); + return (config->allowUndefined || + config->allowUndefinedSymbols.count(sym->getName()) != 0); } -static void reportUndefined(const Symbol* Sym) { - assert(Sym->isUndefined()); - assert(!Sym->isWeak()); - if (!allowUndefined(Sym)) - error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym)); +static void reportUndefined(const Symbol* sym) { + assert(sym->isUndefined()); + assert(!sym->isWeak()); + if (!allowUndefined(sym)) + error(toString(sym->getFile()) + ": undefined symbol: " + toString(*sym)); } -void lld::wasm::scanRelocations(InputChunk *Chunk) { - if (!Chunk->Live) +void lld::wasm::scanRelocations(InputChunk *chunk) { + if (!chunk->live) return; - ObjFile *File = Chunk->File; - ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); - for (const WasmRelocation &Reloc : Chunk->getRelocations()) { - if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { + ObjFile *file = chunk->file; + ArrayRef<WasmSignature> types = file->getWasmObj()->types(); + for (const WasmRelocation &reloc : chunk->getRelocations()) { + if (reloc.Type == R_WASM_TYPE_INDEX_LEB) { // Mark target type as live - File->TypeMap[Reloc.Index] = - Out.TypeSec->registerType(Types[Reloc.Index]); - File->TypeIsUsed[Reloc.Index] = true; + file->typeMap[reloc.Index] = + out.typeSec->registerType(types[reloc.Index]); + file->typeIsUsed[reloc.Index] = true; continue; } // Other relocation types all have a corresponding symbol - Symbol *Sym = File->getSymbols()[Reloc.Index]; + Symbol *sym = file->getSymbols()[reloc.Index]; - switch (Reloc.Type) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: - if (requiresGOTAccess(Sym)) + if (requiresGOTAccess(sym)) break; - Out.ElemSec->addEntry(cast<FunctionSymbol>(Sym)); + out.elemSec->addEntry(cast<FunctionSymbol>(sym)); break; case R_WASM_GLOBAL_INDEX_LEB: - if (!isa<GlobalSymbol>(Sym)) - Out.ImportSec->addGOTEntry(Sym); + if (!isa<GlobalSymbol>(sym)) + out.importSec->addGOTEntry(sym); break; } - if (Config->Pic) { - switch (Reloc.Type) { + if (config->isPic) { + switch (reloc.Type) { case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_LEB: // Certain relocation types can't be used when building PIC output, // since they would require absolute symbol addresses at link time. - error(toString(File) + ": relocation " + relocTypeToString(Reloc.Type) + - " cannot be used against symbol " + toString(*Sym) + + error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) + + " cannot be used against symbol " + toString(*sym) + "; recompile with -fPIC"); break; case R_WASM_TABLE_INDEX_I32: @@ -87,14 +87,14 @@ void lld::wasm::scanRelocations(InputChunk *Chunk) { // These relocation types are only present in the data section and // will be converted into code by `generateRelocationCode`. This code // requires the symbols to have GOT entires. - if (requiresGOTAccess(Sym)) - Out.ImportSec->addGOTEntry(Sym); + if (requiresGOTAccess(sym)) + out.importSec->addGOTEntry(sym); break; } } else { // Report undefined symbols - if (Sym->isUndefined() && !Config->Relocatable && !Sym->isWeak()) - reportUndefined(Sym); + if (sym->isUndefined() && !config->relocatable && !sym->isWeak()) + reportUndefined(sym); } } diff --git a/lld/wasm/Relocations.h b/lld/wasm/Relocations.h index 09a632cca0c..02787f551d8 100644 --- a/lld/wasm/Relocations.h +++ b/lld/wasm/Relocations.h @@ -14,7 +14,7 @@ namespace wasm { class InputChunk; -void scanRelocations(InputChunk *Chunk); +void scanRelocations(InputChunk *chunk); } // namespace wasm } // namespace lld diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index 35ceed6d2a9..b6181252340 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -24,37 +24,37 @@ using namespace llvm::object; using namespace lld; using namespace lld::wasm; -SymbolTable *lld::wasm::Symtab; +SymbolTable *lld::wasm::symtab; -void SymbolTable::addFile(InputFile *File) { - log("Processing: " + toString(File)); +void SymbolTable::addFile(InputFile *file) { + log("Processing: " + toString(file)); // .a file - if (auto *F = dyn_cast<ArchiveFile>(File)) { - F->parse(); + if (auto *f = dyn_cast<ArchiveFile>(file)) { + f->parse(); return; } // .so file - if (auto *F = dyn_cast<SharedFile>(File)) { - SharedFiles.push_back(F); + if (auto *f = dyn_cast<SharedFile>(file)) { + sharedFiles.push_back(f); return; } - if (Config->Trace) - message(toString(File)); + if (config->trace) + message(toString(file)); // LLVM bitcode file - if (auto *F = dyn_cast<BitcodeFile>(File)) { - F->parse(); - BitcodeFiles.push_back(F); + if (auto *f = dyn_cast<BitcodeFile>(file)) { + f->parse(); + bitcodeFiles.push_back(f); return; } // Regular object file - auto *F = cast<ObjFile>(File); - F->parse(false); - ObjectFiles.push_back(F); + auto *f = cast<ObjFile>(file); + f->parse(false); + objectFiles.push_back(f); } // This function is where all the optimizations of link-time @@ -65,512 +65,512 @@ void SymbolTable::addFile(InputFile *File) { // Because all bitcode files that the program consists of are passed // to the compiler at once, it can do whole-program optimization. void SymbolTable::addCombinedLTOObject() { - if (BitcodeFiles.empty()) + if (bitcodeFiles.empty()) return; // Compile bitcode files and replace bitcode symbols. - LTO.reset(new BitcodeCompiler); - for (BitcodeFile *F : BitcodeFiles) - LTO->add(*F); - - for (StringRef Filename : LTO->compile()) { - auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"), ""); - Obj->parse(true); - ObjectFiles.push_back(Obj); + lto.reset(new BitcodeCompiler); + for (BitcodeFile *f : bitcodeFiles) + lto->add(*f); + + for (StringRef filename : lto->compile()) { + auto *obj = make<ObjFile>(MemoryBufferRef(filename, "lto.tmp"), ""); + obj->parse(true); + objectFiles.push_back(obj); } } -Symbol *SymbolTable::find(StringRef Name) { - auto It = SymMap.find(CachedHashStringRef(Name)); - if (It == SymMap.end() || It->second == -1) +Symbol *SymbolTable::find(StringRef name) { + auto it = symMap.find(CachedHashStringRef(name)); + if (it == symMap.end() || it->second == -1) return nullptr; - return SymVector[It->second]; + return symVector[it->second]; } -void SymbolTable::replace(StringRef Name, Symbol* Sym) { - auto It = SymMap.find(CachedHashStringRef(Name)); - SymVector[It->second] = Sym; +void SymbolTable::replace(StringRef name, Symbol* sym) { + auto it = symMap.find(CachedHashStringRef(name)); + symVector[it->second] = sym; } -std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) { - bool Trace = false; - auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()}); - int &SymIndex = P.first->second; - bool IsNew = P.second; - if (SymIndex == -1) { - SymIndex = SymVector.size(); - Trace = true; - IsNew = true; +std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) { + bool trace = false; + auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()}); + int &symIndex = p.first->second; + bool isNew = p.second; + if (symIndex == -1) { + symIndex = symVector.size(); + trace = true; + isNew = true; } - if (!IsNew) - return {SymVector[SymIndex], false}; + if (!isNew) + return {symVector[symIndex], false}; - Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); - Sym->IsUsedInRegularObj = false; - Sym->CanInline = true; - Sym->Traced = Trace; - SymVector.emplace_back(Sym); - return {Sym, true}; + Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); + sym->isUsedInRegularObj = false; + sym->canInline = true; + sym->traced = trace; + symVector.emplace_back(sym); + return {sym, true}; } -std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, - const InputFile *File) { - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insertName(Name); +std::pair<Symbol *, bool> SymbolTable::insert(StringRef name, + const InputFile *file) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insertName(name); - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + if (!file || file->kind() == InputFile::ObjectKind) + s->isUsedInRegularObj = true; - return {S, WasInserted}; + return {s, wasInserted}; } -static void reportTypeError(const Symbol *Existing, const InputFile *File, - llvm::wasm::WasmSymbolType Type) { - error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + - toString(Existing->getWasmType()) + " in " + - toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + - " in " + toString(File)); +static void reportTypeError(const Symbol *existing, const InputFile *file, + llvm::wasm::WasmSymbolType type) { + error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " + + toString(existing->getWasmType()) + " in " + + toString(existing->getFile()) + "\n>>> defined as " + toString(type) + + " in " + toString(file)); } // Check the type of new symbol matches that of the symbol is replacing. // Returns true if the function types match, false is there is a singature // mismatch. -static bool signatureMatches(FunctionSymbol *Existing, - const WasmSignature *NewSig) { - const WasmSignature *OldSig = Existing->Signature; +static bool signatureMatches(FunctionSymbol *existing, + const WasmSignature *newSig) { + const WasmSignature *oldSig = existing->signature; // If either function is missing a signature (this happend for bitcode // symbols) then assume they match. Any mismatch will be reported later // when the LTO objects are added. - if (!NewSig || !OldSig) + if (!newSig || !oldSig) return true; - return *NewSig == *OldSig; + return *newSig == *oldSig; } -static void checkGlobalType(const Symbol *Existing, const InputFile *File, - const WasmGlobalType *NewType) { - if (!isa<GlobalSymbol>(Existing)) { - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL); +static void checkGlobalType(const Symbol *existing, const InputFile *file, + const WasmGlobalType *newType) { + if (!isa<GlobalSymbol>(existing)) { + reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL); return; } - const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType(); - if (*NewType != *OldType) { - error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " + - toString(*OldType) + " in " + toString(Existing->getFile()) + - "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); + const WasmGlobalType *oldType = cast<GlobalSymbol>(existing)->getGlobalType(); + if (*newType != *oldType) { + error("Global type mismatch: " + existing->getName() + "\n>>> defined as " + + toString(*oldType) + " in " + toString(existing->getFile()) + + "\n>>> defined as " + toString(*newType) + " in " + toString(file)); } } -static void checkEventType(const Symbol *Existing, const InputFile *File, - const WasmEventType *NewType, - const WasmSignature *NewSig) { - auto ExistingEvent = dyn_cast<EventSymbol>(Existing); - if (!isa<EventSymbol>(Existing)) { - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); +static void checkEventType(const Symbol *existing, const InputFile *file, + const WasmEventType *newType, + const WasmSignature *newSig) { + auto existingEvent = dyn_cast<EventSymbol>(existing); + if (!isa<EventSymbol>(existing)) { + reportTypeError(existing, file, WASM_SYMBOL_TYPE_EVENT); return; } - const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType(); - const WasmSignature *OldSig = ExistingEvent->Signature; - if (NewType->Attribute != OldType->Attribute) - error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + - toString(*OldType) + " in " + toString(Existing->getFile()) + - "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); - if (*NewSig != *OldSig) - warn("Event signature mismatch: " + Existing->getName() + - "\n>>> defined as " + toString(*OldSig) + " in " + - toString(Existing->getFile()) + "\n>>> defined as " + - toString(*NewSig) + " in " + toString(File)); + const WasmEventType *oldType = cast<EventSymbol>(existing)->getEventType(); + const WasmSignature *oldSig = existingEvent->signature; + if (newType->Attribute != oldType->Attribute) + error("Event type mismatch: " + existing->getName() + "\n>>> defined as " + + toString(*oldType) + " in " + toString(existing->getFile()) + + "\n>>> defined as " + toString(*newType) + " in " + toString(file)); + if (*newSig != *oldSig) + warn("Event signature mismatch: " + existing->getName() + + "\n>>> defined as " + toString(*oldSig) + " in " + + toString(existing->getFile()) + "\n>>> defined as " + + toString(*newSig) + " in " + toString(file)); } -static void checkDataType(const Symbol *Existing, const InputFile *File) { - if (!isa<DataSymbol>(Existing)) - reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); +static void checkDataType(const Symbol *existing, const InputFile *file) { + if (!isa<DataSymbol>(existing)) + reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA); } -DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, - uint32_t Flags, - InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); - assert(!find(Name)); - SyntheticFunctions.emplace_back(Function); - return replaceSymbol<DefinedFunction>(insertName(Name).first, Name, - Flags, nullptr, Function); +DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name, + uint32_t flags, + InputFunction *function) { + LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << name << "\n"); + assert(!find(name)); + syntheticFunctions.emplace_back(function); + return replaceSymbol<DefinedFunction>(insertName(name).first, name, + flags, nullptr, function); } // Adds an optional, linker generated, data symbols. The symbol will only be // added if there is an undefine reference to it, or if it is explictly exported // via the --export flag. Otherwise we don't add the symbol and return nullptr. -DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value, - uint32_t Flags) { - Symbol *S = find(Name); - if (!S && (Config->ExportAll || Config->ExportedSymbols.count(Name) != 0)) - S = insertName(Name).first; - else if (!S || S->isDefined()) +DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name, uint32_t value, + uint32_t flags) { + Symbol *s = find(name); + if (!s && (config->exportAll || config->exportedSymbols.count(name) != 0)) + s = insertName(name).first; + else if (!s || s->isDefined()) return nullptr; - LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n"); - auto *rtn = replaceSymbol<DefinedData>(S, Name, Flags); - rtn->setVirtualAddress(Value); - rtn->Referenced = true; + LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << name << "\n"); + auto *rtn = replaceSymbol<DefinedData>(s, name, flags); + rtn->setVirtualAddress(value); + rtn->referenced = true; return rtn; } -DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, - uint32_t Flags) { - LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); - assert(!find(Name)); - return replaceSymbol<DefinedData>(insertName(Name).first, Name, Flags); +DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef name, + uint32_t flags) { + LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << name << "\n"); + assert(!find(name)); + return replaceSymbol<DefinedData>(insertName(name).first, name, flags); } -DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, - InputGlobal *Global) { - LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global +DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags, + InputGlobal *global) { + LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << name << " -> " << global << "\n"); - assert(!find(Name)); - SyntheticGlobals.emplace_back(Global); - return replaceSymbol<DefinedGlobal>(insertName(Name).first, Name, Flags, - nullptr, Global); + assert(!find(name)); + syntheticGlobals.emplace_back(global); + return replaceSymbol<DefinedGlobal>(insertName(name).first, name, flags, + nullptr, global); } -static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, - uint32_t NewFlags) { +static bool shouldReplace(const Symbol *existing, InputFile *newFile, + uint32_t newFlags) { // If existing symbol is undefined, replace it. - if (!Existing->isDefined()) { + if (!existing->isDefined()) { LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " - << Existing->getName() << "\n"); + << existing->getName() << "\n"); return true; } // Now we have two defined symbols. If the new one is weak, we can ignore it. - if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { + if ((newFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); return false; } // If the existing symbol is weak, we should replace it. - if (Existing->isWeak()) { + if (existing->isWeak()) { LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); return true; } // Neither symbol is week. They conflict. - error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + - toString(Existing->getFile()) + "\n>>> defined in " + - toString(NewFile)); + error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " + + toString(existing->getFile()) + "\n>>> defined in " + + toString(newFile)); return true; } -Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, - InputFile *File, - InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" - << (Function ? toString(Function->Signature) : "none") +Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags, + InputFile *file, + InputFunction *function) { + LLVM_DEBUG(dbgs() << "addDefinedFunction: " << name << " [" + << (function ? toString(function->signature) : "none") << "]\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&](Symbol *Sym) { + auto replaceSym = [&](Symbol *sym) { // If the new defined function doesn't have signture (i.e. bitcode // functions) but the old symbol does, then preserve the old signature - const WasmSignature *OldSig = S->getSignature(); - auto* NewSym = replaceSymbol<DefinedFunction>(Sym, Name, Flags, File, Function); - if (!NewSym->Signature) - NewSym->Signature = OldSig; + const WasmSignature *oldSig = s->getSignature(); + auto* newSym = replaceSymbol<DefinedFunction>(sym, name, flags, file, function); + if (!newSym->signature) + newSym->signature = oldSig; }; - if (WasInserted || S->isLazy()) { - ReplaceSym(S); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(s); + return s; } - auto ExistingFunction = dyn_cast<FunctionSymbol>(S); - if (!ExistingFunction) { - reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION); - return S; + auto existingFunction = dyn_cast<FunctionSymbol>(s); + if (!existingFunction) { + reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION); + return s; } - bool CheckSig = true; - if (auto UD = dyn_cast<UndefinedFunction>(ExistingFunction)) - CheckSig = UD->IsCalledDirectly; + bool checkSig = true; + if (auto ud = dyn_cast<UndefinedFunction>(existingFunction)) + checkSig = ud->isCalledDirectly; - if (CheckSig && Function && !signatureMatches(ExistingFunction, &Function->Signature)) { - Symbol* Variant; - if (getFunctionVariant(S, &Function->Signature, File, &Variant)) + if (checkSig && function && !signatureMatches(existingFunction, &function->signature)) { + Symbol* variant; + if (getFunctionVariant(s, &function->signature, file, &variant)) // New variant, always replace - ReplaceSym(Variant); - else if (shouldReplace(S, File, Flags)) + replaceSym(variant); + else if (shouldReplace(s, file, flags)) // Variant already exists, replace it after checking shouldReplace - ReplaceSym(Variant); + replaceSym(variant); // This variant we found take the place in the symbol table as the primary // variant. - replace(Name, Variant); - return Variant; + replace(name, variant); + return variant; } // Existing function with matching signature. - if (shouldReplace(S, File, Flags)) - ReplaceSym(S); + if (shouldReplace(s, file, flags)) + replaceSym(s); - return S; + return s; } -Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, - InputFile *File, InputSegment *Segment, - uint32_t Address, uint32_t Size) { - LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address +Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags, + InputFile *file, InputSegment *segment, + uint32_t address, uint32_t size) { + LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); + auto replaceSym = [&]() { + replaceSymbol<DefinedData>(s, name, flags, file, segment, address, size); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkDataType(S, File); + checkDataType(s, file); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, - InputFile *File, InputGlobal *Global) { - LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); +Symbol *SymbolTable::addDefinedGlobal(StringRef name, uint32_t flags, + InputFile *file, InputGlobal *global) { + LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); + auto replaceSym = [&]() { + replaceSymbol<DefinedGlobal>(s, name, flags, file, global); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkGlobalType(S, File, &Global->getType()); + checkGlobalType(s, file, &global->getType()); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, - InputFile *File, InputEvent *Event) { - LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); +Symbol *SymbolTable::addDefinedEvent(StringRef name, uint32_t flags, + InputFile *file, InputEvent *event) { + LLVM_DEBUG(dbgs() << "addDefinedEvent:" << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); - auto ReplaceSym = [&]() { - replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); + auto replaceSym = [&]() { + replaceSymbol<DefinedEvent>(s, name, flags, file, event); }; - if (WasInserted || S->isLazy()) { - ReplaceSym(); - return S; + if (wasInserted || s->isLazy()) { + replaceSym(); + return s; } - checkEventType(S, File, &Event->getType(), &Event->Signature); + checkEventType(s, file, &event->getType(), &event->signature); - if (shouldReplace(S, File, Flags)) - ReplaceSym(); - return S; + if (shouldReplace(s, file, flags)) + replaceSym(); + return s; } -Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, - uint32_t Flags, InputFile *File, - const WasmSignature *Sig, - bool IsCalledDirectly) { - LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" - << (Sig ? toString(*Sig) : "none") - << "] IsCalledDirectly:" << IsCalledDirectly << "\n"); +Symbol *SymbolTable::addUndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, + uint32_t flags, InputFile *file, + const WasmSignature *sig, + bool isCalledDirectly) { + LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " [" + << (sig ? toString(*sig) : "none") + << "] IsCalledDirectly:" << isCalledDirectly << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - auto ReplaceSym = [&]() { - replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags, - File, Sig, IsCalledDirectly); + auto replaceSym = [&]() { + replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags, + file, sig, isCalledDirectly); }; - if (WasInserted) - ReplaceSym(); - else if (auto *Lazy = dyn_cast<LazySymbol>(S)) - Lazy->fetch(); + if (wasInserted) + replaceSym(); + else if (auto *lazy = dyn_cast<LazySymbol>(s)) + lazy->fetch(); else { - auto ExistingFunction = dyn_cast<FunctionSymbol>(S); - if (!ExistingFunction) { - reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION); - return S; + auto existingFunction = dyn_cast<FunctionSymbol>(s); + if (!existingFunction) { + reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION); + return s; } - if (!ExistingFunction->Signature && Sig) - ExistingFunction->Signature = Sig; - if (IsCalledDirectly && !signatureMatches(ExistingFunction, Sig)) - if (getFunctionVariant(S, Sig, File, &S)) - ReplaceSym(); + if (!existingFunction->signature && sig) + existingFunction->signature = sig; + if (isCalledDirectly && !signatureMatches(existingFunction, sig)) + if (getFunctionVariant(s, sig, file, &s)) + replaceSym(); } - return S; + return s; } -Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, - InputFile *File) { - LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); +Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags, + InputFile *file) { + LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - if (WasInserted) - replaceSymbol<UndefinedData>(S, Name, Flags, File); - else if (auto *Lazy = dyn_cast<LazySymbol>(S)) - Lazy->fetch(); - else if (S->isDefined()) - checkDataType(S, File); - return S; + if (wasInserted) + replaceSymbol<UndefinedData>(s, name, flags, file); + else if (auto *lazy = dyn_cast<LazySymbol>(s)) + lazy->fetch(); + else if (s->isDefined()) + checkDataType(s, file); + return s; } -Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, - const WasmGlobalType *Type) { - LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); +Symbol *SymbolTable::addUndefinedGlobal(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, + const WasmGlobalType *type) { + LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n"); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insert(Name, File); - if (S->Traced) - printTraceSymbolUndefined(Name, File); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name, file); + if (s->traced) + printTraceSymbolUndefined(name, file); - if (WasInserted) - replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags, - File, Type); - else if (auto *Lazy = dyn_cast<LazySymbol>(S)) - Lazy->fetch(); - else if (S->isDefined()) - checkGlobalType(S, File, Type); - return S; + if (wasInserted) + replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags, + file, type); + else if (auto *lazy = dyn_cast<LazySymbol>(s)) + lazy->fetch(); + else if (s->isDefined()) + checkGlobalType(s, file, type); + return s; } -void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { - LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); - StringRef Name = Sym->getName(); +void SymbolTable::addLazy(ArchiveFile *file, const Archive::Symbol *sym) { + LLVM_DEBUG(dbgs() << "addLazy: " << sym->getName() << "\n"); + StringRef name = sym->getName(); - Symbol *S; - bool WasInserted; - std::tie(S, WasInserted) = insertName(Name); + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insertName(name); - if (WasInserted) { - replaceSymbol<LazySymbol>(S, Name, 0, File, *Sym); + if (wasInserted) { + replaceSymbol<LazySymbol>(s, name, 0, file, *sym); return; } - if (!S->isUndefined()) + if (!s->isUndefined()) return; // The existing symbol is undefined, load a new one from the archive, // unless the the existing symbol is weak in which case replace the undefined // symbols with a LazySymbol. - if (S->isWeak()) { - const WasmSignature *OldSig = nullptr; + if (s->isWeak()) { + const WasmSignature *oldSig = nullptr; // In the case of an UndefinedFunction we need to preserve the expected // signature. - if (auto *F = dyn_cast<UndefinedFunction>(S)) - OldSig = F->Signature; + if (auto *f = dyn_cast<UndefinedFunction>(s)) + oldSig = f->signature; LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n"); - auto NewSym = replaceSymbol<LazySymbol>(S, Name, WASM_SYMBOL_BINDING_WEAK, - File, *Sym); - NewSym->Signature = OldSig; + auto newSym = replaceSymbol<LazySymbol>(s, name, WASM_SYMBOL_BINDING_WEAK, + file, *sym); + newSym->signature = oldSig; return; } LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); - File->addMember(Sym); + file->addMember(sym); } -bool SymbolTable::addComdat(StringRef Name) { - return ComdatGroups.insert(CachedHashStringRef(Name)).second; +bool SymbolTable::addComdat(StringRef name) { + return comdatGroups.insert(CachedHashStringRef(name)).second; } // The new signature doesn't match. Create a variant to the symbol with the // signature encoded in the name and return that instead. These symbols are // then unified later in handleSymbolVariants. -bool SymbolTable::getFunctionVariant(Symbol* Sym, const WasmSignature *Sig, - const InputFile *File, Symbol **Out) { - LLVM_DEBUG(dbgs() << "getFunctionVariant: " << Sym->getName() << " -> " - << " " << toString(*Sig) << "\n"); - Symbol *Variant = nullptr; +bool SymbolTable::getFunctionVariant(Symbol* sym, const WasmSignature *sig, + const InputFile *file, Symbol **out) { + LLVM_DEBUG(dbgs() << "getFunctionVariant: " << sym->getName() << " -> " + << " " << toString(*sig) << "\n"); + Symbol *variant = nullptr; // Linear search through symbol variants. Should never be more than two // or three entries here. - auto &Variants = SymVariants[CachedHashStringRef(Sym->getName())]; - if (Variants.empty()) - Variants.push_back(Sym); + auto &variants = symVariants[CachedHashStringRef(sym->getName())]; + if (variants.empty()) + variants.push_back(sym); - for (Symbol* V : Variants) { - if (*V->getSignature() == *Sig) { - Variant = V; + for (Symbol* v : variants) { + if (*v->getSignature() == *sig) { + variant = v; break; } } - bool WasAdded = !Variant; - if (WasAdded) { + bool wasAdded = !variant; + if (wasAdded) { // Create a new variant; LLVM_DEBUG(dbgs() << "added new variant\n"); - Variant = reinterpret_cast<Symbol *>(make<SymbolUnion>()); - Variants.push_back(Variant); + variant = reinterpret_cast<Symbol *>(make<SymbolUnion>()); + variants.push_back(variant); } else { - LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*Variant) << "\n"); - assert(*Variant->getSignature() == *Sig); + LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n"); + assert(*variant->getSignature() == *sig); } - *Out = Variant; - return WasAdded; + *out = variant; + return wasAdded; } // Set a flag for --trace-symbol so that we can print out a log message // if a new symbol with the same name is inserted into the symbol table. -void SymbolTable::trace(StringRef Name) { - SymMap.insert({CachedHashStringRef(Name), -1}); +void SymbolTable::trace(StringRef name) { + symMap.insert({CachedHashStringRef(name), -1}); } -void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) { +void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) { // Swap symbols as instructed by -wrap. - int &OrigIdx = SymMap[CachedHashStringRef(Sym->getName())]; - int &RealIdx= SymMap[CachedHashStringRef(Real->getName())]; - int &WrapIdx = SymMap[CachedHashStringRef(Wrap->getName())]; - LLVM_DEBUG(dbgs() << "wrap: " << Sym->getName() << "\n"); + int &origIdx = symMap[CachedHashStringRef(sym->getName())]; + int &realIdx= symMap[CachedHashStringRef(real->getName())]; + int &wrapIdx = symMap[CachedHashStringRef(wrap->getName())]; + LLVM_DEBUG(dbgs() << "wrap: " << sym->getName() << "\n"); // Anyone looking up __real symbols should get the original - RealIdx = OrigIdx; + realIdx = origIdx; // Anyone looking up the original should get the __wrap symbol - OrigIdx = WrapIdx; + origIdx = wrapIdx; } -static const uint8_t UnreachableFn[] = { +static const uint8_t unreachableFn[] = { 0x03 /* ULEB length */, 0x00 /* ULEB num locals */, 0x00 /* opcode unreachable */, 0x0b /* opcode end */ }; @@ -579,15 +579,15 @@ static const uint8_t UnreachableFn[] = { // This is used by handleWeakUndefines in order to generate a callable // equivalent of an undefined function and also handleSymbolVariants for // undefined functions that don't match the signature of the definition. -InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym, - const WasmSignature &Sig, - StringRef DebugName) { - auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName); - Func->setBody(UnreachableFn); - SyntheticFunctions.emplace_back(Func); - replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Sym->getFlags(), nullptr, - Func); - return Func; +InputFunction *SymbolTable::replaceWithUnreachable(Symbol *sym, + const WasmSignature &sig, + StringRef debugName) { + auto *func = make<SyntheticFunction>(sig, sym->getName(), debugName); + func->setBody(unreachableFn); + syntheticFunctions.emplace_back(func); + replaceSymbol<DefinedFunction>(sym, sym->getName(), sym->getFlags(), nullptr, + func); + return func; } // For weak undefined functions, there may be "call" instructions that reference @@ -595,41 +595,41 @@ InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym, // will abort at runtime, so that relocations can still provided an operand to // the call instruction that passes Wasm validation. void SymbolTable::handleWeakUndefines() { - for (Symbol *Sym : getSymbols()) { - if (!Sym->isUndefWeak()) + for (Symbol *sym : getSymbols()) { + if (!sym->isUndefWeak()) continue; - const WasmSignature *Sig = Sym->getSignature(); - if (!Sig) { + const WasmSignature *sig = sym->getSignature(); + if (!sig) { // It is possible for undefined functions not to have a signature (eg. if // added via "--undefined"), but weak undefined ones do have a signature. // Lazy symbols may not be functions and therefore Sig can still be null // in some circumstantce. - assert(!isa<FunctionSymbol>(Sym)); + assert(!isa<FunctionSymbol>(sym)); continue; } // Add a synthetic dummy for weak undefined functions. These dummies will // be GC'd if not used as the target of any "call" instructions. - StringRef DebugName = Saver.save("undefined:" + toString(*Sym)); - InputFunction* Func = replaceWithUnreachable(Sym, *Sig, DebugName); + StringRef debugName = saver.save("undefined:" + toString(*sym)); + InputFunction* func = replaceWithUnreachable(sym, *sig, debugName); // Ensure it compares equal to the null pointer, and so that table relocs // don't pull in the stub body (only call-operand relocs should do that). - Func->setTableIndex(0); + func->setTableIndex(0); // Hide our dummy to prevent export. - Sym->setHidden(true); + sym->setHidden(true); } } -static void reportFunctionSignatureMismatch(StringRef SymName, - FunctionSymbol *A, - FunctionSymbol *B, bool IsError) { - std::string msg = ("function signature mismatch: " + SymName + - "\n>>> defined as " + toString(*A->Signature) + " in " + - toString(A->getFile()) + "\n>>> defined as " + - toString(*B->Signature) + " in " + toString(B->getFile())) +static void reportFunctionSignatureMismatch(StringRef symName, + FunctionSymbol *a, + FunctionSymbol *b, bool isError) { + std::string msg = ("function signature mismatch: " + symName + + "\n>>> defined as " + toString(*a->signature) + " in " + + toString(a->getFile()) + "\n>>> defined as " + + toString(*b->signature) + " in " + toString(b->getFile())) .str(); - if (IsError) + if (isError) error(msg); else warn(msg); @@ -638,26 +638,26 @@ static void reportFunctionSignatureMismatch(StringRef SymName, // Remove any variant symbols that were created due to function signature // mismatches. void SymbolTable::handleSymbolVariants() { - for (auto Pair : SymVariants) { + for (auto pair : symVariants) { // Push the initial symbol onto the list of variants. - StringRef SymName = Pair.first.val(); - std::vector<Symbol *> &Variants = Pair.second; + StringRef symName = pair.first.val(); + std::vector<Symbol *> &variants = pair.second; #ifndef NDEBUG - LLVM_DEBUG(dbgs() << "symbol with (" << Variants.size() - << ") variants: " << SymName << "\n"); - for (auto *S: Variants) { - auto *F = cast<FunctionSymbol>(S); - LLVM_DEBUG(dbgs() << " variant: " + F->getName() << " " - << toString(*F->Signature) << "\n"); + LLVM_DEBUG(dbgs() << "symbol with (" << variants.size() + << ") variants: " << symName << "\n"); + for (auto *s: variants) { + auto *f = cast<FunctionSymbol>(s); + LLVM_DEBUG(dbgs() << " variant: " + f->getName() << " " + << toString(*f->signature) << "\n"); } #endif // Find the one definition. - DefinedFunction *Defined = nullptr; - for (auto *Symbol : Variants) { - if (auto F = dyn_cast<DefinedFunction>(Symbol)) { - Defined = F; + DefinedFunction *defined = nullptr; + for (auto *symbol : variants) { + if (auto f = dyn_cast<DefinedFunction>(symbol)) { + defined = f; break; } } @@ -665,19 +665,19 @@ void SymbolTable::handleSymbolVariants() { // If there are no definitions, and the undefined symbols disagree on // the signature, there is not we can do since we don't know which one // to use as the signature on the import. - if (!Defined) { - reportFunctionSignatureMismatch(SymName, - cast<FunctionSymbol>(Variants[0]), - cast<FunctionSymbol>(Variants[1]), true); + if (!defined) { + reportFunctionSignatureMismatch(symName, + cast<FunctionSymbol>(variants[0]), + cast<FunctionSymbol>(variants[1]), true); return; } - for (auto *Symbol : Variants) { - if (Symbol != Defined) { - auto *F = cast<FunctionSymbol>(Symbol); - reportFunctionSignatureMismatch(SymName, F, Defined, false); - StringRef DebugName = Saver.save("unreachable:" + toString(*F)); - replaceWithUnreachable(F, *F->Signature, DebugName); + for (auto *symbol : variants) { + if (symbol != defined) { + auto *f = cast<FunctionSymbol>(symbol); + reportFunctionSignatureMismatch(symName, f, defined, false); + StringRef debugName = saver.save("unreachable:" + toString(*f)); + replaceWithUnreachable(f, *f->signature, debugName); } } } diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index d98d3273c37..33f02ddaf91 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -35,89 +35,89 @@ class InputSegment; // There is one add* function per symbol type. class SymbolTable { public: - void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap); + void wrap(Symbol *sym, Symbol *real, Symbol *wrap); - void addFile(InputFile *File); + void addFile(InputFile *file); void addCombinedLTOObject(); - ArrayRef<Symbol *> getSymbols() const { return SymVector; } + ArrayRef<Symbol *> getSymbols() const { return symVector; } - Symbol *find(StringRef Name); + Symbol *find(StringRef name); - void replace(StringRef Name, Symbol* Sym); + void replace(StringRef name, Symbol* sym); - void trace(StringRef Name); + void trace(StringRef name); - Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, - InputFunction *Function); - Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File, - InputSegment *Segment, uint32_t Address, - uint32_t Size); - Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *G); - Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *E); + Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file, + InputFunction *function); + Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file, + InputSegment *segment, uint32_t address, + uint32_t size); + Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *g); + Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *e); - Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, const WasmSignature *Signature, - bool IsCalledDirectly); - Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); - Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File, const WasmGlobalType *Type); + Symbol *addUndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, const WasmSignature *signature, + bool isCalledDirectly); + Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file); + Symbol *addUndefinedGlobal(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file, const WasmGlobalType *type); - void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym); + void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym); - bool addComdat(StringRef Name); + bool addComdat(StringRef name); - DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); - DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, - InputGlobal *Global); - DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags, - InputFunction *Function); - DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value = 0, - uint32_t Flags = 0); + DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags); + DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags, + InputGlobal *global); + DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags, + InputFunction *function); + DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0, + uint32_t flags = 0); void handleSymbolVariants(); void handleWeakUndefines(); - std::vector<ObjFile *> ObjectFiles; - std::vector<SharedFile *> SharedFiles; - std::vector<BitcodeFile *> BitcodeFiles; - std::vector<InputFunction *> SyntheticFunctions; - std::vector<InputGlobal *> SyntheticGlobals; + std::vector<ObjFile *> objectFiles; + std::vector<SharedFile *> sharedFiles; + std::vector<BitcodeFile *> bitcodeFiles; + std::vector<InputFunction *> syntheticFunctions; + std::vector<InputGlobal *> syntheticGlobals; private: - std::pair<Symbol *, bool> insert(StringRef Name, const InputFile *File); - std::pair<Symbol *, bool> insertName(StringRef Name); + std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file); + std::pair<Symbol *, bool> insertName(StringRef name); - bool getFunctionVariant(Symbol* Sym, const WasmSignature *Sig, - const InputFile *File, Symbol **Out); - InputFunction *replaceWithUnreachable(Symbol *Sym, const WasmSignature &Sig, - StringRef DebugName); + bool getFunctionVariant(Symbol* sym, const WasmSignature *sig, + const InputFile *file, Symbol **out); + InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig, + StringRef debugName); // Maps symbol names to index into the SymVector. -1 means that symbols // is to not yet in the vector but it should have tracing enabled if it is // ever added. - llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap; - std::vector<Symbol *> SymVector; + llvm::DenseMap<llvm::CachedHashStringRef, int> symMap; + std::vector<Symbol *> symVector; // For certain symbols types, e.g. function symbols, we allow for muliple // variants of the same symbol with different signatures. - llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> SymVariants; + llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants; // Comdat groups define "link once" sections. If two comdat groups have the // same name, only one of them is linked, and the other is ignored. This set // is used to uniquify them. - llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups; + llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups; // For LTO. - std::unique_ptr<BitcodeCompiler> LTO; + std::unique_ptr<BitcodeCompiler> lto; }; -extern SymbolTable *Symtab; +extern SymbolTable *symtab; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 941f500732b..61868f37577 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -24,16 +24,16 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -DefinedFunction *WasmSym::CallCtors; -DefinedFunction *WasmSym::InitMemory; -DefinedFunction *WasmSym::ApplyRelocs; -DefinedData *WasmSym::DsoHandle; -DefinedData *WasmSym::DataEnd; -DefinedData *WasmSym::GlobalBase; -DefinedData *WasmSym::HeapBase; -GlobalSymbol *WasmSym::StackPointer; -UndefinedGlobal *WasmSym::TableBase; -UndefinedGlobal *WasmSym::MemoryBase; +DefinedFunction *WasmSym::callCtors; +DefinedFunction *WasmSym::initMemory; +DefinedFunction *WasmSym::applyRelocs; +DefinedData *WasmSym::dsoHandle; +DefinedData *WasmSym::dataEnd; +DefinedData *WasmSym::globalBase; +DefinedData *WasmSym::heapBase; +GlobalSymbol *WasmSym::stackPointer; +UndefinedGlobal *WasmSym::tableBase; +UndefinedGlobal *WasmSym::memoryBase; WasmSymbolType Symbol::getWasmType() const { if (isa<FunctionSymbol>(this)) @@ -50,248 +50,248 @@ WasmSymbolType Symbol::getWasmType() const { } const WasmSignature *Symbol::getSignature() const { - if (auto* F = dyn_cast<FunctionSymbol>(this)) - return F->Signature; - if (auto *L = dyn_cast<LazySymbol>(this)) - return L->Signature; + if (auto* f = dyn_cast<FunctionSymbol>(this)) + return f->signature; + if (auto *l = dyn_cast<LazySymbol>(this)) + return l->signature; return nullptr; } InputChunk *Symbol::getChunk() const { - if (auto *F = dyn_cast<DefinedFunction>(this)) - return F->Function; - if (auto *D = dyn_cast<DefinedData>(this)) - return D->Segment; + if (auto *f = dyn_cast<DefinedFunction>(this)) + return f->function; + if (auto *d = dyn_cast<DefinedData>(this)) + return d->segment; return nullptr; } bool Symbol::isDiscarded() const { - if (InputChunk *C = getChunk()) - return C->Discarded; + if (InputChunk *c = getChunk()) + return c->discarded; return false; } bool Symbol::isLive() const { - if (auto *G = dyn_cast<DefinedGlobal>(this)) - return G->Global->Live; - if (auto *E = dyn_cast<DefinedEvent>(this)) - return E->Event->Live; - if (InputChunk *C = getChunk()) - return C->Live; - return Referenced; + if (auto *g = dyn_cast<DefinedGlobal>(this)) + return g->global->live; + if (auto *e = dyn_cast<DefinedEvent>(this)) + return e->event->live; + if (InputChunk *c = getChunk()) + return c->live; + return referenced; } void Symbol::markLive() { assert(!isDiscarded()); - if (auto *G = dyn_cast<DefinedGlobal>(this)) - G->Global->Live = true; - if (auto *E = dyn_cast<DefinedEvent>(this)) - E->Event->Live = true; - if (InputChunk *C = getChunk()) - C->Live = true; - Referenced = true; + if (auto *g = dyn_cast<DefinedGlobal>(this)) + g->global->live = true; + if (auto *e = dyn_cast<DefinedEvent>(this)) + e->event->live = true; + if (InputChunk *c = getChunk()) + c->live = true; + referenced = true; } uint32_t Symbol::getOutputSymbolIndex() const { - assert(OutputSymbolIndex != INVALID_INDEX); - return OutputSymbolIndex; + assert(outputSymbolIndex != INVALID_INDEX); + return outputSymbolIndex; } -void Symbol::setOutputSymbolIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index +void Symbol::setOutputSymbolIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << name << " -> " << index << "\n"); - assert(OutputSymbolIndex == INVALID_INDEX); - OutputSymbolIndex = Index; + assert(outputSymbolIndex == INVALID_INDEX); + outputSymbolIndex = index; } -void Symbol::setGOTIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setGOTIndex " << Name << " -> " << Index << "\n"); - assert(GOTIndex == INVALID_INDEX); +void Symbol::setGOTIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setGOTIndex " << name << " -> " << index << "\n"); + assert(gotIndex == INVALID_INDEX); // Any symbol that is assigned a GOT entry must be exported othewise the // dynamic linker won't be able create the entry that contains it. - ForceExport = true; - GOTIndex = Index; + forceExport = true; + gotIndex = index; } bool Symbol::isWeak() const { - return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; + return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; } bool Symbol::isLocal() const { - return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; + return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; } bool Symbol::isHidden() const { - return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; + return (flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; } -void Symbol::setHidden(bool IsHidden) { - LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n"); - Flags &= ~WASM_SYMBOL_VISIBILITY_MASK; - if (IsHidden) - Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; +void Symbol::setHidden(bool isHidden) { + LLVM_DEBUG(dbgs() << "setHidden: " << name << " -> " << isHidden << "\n"); + flags &= ~WASM_SYMBOL_VISIBILITY_MASK; + if (isHidden) + flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; else - Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; + flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } bool Symbol::isExported() const { if (!isDefined() || isLocal()) return false; - if (ForceExport || Config->ExportAll) + if (forceExport || config->exportAll) return true; - if (Config->ExportDynamic && !isHidden()) + if (config->exportDynamic && !isHidden()) return true; - return Flags & WASM_SYMBOL_EXPORTED; + return flags & WASM_SYMBOL_EXPORTED; } uint32_t FunctionSymbol::getFunctionIndex() const { - if (auto *F = dyn_cast<DefinedFunction>(this)) - return F->Function->getFunctionIndex(); - assert(FunctionIndex != INVALID_INDEX); - return FunctionIndex; + if (auto *f = dyn_cast<DefinedFunction>(this)) + return f->function->getFunctionIndex(); + assert(functionIndex != INVALID_INDEX); + return functionIndex; } -void FunctionSymbol::setFunctionIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n"); - assert(FunctionIndex == INVALID_INDEX); - FunctionIndex = Index; +void FunctionSymbol::setFunctionIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setFunctionIndex " << name << " -> " << index << "\n"); + assert(functionIndex == INVALID_INDEX); + functionIndex = index; } bool FunctionSymbol::hasFunctionIndex() const { - if (auto *F = dyn_cast<DefinedFunction>(this)) - return F->Function->hasFunctionIndex(); - return FunctionIndex != INVALID_INDEX; + if (auto *f = dyn_cast<DefinedFunction>(this)) + return f->function->hasFunctionIndex(); + return functionIndex != INVALID_INDEX; } uint32_t FunctionSymbol::getTableIndex() const { - if (auto *F = dyn_cast<DefinedFunction>(this)) - return F->Function->getTableIndex(); - assert(TableIndex != INVALID_INDEX); - return TableIndex; + if (auto *f = dyn_cast<DefinedFunction>(this)) + return f->function->getTableIndex(); + assert(tableIndex != INVALID_INDEX); + return tableIndex; } bool FunctionSymbol::hasTableIndex() const { - if (auto *F = dyn_cast<DefinedFunction>(this)) - return F->Function->hasTableIndex(); - return TableIndex != INVALID_INDEX; + if (auto *f = dyn_cast<DefinedFunction>(this)) + return f->function->hasTableIndex(); + return tableIndex != INVALID_INDEX; } -void FunctionSymbol::setTableIndex(uint32_t Index) { +void FunctionSymbol::setTableIndex(uint32_t index) { // For imports, we set the table index here on the Symbol; for defined // functions we set the index on the InputFunction so that we don't export // the same thing twice (keeps the table size down). - if (auto *F = dyn_cast<DefinedFunction>(this)) { - F->Function->setTableIndex(Index); + if (auto *f = dyn_cast<DefinedFunction>(this)) { + f->function->setTableIndex(index); return; } - LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); - assert(TableIndex == INVALID_INDEX); - TableIndex = Index; + LLVM_DEBUG(dbgs() << "setTableIndex " << name << " -> " << index << "\n"); + assert(tableIndex == INVALID_INDEX); + tableIndex = index; } -DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, - InputFunction *Function) - : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, - Function ? &Function->Signature : nullptr), - Function(Function) {} +DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f, + InputFunction *function) + : FunctionSymbol(name, DefinedFunctionKind, flags, f, + function ? &function->signature : nullptr), + function(function) {} uint32_t DefinedData::getVirtualAddress() const { LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); - if (Segment) - return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset; - return Offset; + if (segment) + return segment->outputSeg->startVA + segment->outputSegmentOffset + offset; + return offset; } -void DefinedData::setVirtualAddress(uint32_t Value) { - LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); - assert(!Segment); - Offset = Value; +void DefinedData::setVirtualAddress(uint32_t value) { + LLVM_DEBUG(dbgs() << "setVirtualAddress " << name << " -> " << value << "\n"); + assert(!segment); + offset = value; } uint32_t DefinedData::getOutputSegmentOffset() const { LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); - return Segment->OutputSegmentOffset + Offset; + return segment->outputSegmentOffset + offset; } uint32_t DefinedData::getOutputSegmentIndex() const { LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n"); - return Segment->OutputSeg->Index; + return segment->outputSeg->index; } uint32_t GlobalSymbol::getGlobalIndex() const { - if (auto *F = dyn_cast<DefinedGlobal>(this)) - return F->Global->getGlobalIndex(); - assert(GlobalIndex != INVALID_INDEX); - return GlobalIndex; + if (auto *f = dyn_cast<DefinedGlobal>(this)) + return f->global->getGlobalIndex(); + assert(globalIndex != INVALID_INDEX); + return globalIndex; } -void GlobalSymbol::setGlobalIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n"); - assert(GlobalIndex == INVALID_INDEX); - GlobalIndex = Index; +void GlobalSymbol::setGlobalIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setGlobalIndex " << name << " -> " << index << "\n"); + assert(globalIndex == INVALID_INDEX); + globalIndex = index; } bool GlobalSymbol::hasGlobalIndex() const { - if (auto *F = dyn_cast<DefinedGlobal>(this)) - return F->Global->hasGlobalIndex(); - return GlobalIndex != INVALID_INDEX; + if (auto *f = dyn_cast<DefinedGlobal>(this)) + return f->global->hasGlobalIndex(); + return globalIndex != INVALID_INDEX; } -DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *Global) - : GlobalSymbol(Name, DefinedGlobalKind, Flags, File, - Global ? &Global->getType() : nullptr), - Global(Global) {} +DefinedGlobal::DefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *global) + : GlobalSymbol(name, DefinedGlobalKind, flags, file, + global ? &global->getType() : nullptr), + global(global) {} uint32_t EventSymbol::getEventIndex() const { - if (auto *F = dyn_cast<DefinedEvent>(this)) - return F->Event->getEventIndex(); - assert(EventIndex != INVALID_INDEX); - return EventIndex; + if (auto *f = dyn_cast<DefinedEvent>(this)) + return f->event->getEventIndex(); + assert(eventIndex != INVALID_INDEX); + return eventIndex; } -void EventSymbol::setEventIndex(uint32_t Index) { - LLVM_DEBUG(dbgs() << "setEventIndex " << Name << " -> " << Index << "\n"); - assert(EventIndex == INVALID_INDEX); - EventIndex = Index; +void EventSymbol::setEventIndex(uint32_t index) { + LLVM_DEBUG(dbgs() << "setEventIndex " << name << " -> " << index << "\n"); + assert(eventIndex == INVALID_INDEX); + eventIndex = index; } bool EventSymbol::hasEventIndex() const { - if (auto *F = dyn_cast<DefinedEvent>(this)) - return F->Event->hasEventIndex(); - return EventIndex != INVALID_INDEX; + if (auto *f = dyn_cast<DefinedEvent>(this)) + return f->event->hasEventIndex(); + return eventIndex != INVALID_INDEX; } -DefinedEvent::DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *Event) - : EventSymbol(Name, DefinedEventKind, Flags, File, - Event ? &Event->getType() : nullptr, - Event ? &Event->Signature : nullptr), - Event(Event) {} +DefinedEvent::DefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *event) + : EventSymbol(name, DefinedEventKind, flags, file, + event ? &event->getType() : nullptr, + event ? &event->signature : nullptr), + event(event) {} const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const { - assert(Section->OutputSec && Section->OutputSec->SectionSym); - return Section->OutputSec->SectionSym; + assert(section->outputSec && section->outputSec->sectionSym); + return section->outputSec->sectionSym; } -void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); } +void LazySymbol::fetch() { cast<ArchiveFile>(file)->addMember(&archiveSymbol); } -std::string lld::toString(const wasm::Symbol &Sym) { - return lld::maybeDemangleSymbol(Sym.getName()); +std::string lld::toString(const wasm::Symbol &sym) { + return lld::maybeDemangleSymbol(sym.getName()); } -std::string lld::maybeDemangleSymbol(StringRef Name) { - if (Config->Demangle) - if (Optional<std::string> S = demangleItanium(Name)) - return *S; - return Name; +std::string lld::maybeDemangleSymbol(StringRef name) { + if (config->demangle) + if (Optional<std::string> s = demangleItanium(name)) + return *s; + return name; } -std::string lld::toString(wasm::Symbol::Kind Kind) { - switch (Kind) { +std::string lld::toString(wasm::Symbol::Kind kind) { + switch (kind) { case wasm::Symbol::DefinedFunctionKind: return "DefinedFunction"; case wasm::Symbol::DefinedDataKind: @@ -317,24 +317,24 @@ std::string lld::toString(wasm::Symbol::Kind Kind) { } -void lld::wasm::printTraceSymbolUndefined(StringRef Name, const InputFile* File) { - message(toString(File) + ": reference to " + Name); +void lld::wasm::printTraceSymbolUndefined(StringRef name, const InputFile* file) { + message(toString(file) + ": reference to " + name); } // Print out a log message for --trace-symbol. -void lld::wasm::printTraceSymbol(Symbol *Sym) { +void lld::wasm::printTraceSymbol(Symbol *sym) { // Undefined symbols are traced via printTraceSymbolUndefined - if (Sym->isUndefined()) + if (sym->isUndefined()) return; - std::string S; - if (Sym->isLazy()) - S = ": lazy definition of "; + std::string s; + if (sym->isLazy()) + s = ": lazy definition of "; else - S = ": definition of "; + s = ": definition of "; - message(toString(Sym->getFile()) + S + Sym->getName()); + message(toString(sym->getFile()) + s + sym->getName()); } -const char *lld::wasm::DefaultModule = "env"; -const char *lld::wasm::FunctionTableName = "__indirect_function_table"; +const char *lld::wasm::defaultModule = "env"; +const char *lld::wasm::functionTableName = "__indirect_function_table"; diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index cb4691395eb..499a265be73 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -20,10 +20,10 @@ namespace wasm { // Shared string constants // The default module name to use for symbol imports. -extern const char *DefaultModule; +extern const char *defaultModule; // The name under which to import or export the wasm table. -extern const char *FunctionTableName; +extern const char *functionTableName; using llvm::wasm::WasmSymbolType; @@ -54,16 +54,16 @@ public: LazyKind, }; - Kind kind() const { return SymbolKind; } + Kind kind() const { return symbolKind; } bool isDefined() const { return !isLazy() && !isUndefined(); } bool isUndefined() const { - return SymbolKind == UndefinedFunctionKind || - SymbolKind == UndefinedDataKind || SymbolKind == UndefinedGlobalKind; + return symbolKind == UndefinedFunctionKind || + symbolKind == UndefinedDataKind || symbolKind == UndefinedGlobalKind; } - bool isLazy() const { return SymbolKind == LazyKind; } + bool isLazy() const { return symbolKind == LazyKind; } bool isLocal() const; bool isWeak() const; @@ -80,12 +80,12 @@ public: } // Returns the symbol name. - StringRef getName() const { return Name; } + StringRef getName() const { return name; } // Returns the file from which this symbol was created. - InputFile *getFile() const { return File; } + InputFile *getFile() const { return file; } - uint32_t getFlags() const { return Flags; } + uint32_t getFlags() const { return flags; } InputChunk *getChunk() const; @@ -97,120 +97,120 @@ public: // final image. void markLive(); - void setHidden(bool IsHidden); + void setHidden(bool isHidden); // Get/set the index in the output symbol table. This is only used for // relocatable output. uint32_t getOutputSymbolIndex() const; - void setOutputSymbolIndex(uint32_t Index); + void setOutputSymbolIndex(uint32_t index); WasmSymbolType getWasmType() const; bool isExported() const; const WasmSignature* getSignature() const; - bool isInGOT() const { return GOTIndex != INVALID_INDEX; } + bool isInGOT() const { return gotIndex != INVALID_INDEX; } uint32_t getGOTIndex() const { - assert(GOTIndex != INVALID_INDEX); - return GOTIndex; + assert(gotIndex != INVALID_INDEX); + return gotIndex; } - void setGOTIndex(uint32_t Index); - bool hasGOTIndex() const { return GOTIndex != INVALID_INDEX; } + void setGOTIndex(uint32_t index); + bool hasGOTIndex() const { return gotIndex != INVALID_INDEX; } protected: - Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) - : Name(Name), File(F), Flags(Flags), SymbolKind(K), - Referenced(!Config->GcSections), IsUsedInRegularObj(false), - ForceExport(false), CanInline(false), Traced(false) {} - - StringRef Name; - InputFile *File; - uint32_t Flags; - uint32_t OutputSymbolIndex = INVALID_INDEX; - uint32_t GOTIndex = INVALID_INDEX; - Kind SymbolKind; + Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f) + : name(name), file(f), flags(flags), symbolKind(k), + referenced(!config->gcSections), isUsedInRegularObj(false), + forceExport(false), canInline(false), traced(false) {} + + StringRef name; + InputFile *file; + uint32_t flags; + uint32_t outputSymbolIndex = INVALID_INDEX; + uint32_t gotIndex = INVALID_INDEX; + Kind symbolKind; public: - bool Referenced : 1; + bool referenced : 1; // True if the symbol was used for linking and thus need to be added to the // output file's symbol table. This is true for all symbols except for // unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that // are unreferenced except by other bitcode objects. - bool IsUsedInRegularObj : 1; + bool isUsedInRegularObj : 1; // True if ths symbol is explicity marked for export (i.e. via the -e/--export // command line flag) - bool ForceExport : 1; + bool forceExport : 1; // False if LTO shouldn't inline whatever this symbol points to. If a symbol // is overwritten after LTO, LTO shouldn't inline the symbol because it // doesn't know the final contents of the symbol. - bool CanInline : 1; + bool canInline : 1; // True if this symbol is specified by --trace-symbol option. - bool Traced : 1; + bool traced : 1; }; class FunctionSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedFunctionKind || - S->kind() == UndefinedFunctionKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedFunctionKind || + s->kind() == UndefinedFunctionKind; } // Get/set the table index - void setTableIndex(uint32_t Index); + void setTableIndex(uint32_t index); uint32_t getTableIndex() const; bool hasTableIndex() const; // Get/set the function index uint32_t getFunctionIndex() const; - void setFunctionIndex(uint32_t Index); + void setFunctionIndex(uint32_t index); bool hasFunctionIndex() const; - const WasmSignature *Signature; + const WasmSignature *signature; protected: - FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmSignature *Sig) - : Symbol(Name, K, Flags, F), Signature(Sig) {} + FunctionSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmSignature *sig) + : Symbol(name, k, flags, f), signature(sig) {} - uint32_t TableIndex = INVALID_INDEX; - uint32_t FunctionIndex = INVALID_INDEX; + uint32_t tableIndex = INVALID_INDEX; + uint32_t functionIndex = INVALID_INDEX; }; class DefinedFunction : public FunctionSymbol { public: - DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, - InputFunction *Function); + DefinedFunction(StringRef name, uint32_t flags, InputFile *f, + InputFunction *function); - static bool classof(const Symbol *S) { - return S->kind() == DefinedFunctionKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedFunctionKind; } - InputFunction *Function; + InputFunction *function; }; class UndefinedFunction : public FunctionSymbol { public: - UndefinedFunction(StringRef Name, StringRef ImportName, - StringRef ImportModule, uint32_t Flags, - InputFile *File = nullptr, - const WasmSignature *Type = nullptr, - bool IsCalledDirectly = true) - : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type), - ImportName(ImportName), ImportModule(ImportModule), IsCalledDirectly(IsCalledDirectly) {} - - static bool classof(const Symbol *S) { - return S->kind() == UndefinedFunctionKind; + UndefinedFunction(StringRef name, StringRef importName, + StringRef importModule, uint32_t flags, + InputFile *file = nullptr, + const WasmSignature *type = nullptr, + bool isCalledDirectly = true) + : FunctionSymbol(name, UndefinedFunctionKind, flags, file, type), + importName(importName), importModule(importModule), isCalledDirectly(isCalledDirectly) {} + + static bool classof(const Symbol *s) { + return s->kind() == UndefinedFunctionKind; } - StringRef ImportName; - StringRef ImportModule; - bool IsCalledDirectly; + StringRef importName; + StringRef importModule; + bool isCalledDirectly; }; // Section symbols for output sections are different from those for input @@ -218,128 +218,128 @@ public: // rather than an InputSection. class OutputSectionSymbol : public Symbol { public: - OutputSectionSymbol(const OutputSection *S) + OutputSectionSymbol(const OutputSection *s) : Symbol("", OutputSectionKind, llvm::wasm::WASM_SYMBOL_BINDING_LOCAL, nullptr), - Section(S) {} + section(s) {} - static bool classof(const Symbol *S) { - return S->kind() == OutputSectionKind; + static bool classof(const Symbol *s) { + return s->kind() == OutputSectionKind; } - const OutputSection *Section; + const OutputSection *section; }; class SectionSymbol : public Symbol { public: - SectionSymbol(uint32_t Flags, const InputSection *S, InputFile *F = nullptr) - : Symbol("", SectionKind, Flags, F), Section(S) {} + SectionSymbol(uint32_t flags, const InputSection *s, InputFile *f = nullptr) + : Symbol("", SectionKind, flags, f), section(s) {} - static bool classof(const Symbol *S) { return S->kind() == SectionKind; } + static bool classof(const Symbol *s) { return s->kind() == SectionKind; } const OutputSectionSymbol *getOutputSectionSymbol() const; - const InputSection *Section; + const InputSection *section; }; class DataSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedDataKind || S->kind() == UndefinedDataKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedDataKind || s->kind() == UndefinedDataKind; } protected: - DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) - : Symbol(Name, K, Flags, F) {} + DataSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f) + : Symbol(name, k, flags, f) {} }; class DefinedData : public DataSymbol { public: // Constructor for regular data symbols originating from input files. - DefinedData(StringRef Name, uint32_t Flags, InputFile *F, - InputSegment *Segment, uint32_t Offset, uint32_t Size) - : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment), - Offset(Offset), Size(Size) {} + DefinedData(StringRef name, uint32_t flags, InputFile *f, + InputSegment *segment, uint32_t offset, uint32_t size) + : DataSymbol(name, DefinedDataKind, flags, f), segment(segment), + offset(offset), size(size) {} // Constructor for linker synthetic data symbols. - DefinedData(StringRef Name, uint32_t Flags) - : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {} + DefinedData(StringRef name, uint32_t flags) + : DataSymbol(name, DefinedDataKind, flags, nullptr) {} - static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedDataKind; } // Returns the output virtual address of a defined data symbol. uint32_t getVirtualAddress() const; - void setVirtualAddress(uint32_t VA); + void setVirtualAddress(uint32_t va); // Returns the offset of a defined data symbol within its OutputSegment. uint32_t getOutputSegmentOffset() const; uint32_t getOutputSegmentIndex() const; - uint32_t getSize() const { return Size; } + uint32_t getSize() const { return size; } - InputSegment *Segment = nullptr; + InputSegment *segment = nullptr; protected: - uint32_t Offset = 0; - uint32_t Size = 0; + uint32_t offset = 0; + uint32_t size = 0; }; class UndefinedData : public DataSymbol { public: - UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr) - : DataSymbol(Name, UndefinedDataKind, Flags, File) {} - static bool classof(const Symbol *S) { - return S->kind() == UndefinedDataKind; + UndefinedData(StringRef name, uint32_t flags, InputFile *file = nullptr) + : DataSymbol(name, UndefinedDataKind, flags, file) {} + static bool classof(const Symbol *s) { + return s->kind() == UndefinedDataKind; } }; class GlobalSymbol : public Symbol { public: - static bool classof(const Symbol *S) { - return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedGlobalKind || s->kind() == UndefinedGlobalKind; } - const WasmGlobalType *getGlobalType() const { return GlobalType; } + const WasmGlobalType *getGlobalType() const { return globalType; } // Get/set the global index uint32_t getGlobalIndex() const; - void setGlobalIndex(uint32_t Index); + void setGlobalIndex(uint32_t index); bool hasGlobalIndex() const; protected: - GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmGlobalType *GlobalType) - : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {} + GlobalSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmGlobalType *globalType) + : Symbol(name, k, flags, f), globalType(globalType) {} - const WasmGlobalType *GlobalType; - uint32_t GlobalIndex = INVALID_INDEX; + const WasmGlobalType *globalType; + uint32_t globalIndex = INVALID_INDEX; }; class DefinedGlobal : public GlobalSymbol { public: - DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - InputGlobal *Global); + DefinedGlobal(StringRef name, uint32_t flags, InputFile *file, + InputGlobal *global); - static bool classof(const Symbol *S) { - return S->kind() == DefinedGlobalKind; + static bool classof(const Symbol *s) { + return s->kind() == DefinedGlobalKind; } - InputGlobal *Global; + InputGlobal *global; }; class UndefinedGlobal : public GlobalSymbol { public: - UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule, - uint32_t Flags, InputFile *File = nullptr, - const WasmGlobalType *Type = nullptr) - : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type), - ImportName(ImportName), ImportModule(ImportModule) {} - - static bool classof(const Symbol *S) { - return S->kind() == UndefinedGlobalKind; + UndefinedGlobal(StringRef name, StringRef importName, StringRef importModule, + uint32_t flags, InputFile *file = nullptr, + const WasmGlobalType *type = nullptr) + : GlobalSymbol(name, UndefinedGlobalKind, flags, file, type), + importName(importName), importModule(importModule) {} + + static bool classof(const Symbol *s) { + return s->kind() == UndefinedGlobalKind; } - StringRef ImportName; - StringRef ImportModule; + StringRef importName; + StringRef importModule; }; // Wasm events are features that suspend the current execution and transfer the @@ -356,34 +356,34 @@ public: // are used, and has name '__cpp_exception' for linking. class EventSymbol : public Symbol { public: - static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; } - const WasmEventType *getEventType() const { return EventType; } + const WasmEventType *getEventType() const { return eventType; } // Get/set the event index uint32_t getEventIndex() const; - void setEventIndex(uint32_t Index); + void setEventIndex(uint32_t index); bool hasEventIndex() const; - const WasmSignature *Signature; + const WasmSignature *signature; protected: - EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, - const WasmEventType *EventType, const WasmSignature *Sig) - : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {} + EventSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f, + const WasmEventType *eventType, const WasmSignature *sig) + : Symbol(name, k, flags, f), signature(sig), eventType(eventType) {} - const WasmEventType *EventType; - uint32_t EventIndex = INVALID_INDEX; + const WasmEventType *eventType; + uint32_t eventIndex = INVALID_INDEX; }; class DefinedEvent : public EventSymbol { public: - DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, - InputEvent *Event); + DefinedEvent(StringRef name, uint32_t flags, InputFile *file, + InputEvent *event); - static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; } + static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; } - InputEvent *Event; + InputEvent *event; }; // LazySymbol represents a symbol that is not yet in the link, but we know where @@ -397,11 +397,11 @@ public: // symbols into consideration. class LazySymbol : public Symbol { public: - LazySymbol(StringRef Name, uint32_t Flags, InputFile *File, - const llvm::object::Archive::Symbol &Sym) - : Symbol(Name, LazyKind, Flags, File), ArchiveSymbol(Sym) {} + LazySymbol(StringRef name, uint32_t flags, InputFile *file, + const llvm::object::Archive::Symbol &sym) + : Symbol(name, LazyKind, flags, file), archiveSymbol(sym) {} - static bool classof(const Symbol *S) { return S->kind() == LazyKind; } + static bool classof(const Symbol *s) { return s->kind() == LazyKind; } void fetch(); // Lazy symbols can have a signature because they can replace an @@ -409,71 +409,71 @@ public: // signture. // TODO(sbc): This repetition of the signature field is inelegant. Revisit // the use of class hierarchy to represent symbol taxonomy. - const WasmSignature *Signature = nullptr; + const WasmSignature *signature = nullptr; private: - llvm::object::Archive::Symbol ArchiveSymbol; + llvm::object::Archive::Symbol archiveSymbol; }; // linker-generated symbols struct WasmSym { // __global_base // Symbol marking the start of the global section. - static DefinedData *GlobalBase; + static DefinedData *globalBase; // __stack_pointer // Global that holds the address of the top of the explicit value stack in // linear memory. - static GlobalSymbol *StackPointer; + static GlobalSymbol *stackPointer; // __data_end // Symbol marking the end of the data and bss. - static DefinedData *DataEnd; + static DefinedData *dataEnd; // __heap_base // Symbol marking the end of the data, bss and explicit stack. Any linear // memory following this address is not used by the linked code and can // therefore be used as a backing store for brk()/malloc() implementations. - static DefinedData *HeapBase; + static DefinedData *heapBase; // __wasm_call_ctors // Function that directly calls all ctors in priority order. - static DefinedFunction *CallCtors; + static DefinedFunction *callCtors; // __wasm_init_memory // Function that initializes passive data segments post-instantiation. - static DefinedFunction *InitMemory; + static DefinedFunction *initMemory; // __wasm_apply_relocs // Function that applies relocations to data segment post-instantiation. - static DefinedFunction *ApplyRelocs; + static DefinedFunction *applyRelocs; // __dso_handle // Symbol used in calls to __cxa_atexit to determine current DLL - static DefinedData *DsoHandle; + static DefinedData *dsoHandle; // __table_base // Used in PIC code for offset of indirect function table - static UndefinedGlobal *TableBase; + static UndefinedGlobal *tableBase; // __memory_base // Used in PIC code for offset of global data - static UndefinedGlobal *MemoryBase; + static UndefinedGlobal *memoryBase; }; // A buffer class that is large enough to hold any Symbol-derived // object. We allocate memory using this class and instantiate a symbol // using the placement new. union SymbolUnion { - alignas(DefinedFunction) char A[sizeof(DefinedFunction)]; - alignas(DefinedData) char B[sizeof(DefinedData)]; - alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)]; - alignas(DefinedEvent) char D[sizeof(DefinedEvent)]; - alignas(LazySymbol) char E[sizeof(LazySymbol)]; - alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)]; - alignas(UndefinedData) char G[sizeof(UndefinedData)]; - alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)]; - alignas(SectionSymbol) char I[sizeof(SectionSymbol)]; + alignas(DefinedFunction) char a[sizeof(DefinedFunction)]; + alignas(DefinedData) char b[sizeof(DefinedData)]; + alignas(DefinedGlobal) char c[sizeof(DefinedGlobal)]; + alignas(DefinedEvent) char d[sizeof(DefinedEvent)]; + alignas(LazySymbol) char e[sizeof(LazySymbol)]; + alignas(UndefinedFunction) char f[sizeof(UndefinedFunction)]; + alignas(UndefinedData) char g[sizeof(UndefinedData)]; + alignas(UndefinedGlobal) char h[sizeof(UndefinedGlobal)]; + alignas(SectionSymbol) char i[sizeof(SectionSymbol)]; }; // It is important to keep the size of SymbolUnion small for performance and @@ -481,11 +481,11 @@ union SymbolUnion { // UndefinedFunction on a 64-bit system. static_assert(sizeof(SymbolUnion) <= 96, "SymbolUnion too large"); -void printTraceSymbol(Symbol *Sym); -void printTraceSymbolUndefined(StringRef Name, const InputFile* File); +void printTraceSymbol(Symbol *sym); +void printTraceSymbolUndefined(StringRef name, const InputFile* file); template <typename T, typename... ArgT> -T *replaceSymbol(Symbol *S, ArgT &&... Arg) { +T *replaceSymbol(Symbol *s, ArgT &&... arg) { static_assert(std::is_trivially_destructible<T>(), "Symbol types must be trivially destructible"); static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); @@ -494,28 +494,28 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) { assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr && "Not a Symbol"); - Symbol SymCopy = *S; + Symbol symCopy = *s; - T *S2 = new (S) T(std::forward<ArgT>(Arg)...); - S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj; - S2->ForceExport = SymCopy.ForceExport; - S2->CanInline = SymCopy.CanInline; - S2->Traced = SymCopy.Traced; + T *s2 = new (s) T(std::forward<ArgT>(arg)...); + s2->isUsedInRegularObj = symCopy.isUsedInRegularObj; + s2->forceExport = symCopy.forceExport; + s2->canInline = symCopy.canInline; + s2->traced = symCopy.traced; // Print out a log message if --trace-symbol was specified. // This is for debugging. - if (S2->Traced) - printTraceSymbol(S2); + if (s2->traced) + printTraceSymbol(s2); - return S2; + return s2; } } // namespace wasm // Returns a symbol name for an error message. -std::string toString(const wasm::Symbol &Sym); -std::string toString(wasm::Symbol::Kind Kind); -std::string maybeDemangleSymbol(StringRef Name); +std::string toString(const wasm::Symbol &sym); +std::string toString(wasm::Symbol::Kind kind); +std::string maybeDemangleSymbol(StringRef name); } // namespace lld diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index 8e8a0a13da8..020d2c0b992 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -25,7 +25,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -OutStruct lld::wasm::Out; +OutStruct lld::wasm::out; namespace { @@ -36,512 +36,512 @@ namespace { // of the parent section. class SubSection { public: - explicit SubSection(uint32_t Type) : Type(Type) {} + explicit SubSection(uint32_t type) : type(type) {} - void writeTo(raw_ostream &To) { - OS.flush(); - writeUleb128(To, Type, "subsection type"); - writeUleb128(To, Body.size(), "subsection size"); - To.write(Body.data(), Body.size()); + void writeTo(raw_ostream &to) { + os.flush(); + writeUleb128(to, type, "subsection type"); + writeUleb128(to, body.size(), "subsection size"); + to.write(body.data(), body.size()); } private: - uint32_t Type; - std::string Body; + uint32_t type; + std::string body; public: - raw_string_ostream OS{Body}; + raw_string_ostream os{body}; }; } // namespace void DylinkSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, MemSize, "MemSize"); - writeUleb128(OS, MemAlign, "MemAlign"); - writeUleb128(OS, Out.ElemSec->numEntries(), "TableSize"); - writeUleb128(OS, 0, "TableAlign"); - writeUleb128(OS, Symtab->SharedFiles.size(), "Needed"); - for (auto *SO : Symtab->SharedFiles) - writeStr(OS, llvm::sys::path::filename(SO->getName()), "so name"); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, memSize, "MemSize"); + writeUleb128(os, memAlign, "MemAlign"); + writeUleb128(os, out.elemSec->numEntries(), "TableSize"); + writeUleb128(os, 0, "TableAlign"); + writeUleb128(os, symtab->sharedFiles.size(), "Needed"); + for (auto *so : symtab->sharedFiles) + writeStr(os, llvm::sys::path::filename(so->getName()), "so name"); } -uint32_t TypeSection::registerType(const WasmSignature &Sig) { - auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); - if (Pair.second) { - LLVM_DEBUG(llvm::dbgs() << "type " << toString(Sig) << "\n"); - Types.push_back(&Sig); +uint32_t TypeSection::registerType(const WasmSignature &sig) { + auto pair = typeIndices.insert(std::make_pair(sig, types.size())); + if (pair.second) { + LLVM_DEBUG(llvm::dbgs() << "type " << toString(sig) << "\n"); + types.push_back(&sig); } - return Pair.first->second; + return pair.first->second; } -uint32_t TypeSection::lookupType(const WasmSignature &Sig) { - auto It = TypeIndices.find(Sig); - if (It == TypeIndices.end()) { - error("type not found: " + toString(Sig)); +uint32_t TypeSection::lookupType(const WasmSignature &sig) { + auto it = typeIndices.find(sig); + if (it == typeIndices.end()) { + error("type not found: " + toString(sig)); return 0; } - return It->second; + return it->second; } void TypeSection::writeBody() { - writeUleb128(BodyOutputStream, Types.size(), "type count"); - for (const WasmSignature *Sig : Types) - writeSig(BodyOutputStream, *Sig); + writeUleb128(bodyOutputStream, types.size(), "type count"); + for (const WasmSignature *sig : types) + writeSig(bodyOutputStream, *sig); } uint32_t ImportSection::getNumImports() const { - assert(IsSealed); - uint32_t NumImports = ImportedSymbols.size() + GOTSymbols.size(); - if (Config->ImportMemory) - ++NumImports; - if (Config->ImportTable) - ++NumImports; - return NumImports; + assert(isSealed); + uint32_t numImports = importedSymbols.size() + gotSymbols.size(); + if (config->importMemory) + ++numImports; + if (config->importTable) + ++numImports; + return numImports; } -void ImportSection::addGOTEntry(Symbol *Sym) { - assert(!IsSealed); - if (Sym->hasGOTIndex()) +void ImportSection::addGOTEntry(Symbol *sym) { + assert(!isSealed); + if (sym->hasGOTIndex()) return; - Sym->setGOTIndex(NumImportedGlobals++); - GOTSymbols.push_back(Sym); + sym->setGOTIndex(numImportedGlobals++); + gotSymbols.push_back(sym); } -void ImportSection::addImport(Symbol *Sym) { - assert(!IsSealed); - ImportedSymbols.emplace_back(Sym); - if (auto *F = dyn_cast<FunctionSymbol>(Sym)) - F->setFunctionIndex(NumImportedFunctions++); - else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) - G->setGlobalIndex(NumImportedGlobals++); +void ImportSection::addImport(Symbol *sym) { + assert(!isSealed); + importedSymbols.emplace_back(sym); + if (auto *f = dyn_cast<FunctionSymbol>(sym)) + f->setFunctionIndex(numImportedFunctions++); + else if (auto *g = dyn_cast<GlobalSymbol>(sym)) + g->setGlobalIndex(numImportedGlobals++); else - cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++); + cast<EventSymbol>(sym)->setEventIndex(numImportedEvents++); } void ImportSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, getNumImports(), "import count"); - - if (Config->ImportMemory) { - WasmImport Import; - Import.Module = DefaultModule; - Import.Field = "memory"; - Import.Kind = WASM_EXTERNAL_MEMORY; - Import.Memory.Flags = 0; - Import.Memory.Initial = Out.MemorySec->NumMemoryPages; - if (Out.MemorySec->MaxMemoryPages != 0 || Config->SharedMemory) { - Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; - Import.Memory.Maximum = Out.MemorySec->MaxMemoryPages; + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, getNumImports(), "import count"); + + if (config->importMemory) { + WasmImport import; + import.Module = defaultModule; + import.Field = "memory"; + import.Kind = WASM_EXTERNAL_MEMORY; + import.Memory.Flags = 0; + import.Memory.Initial = out.memorySec->numMemoryPages; + if (out.memorySec->maxMemoryPages != 0 || config->sharedMemory) { + import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; + import.Memory.Maximum = out.memorySec->maxMemoryPages; } - if (Config->SharedMemory) - Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; - writeImport(OS, Import); + if (config->sharedMemory) + import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; + writeImport(os, import); } - if (Config->ImportTable) { - uint32_t TableSize = Out.ElemSec->ElemOffset + Out.ElemSec->numEntries(); - WasmImport Import; - Import.Module = DefaultModule; - Import.Field = FunctionTableName; - Import.Kind = WASM_EXTERNAL_TABLE; - Import.Table.ElemType = WASM_TYPE_FUNCREF; - Import.Table.Limits = {0, TableSize, 0}; - writeImport(OS, Import); + if (config->importTable) { + uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); + WasmImport import; + import.Module = defaultModule; + import.Field = functionTableName; + import.Kind = WASM_EXTERNAL_TABLE; + import.Table.ElemType = WASM_TYPE_FUNCREF; + import.Table.Limits = {0, tableSize, 0}; + writeImport(os, import); } - for (const Symbol *Sym : ImportedSymbols) { - WasmImport Import; - if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { - Import.Field = F->ImportName; - Import.Module = F->ImportModule; - } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { - Import.Field = G->ImportName; - Import.Module = G->ImportModule; + for (const Symbol *sym : importedSymbols) { + WasmImport import; + if (auto *f = dyn_cast<UndefinedFunction>(sym)) { + import.Field = f->importName; + import.Module = f->importModule; + } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) { + import.Field = g->importName; + import.Module = g->importModule; } else { - Import.Field = Sym->getName(); - Import.Module = DefaultModule; + import.Field = sym->getName(); + import.Module = defaultModule; } - if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) { - Import.Kind = WASM_EXTERNAL_FUNCTION; - Import.SigIndex = Out.TypeSec->lookupType(*FunctionSym->Signature); - } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) { - Import.Kind = WASM_EXTERNAL_GLOBAL; - Import.Global = *GlobalSym->getGlobalType(); + if (auto *functionSym = dyn_cast<FunctionSymbol>(sym)) { + import.Kind = WASM_EXTERNAL_FUNCTION; + import.SigIndex = out.typeSec->lookupType(*functionSym->signature); + } else if (auto *globalSym = dyn_cast<GlobalSymbol>(sym)) { + import.Kind = WASM_EXTERNAL_GLOBAL; + import.Global = *globalSym->getGlobalType(); } else { - auto *EventSym = cast<EventSymbol>(Sym); - Import.Kind = WASM_EXTERNAL_EVENT; - Import.Event.Attribute = EventSym->getEventType()->Attribute; - Import.Event.SigIndex = Out.TypeSec->lookupType(*EventSym->Signature); + auto *eventSym = cast<EventSymbol>(sym); + import.Kind = WASM_EXTERNAL_EVENT; + import.Event.Attribute = eventSym->getEventType()->Attribute; + import.Event.SigIndex = out.typeSec->lookupType(*eventSym->signature); } - writeImport(OS, Import); + writeImport(os, import); } - for (const Symbol *Sym : GOTSymbols) { - WasmImport Import; - Import.Kind = WASM_EXTERNAL_GLOBAL; - Import.Global = {WASM_TYPE_I32, true}; - if (isa<DataSymbol>(Sym)) - Import.Module = "GOT.mem"; + for (const Symbol *sym : gotSymbols) { + WasmImport import; + import.Kind = WASM_EXTERNAL_GLOBAL; + import.Global = {WASM_TYPE_I32, true}; + if (isa<DataSymbol>(sym)) + import.Module = "GOT.mem"; else - Import.Module = "GOT.func"; - Import.Field = Sym->getName(); - writeImport(OS, Import); + import.Module = "GOT.func"; + import.Field = sym->getName(); + writeImport(os, import); } } void FunctionSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, InputFunctions.size(), "function count"); - for (const InputFunction *Func : InputFunctions) - writeUleb128(OS, Out.TypeSec->lookupType(Func->Signature), "sig index"); + writeUleb128(os, inputFunctions.size(), "function count"); + for (const InputFunction *func : inputFunctions) + writeUleb128(os, out.typeSec->lookupType(func->signature), "sig index"); } -void FunctionSection::addFunction(InputFunction *Func) { - if (!Func->Live) +void FunctionSection::addFunction(InputFunction *func) { + if (!func->live) return; - uint32_t FunctionIndex = - Out.ImportSec->getNumImportedFunctions() + InputFunctions.size(); - InputFunctions.emplace_back(Func); - Func->setFunctionIndex(FunctionIndex); + uint32_t functionIndex = + out.importSec->getNumImportedFunctions() + inputFunctions.size(); + inputFunctions.emplace_back(func); + func->setFunctionIndex(functionIndex); } void TableSection::writeBody() { - uint32_t TableSize = Out.ElemSec->ElemOffset + Out.ElemSec->numEntries(); + uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); - raw_ostream &OS = BodyOutputStream; - writeUleb128(OS, 1, "table count"); - WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; - writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits}); + raw_ostream &os = bodyOutputStream; + writeUleb128(os, 1, "table count"); + WasmLimits limits = {WASM_LIMITS_FLAG_HAS_MAX, tableSize, tableSize}; + writeTableType(os, WasmTable{WASM_TYPE_FUNCREF, limits}); } void MemorySection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - bool HasMax = MaxMemoryPages != 0 || Config->SharedMemory; - writeUleb128(OS, 1, "memory count"); - unsigned Flags = 0; - if (HasMax) - Flags |= WASM_LIMITS_FLAG_HAS_MAX; - if (Config->SharedMemory) - Flags |= WASM_LIMITS_FLAG_IS_SHARED; - writeUleb128(OS, Flags, "memory limits flags"); - writeUleb128(OS, NumMemoryPages, "initial pages"); - if (HasMax) - writeUleb128(OS, MaxMemoryPages, "max pages"); + raw_ostream &os = bodyOutputStream; + + bool hasMax = maxMemoryPages != 0 || config->sharedMemory; + writeUleb128(os, 1, "memory count"); + unsigned flags = 0; + if (hasMax) + flags |= WASM_LIMITS_FLAG_HAS_MAX; + if (config->sharedMemory) + flags |= WASM_LIMITS_FLAG_IS_SHARED; + writeUleb128(os, flags, "memory limits flags"); + writeUleb128(os, numMemoryPages, "initial pages"); + if (hasMax) + writeUleb128(os, maxMemoryPages, "max pages"); } void GlobalSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, numGlobals(), "global count"); - for (const InputGlobal *G : InputGlobals) - writeGlobal(OS, G->Global); - for (const DefinedData *Sym : DefinedFakeGlobals) { - WasmGlobal Global; - Global.Type = {WASM_TYPE_I32, false}; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); - writeGlobal(OS, Global); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, numGlobals(), "global count"); + for (const InputGlobal *g : inputGlobals) + writeGlobal(os, g->global); + for (const DefinedData *sym : definedFakeGlobals) { + WasmGlobal global; + global.Type = {WASM_TYPE_I32, false}; + global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + global.InitExpr.Value.Int32 = sym->getVirtualAddress(); + writeGlobal(os, global); } } -void GlobalSection::addGlobal(InputGlobal *Global) { - if (!Global->Live) +void GlobalSection::addGlobal(InputGlobal *global) { + if (!global->live) return; - uint32_t GlobalIndex = - Out.ImportSec->getNumImportedGlobals() + InputGlobals.size(); - LLVM_DEBUG(dbgs() << "addGlobal: " << GlobalIndex << "\n"); - Global->setGlobalIndex(GlobalIndex); - Out.GlobalSec->InputGlobals.push_back(Global); + uint32_t globalIndex = + out.importSec->getNumImportedGlobals() + inputGlobals.size(); + LLVM_DEBUG(dbgs() << "addGlobal: " << globalIndex << "\n"); + global->setGlobalIndex(globalIndex); + out.globalSec->inputGlobals.push_back(global); } void EventSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, InputEvents.size(), "event count"); - for (InputEvent *E : InputEvents) { - E->Event.Type.SigIndex = Out.TypeSec->lookupType(E->Signature); - writeEvent(OS, E->Event); + writeUleb128(os, inputEvents.size(), "event count"); + for (InputEvent *e : inputEvents) { + e->event.Type.SigIndex = out.typeSec->lookupType(e->signature); + writeEvent(os, e->event); } } -void EventSection::addEvent(InputEvent *Event) { - if (!Event->Live) +void EventSection::addEvent(InputEvent *event) { + if (!event->live) return; - uint32_t EventIndex = - Out.ImportSec->getNumImportedEvents() + InputEvents.size(); - LLVM_DEBUG(dbgs() << "addEvent: " << EventIndex << "\n"); - Event->setEventIndex(EventIndex); - InputEvents.push_back(Event); + uint32_t eventIndex = + out.importSec->getNumImportedEvents() + inputEvents.size(); + LLVM_DEBUG(dbgs() << "addEvent: " << eventIndex << "\n"); + event->setEventIndex(eventIndex); + inputEvents.push_back(event); } void ExportSection::writeBody() { - raw_ostream &OS = BodyOutputStream; + raw_ostream &os = bodyOutputStream; - writeUleb128(OS, Exports.size(), "export count"); - for (const WasmExport &Export : Exports) - writeExport(OS, Export); + writeUleb128(os, exports.size(), "export count"); + for (const WasmExport &export_ : exports) + writeExport(os, export_); } -void ElemSection::addEntry(FunctionSymbol *Sym) { - if (Sym->hasTableIndex()) +void ElemSection::addEntry(FunctionSymbol *sym) { + if (sym->hasTableIndex()) return; - Sym->setTableIndex(ElemOffset + IndirectFunctions.size()); - IndirectFunctions.emplace_back(Sym); + sym->setTableIndex(elemOffset + indirectFunctions.size()); + indirectFunctions.emplace_back(sym); } void ElemSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, 1, "segment count"); - writeUleb128(OS, 0, "table index"); - WasmInitExpr InitExpr; - if (Config->Pic) { - InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex(); + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, 1, "segment count"); + writeUleb128(os, 0, "table index"); + WasmInitExpr initExpr; + if (config->isPic) { + initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Value.Global = WasmSym::tableBase->getGlobalIndex(); } else { - InitExpr.Opcode = WASM_OPCODE_I32_CONST; - InitExpr.Value.Int32 = ElemOffset; + initExpr.Opcode = WASM_OPCODE_I32_CONST; + initExpr.Value.Int32 = elemOffset; } - writeInitExpr(OS, InitExpr); - writeUleb128(OS, IndirectFunctions.size(), "elem count"); - - uint32_t TableIndex = ElemOffset; - for (const FunctionSymbol *Sym : IndirectFunctions) { - assert(Sym->getTableIndex() == TableIndex); - writeUleb128(OS, Sym->getFunctionIndex(), "function index"); - ++TableIndex; + writeInitExpr(os, initExpr); + writeUleb128(os, indirectFunctions.size(), "elem count"); + + uint32_t tableIndex = elemOffset; + for (const FunctionSymbol *sym : indirectFunctions) { + assert(sym->getTableIndex() == tableIndex); + writeUleb128(os, sym->getFunctionIndex(), "function index"); + ++tableIndex; } } void DataCountSection::writeBody() { - writeUleb128(BodyOutputStream, NumSegments, "data count"); + writeUleb128(bodyOutputStream, numSegments, "data count"); } bool DataCountSection::isNeeded() const { - return NumSegments && Config->PassiveSegments; + return numSegments && config->passiveSegments; } -static uint32_t getWasmFlags(const Symbol *Sym) { - uint32_t Flags = 0; - if (Sym->isLocal()) - Flags |= WASM_SYMBOL_BINDING_LOCAL; - if (Sym->isWeak()) - Flags |= WASM_SYMBOL_BINDING_WEAK; - if (Sym->isHidden()) - Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; - if (Sym->isUndefined()) - Flags |= WASM_SYMBOL_UNDEFINED; - if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { - if (F->getName() != F->ImportName) - Flags |= WASM_SYMBOL_EXPLICIT_NAME; - } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { - if (G->getName() != G->ImportName) - Flags |= WASM_SYMBOL_EXPLICIT_NAME; +static uint32_t getWasmFlags(const Symbol *sym) { + uint32_t flags = 0; + if (sym->isLocal()) + flags |= WASM_SYMBOL_BINDING_LOCAL; + if (sym->isWeak()) + flags |= WASM_SYMBOL_BINDING_WEAK; + if (sym->isHidden()) + flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; + if (sym->isUndefined()) + flags |= WASM_SYMBOL_UNDEFINED; + if (auto *f = dyn_cast<UndefinedFunction>(sym)) { + if (f->getName() != f->importName) + flags |= WASM_SYMBOL_EXPLICIT_NAME; + } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) { + if (g->getName() != g->importName) + flags |= WASM_SYMBOL_EXPLICIT_NAME; } - return Flags; + return flags; } void LinkingSection::writeBody() { - raw_ostream &OS = BodyOutputStream; - - writeUleb128(OS, WasmMetadataVersion, "Version"); - - if (!SymtabEntries.empty()) { - SubSection Sub(WASM_SYMBOL_TABLE); - writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); - - for (const Symbol *Sym : SymtabEntries) { - assert(Sym->isDefined() || Sym->isUndefined()); - WasmSymbolType Kind = Sym->getWasmType(); - uint32_t Flags = getWasmFlags(Sym); - - writeU8(Sub.OS, Kind, "sym kind"); - writeUleb128(Sub.OS, Flags, "sym flags"); - - if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { - writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (auto *E = dyn_cast<EventSymbol>(Sym)) { - writeUleb128(Sub.OS, E->getEventIndex(), "index"); - if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) - writeStr(Sub.OS, Sym->getName(), "sym name"); - } else if (isa<DataSymbol>(Sym)) { - writeStr(Sub.OS, Sym->getName(), "sym name"); - if (auto *DataSym = dyn_cast<DefinedData>(Sym)) { - writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); - writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), + raw_ostream &os = bodyOutputStream; + + writeUleb128(os, WasmMetadataVersion, "Version"); + + if (!symtabEntries.empty()) { + SubSection sub(WASM_SYMBOL_TABLE); + writeUleb128(sub.os, symtabEntries.size(), "num symbols"); + + for (const Symbol *sym : symtabEntries) { + assert(sym->isDefined() || sym->isUndefined()); + WasmSymbolType kind = sym->getWasmType(); + uint32_t flags = getWasmFlags(sym); + + writeU8(sub.os, kind, "sym kind"); + writeUleb128(sub.os, flags, "sym flags"); + + if (auto *f = dyn_cast<FunctionSymbol>(sym)) { + writeUleb128(sub.os, f->getFunctionIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) { + writeUleb128(sub.os, g->getGlobalIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (auto *e = dyn_cast<EventSymbol>(sym)) { + writeUleb128(sub.os, e->getEventIndex(), "index"); + if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) + writeStr(sub.os, sym->getName(), "sym name"); + } else if (isa<DataSymbol>(sym)) { + writeStr(sub.os, sym->getName(), "sym name"); + if (auto *dataSym = dyn_cast<DefinedData>(sym)) { + writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index"); + writeUleb128(sub.os, dataSym->getOutputSegmentOffset(), "data offset"); - writeUleb128(Sub.OS, DataSym->getSize(), "data size"); + writeUleb128(sub.os, dataSym->getSize(), "data size"); } } else { - auto *S = cast<OutputSectionSymbol>(Sym); - writeUleb128(Sub.OS, S->Section->SectionIndex, "sym section index"); + auto *s = cast<OutputSectionSymbol>(sym); + writeUleb128(sub.os, s->section->sectionIndex, "sym section index"); } } - Sub.writeTo(OS); + sub.writeTo(os); } - if (DataSegments.size()) { - SubSection Sub(WASM_SEGMENT_INFO); - writeUleb128(Sub.OS, DataSegments.size(), "num data segments"); - for (const OutputSegment *S : DataSegments) { - writeStr(Sub.OS, S->Name, "segment name"); - writeUleb128(Sub.OS, S->Alignment, "alignment"); - writeUleb128(Sub.OS, 0, "flags"); + if (dataSegments.size()) { + SubSection sub(WASM_SEGMENT_INFO); + writeUleb128(sub.os, dataSegments.size(), "num data segments"); + for (const OutputSegment *s : dataSegments) { + writeStr(sub.os, s->name, "segment name"); + writeUleb128(sub.os, s->alignment, "alignment"); + writeUleb128(sub.os, 0, "flags"); } - Sub.writeTo(OS); + sub.writeTo(os); } - if (!InitFunctions.empty()) { - SubSection Sub(WASM_INIT_FUNCS); - writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); - for (const WasmInitEntry &F : InitFunctions) { - writeUleb128(Sub.OS, F.Priority, "priority"); - writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); + if (!initFunctions.empty()) { + SubSection sub(WASM_INIT_FUNCS); + writeUleb128(sub.os, initFunctions.size(), "num init functions"); + for (const WasmInitEntry &f : initFunctions) { + writeUleb128(sub.os, f.priority, "priority"); + writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index"); } - Sub.writeTo(OS); + sub.writeTo(os); } struct ComdatEntry { - unsigned Kind; - uint32_t Index; + unsigned kind; + uint32_t index; }; - std::map<StringRef, std::vector<ComdatEntry>> Comdats; + std::map<StringRef, std::vector<ComdatEntry>> comdats; - for (const InputFunction *F : Out.FunctionSec->InputFunctions) { - StringRef Comdat = F->getComdatName(); - if (!Comdat.empty()) - Comdats[Comdat].emplace_back( - ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); + for (const InputFunction *f : out.functionSec->inputFunctions) { + StringRef comdat = f->getComdatName(); + if (!comdat.empty()) + comdats[comdat].emplace_back( + ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()}); } - for (uint32_t I = 0; I < DataSegments.size(); ++I) { - const auto &InputSegments = DataSegments[I]->InputSegments; - if (InputSegments.empty()) + for (uint32_t i = 0; i < dataSegments.size(); ++i) { + const auto &inputSegments = dataSegments[i]->inputSegments; + if (inputSegments.empty()) continue; - StringRef Comdat = InputSegments[0]->getComdatName(); + StringRef comdat = inputSegments[0]->getComdatName(); #ifndef NDEBUG - for (const InputSegment *IS : InputSegments) - assert(IS->getComdatName() == Comdat); + for (const InputSegment *isec : inputSegments) + assert(isec->getComdatName() == comdat); #endif - if (!Comdat.empty()) - Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); + if (!comdat.empty()) + comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i}); } - if (!Comdats.empty()) { - SubSection Sub(WASM_COMDAT_INFO); - writeUleb128(Sub.OS, Comdats.size(), "num comdats"); - for (const auto &C : Comdats) { - writeStr(Sub.OS, C.first, "comdat name"); - writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use - writeUleb128(Sub.OS, C.second.size(), "num entries"); - for (const ComdatEntry &Entry : C.second) { - writeU8(Sub.OS, Entry.Kind, "entry kind"); - writeUleb128(Sub.OS, Entry.Index, "entry index"); + if (!comdats.empty()) { + SubSection sub(WASM_COMDAT_INFO); + writeUleb128(sub.os, comdats.size(), "num comdats"); + for (const auto &c : comdats) { + writeStr(sub.os, c.first, "comdat name"); + writeUleb128(sub.os, 0, "comdat flags"); // flags for future use + writeUleb128(sub.os, c.second.size(), "num entries"); + for (const ComdatEntry &entry : c.second) { + writeU8(sub.os, entry.kind, "entry kind"); + writeUleb128(sub.os, entry.index, "entry index"); } } - Sub.writeTo(OS); + sub.writeTo(os); } } -void LinkingSection::addToSymtab(Symbol *Sym) { - Sym->setOutputSymbolIndex(SymtabEntries.size()); - SymtabEntries.emplace_back(Sym); +void LinkingSection::addToSymtab(Symbol *sym) { + sym->setOutputSymbolIndex(symtabEntries.size()); + symtabEntries.emplace_back(sym); } unsigned NameSection::numNames() const { - unsigned NumNames = Out.ImportSec->getNumImportedFunctions(); - for (const InputFunction *F : Out.FunctionSec->InputFunctions) - if (!F->getName().empty() || !F->getDebugName().empty()) - ++NumNames; + unsigned numNames = out.importSec->getNumImportedFunctions(); + for (const InputFunction *f : out.functionSec->inputFunctions) + if (!f->getName().empty() || !f->getDebugName().empty()) + ++numNames; - return NumNames; + return numNames; } // Create the custom "name" section containing debug symbol names. void NameSection::writeBody() { - SubSection Sub(WASM_NAMES_FUNCTION); - writeUleb128(Sub.OS, numNames(), "name count"); + SubSection sub(WASM_NAMES_FUNCTION); + writeUleb128(sub.os, numNames(), "name count"); // Names must appear in function index order. As it happens ImportedSymbols // and InputFunctions are numbered in order with imported functions coming // first. - for (const Symbol *S : Out.ImportSec->ImportedSymbols) { - if (auto *F = dyn_cast<FunctionSymbol>(S)) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); - writeStr(Sub.OS, toString(*S), "symbol name"); + for (const Symbol *s : out.importSec->importedSymbols) { + if (auto *f = dyn_cast<FunctionSymbol>(s)) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + writeStr(sub.os, toString(*s), "symbol name"); } } - for (const InputFunction *F : Out.FunctionSec->InputFunctions) { - if (!F->getName().empty()) { - writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); - if (!F->getDebugName().empty()) { - writeStr(Sub.OS, F->getDebugName(), "symbol name"); + for (const InputFunction *f : out.functionSec->inputFunctions) { + if (!f->getName().empty()) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + if (!f->getDebugName().empty()) { + writeStr(sub.os, f->getDebugName(), "symbol name"); } else { - writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name"); + writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); } } } - Sub.writeTo(BodyOutputStream); + sub.writeTo(bodyOutputStream); } -void ProducersSection::addInfo(const WasmProducerInfo &Info) { - for (auto &Producers : - {std::make_pair(&Info.Languages, &Languages), - std::make_pair(&Info.Tools, &Tools), std::make_pair(&Info.SDKs, &SDKs)}) - for (auto &Producer : *Producers.first) - if (Producers.second->end() == - llvm::find_if(*Producers.second, - [&](std::pair<std::string, std::string> Seen) { - return Seen.first == Producer.first; +void ProducersSection::addInfo(const WasmProducerInfo &info) { + for (auto &producers : + {std::make_pair(&info.Languages, &languages), + std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)}) + for (auto &producer : *producers.first) + if (producers.second->end() == + llvm::find_if(*producers.second, + [&](std::pair<std::string, std::string> seen) { + return seen.first == producer.first; })) - Producers.second->push_back(Producer); + producers.second->push_back(producer); } void ProducersSection::writeBody() { - auto &OS = BodyOutputStream; - writeUleb128(OS, fieldCount(), "field count"); - for (auto &Field : - {std::make_pair("language", Languages), - std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) { - if (Field.second.empty()) + auto &os = bodyOutputStream; + writeUleb128(os, fieldCount(), "field count"); + for (auto &field : + {std::make_pair("language", languages), + std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) { + if (field.second.empty()) continue; - writeStr(OS, Field.first, "field name"); - writeUleb128(OS, Field.second.size(), "number of entries"); - for (auto &Entry : Field.second) { - writeStr(OS, Entry.first, "producer name"); - writeStr(OS, Entry.second, "producer version"); + writeStr(os, field.first, "field name"); + writeUleb128(os, field.second.size(), "number of entries"); + for (auto &entry : field.second) { + writeStr(os, entry.first, "producer name"); + writeStr(os, entry.second, "producer version"); } } } void TargetFeaturesSection::writeBody() { - SmallVector<std::string, 8> Emitted(Features.begin(), Features.end()); - llvm::sort(Emitted); - auto &OS = BodyOutputStream; - writeUleb128(OS, Emitted.size(), "feature count"); - for (auto &Feature : Emitted) { - writeU8(OS, WASM_FEATURE_PREFIX_USED, "feature used prefix"); - writeStr(OS, Feature, "feature name"); + SmallVector<std::string, 8> emitted(features.begin(), features.end()); + llvm::sort(emitted); + auto &os = bodyOutputStream; + writeUleb128(os, emitted.size(), "feature count"); + for (auto &feature : emitted) { + writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix"); + writeStr(os, feature, "feature name"); } } void RelocSection::writeBody() { - uint32_t Count = Sec->getNumRelocations(); - assert(Sec->SectionIndex != UINT32_MAX); - writeUleb128(BodyOutputStream, Sec->SectionIndex, "reloc section"); - writeUleb128(BodyOutputStream, Count, "reloc count"); - Sec->writeRelocations(BodyOutputStream); + uint32_t count = sec->getNumRelocations(); + assert(sec->sectionIndex != UINT32_MAX); + writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section"); + writeUleb128(bodyOutputStream, count, "reloc count"); + sec->writeRelocations(bodyOutputStream); } diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h index c2a9c4b55aa..1d3b8b7a369 100644 --- a/lld/wasm/SyntheticSections.h +++ b/lld/wasm/SyntheticSections.h @@ -29,41 +29,41 @@ namespace wasm { // An init entry to be written to either the synthetic init func or the // linking metadata. struct WasmInitEntry { - const FunctionSymbol *Sym; - uint32_t Priority; + const FunctionSymbol *sym; + uint32_t priority; }; class SyntheticSection : public OutputSection { public: - SyntheticSection(uint32_t Type, std::string Name = "") - : OutputSection(Type, Name), BodyOutputStream(Body) { - if (!Name.empty()) - writeStr(BodyOutputStream, Name, "section name"); + SyntheticSection(uint32_t type, std::string name = "") + : OutputSection(type, name), bodyOutputStream(body) { + if (!name.empty()) + writeStr(bodyOutputStream, name, "section name"); } - void writeTo(uint8_t *Buf) override { - assert(Offset); + void writeTo(uint8_t *buf) override { + assert(offset); log("writing " + toString(*this)); - memcpy(Buf + Offset, Header.data(), Header.size()); - memcpy(Buf + Offset + Header.size(), Body.data(), Body.size()); + memcpy(buf + offset, header.data(), header.size()); + memcpy(buf + offset + header.size(), body.data(), body.size()); } - size_t getSize() const override { return Header.size() + Body.size(); } + size_t getSize() const override { return header.size() + body.size(); } virtual void writeBody() {} void finalizeContents() override { writeBody(); - BodyOutputStream.flush(); - createHeader(Body.size()); + bodyOutputStream.flush(); + createHeader(body.size()); } - raw_ostream &getStream() { return BodyOutputStream; } + raw_ostream &getStream() { return bodyOutputStream; } - std::string Body; + std::string body; protected: - llvm::raw_string_ostream BodyOutputStream; + llvm::raw_string_ostream bodyOutputStream; }; // Create the custom "dylink" section containing information for the dynamic @@ -73,25 +73,25 @@ protected: class DylinkSection : public SyntheticSection { public: DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink") {} - bool isNeeded() const override { return Config->Pic; } + bool isNeeded() const override { return config->isPic; } void writeBody() override; - uint32_t MemAlign = 0; - uint32_t MemSize = 0; + uint32_t memAlign = 0; + uint32_t memSize = 0; }; class TypeSection : public SyntheticSection { public: TypeSection() : SyntheticSection(llvm::wasm::WASM_SEC_TYPE) {} - bool isNeeded() const override { return Types.size() > 0; }; + bool isNeeded() const override { return types.size() > 0; }; void writeBody() override; - uint32_t registerType(const WasmSignature &Sig); - uint32_t lookupType(const WasmSignature &Sig); + uint32_t registerType(const WasmSignature &sig); + uint32_t lookupType(const WasmSignature &sig); protected: - std::vector<const WasmSignature *> Types; - llvm::DenseMap<WasmSignature, int32_t> TypeIndices; + std::vector<const WasmSignature *> types; + llvm::DenseMap<WasmSignature, int32_t> typeIndices; }; class ImportSection : public SyntheticSection { @@ -99,42 +99,42 @@ public: ImportSection() : SyntheticSection(llvm::wasm::WASM_SEC_IMPORT) {} bool isNeeded() const override { return getNumImports() > 0; } void writeBody() override; - void addImport(Symbol *Sym); - void addGOTEntry(Symbol *Sym); - void seal() { IsSealed = true; } + void addImport(Symbol *sym); + void addGOTEntry(Symbol *sym); + void seal() { isSealed = true; } uint32_t getNumImports() const; uint32_t getNumImportedGlobals() const { - assert(IsSealed); - return NumImportedGlobals; + assert(isSealed); + return numImportedGlobals; } uint32_t getNumImportedFunctions() const { - assert(IsSealed); - return NumImportedFunctions; + assert(isSealed); + return numImportedFunctions; } uint32_t getNumImportedEvents() const { - assert(IsSealed); - return NumImportedEvents; + assert(isSealed); + return numImportedEvents; } - std::vector<const Symbol *> ImportedSymbols; + std::vector<const Symbol *> importedSymbols; protected: - bool IsSealed = false; - unsigned NumImportedGlobals = 0; - unsigned NumImportedFunctions = 0; - unsigned NumImportedEvents = 0; - std::vector<const Symbol *> GOTSymbols; + bool isSealed = false; + unsigned numImportedGlobals = 0; + unsigned numImportedFunctions = 0; + unsigned numImportedEvents = 0; + std::vector<const Symbol *> gotSymbols; }; class FunctionSection : public SyntheticSection { public: FunctionSection() : SyntheticSection(llvm::wasm::WASM_SEC_FUNCTION) {} - bool isNeeded() const override { return InputFunctions.size() > 0; }; + bool isNeeded() const override { return inputFunctions.size() > 0; }; void writeBody() override; - void addFunction(InputFunction *Func); + void addFunction(InputFunction *func); - std::vector<InputFunction *> InputFunctions; + std::vector<InputFunction *> inputFunctions; protected: }; @@ -143,11 +143,11 @@ class MemorySection : public SyntheticSection { public: MemorySection() : SyntheticSection(llvm::wasm::WASM_SEC_MEMORY) {} - bool isNeeded() const override { return !Config->ImportMemory; } + bool isNeeded() const override { return !config->importMemory; } void writeBody() override; - uint32_t NumMemoryPages = 0; - uint32_t MaxMemoryPages = 0; + uint32_t numMemoryPages = 0; + uint32_t maxMemoryPages = 0; }; class TableSection : public SyntheticSection { @@ -163,7 +163,7 @@ public: // no address-taken function will fail at validation time since it is // a validation error to include a call_indirect instruction if there // is not table. - return !Config->ImportTable; + return !config->importTable; } void writeBody() override; @@ -173,14 +173,14 @@ class GlobalSection : public SyntheticSection { public: GlobalSection() : SyntheticSection(llvm::wasm::WASM_SEC_GLOBAL) {} uint32_t numGlobals() const { - return InputGlobals.size() + DefinedFakeGlobals.size(); + return inputGlobals.size() + definedFakeGlobals.size(); } bool isNeeded() const override { return numGlobals() > 0; } void writeBody() override; - void addGlobal(InputGlobal *Global); + void addGlobal(InputGlobal *global); - std::vector<const DefinedData *> DefinedFakeGlobals; - std::vector<InputGlobal *> InputGlobals; + std::vector<const DefinedData *> definedFakeGlobals; + std::vector<InputGlobal *> inputGlobals; }; // The event section contains a list of declared wasm events associated with the @@ -197,66 +197,66 @@ class EventSection : public SyntheticSection { public: EventSection() : SyntheticSection(llvm::wasm::WASM_SEC_EVENT) {} void writeBody() override; - bool isNeeded() const override { return InputEvents.size() > 0; } - void addEvent(InputEvent *Event); + bool isNeeded() const override { return inputEvents.size() > 0; } + void addEvent(InputEvent *event); - std::vector<InputEvent *> InputEvents; + std::vector<InputEvent *> inputEvents; }; class ExportSection : public SyntheticSection { public: ExportSection() : SyntheticSection(llvm::wasm::WASM_SEC_EXPORT) {} - bool isNeeded() const override { return Exports.size() > 0; } + bool isNeeded() const override { return exports.size() > 0; } void writeBody() override; - std::vector<llvm::wasm::WasmExport> Exports; + std::vector<llvm::wasm::WasmExport> exports; }; class ElemSection : public SyntheticSection { public: - ElemSection(uint32_t Offset) - : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), ElemOffset(Offset) {} - bool isNeeded() const override { return IndirectFunctions.size() > 0; }; + ElemSection(uint32_t offset) + : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), elemOffset(offset) {} + bool isNeeded() const override { return indirectFunctions.size() > 0; }; void writeBody() override; - void addEntry(FunctionSymbol *Sym); - uint32_t numEntries() const { return IndirectFunctions.size(); } - uint32_t ElemOffset; + void addEntry(FunctionSymbol *sym); + uint32_t numEntries() const { return indirectFunctions.size(); } + uint32_t elemOffset; protected: - std::vector<const FunctionSymbol *> IndirectFunctions; + std::vector<const FunctionSymbol *> indirectFunctions; }; class DataCountSection : public SyntheticSection { public: - DataCountSection(uint32_t NumSegments) + DataCountSection(uint32_t numSegments) : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT), - NumSegments(NumSegments) {} + numSegments(numSegments) {} bool isNeeded() const override; void writeBody() override; protected: - uint32_t NumSegments; + uint32_t numSegments; }; // Create the custom "linking" section containing linker metadata. // This is only created when relocatable output is requested. class LinkingSection : public SyntheticSection { public: - LinkingSection(const std::vector<WasmInitEntry> &InitFunctions, - const std::vector<OutputSegment *> &DataSegments) + LinkingSection(const std::vector<WasmInitEntry> &initFunctions, + const std::vector<OutputSegment *> &dataSegments) : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"), - InitFunctions(InitFunctions), DataSegments(DataSegments) {} + initFunctions(initFunctions), dataSegments(dataSegments) {} bool isNeeded() const override { - return Config->Relocatable || Config->EmitRelocs; + return config->relocatable || config->emitRelocs; } void writeBody() override; - void addToSymtab(Symbol *Sym); + void addToSymtab(Symbol *sym); protected: - std::vector<const Symbol *> SymtabEntries; - llvm::StringMap<uint32_t> SectionSymbolIndices; - const std::vector<WasmInitEntry> &InitFunctions; - const std::vector<OutputSegment *> &DataSegments; + std::vector<const Symbol *> symtabEntries; + llvm::StringMap<uint32_t> sectionSymbolIndices; + const std::vector<WasmInitEntry> &initFunctions; + const std::vector<OutputSegment *> &dataSegments; }; // Create the custom "name" section containing debug symbol names. @@ -264,7 +264,7 @@ class NameSection : public SyntheticSection { public: NameSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name") {} bool isNeeded() const override { - return !Config->StripDebug && !Config->StripAll && numNames() > 0; + return !config->stripDebug && !config->stripAll && numNames() > 0; } void writeBody() override; unsigned numNames() const; @@ -275,18 +275,18 @@ public: ProducersSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "producers") {} bool isNeeded() const override { - return !Config->StripAll && fieldCount() > 0; + return !config->stripAll && fieldCount() > 0; } void writeBody() override; - void addInfo(const llvm::wasm::WasmProducerInfo &Info); + void addInfo(const llvm::wasm::WasmProducerInfo &info); protected: int fieldCount() const { - return int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty()); + return int(!languages.empty()) + int(!tools.empty()) + int(!sDKs.empty()); } - SmallVector<std::pair<std::string, std::string>, 8> Languages; - SmallVector<std::pair<std::string, std::string>, 8> Tools; - SmallVector<std::pair<std::string, std::string>, 8> SDKs; + SmallVector<std::pair<std::string, std::string>, 8> languages; + SmallVector<std::pair<std::string, std::string>, 8> tools; + SmallVector<std::pair<std::string, std::string>, 8> sDKs; }; class TargetFeaturesSection : public SyntheticSection { @@ -294,44 +294,44 @@ public: TargetFeaturesSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "target_features") {} bool isNeeded() const override { - return !Config->StripAll && Features.size() > 0; + return !config->stripAll && features.size() > 0; } void writeBody() override; - llvm::SmallSet<std::string, 8> Features; + llvm::SmallSet<std::string, 8> features; }; class RelocSection : public SyntheticSection { public: - RelocSection(StringRef Name, OutputSection *Sec) - : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, Name), Sec(Sec) {} + RelocSection(StringRef name, OutputSection *sec) + : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, name), sec(sec) {} void writeBody() override; - bool isNeeded() const override { return Sec->getNumRelocations() > 0; }; + bool isNeeded() const override { return sec->getNumRelocations() > 0; }; protected: - OutputSection *Sec; + OutputSection *sec; }; // Linker generated output sections struct OutStruct { - DylinkSection *DylinkSec; - TypeSection *TypeSec; - FunctionSection *FunctionSec; - ImportSection *ImportSec; - TableSection *TableSec; - MemorySection *MemorySec; - GlobalSection *GlobalSec; - EventSection *EventSec; - ExportSection *ExportSec; - ElemSection *ElemSec; - DataCountSection *DataCountSec; - LinkingSection *LinkingSec; - NameSection *NameSec; - ProducersSection *ProducersSec; - TargetFeaturesSection *TargetFeaturesSec; + DylinkSection *dylinkSec; + TypeSection *typeSec; + FunctionSection *functionSec; + ImportSection *importSec; + TableSection *tableSec; + MemorySection *memorySec; + GlobalSection *globalSec; + EventSection *eventSec; + ExportSection *exportSec; + ElemSection *elemSec; + DataCountSection *dataCountSec; + LinkingSection *linkingSec; + NameSection *nameSec; + ProducersSection *producersSec; + TargetFeaturesSection *targetFeaturesSec; }; -extern OutStruct Out; +extern OutStruct out; } // namespace wasm } // namespace lld diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 5fabd976e61..11c4b913fd3 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -42,7 +42,7 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static constexpr int StackAlignment = 16; +static constexpr int stackAlignment = 16; namespace { @@ -71,7 +71,7 @@ private: void layoutMemory(); void createHeader(); - void addSection(OutputSection *Sec); + void addSection(OutputSection *sec); void addSections(); @@ -85,56 +85,56 @@ private: void writeHeader(); void writeSections(); - uint64_t FileSize = 0; - uint32_t TableBase = 0; + uint64_t fileSize = 0; + uint32_t tableBase = 0; - std::vector<WasmInitEntry> InitFunctions; - llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; + std::vector<WasmInitEntry> initFunctions; + llvm::StringMap<std::vector<InputSection *>> customSectionMapping; // Elements that are used to construct the final output - std::string Header; - std::vector<OutputSection *> OutputSections; + std::string header; + std::vector<OutputSection *> outputSections; - std::unique_ptr<FileOutputBuffer> Buffer; + std::unique_ptr<FileOutputBuffer> buffer; - std::vector<OutputSegment *> Segments; - llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; + std::vector<OutputSegment *> segments; + llvm::SmallDenseMap<StringRef, OutputSegment *> segmentMap; }; } // anonymous namespace void Writer::calculateCustomSections() { log("calculateCustomSections"); - bool StripDebug = Config->StripDebug || Config->StripAll; - for (ObjFile *File : Symtab->ObjectFiles) { - for (InputSection *Section : File->CustomSections) { - StringRef Name = Section->getName(); + bool stripDebug = config->stripDebug || config->stripAll; + for (ObjFile *file : symtab->objectFiles) { + for (InputSection *section : file->customSections) { + StringRef name = section->getName(); // These custom sections are known the linker and synthesized rather than // blindly copied - if (Name == "linking" || Name == "name" || Name == "producers" || - Name == "target_features" || Name.startswith("reloc.")) + if (name == "linking" || name == "name" || name == "producers" || + name == "target_features" || name.startswith("reloc.")) continue; // .. or it is a debug section - if (StripDebug && Name.startswith(".debug_")) + if (stripDebug && name.startswith(".debug_")) continue; - CustomSectionMapping[Name].push_back(Section); + customSectionMapping[name].push_back(section); } } } void Writer::createCustomSections() { log("createCustomSections"); - for (auto &Pair : CustomSectionMapping) { - StringRef Name = Pair.first(); - LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); - - OutputSection *Sec = make<CustomSection>(Name, Pair.second); - if (Config->Relocatable || Config->EmitRelocs) { - auto *Sym = make<OutputSectionSymbol>(Sec); - Out.LinkingSec->addToSymtab(Sym); - Sec->SectionSym = Sym; + for (auto &pair : customSectionMapping) { + StringRef name = pair.first(); + LLVM_DEBUG(dbgs() << "createCustomSection: " << name << "\n"); + + OutputSection *sec = make<CustomSection>(name, pair.second); + if (config->relocatable || config->emitRelocs) { + auto *sym = make<OutputSectionSymbol>(sec); + out.linkingSec->addToSymtab(sym); + sec->sectionSym = sym; } - addSection(Sec); + addSection(sec); } } @@ -143,47 +143,47 @@ void Writer::createCustomSections() { void Writer::createRelocSections() { log("createRelocSections"); // Don't use iterator here since we are adding to OutputSection - size_t OrigSize = OutputSections.size(); - for (size_t I = 0; I < OrigSize; I++) { - LLVM_DEBUG(dbgs() << "check section " << I << "\n"); - OutputSection *Sec = OutputSections[I]; + size_t origSize = outputSections.size(); + for (size_t i = 0; i < origSize; i++) { + LLVM_DEBUG(dbgs() << "check section " << i << "\n"); + OutputSection *sec = outputSections[i]; // Count the number of needed sections. - uint32_t Count = Sec->getNumRelocations(); - if (!Count) + uint32_t count = sec->getNumRelocations(); + if (!count) continue; - StringRef Name; - if (Sec->Type == WASM_SEC_DATA) - Name = "reloc.DATA"; - else if (Sec->Type == WASM_SEC_CODE) - Name = "reloc.CODE"; - else if (Sec->Type == WASM_SEC_CUSTOM) - Name = Saver.save("reloc." + Sec->Name); + StringRef name; + if (sec->type == WASM_SEC_DATA) + name = "reloc.DATA"; + else if (sec->type == WASM_SEC_CODE) + name = "reloc.CODE"; + else if (sec->type == WASM_SEC_CUSTOM) + name = saver.save("reloc." + sec->name); else llvm_unreachable( "relocations only supported for code, data, or custom sections"); - addSection(make<RelocSection>(Name, Sec)); + addSection(make<RelocSection>(name, sec)); } } void Writer::populateProducers() { - for (ObjFile *File : Symtab->ObjectFiles) { - const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); - Out.ProducersSec->addInfo(Info); + for (ObjFile *file : symtab->objectFiles) { + const WasmProducerInfo &info = file->getWasmObj()->getProducerInfo(); + out.producersSec->addInfo(info); } } void Writer::writeHeader() { - memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); + memcpy(buffer->getBufferStart(), header.data(), header.size()); } void Writer::writeSections() { - uint8_t *Buf = Buffer->getBufferStart(); - parallelForEach(OutputSections, [Buf](OutputSection *S) { - assert(S->isNeeded()); - S->writeTo(Buf); + uint8_t *buf = buffer->getBufferStart(); + parallelForEach(outputSections, [buf](OutputSection *s) { + assert(s->isNeeded()); + s->writeTo(buf); }); } @@ -201,100 +201,100 @@ void Writer::writeSections() { // rather than overwriting global data, but also increases code size since all // static data loads and stores requires larger offsets. void Writer::layoutMemory() { - uint32_t MemoryPtr = 0; + uint32_t memoryPtr = 0; - auto PlaceStack = [&]() { - if (Config->Relocatable || Config->Shared) + auto placeStack = [&]() { + if (config->relocatable || config->shared) return; - MemoryPtr = alignTo(MemoryPtr, StackAlignment); - if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) - error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); - log("mem: stack size = " + Twine(Config->ZStackSize)); - log("mem: stack base = " + Twine(MemoryPtr)); - MemoryPtr += Config->ZStackSize; - auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer); - SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; - log("mem: stack top = " + Twine(MemoryPtr)); + memoryPtr = alignTo(memoryPtr, stackAlignment); + if (config->zStackSize != alignTo(config->zStackSize, stackAlignment)) + error("stack size must be " + Twine(stackAlignment) + "-byte aligned"); + log("mem: stack size = " + Twine(config->zStackSize)); + log("mem: stack base = " + Twine(memoryPtr)); + memoryPtr += config->zStackSize; + auto *sp = cast<DefinedGlobal>(WasmSym::stackPointer); + sp->global->global.InitExpr.Value.Int32 = memoryPtr; + log("mem: stack top = " + Twine(memoryPtr)); }; - if (Config->StackFirst) { - PlaceStack(); + if (config->stackFirst) { + placeStack(); } else { - MemoryPtr = Config->GlobalBase; - log("mem: global base = " + Twine(Config->GlobalBase)); + memoryPtr = config->globalBase; + log("mem: global base = " + Twine(config->globalBase)); } - if (WasmSym::GlobalBase) - WasmSym::GlobalBase->setVirtualAddress(Config->GlobalBase); + if (WasmSym::globalBase) + WasmSym::globalBase->setVirtualAddress(config->globalBase); - uint32_t DataStart = MemoryPtr; + uint32_t dataStart = memoryPtr; // Arbitrarily set __dso_handle handle to point to the start of the data // segments. - if (WasmSym::DsoHandle) - WasmSym::DsoHandle->setVirtualAddress(DataStart); + if (WasmSym::dsoHandle) + WasmSym::dsoHandle->setVirtualAddress(dataStart); - Out.DylinkSec->MemAlign = 0; - for (OutputSegment *Seg : Segments) { - Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment); - MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); - Seg->StartVA = MemoryPtr; - log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, - MemoryPtr, Seg->Size, Seg->Alignment)); - MemoryPtr += Seg->Size; + out.dylinkSec->memAlign = 0; + for (OutputSegment *seg : segments) { + out.dylinkSec->memAlign = std::max(out.dylinkSec->memAlign, seg->alignment); + memoryPtr = alignTo(memoryPtr, 1ULL << seg->alignment); + seg->startVA = memoryPtr; + log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name, + memoryPtr, seg->size, seg->alignment)); + memoryPtr += seg->size; } // TODO: Add .bss space here. - if (WasmSym::DataEnd) - WasmSym::DataEnd->setVirtualAddress(MemoryPtr); + if (WasmSym::dataEnd) + WasmSym::dataEnd->setVirtualAddress(memoryPtr); - log("mem: static data = " + Twine(MemoryPtr - DataStart)); + log("mem: static data = " + Twine(memoryPtr - dataStart)); - if (Config->Shared) { - Out.DylinkSec->MemSize = MemoryPtr; + if (config->shared) { + out.dylinkSec->memSize = memoryPtr; return; } - if (!Config->StackFirst) - PlaceStack(); + if (!config->stackFirst) + placeStack(); // Set `__heap_base` to directly follow the end of the stack or global data. // The fact that this comes last means that a malloc/brk implementation // can grow the heap at runtime. - log("mem: heap base = " + Twine(MemoryPtr)); - if (WasmSym::HeapBase) - WasmSym::HeapBase->setVirtualAddress(MemoryPtr); + log("mem: heap base = " + Twine(memoryPtr)); + if (WasmSym::heapBase) + WasmSym::heapBase->setVirtualAddress(memoryPtr); - if (Config->InitialMemory != 0) { - if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) + if (config->initialMemory != 0) { + if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize)) error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); - if (MemoryPtr > Config->InitialMemory) - error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); + if (memoryPtr > config->initialMemory) + error("initial memory too small, " + Twine(memoryPtr) + " bytes needed"); else - MemoryPtr = Config->InitialMemory; + memoryPtr = config->initialMemory; } - Out.DylinkSec->MemSize = MemoryPtr; - Out.MemorySec->NumMemoryPages = - alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; - log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages)); + out.dylinkSec->memSize = memoryPtr; + out.memorySec->numMemoryPages = + alignTo(memoryPtr, WasmPageSize) / WasmPageSize; + log("mem: total pages = " + Twine(out.memorySec->numMemoryPages)); // Check max if explicitly supplied or required by shared memory - if (Config->MaxMemory != 0 || Config->SharedMemory) { - if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) + if (config->maxMemory != 0 || config->sharedMemory) { + if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize)) error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); - if (MemoryPtr > Config->MaxMemory) - error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); - Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize; - log("mem: max pages = " + Twine(Out.MemorySec->MaxMemoryPages)); + if (memoryPtr > config->maxMemory) + error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed"); + out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize; + log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages)); } } -void Writer::addSection(OutputSection *Sec) { - if (!Sec->isNeeded()) +void Writer::addSection(OutputSection *sec) { + if (!sec->isNeeded()) return; - log("addSection: " + toString(*Sec)); - Sec->SectionIndex = OutputSections.size(); - OutputSections.push_back(Sec); + log("addSection: " + toString(*sec)); + sec->sectionIndex = outputSections.size(); + outputSections.push_back(sec); } // If a section name is valid as a C identifier (which is rare because of @@ -302,227 +302,227 @@ void Writer::addSection(OutputSection *Sec) { // __stop_<secname> symbols. They are at beginning and end of the section, // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. -static void addStartStopSymbols(const OutputSegment *Seg) { - StringRef Name = Seg->Name; - if (!isValidCIdentifier(Name)) +static void addStartStopSymbols(const OutputSegment *seg) { + StringRef name = seg->name; + if (!isValidCIdentifier(name)) return; - LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << Name << "\n"); - uint32_t Start = Seg->StartVA; - uint32_t Stop = Start + Seg->Size; - Symtab->addOptionalDataSymbol(Saver.save("__start_" + Name), Start); - Symtab->addOptionalDataSymbol(Saver.save("__stop_" + Name), Stop); + LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << name << "\n"); + uint32_t start = seg->startVA; + uint32_t stop = start + seg->size; + symtab->addOptionalDataSymbol(saver.save("__start_" + name), start); + symtab->addOptionalDataSymbol(saver.save("__stop_" + name), stop); } void Writer::addSections() { - addSection(Out.DylinkSec); - addSection(Out.TypeSec); - addSection(Out.ImportSec); - addSection(Out.FunctionSec); - addSection(Out.TableSec); - addSection(Out.MemorySec); - addSection(Out.GlobalSec); - addSection(Out.EventSec); - addSection(Out.ExportSec); - addSection(Out.ElemSec); - addSection(Out.DataCountSec); - - addSection(make<CodeSection>(Out.FunctionSec->InputFunctions)); - addSection(make<DataSection>(Segments)); + addSection(out.dylinkSec); + addSection(out.typeSec); + addSection(out.importSec); + addSection(out.functionSec); + addSection(out.tableSec); + addSection(out.memorySec); + addSection(out.globalSec); + addSection(out.eventSec); + addSection(out.exportSec); + addSection(out.elemSec); + addSection(out.dataCountSec); + + addSection(make<CodeSection>(out.functionSec->inputFunctions)); + addSection(make<DataSection>(segments)); createCustomSections(); - addSection(Out.LinkingSec); - if (Config->EmitRelocs || Config->Relocatable) { + addSection(out.linkingSec); + if (config->emitRelocs || config->relocatable) { createRelocSections(); } - addSection(Out.NameSec); - addSection(Out.ProducersSec); - addSection(Out.TargetFeaturesSec); + addSection(out.nameSec); + addSection(out.producersSec); + addSection(out.targetFeaturesSec); } void Writer::finalizeSections() { - for (OutputSection *S : OutputSections) { - S->setOffset(FileSize); - S->finalizeContents(); - FileSize += S->getSize(); + for (OutputSection *s : outputSections) { + s->setOffset(fileSize); + s->finalizeContents(); + fileSize += s->getSize(); } } void Writer::populateTargetFeatures() { - StringMap<std::string> Used; - StringMap<std::string> Required; - StringMap<std::string> Disallowed; + StringMap<std::string> used; + StringMap<std::string> required; + StringMap<std::string> disallowed; // Only infer used features if user did not specify features - bool InferFeatures = !Config->Features.hasValue(); + bool inferFeatures = !config->features.hasValue(); - if (!InferFeatures) { - for (auto &Feature : Config->Features.getValue()) - Out.TargetFeaturesSec->Features.insert(Feature); + if (!inferFeatures) { + for (auto &feature : config->features.getValue()) + out.targetFeaturesSec->features.insert(feature); // No need to read or check features - if (!Config->CheckFeatures) + if (!config->checkFeatures) return; } // Find the sets of used, required, and disallowed features - for (ObjFile *File : Symtab->ObjectFiles) { - StringRef FileName(File->getName()); - for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { - switch (Feature.Prefix) { + for (ObjFile *file : symtab->objectFiles) { + StringRef fileName(file->getName()); + for (auto &feature : file->getWasmObj()->getTargetFeatures()) { + switch (feature.Prefix) { case WASM_FEATURE_PREFIX_USED: - Used.insert({Feature.Name, FileName}); + used.insert({feature.Name, fileName}); break; case WASM_FEATURE_PREFIX_REQUIRED: - Used.insert({Feature.Name, FileName}); - Required.insert({Feature.Name, FileName}); + used.insert({feature.Name, fileName}); + required.insert({feature.Name, fileName}); break; case WASM_FEATURE_PREFIX_DISALLOWED: - Disallowed.insert({Feature.Name, FileName}); + disallowed.insert({feature.Name, fileName}); break; default: error("Unrecognized feature policy prefix " + - std::to_string(Feature.Prefix)); + std::to_string(feature.Prefix)); } } } - if (InferFeatures) - Out.TargetFeaturesSec->Features.insert(Used.keys().begin(), - Used.keys().end()); + if (inferFeatures) + out.targetFeaturesSec->features.insert(used.keys().begin(), + used.keys().end()); - if (Out.TargetFeaturesSec->Features.count("atomics") && - !Config->SharedMemory) { - if (InferFeatures) - error(Twine("'atomics' feature is used by ") + Used["atomics"] + + if (out.targetFeaturesSec->features.count("atomics") && + !config->sharedMemory) { + if (inferFeatures) + error(Twine("'atomics' feature is used by ") + used["atomics"] + ", so --shared-memory must be used"); else error("'atomics' feature is used, so --shared-memory must be used"); } - if (!Config->CheckFeatures) + if (!config->checkFeatures) return; - if (Disallowed.count("atomics") && Config->SharedMemory) - error("'atomics' feature is disallowed by " + Disallowed["atomics"] + + if (disallowed.count("atomics") && config->sharedMemory) + error("'atomics' feature is disallowed by " + disallowed["atomics"] + ", so --shared-memory must not be used"); - if (!Used.count("bulk-memory") && Config->PassiveSegments) + if (!used.count("bulk-memory") && config->passiveSegments) error("'bulk-memory' feature must be used in order to emit passive " "segments"); // Validate that used features are allowed in output - if (!InferFeatures) { - for (auto &Feature : Used.keys()) { - if (!Out.TargetFeaturesSec->Features.count(Feature)) - error(Twine("Target feature '") + Feature + "' used by " + - Used[Feature] + " is not allowed."); + if (!inferFeatures) { + for (auto &feature : used.keys()) { + if (!out.targetFeaturesSec->features.count(feature)) + error(Twine("Target feature '") + feature + "' used by " + + used[feature] + " is not allowed."); } } // Validate the required and disallowed constraints for each file - for (ObjFile *File : Symtab->ObjectFiles) { - StringRef FileName(File->getName()); - SmallSet<std::string, 8> ObjectFeatures; - for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { - if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) + for (ObjFile *file : symtab->objectFiles) { + StringRef fileName(file->getName()); + SmallSet<std::string, 8> objectFeatures; + for (auto &feature : file->getWasmObj()->getTargetFeatures()) { + if (feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) continue; - ObjectFeatures.insert(Feature.Name); - if (Disallowed.count(Feature.Name)) - error(Twine("Target feature '") + Feature.Name + "' used in " + - FileName + " is disallowed by " + Disallowed[Feature.Name] + + objectFeatures.insert(feature.Name); + if (disallowed.count(feature.Name)) + error(Twine("Target feature '") + feature.Name + "' used in " + + fileName + " is disallowed by " + disallowed[feature.Name] + ". Use --no-check-features to suppress."); } - for (auto &Feature : Required.keys()) { - if (!ObjectFeatures.count(Feature)) - error(Twine("Missing target feature '") + Feature + "' in " + FileName + - ", required by " + Required[Feature] + + for (auto &feature : required.keys()) { + if (!objectFeatures.count(feature)) + error(Twine("Missing target feature '") + feature + "' in " + fileName + + ", required by " + required[feature] + ". Use --no-check-features to suppress."); } } } void Writer::calculateImports() { - for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isUndefined()) + for (Symbol *sym : symtab->getSymbols()) { + if (!sym->isUndefined()) continue; - if (Sym->isWeak() && !Config->Relocatable) + if (sym->isWeak() && !config->relocatable) continue; - if (!Sym->isLive()) + if (!sym->isLive()) continue; - if (!Sym->IsUsedInRegularObj) + if (!sym->isUsedInRegularObj) continue; // We don't generate imports for data symbols. They however can be imported // as GOT entries. - if (isa<DataSymbol>(Sym)) + if (isa<DataSymbol>(sym)) continue; - LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); - Out.ImportSec->addImport(Sym); + LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n"); + out.importSec->addImport(sym); } } void Writer::calculateExports() { - if (Config->Relocatable) + if (config->relocatable) return; - if (!Config->Relocatable && !Config->ImportMemory) - Out.ExportSec->Exports.push_back( + if (!config->relocatable && !config->importMemory) + out.exportSec->exports.push_back( WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); - if (!Config->Relocatable && Config->ExportTable) - Out.ExportSec->Exports.push_back( - WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); + if (!config->relocatable && config->exportTable) + out.exportSec->exports.push_back( + WasmExport{functionTableName, WASM_EXTERNAL_TABLE, 0}); - unsigned FakeGlobalIndex = Out.ImportSec->getNumImportedGlobals() + - Out.GlobalSec->InputGlobals.size(); + unsigned fakeGlobalIndex = out.importSec->getNumImportedGlobals() + + out.globalSec->inputGlobals.size(); - for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isExported()) + for (Symbol *sym : symtab->getSymbols()) { + if (!sym->isExported()) continue; - if (!Sym->isLive()) + if (!sym->isLive()) continue; - StringRef Name = Sym->getName(); - WasmExport Export; - if (auto *F = dyn_cast<DefinedFunction>(Sym)) { - Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; - } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { + StringRef name = sym->getName(); + WasmExport export_; + if (auto *f = dyn_cast<DefinedFunction>(sym)) { + export_ = {name, WASM_EXTERNAL_FUNCTION, f->getFunctionIndex()}; + } else if (auto *g = dyn_cast<DefinedGlobal>(sym)) { // TODO(sbc): Remove this check once to mutable global proposal is // implement in all major browsers. // See: https://github.com/WebAssembly/mutable-global - if (G->getGlobalType()->Mutable) { + if (g->getGlobalType()->Mutable) { // Only the __stack_pointer should ever be create as mutable. - assert(G == WasmSym::StackPointer); + assert(g == WasmSym::stackPointer); continue; } - Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; - } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) { - Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()}; + export_ = {name, WASM_EXTERNAL_GLOBAL, g->getGlobalIndex()}; + } else if (auto *e = dyn_cast<DefinedEvent>(sym)) { + export_ = {name, WASM_EXTERNAL_EVENT, e->getEventIndex()}; } else { - auto *D = cast<DefinedData>(Sym); - Out.GlobalSec->DefinedFakeGlobals.emplace_back(D); - Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; + auto *d = cast<DefinedData>(sym); + out.globalSec->definedFakeGlobals.emplace_back(d); + export_ = {name, WASM_EXTERNAL_GLOBAL, fakeGlobalIndex++}; } - LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); - Out.ExportSec->Exports.push_back(Export); + LLVM_DEBUG(dbgs() << "Export: " << name << "\n"); + out.exportSec->exports.push_back(export_); } } void Writer::populateSymtab() { - if (!Config->Relocatable && !Config->EmitRelocs) + if (!config->relocatable && !config->emitRelocs) return; - for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->IsUsedInRegularObj && Sym->isLive()) - Out.LinkingSec->addToSymtab(Sym); + for (Symbol *sym : symtab->getSymbols()) + if (sym->isUsedInRegularObj && sym->isLive()) + out.linkingSec->addToSymtab(sym); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); - for (Symbol *Sym : File->getSymbols()) - if (Sym->isLocal() && !isa<SectionSymbol>(Sym) && Sym->isLive()) - Out.LinkingSec->addToSymtab(Sym); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Local symtab entries: " << file->getName() << "\n"); + for (Symbol *sym : file->getSymbols()) + if (sym->isLocal() && !isa<SectionSymbol>(sym) && sym->isLive()) + out.linkingSec->addToSymtab(sym); } } @@ -534,152 +534,152 @@ void Writer::calculateTypes() { // 4. The signatures of all imported events // 5. The signatures of all defined events - for (ObjFile *File : Symtab->ObjectFiles) { - ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); - for (uint32_t I = 0; I < Types.size(); I++) - if (File->TypeIsUsed[I]) - File->TypeMap[I] = Out.TypeSec->registerType(Types[I]); + for (ObjFile *file : symtab->objectFiles) { + ArrayRef<WasmSignature> types = file->getWasmObj()->types(); + for (uint32_t i = 0; i < types.size(); i++) + if (file->typeIsUsed[i]) + file->typeMap[i] = out.typeSec->registerType(types[i]); } - for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) { - if (auto *F = dyn_cast<FunctionSymbol>(Sym)) - Out.TypeSec->registerType(*F->Signature); - else if (auto *E = dyn_cast<EventSymbol>(Sym)) - Out.TypeSec->registerType(*E->Signature); + for (const Symbol *sym : out.importSec->importedSymbols) { + if (auto *f = dyn_cast<FunctionSymbol>(sym)) + out.typeSec->registerType(*f->signature); + else if (auto *e = dyn_cast<EventSymbol>(sym)) + out.typeSec->registerType(*e->signature); } - for (const InputFunction *F : Out.FunctionSec->InputFunctions) - Out.TypeSec->registerType(F->Signature); + for (const InputFunction *f : out.functionSec->inputFunctions) + out.typeSec->registerType(f->signature); - for (const InputEvent *E : Out.EventSec->InputEvents) - Out.TypeSec->registerType(E->Signature); + for (const InputEvent *e : out.eventSec->inputEvents) + out.typeSec->registerType(e->signature); } static void scanRelocations() { - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n"); - for (InputChunk *Chunk : File->Functions) - scanRelocations(Chunk); - for (InputChunk *Chunk : File->Segments) - scanRelocations(Chunk); - for (auto &P : File->CustomSections) - scanRelocations(P); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "scanRelocations: " << file->getName() << "\n"); + for (InputChunk *chunk : file->functions) + scanRelocations(chunk); + for (InputChunk *chunk : file->segments) + scanRelocations(chunk); + for (auto &p : file->customSections) + scanRelocations(p); } } void Writer::assignIndexes() { // Seal the import section, since other index spaces such as function and // global are effected by the number of imports. - Out.ImportSec->seal(); + out.importSec->seal(); - for (InputFunction *Func : Symtab->SyntheticFunctions) - Out.FunctionSec->addFunction(Func); + for (InputFunction *func : symtab->syntheticFunctions) + out.functionSec->addFunction(func); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); - for (InputFunction *Func : File->Functions) - Out.FunctionSec->addFunction(Func); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Functions: " << file->getName() << "\n"); + for (InputFunction *func : file->functions) + out.functionSec->addFunction(func); } - for (InputGlobal *Global : Symtab->SyntheticGlobals) - Out.GlobalSec->addGlobal(Global); + for (InputGlobal *global : symtab->syntheticGlobals) + out.globalSec->addGlobal(global); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); - for (InputGlobal *Global : File->Globals) - Out.GlobalSec->addGlobal(Global); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Globals: " << file->getName() << "\n"); + for (InputGlobal *global : file->globals) + out.globalSec->addGlobal(global); } - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n"); - for (InputEvent *Event : File->Events) - Out.EventSec->addEvent(Event); + for (ObjFile *file : symtab->objectFiles) { + LLVM_DEBUG(dbgs() << "Events: " << file->getName() << "\n"); + for (InputEvent *event : file->events) + out.eventSec->addEvent(event); } } -static StringRef getOutputDataSegmentName(StringRef Name) { +static StringRef getOutputDataSegmentName(StringRef name) { // With PIC code we currently only support a single data segment since // we only have a single __memory_base to use as our base address. - if (Config->Pic) + if (config->isPic) return ".data"; - if (!Config->MergeDataSegments) - return Name; - if (Name.startswith(".text.")) + if (!config->mergeDataSegments) + return name; + if (name.startswith(".text.")) return ".text"; - if (Name.startswith(".data.")) + if (name.startswith(".data.")) return ".data"; - if (Name.startswith(".bss.")) + if (name.startswith(".bss.")) return ".bss"; - if (Name.startswith(".rodata.")) + if (name.startswith(".rodata.")) return ".rodata"; - return Name; + return name; } void Writer::createOutputSegments() { - for (ObjFile *File : Symtab->ObjectFiles) { - for (InputSegment *Segment : File->Segments) { - if (!Segment->Live) + for (ObjFile *file : symtab->objectFiles) { + for (InputSegment *segment : file->segments) { + if (!segment->live) continue; - StringRef Name = getOutputDataSegmentName(Segment->getName()); - OutputSegment *&S = SegmentMap[Name]; - if (S == nullptr) { - LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); - S = make<OutputSegment>(Name, Segments.size()); - if (Config->PassiveSegments) - S->InitFlags = WASM_SEGMENT_IS_PASSIVE; - Segments.push_back(S); + StringRef name = getOutputDataSegmentName(segment->getName()); + OutputSegment *&s = segmentMap[name]; + if (s == nullptr) { + LLVM_DEBUG(dbgs() << "new segment: " << name << "\n"); + s = make<OutputSegment>(name, segments.size()); + if (config->passiveSegments) + s->initFlags = WASM_SEGMENT_IS_PASSIVE; + segments.push_back(s); } - S->addInputSegment(Segment); - LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); + s->addInputSegment(segment); + LLVM_DEBUG(dbgs() << "added data: " << name << ": " << s->size << "\n"); } } } -static void createFunction(DefinedFunction *Func, StringRef BodyContent) { - std::string FunctionBody; +static void createFunction(DefinedFunction *func, StringRef bodyContent) { + std::string functionBody; { - raw_string_ostream OS(FunctionBody); - writeUleb128(OS, BodyContent.size(), "function size"); - OS << BodyContent; + raw_string_ostream os(functionBody); + writeUleb128(os, bodyContent.size(), "function size"); + os << bodyContent; } - ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); - cast<SyntheticFunction>(Func->Function)->setBody(Body); + ArrayRef<uint8_t> body = arrayRefFromStringRef(saver.save(functionBody)); + cast<SyntheticFunction>(func->function)->setBody(body); } void Writer::createInitMemoryFunction() { LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); // initialize passive data segments - for (const OutputSegment *S : Segments) { - if (S->InitFlags & WASM_SEGMENT_IS_PASSIVE) { + for (const OutputSegment *s : segments) { + if (s->initFlags & WASM_SEGMENT_IS_PASSIVE) { // destination address - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, S->StartVA, "destination address"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, s->startVA, "destination address"); // source segment offset - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, 0, "segment offset"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, 0, "segment offset"); // memory region size - writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); - writeUleb128(OS, S->Size, "memory region size"); + writeU8(os, WASM_OPCODE_I32_CONST, "i32.const"); + writeUleb128(os, s->size, "memory region size"); // memory.init instruction - writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); - writeUleb128(OS, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT"); - writeUleb128(OS, S->Index, "segment index immediate"); - writeU8(OS, 0, "memory index immediate"); + writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); + writeUleb128(os, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT"); + writeUleb128(os, s->index, "segment index immediate"); + writeU8(os, 0, "memory index immediate"); // data.drop instruction - writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); - writeUleb128(OS, WASM_OPCODE_DATA_DROP, "DATA.DROP"); - writeUleb128(OS, S->Index, "segment index immediate"); + writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); + writeUleb128(os, WASM_OPCODE_DATA_DROP, "DATA.DROP"); + writeUleb128(os, s->index, "segment index immediate"); } } - writeU8(OS, WASM_OPCODE_END, "END"); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::InitMemory, BodyContent); + createFunction(WasmSym::initMemory, bodyContent); } // For -shared (PIC) output, we create create a synthetic function which will @@ -689,109 +689,109 @@ void Writer::createInitMemoryFunction() { void Writer::createApplyRelocationsFunction() { LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n"); // First write the body's contents to a string. - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); - for (const OutputSegment *Seg : Segments) - for (const InputSegment *InSeg : Seg->InputSegments) - InSeg->generateRelocationCode(OS); - writeU8(OS, WASM_OPCODE_END, "END"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); + for (const OutputSegment *seg : segments) + for (const InputSegment *inSeg : seg->inputSegments) + inSeg->generateRelocationCode(os); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::ApplyRelocs, BodyContent); + createFunction(WasmSym::applyRelocs, bodyContent); } // Create synthetic "__wasm_call_ctors" function based on ctor functions // in input object. void Writer::createCallCtorsFunction() { - if (!WasmSym::CallCtors->isLive()) + if (!WasmSym::callCtors->isLive()) return; // First write the body's contents to a string. - std::string BodyContent; + std::string bodyContent; { - raw_string_ostream OS(BodyContent); - writeUleb128(OS, 0, "num locals"); + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); - if (Config->PassiveSegments) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, WasmSym::InitMemory->getFunctionIndex(), + if (config->passiveSegments) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, WasmSym::initMemory->getFunctionIndex(), "function index"); } - if (Config->Pic) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(), + if (config->isPic) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, WasmSym::applyRelocs->getFunctionIndex(), "function index"); } // Call constructors - for (const WasmInitEntry &F : InitFunctions) { - writeU8(OS, WASM_OPCODE_CALL, "CALL"); - writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); + for (const WasmInitEntry &f : initFunctions) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, f.sym->getFunctionIndex(), "function index"); } - writeU8(OS, WASM_OPCODE_END, "END"); + writeU8(os, WASM_OPCODE_END, "END"); } - createFunction(WasmSym::CallCtors, BodyContent); + createFunction(WasmSym::callCtors, bodyContent); } // Populate InitFunctions vector with init functions from all input objects. // This is then used either when creating the output linking section or to // synthesize the "__wasm_call_ctors" function. void Writer::calculateInitFunctions() { - if (!Config->Relocatable && !WasmSym::CallCtors->isLive()) + if (!config->relocatable && !WasmSym::callCtors->isLive()) return; - for (ObjFile *File : Symtab->ObjectFiles) { - const WasmLinkingData &L = File->getWasmObj()->linkingData(); - for (const WasmInitFunc &F : L.InitFunctions) { - FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); + for (ObjFile *file : symtab->objectFiles) { + const WasmLinkingData &l = file->getWasmObj()->linkingData(); + for (const WasmInitFunc &f : l.InitFunctions) { + FunctionSymbol *sym = file->getFunctionSymbol(f.Symbol); // comdat exclusions can cause init functions be discarded. - if (Sym->isDiscarded()) + if (sym->isDiscarded()) continue; - assert(Sym->isLive()); - if (*Sym->Signature != WasmSignature{{}, {}}) - error("invalid signature for init func: " + toString(*Sym)); - InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); + assert(sym->isLive()); + if (*sym->signature != WasmSignature{{}, {}}) + error("invalid signature for init func: " + toString(*sym)); + initFunctions.emplace_back(WasmInitEntry{sym, f.Priority}); } } // Sort in order of priority (lowest first) so that they are called // in the correct order. - llvm::stable_sort(InitFunctions, - [](const WasmInitEntry &L, const WasmInitEntry &R) { - return L.Priority < R.Priority; + llvm::stable_sort(initFunctions, + [](const WasmInitEntry &l, const WasmInitEntry &r) { + return l.priority < r.priority; }); } void Writer::createSyntheticSections() { - Out.DylinkSec = make<DylinkSection>(); - Out.TypeSec = make<TypeSection>(); - Out.ImportSec = make<ImportSection>(); - Out.FunctionSec = make<FunctionSection>(); - Out.TableSec = make<TableSection>(); - Out.MemorySec = make<MemorySection>(); - Out.GlobalSec = make<GlobalSection>(); - Out.EventSec = make<EventSection>(); - Out.ExportSec = make<ExportSection>(); - Out.ElemSec = make<ElemSection>(TableBase); - Out.DataCountSec = make<DataCountSection>(Segments.size()); - Out.LinkingSec = make<LinkingSection>(InitFunctions, Segments); - Out.NameSec = make<NameSection>(); - Out.ProducersSec = make<ProducersSection>(); - Out.TargetFeaturesSec = make<TargetFeaturesSection>(); + out.dylinkSec = make<DylinkSection>(); + out.typeSec = make<TypeSection>(); + out.importSec = make<ImportSection>(); + out.functionSec = make<FunctionSection>(); + out.tableSec = make<TableSection>(); + out.memorySec = make<MemorySection>(); + out.globalSec = make<GlobalSection>(); + out.eventSec = make<EventSection>(); + out.exportSec = make<ExportSection>(); + out.elemSec = make<ElemSection>(tableBase); + out.dataCountSec = make<DataCountSection>(segments.size()); + out.linkingSec = make<LinkingSection>(initFunctions, segments); + out.nameSec = make<NameSection>(); + out.producersSec = make<ProducersSection>(); + out.targetFeaturesSec = make<TargetFeaturesSection>(); } void Writer::run() { - if (Config->Relocatable || Config->Pic) - Config->GlobalBase = 0; + if (config->relocatable || config->isPic) + config->globalBase = 0; // For PIC code the table base is assigned dynamically by the loader. // For non-PIC, we start at 1 so that accessing table index 0 always traps. - if (!Config->Pic) - TableBase = 1; + if (!config->isPic) + tableBase = 1; log("-- createOutputSegments"); createOutputSegments(); @@ -806,11 +806,11 @@ void Writer::run() { log("-- layoutMemory"); layoutMemory(); - if (!Config->Relocatable) { + if (!config->relocatable) { // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols // This has to be done after memory layout is performed. - for (const OutputSegment *Seg : Segments) - addStartStopSymbols(Seg); + for (const OutputSegment *seg : segments) + addStartStopSymbols(seg); } log("-- scanRelocations"); @@ -820,11 +820,11 @@ void Writer::run() { log("-- calculateInitFunctions"); calculateInitFunctions(); - if (!Config->Relocatable) { + if (!config->relocatable) { // Create linker synthesized functions - if (Config->PassiveSegments) + if (config->passiveSegments) createInitMemoryFunction(); - if (Config->Pic) + if (config->isPic) createApplyRelocationsFunction(); createCallCtorsFunction(); } @@ -840,16 +840,16 @@ void Writer::run() { log("-- addSections"); addSections(); - if (errorHandler().Verbose) { - log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size())); - log("Defined Globals : " + Twine(Out.GlobalSec->InputGlobals.size())); - log("Defined Events : " + Twine(Out.EventSec->InputEvents.size())); + if (errorHandler().verbose) { + log("Defined Functions: " + Twine(out.functionSec->inputFunctions.size())); + log("Defined Globals : " + Twine(out.globalSec->inputGlobals.size())); + log("Defined Events : " + Twine(out.eventSec->inputEvents.size())); log("Function Imports : " + - Twine(Out.ImportSec->getNumImportedFunctions())); - log("Global Imports : " + Twine(Out.ImportSec->getNumImportedGlobals())); - log("Event Imports : " + Twine(Out.ImportSec->getNumImportedEvents())); - for (ObjFile *File : Symtab->ObjectFiles) - File->dumpInfo(); + Twine(out.importSec->getNumImportedFunctions())); + log("Global Imports : " + Twine(out.importSec->getNumImportedGlobals())); + log("Event Imports : " + Twine(out.importSec->getNumImportedEvents())); + for (ObjFile *file : symtab->objectFiles) + file->dumpInfo(); } createHeader(); @@ -868,31 +868,31 @@ void Writer::run() { if (errorCount()) return; - if (Error E = Buffer->commit()) - fatal("failed to write the output file: " + toString(std::move(E))); + if (Error e = buffer->commit()) + fatal("failed to write the output file: " + toString(std::move(e))); } // Open a result file. void Writer::openFile() { - log("writing: " + Config->OutputFile); + log("writing: " + config->outputFile); - Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = - FileOutputBuffer::create(Config->OutputFile, FileSize, + Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr = + FileOutputBuffer::create(config->outputFile, fileSize, FileOutputBuffer::F_executable); - if (!BufferOrErr) - error("failed to open " + Config->OutputFile + ": " + - toString(BufferOrErr.takeError())); + if (!bufferOrErr) + error("failed to open " + config->outputFile + ": " + + toString(bufferOrErr.takeError())); else - Buffer = std::move(*BufferOrErr); + buffer = std::move(*bufferOrErr); } void Writer::createHeader() { - raw_string_ostream OS(Header); - writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); - writeU32(OS, WasmVersion, "wasm version"); - OS.flush(); - FileSize += Header.size(); + raw_string_ostream os(header); + writeBytes(os, WasmMagic, sizeof(WasmMagic), "wasm magic"); + writeU32(os, WasmVersion, "wasm version"); + os.flush(); + fileSize += header.size(); } void lld::wasm::writeResult() { Writer().run(); } diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp index 198c1b988b0..d45f6a4c77f 100644 --- a/lld/wasm/WriterUtils.cpp +++ b/lld/wasm/WriterUtils.cpp @@ -19,159 +19,159 @@ using namespace llvm::wasm; namespace lld { -void wasm::debugWrite(uint64_t Offset, const Twine &Msg) { - LLVM_DEBUG(dbgs() << format(" | %08lld: ", Offset) << Msg << "\n"); +void wasm::debugWrite(uint64_t offset, const Twine &msg) { + LLVM_DEBUG(dbgs() << format(" | %08lld: ", offset) << msg << "\n"); } -void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); - encodeULEB128(Number, OS); +void wasm::writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]"); + encodeULEB128(number, os); } -void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); - encodeSLEB128(Number, OS); +void wasm::writeSleb128(raw_ostream &os, int32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]"); + encodeSLEB128(number, os); } -void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count, - const Twine &Msg) { - debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]"); - OS.write(Bytes, Count); +void wasm::writeBytes(raw_ostream &os, const char *bytes, size_t count, + const Twine &msg) { + debugWrite(os.tell(), msg + " [data[" + Twine(count) + "]]"); + os.write(bytes, count); } -void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) { - debugWrite(OS.tell(), - Msg + " [str[" + Twine(String.size()) + "]: " + String + "]"); - encodeULEB128(String.size(), OS); - OS.write(String.data(), String.size()); +void wasm::writeStr(raw_ostream &os, StringRef string, const Twine &msg) { + debugWrite(os.tell(), + msg + " [str[" + Twine(string.size()) + "]: " + string + "]"); + encodeULEB128(string.size(), os); + os.write(string.data(), string.size()); } -void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) { - debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]"); - OS << Byte; +void wasm::writeU8(raw_ostream &os, uint8_t byte, const Twine &msg) { + debugWrite(os.tell(), msg + " [0x" + utohexstr(byte) + "]"); + os << byte; } -void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) { - debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]"); - support::endian::write(OS, Number, support::little); +void wasm::writeU32(raw_ostream &os, uint32_t number, const Twine &msg) { + debugWrite(os.tell(), msg + "[0x" + utohexstr(number) + "]"); + support::endian::write(os, number, support::little); } -void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) { - writeU8(OS, static_cast<uint8_t>(Type), - Msg + "[type: " + toString(Type) + "]"); +void wasm::writeValueType(raw_ostream &os, ValType type, const Twine &msg) { + writeU8(os, static_cast<uint8_t>(type), + msg + "[type: " + toString(type) + "]"); } -void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) { - writeU8(OS, WASM_TYPE_FUNC, "signature type"); - writeUleb128(OS, Sig.Params.size(), "param Count"); - for (ValType ParamType : Sig.Params) { - writeValueType(OS, ParamType, "param type"); +void wasm::writeSig(raw_ostream &os, const WasmSignature &sig) { + writeU8(os, WASM_TYPE_FUNC, "signature type"); + writeUleb128(os, sig.Params.size(), "param Count"); + for (ValType paramType : sig.Params) { + writeValueType(os, paramType, "param type"); } - writeUleb128(OS, Sig.Returns.size(), "result Count"); - if (Sig.Returns.size()) { - writeValueType(OS, Sig.Returns[0], "result type"); + writeUleb128(os, sig.Returns.size(), "result Count"); + if (sig.Returns.size()) { + writeValueType(os, sig.Returns[0], "result type"); } } -void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) { - writeU8(OS, InitExpr.Opcode, "opcode"); - switch (InitExpr.Opcode) { +void wasm::writeInitExpr(raw_ostream &os, const WasmInitExpr &initExpr) { + writeU8(os, initExpr.Opcode, "opcode"); + switch (initExpr.Opcode) { case WASM_OPCODE_I32_CONST: - writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)"); + writeSleb128(os, initExpr.Value.Int32, "literal (i32)"); break; case WASM_OPCODE_I64_CONST: - writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)"); + writeSleb128(os, initExpr.Value.Int64, "literal (i64)"); break; case WASM_OPCODE_GLOBAL_GET: - writeUleb128(OS, InitExpr.Value.Global, "literal (global index)"); + writeUleb128(os, initExpr.Value.Global, "literal (global index)"); break; default: - fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode)); + fatal("unknown opcode in init expr: " + Twine(initExpr.Opcode)); } - writeU8(OS, WASM_OPCODE_END, "opcode:end"); + writeU8(os, WASM_OPCODE_END, "opcode:end"); } -void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) { - writeU8(OS, Limits.Flags, "limits flags"); - writeUleb128(OS, Limits.Initial, "limits initial"); - if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) - writeUleb128(OS, Limits.Maximum, "limits max"); +void wasm::writeLimits(raw_ostream &os, const WasmLimits &limits) { + writeU8(os, limits.Flags, "limits flags"); + writeUleb128(os, limits.Initial, "limits initial"); + if (limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) + writeUleb128(os, limits.Maximum, "limits max"); } -void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) { +void wasm::writeGlobalType(raw_ostream &os, const WasmGlobalType &type) { // TODO: Update WasmGlobalType to use ValType and remove this cast. - writeValueType(OS, ValType(Type.Type), "global type"); - writeU8(OS, Type.Mutable, "global mutable"); + writeValueType(os, ValType(type.Type), "global type"); + writeU8(os, type.Mutable, "global mutable"); } -void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { - writeGlobalType(OS, Global.Type); - writeInitExpr(OS, Global.InitExpr); +void wasm::writeGlobal(raw_ostream &os, const WasmGlobal &global) { + writeGlobalType(os, global.Type); + writeInitExpr(os, global.InitExpr); } -void wasm::writeEventType(raw_ostream &OS, const WasmEventType &Type) { - writeUleb128(OS, Type.Attribute, "event attribute"); - writeUleb128(OS, Type.SigIndex, "sig index"); +void wasm::writeEventType(raw_ostream &os, const WasmEventType &type) { + writeUleb128(os, type.Attribute, "event attribute"); + writeUleb128(os, type.SigIndex, "sig index"); } -void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) { - writeEventType(OS, Event.Type); +void wasm::writeEvent(raw_ostream &os, const WasmEvent &event) { + writeEventType(os, event.Type); } -void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) { - writeU8(OS, WASM_TYPE_FUNCREF, "table type"); - writeLimits(OS, Type.Limits); +void wasm::writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type) { + writeU8(os, WASM_TYPE_FUNCREF, "table type"); + writeLimits(os, type.Limits); } -void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { - writeStr(OS, Import.Module, "import module name"); - writeStr(OS, Import.Field, "import field name"); - writeU8(OS, Import.Kind, "import kind"); - switch (Import.Kind) { +void wasm::writeImport(raw_ostream &os, const WasmImport &import) { + writeStr(os, import.Module, "import module name"); + writeStr(os, import.Field, "import field name"); + writeU8(os, import.Kind, "import kind"); + switch (import.Kind) { case WASM_EXTERNAL_FUNCTION: - writeUleb128(OS, Import.SigIndex, "import sig index"); + writeUleb128(os, import.SigIndex, "import sig index"); break; case WASM_EXTERNAL_GLOBAL: - writeGlobalType(OS, Import.Global); + writeGlobalType(os, import.Global); break; case WASM_EXTERNAL_EVENT: - writeEventType(OS, Import.Event); + writeEventType(os, import.Event); break; case WASM_EXTERNAL_MEMORY: - writeLimits(OS, Import.Memory); + writeLimits(os, import.Memory); break; case WASM_EXTERNAL_TABLE: - writeTableType(OS, Import.Table); + writeTableType(os, import.Table); break; default: - fatal("unsupported import type: " + Twine(Import.Kind)); + fatal("unsupported import type: " + Twine(import.Kind)); } } -void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) { - writeStr(OS, Export.Name, "export name"); - writeU8(OS, Export.Kind, "export kind"); - switch (Export.Kind) { +void wasm::writeExport(raw_ostream &os, const WasmExport &export_) { + writeStr(os, export_.Name, "export name"); + writeU8(os, export_.Kind, "export kind"); + switch (export_.Kind) { case WASM_EXTERNAL_FUNCTION: - writeUleb128(OS, Export.Index, "function index"); + writeUleb128(os, export_.Index, "function index"); break; case WASM_EXTERNAL_GLOBAL: - writeUleb128(OS, Export.Index, "global index"); + writeUleb128(os, export_.Index, "global index"); break; case WASM_EXTERNAL_MEMORY: - writeUleb128(OS, Export.Index, "memory index"); + writeUleb128(os, export_.Index, "memory index"); break; case WASM_EXTERNAL_TABLE: - writeUleb128(OS, Export.Index, "table index"); + writeUleb128(os, export_.Index, "table index"); break; default: - fatal("unsupported export type: " + Twine(Export.Kind)); + fatal("unsupported export type: " + Twine(export_.Kind)); } } } // namespace lld -std::string lld::toString(ValType Type) { - switch (Type) { +std::string lld::toString(ValType type) { + switch (type) { case ValType::I32: return "i32"; case ValType::I64: @@ -188,28 +188,28 @@ std::string lld::toString(ValType Type) { llvm_unreachable("Invalid wasm::ValType"); } -std::string lld::toString(const WasmSignature &Sig) { - SmallString<128> S("("); - for (ValType Type : Sig.Params) { - if (S.size() != 1) - S += ", "; - S += toString(Type); +std::string lld::toString(const WasmSignature &sig) { + SmallString<128> s("("); + for (ValType type : sig.Params) { + if (s.size() != 1) + s += ", "; + s += toString(type); } - S += ") -> "; - if (Sig.Returns.empty()) - S += "void"; + s += ") -> "; + if (sig.Returns.empty()) + s += "void"; else - S += toString(Sig.Returns[0]); - return S.str(); + s += toString(sig.Returns[0]); + return s.str(); } -std::string lld::toString(const WasmGlobalType &Type) { - return (Type.Mutable ? "var " : "const ") + - toString(static_cast<ValType>(Type.Type)); +std::string lld::toString(const WasmGlobalType &type) { + return (type.Mutable ? "var " : "const ") + + toString(static_cast<ValType>(type.Type)); } -std::string lld::toString(const WasmEventType &Type) { - if (Type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION) +std::string lld::toString(const WasmEventType &type) { + if (type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION) return "exception"; return "unknown"; } diff --git a/lld/wasm/WriterUtils.h b/lld/wasm/WriterUtils.h index 389f997997c..2d4eaf9662e 100644 --- a/lld/wasm/WriterUtils.h +++ b/lld/wasm/WriterUtils.h @@ -16,50 +16,50 @@ namespace lld { namespace wasm { -void debugWrite(uint64_t Offset, const Twine &Msg); +void debugWrite(uint64_t offset, const Twine &msg); -void writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg); +void writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg); -void writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg); +void writeSleb128(raw_ostream &os, int32_t number, const Twine &msg); -void writeBytes(raw_ostream &OS, const char *Bytes, size_t count, - const Twine &Msg); +void writeBytes(raw_ostream &os, const char *bytes, size_t count, + const Twine &msg); -void writeStr(raw_ostream &OS, StringRef String, const Twine &Msg); +void writeStr(raw_ostream &os, StringRef string, const Twine &msg); -void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg); +void writeU8(raw_ostream &os, uint8_t byte, const Twine &msg); -void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg); +void writeU32(raw_ostream &os, uint32_t number, const Twine &msg); -void writeValueType(raw_ostream &OS, llvm::wasm::ValType Type, - const Twine &Msg); +void writeValueType(raw_ostream &os, llvm::wasm::ValType type, + const Twine &msg); -void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig); +void writeSig(raw_ostream &os, const llvm::wasm::WasmSignature &sig); -void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr); +void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr); -void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); +void writeLimits(raw_ostream &os, const llvm::wasm::WasmLimits &limits); -void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type); +void writeGlobalType(raw_ostream &os, const llvm::wasm::WasmGlobalType &type); -void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); +void writeGlobal(raw_ostream &os, const llvm::wasm::WasmGlobal &global); -void writeEventType(raw_ostream &OS, const llvm::wasm::WasmEventType &Type); +void writeEventType(raw_ostream &os, const llvm::wasm::WasmEventType &type); -void writeEvent(raw_ostream &OS, const llvm::wasm::WasmEvent &Event); +void writeEvent(raw_ostream &os, const llvm::wasm::WasmEvent &event); -void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type); +void writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type); -void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); +void writeImport(raw_ostream &os, const llvm::wasm::WasmImport &import); -void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export); +void writeExport(raw_ostream &os, const llvm::wasm::WasmExport &export_); } // namespace wasm -std::string toString(llvm::wasm::ValType Type); -std::string toString(const llvm::wasm::WasmSignature &Sig); -std::string toString(const llvm::wasm::WasmGlobalType &Type); -std::string toString(const llvm::wasm::WasmEventType &Type); +std::string toString(llvm::wasm::ValType type); +std::string toString(const llvm::wasm::WasmSignature &sig); +std::string toString(const llvm::wasm::WasmGlobalType &type); +std::string toString(const llvm::wasm::WasmEventType &type); } // namespace lld |