summaryrefslogtreecommitdiff
path: root/lib/Object/COFFModuleDefinition.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Object/COFFModuleDefinition.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Object/COFFModuleDefinition.cpp')
-rw-r--r--lib/Object/COFFModuleDefinition.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/Object/COFFModuleDefinition.cpp b/lib/Object/COFFModuleDefinition.cpp
index 510eac8b239ba..a571354648d65 100644
--- a/lib/Object/COFFModuleDefinition.cpp
+++ b/lib/Object/COFFModuleDefinition.cpp
@@ -57,9 +57,27 @@ struct Token {
};
static bool isDecorated(StringRef Sym, bool MingwDef) {
- // mingw does not prepend "_".
- return (!MingwDef && Sym.startswith("_")) || Sym.startswith("@") ||
- Sym.startswith("?");
+ // In def files, the symbols can either be listed decorated or undecorated.
+ //
+ // - For cdecl symbols, only the undecorated form is allowed.
+ // - For fastcall and vectorcall symbols, both fully decorated or
+ // undecorated forms can be present.
+ // - For stdcall symbols in non-MinGW environments, the decorated form is
+ // fully decorated with leading underscore and trailing stack argument
+ // size - like "_Func@0".
+ // - In MinGW def files, a decorated stdcall symbol does not include the
+ // leading underscore though, like "Func@0".
+
+ // This function controls whether a leading underscore should be added to
+ // the given symbol name or not. For MinGW, treat a stdcall symbol name such
+ // as "Func@0" as undecorated, i.e. a leading underscore must be added.
+ // For non-MinGW, look for '@' in the whole string and consider "_Func@0"
+ // as decorated, i.e. don't add any more leading underscores.
+ // We can't check for a leading underscore here, since function names
+ // themselves can start with an underscore, while a second one still needs
+ // to be added.
+ return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") ||
+ (!MingwDef && Sym.contains('@'));
}
static Error createError(const Twine &Err) {
@@ -99,7 +117,7 @@ public:
return Token(Identifier, S);
}
default: {
- size_t End = Buf.find_first_of("=,\r\n \t\v");
+ size_t End = Buf.find_first_of("=,;\r\n \t\v");
StringRef Word = Buf.substr(0, End);
Kind K = llvm::StringSwitch<Kind>(Word)
.Case("BASE", KwBase)
@@ -232,13 +250,18 @@ private:
for (;;) {
read();
if (Tok.K == Identifier && Tok.Value[0] == '@') {
- if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
- // Not an ordinal modifier at all, but the next export (fastcall
- // decorated) - complete the current one.
+ if (Tok.Value == "@") {
+ // "foo @ 10"
+ read();
+ Tok.Value.getAsInteger(10, E.Ordinal);
+ } else if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
+ // "foo \n @bar" - Not an ordinal modifier at all, but the next
+ // export (fastcall decorated) - complete the current one.
unget();
Info.Exports.push_back(E);
return Error::success();
}
+ // "foo @10"
read();
if (Tok.K == KwNoname) {
E.Noname = true;