1//===--- COFFModuleDefinition.cpp - Simple DEF parser ---------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 10// A parser for the module-definition file (.def file). 12// The format of module-definition files are described in this document: 13// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx 15//===----------------------------------------------------------------------===// 59// In def files, the symbols can either be listed decorated or undecorated. 61// - For cdecl symbols, only the undecorated form is allowed. 62// - For fastcall and vectorcall symbols, both fully decorated or 63// undecorated forms can be present. 64// - For stdcall symbols in non-MinGW environments, the decorated form is 65// fully decorated with leading underscore and trailing stack argument 66// size - like "_Func@0". 67// - In MinGW def files, a decorated stdcall symbol does not include the 68// leading underscore though, like "Func@0". 70// This function controls whether a leading underscore should be added to 71// the given symbol name or not. For MinGW, treat a stdcall symbol name such 72// as "Func@0" as undecorated, i.e. a leading underscore must be added. 73// For non-MinGW, look for '@' in the whole string and consider "_Func@0" 74// as decorated, i.e. don't add any more leading underscores. 75// We can't check for a leading underscore here, since function names 76// themselves can start with an underscore, while a second one still needs 78returnSym.starts_with(
"@") ||
Sym.contains(
"@@") ||
Sym.starts_with(
"?") ||
79 (!MingwDef &&
Sym.contains(
'@'));
142 : Lex(S), Machine(M), MingwDef(
B), AddUnderscores(AU) {
144 AddUnderscores =
false;
149if (
Error Err = parseOne())
150return std::move(Err);
151 }
while (Tok.
K !=
Eof);
179void unget() { Stack.push_back(Tok); }
193if (
Error Err = parseExport())
202bool IsDll = Tok.
K ==
KwLibrary;
// Check before parseName. 209// Set the output file, but don't override /out if it was already passed. 212// Append the appropriate file extension if not already present. 228 E.Name = std::string(Tok.
Value);
235 E.Name = std::string(Tok.
Value);
242 E.Name = (std::string(
"_").append(E.Name));
243if (!E.ExtName.empty() && !
isDecorated(E.ExtName, MingwDef))
244 E.ExtName = (std::string(
"_").append(E.ExtName));
250if (Tok.
Value ==
"@") {
255// "foo \n @bar" - Not an ordinal modifier at all, but the next 256// export (fastcall decorated) - complete the current one. 284 E.ImportName = std::string(Tok.
Value);
287// EXPORTAS must be at the end of export definition 292"unexpected end of file, EXPORTAS identifier expected");
293 E.ExportAs = std::string(Tok.
Value);
302// HEAPSIZE/STACKSIZE reserve[,commit] 304if (
Error Err = readAsInt(Reserve))
312if (
Error Err = readAsInt(Commit))
317// NAME outputPath [BASE=address] 321 *Out = std::string(Tok.
Value);
331if (
Error Err = readAsInt(Baseaddr))
340// VERSION major[.minor] 351elseif (
V2.getAsInteger(10, *Minor))
358 std::vector<Token> Stack;
360 COFFModuleDefinition Info;
368bool AddUnderscores) {
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getBuffer() const
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static constexpr size_t npos
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
LLVM Value Representation.
Parser(StringRef S, MachineTypes M, bool B, bool AU)
Expected< COFFModuleDefinition > parse()
@ IMAGE_FILE_MACHINE_I386
Error createError(const Twine &Err)
Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
static bool isDecorated(StringRef Sym, bool MingwDef)
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
This is an optimization pass for GlobalISel generic memory operations.
uint32_t MajorImageVersion
uint32_t MinorImageVersion
std::vector< COFFShortExport > Exports
Token(Kind T=Unknown, StringRef S="")