Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
COFFModuleDefinition.cpp
Go to the documentation of this file.
1//===--- COFFModuleDefinition.cpp - Simple DEF parser ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Windows-specific.
10// A parser for the module-definition file (.def file).
11//
12// The format of module-definition files are described in this document:
13// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Object/COFFModuleDefinition.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Object/COFFImportFile.h"
21#include "llvm/Object/Error.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/Path.h"
24
25using namespacellvm::COFF;
26using namespacellvm;
27
28namespacellvm {
29namespaceobject {
30
31enumKind {
32Unknown,
33Eof,
34Identifier,
35Comma,
36Equal,
37EqualEqual,
38KwBase,
39KwConstant,
40KwData,
41KwExports,
42KwExportAs,
43KwHeapsize,
44KwLibrary,
45KwName,
46KwNoname,
47KwPrivate,
48KwStacksize,
49KwVersion,
50};
51
52structToken {
53explicitToken(KindT =Unknown,StringRef S ="") :K(T),Value(S) {}
54KindK;
55StringRefValue;
56};
57
58staticboolisDecorated(StringRefSym,bool MingwDef) {
59// In def files, the symbols can either be listed decorated or undecorated.
60//
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".
69
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
77// to be added.
78returnSym.starts_with("@") ||Sym.contains("@@") ||Sym.starts_with("?") ||
79 (!MingwDef &&Sym.contains('@'));
80}
81
82classLexer {
83public:
84Lexer(StringRef S) : Buf(S) {}
85
86Tokenlex() {
87 Buf = Buf.trim();
88if (Buf.empty())
89returnToken(Eof);
90
91switch (Buf[0]) {
92case'\0':
93returnToken(Eof);
94case';': {
95size_tEnd = Buf.find('\n');
96 Buf = (End == Buf.npos) ?"" : Buf.drop_front(End);
97returnlex();
98 }
99case'=':
100 Buf = Buf.drop_front();
101if (Buf.consume_front("="))
102returnToken(EqualEqual,"==");
103returnToken(Equal,"=");
104case',':
105 Buf = Buf.drop_front();
106returnToken(Comma,",");
107case'"': {
108StringRef S;
109 std::tie(S, Buf) = Buf.substr(1).split('"');
110returnToken(Identifier, S);
111 }
112default: {
113size_tEnd = Buf.find_first_of("=,;\r\n \t\v");
114StringRef Word = Buf.substr(0,End);
115Kind K =llvm::StringSwitch<Kind>(Word)
116 .Case("BASE",KwBase)
117 .Case("CONSTANT",KwConstant)
118 .Case("DATA",KwData)
119 .Case("EXPORTS",KwExports)
120 .Case("EXPORTAS",KwExportAs)
121 .Case("HEAPSIZE",KwHeapsize)
122 .Case("LIBRARY",KwLibrary)
123 .Case("NAME",KwName)
124 .Case("NONAME",KwNoname)
125 .Case("PRIVATE",KwPrivate)
126 .Case("STACKSIZE",KwStacksize)
127 .Case("VERSION",KwVersion)
128 .Default(Identifier);
129 Buf = (End == Buf.npos) ?"" : Buf.drop_front(End);
130returnToken(K, Word);
131 }
132 }
133 }
134
135private:
136StringRef Buf;
137};
138
139classParser {
140public:
141explicitParser(StringRef S,MachineTypes M,boolB,bool AU)
142 : Lex(S), Machine(M), MingwDef(B), AddUnderscores(AU) {
143if (Machine !=IMAGE_FILE_MACHINE_I386)
144 AddUnderscores =false;
145 }
146
147Expected<COFFModuleDefinition>parse() {
148do {
149if (Error Err = parseOne())
150return std::move(Err);
151 }while (Tok.K !=Eof);
152return Info;
153 }
154
155private:
156void read() {
157if (Stack.empty()) {
158 Tok = Lex.lex();
159return;
160 }
161 Tok = Stack.back();
162 Stack.pop_back();
163 }
164
165Error readAsInt(uint64_t *I) {
166 read();
167if (Tok.K !=Identifier || Tok.Value.getAsInteger(10, *I))
168returncreateError("integer expected");
169returnError::success();
170 }
171
172Error expect(KindExpected,StringRef Msg) {
173 read();
174if (Tok.K !=Expected)
175returncreateError(Msg);
176returnError::success();
177 }
178
179void unget() { Stack.push_back(Tok); }
180
181Error parseOne() {
182 read();
183switch (Tok.K) {
184caseEof:
185returnError::success();
186caseKwExports:
187for (;;) {
188 read();
189if (Tok.K !=Identifier) {
190 unget();
191returnError::success();
192 }
193if (Error Err = parseExport())
194return Err;
195 }
196caseKwHeapsize:
197return parseNumbers(&Info.HeapReserve, &Info.HeapCommit);
198caseKwStacksize:
199return parseNumbers(&Info.StackReserve, &Info.StackCommit);
200caseKwLibrary:
201caseKwName: {
202bool IsDll = Tok.K ==KwLibrary;// Check before parseName.
203 std::stringName;
204if (Error Err = parseName(&Name, &Info.ImageBase))
205return Err;
206
207 Info.ImportName =Name;
208
209// Set the output file, but don't override /out if it was already passed.
210if (Info.OutputFile.empty()) {
211 Info.OutputFile =Name;
212// Append the appropriate file extension if not already present.
213if (!sys::path::has_extension(Name))
214 Info.OutputFile += IsDll ?".dll" :".exe";
215 }
216
217returnError::success();
218 }
219caseKwVersion:
220return parseVersion(&Info.MajorImageVersion, &Info.MinorImageVersion);
221default:
222returncreateError("unknown directive: " + Tok.Value);
223 }
224 }
225
226Error parseExport() {
227 COFFShortExport E;
228 E.Name = std::string(Tok.Value);
229 read();
230if (Tok.K ==Equal) {
231 read();
232if (Tok.K !=Identifier)
233returncreateError("identifier expected, but got " + Tok.Value);
234 E.ExtName = E.Name;
235 E.Name = std::string(Tok.Value);
236 }else {
237 unget();
238 }
239
240if (AddUnderscores) {
241if (!isDecorated(E.Name, MingwDef))
242 E.Name = (std::string("_").append(E.Name));
243if (!E.ExtName.empty() && !isDecorated(E.ExtName, MingwDef))
244 E.ExtName = (std::string("_").append(E.ExtName));
245 }
246
247for (;;) {
248 read();
249if (Tok.K ==Identifier && Tok.Value[0] =='@') {
250if (Tok.Value =="@") {
251// "foo @ 10"
252 read();
253 Tok.Value.getAsInteger(10, E.Ordinal);
254 }elseif (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
255// "foo \n @bar" - Not an ordinal modifier at all, but the next
256// export (fastcall decorated) - complete the current one.
257 unget();
258 Info.Exports.push_back(E);
259returnError::success();
260 }
261// "foo @10"
262 read();
263if (Tok.K ==KwNoname) {
264 E.Noname =true;
265 }else {
266 unget();
267 }
268continue;
269 }
270if (Tok.K ==KwData) {
271 E.Data =true;
272continue;
273 }
274if (Tok.K ==KwConstant) {
275 E.Constant =true;
276continue;
277 }
278if (Tok.K ==KwPrivate) {
279 E.Private =true;
280continue;
281 }
282if (Tok.K ==EqualEqual) {
283 read();
284 E.ImportName = std::string(Tok.Value);
285continue;
286 }
287// EXPORTAS must be at the end of export definition
288if (Tok.K ==KwExportAs) {
289 read();
290if (Tok.K ==Eof)
291returncreateError(
292"unexpected end of file, EXPORTAS identifier expected");
293 E.ExportAs = std::string(Tok.Value);
294 }else {
295 unget();
296 }
297 Info.Exports.push_back(E);
298returnError::success();
299 }
300 }
301
302// HEAPSIZE/STACKSIZE reserve[,commit]
303Error parseNumbers(uint64_t *Reserve,uint64_t *Commit) {
304if (Error Err = readAsInt(Reserve))
305return Err;
306 read();
307if (Tok.K !=Comma) {
308 unget();
309 Commit =nullptr;
310returnError::success();
311 }
312if (Error Err = readAsInt(Commit))
313return Err;
314returnError::success();
315 }
316
317// NAME outputPath [BASE=address]
318Error parseName(std::string *Out,uint64_t *Baseaddr) {
319 read();
320if (Tok.K ==Identifier) {
321 *Out = std::string(Tok.Value);
322 }else {
323 *Out ="";
324 unget();
325returnError::success();
326 }
327 read();
328if (Tok.K ==KwBase) {
329if (Error Err = expect(Equal,"'=' expected"))
330return Err;
331if (Error Err = readAsInt(Baseaddr))
332return Err;
333 }else {
334 unget();
335 *Baseaddr = 0;
336 }
337returnError::success();
338 }
339
340// VERSION major[.minor]
341Error parseVersion(uint32_t *Major,uint32_t *Minor) {
342 read();
343if (Tok.K !=Identifier)
344returncreateError("identifier expected, but got " + Tok.Value);
345StringRef V1,V2;
346 std::tie(V1, V2) = Tok.Value.split('.');
347if (V1.getAsInteger(10, *Major))
348returncreateError("integer expected, but got " + Tok.Value);
349if (V2.empty())
350 *Minor = 0;
351elseif (V2.getAsInteger(10, *Minor))
352returncreateError("integer expected, but got " + Tok.Value);
353returnError::success();
354 }
355
356 Lexer Lex;
357 Token Tok;
358 std::vector<Token> Stack;
359MachineTypes Machine;
360 COFFModuleDefinition Info;
361bool MingwDef;
362bool AddUnderscores;
363};
364
365Expected<COFFModuleDefinition>parseCOFFModuleDefinition(MemoryBufferRef MB,
366MachineTypesMachine,
367bool MingwDef,
368bool AddUnderscores) {
369returnParser(MB.getBuffer(),Machine, MingwDef, AddUnderscores).parse();
370}
371
372}// namespace object
373}// namespace llvm
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
COFFImportFile.h
COFFModuleDefinition.h
Machine
COFF::MachineTypes Machine
Definition:COFFYAML.cpp:390
Name
std::string Name
Definition:ELFObjHandler.cpp:77
End
bool End
Definition:ELF_riscv.cpp:480
Sym
Symbol * Sym
Definition:ELF_riscv.cpp:479
I
#define I(x, y, z)
Definition:MD5.cpp:58
Path.h
StringRef.h
StringSwitch.h
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
T
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::MemoryBufferRef
Definition:MemoryBufferRef.h:22
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition:MemoryBufferRef.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition:StringRef.h:700
llvm::StringRef::getAsInteger
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition:StringRef.h:470
llvm::StringRef::substr
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition:StringRef.h:571
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition:StringRef.h:609
llvm::StringRef::consume_front
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition:StringRef.h:635
llvm::StringRef::find_first_of
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.
Definition:StringRef.h:377
llvm::StringRef::find
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition:StringRef.h:297
llvm::StringRef::trim
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition:StringRef.h:815
llvm::StringRef::npos
static constexpr size_t npos
Definition:StringRef.h:53
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition:StringSwitch.h:44
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition:StringSwitch.h:69
llvm::StringSwitch::Default
R Default(T Value)
Definition:StringSwitch.h:182
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::object::Lexer
Definition:COFFModuleDefinition.cpp:82
llvm::object::Lexer::lex
Token lex()
Definition:COFFModuleDefinition.cpp:86
llvm::object::Lexer::Lexer
Lexer(StringRef S)
Definition:COFFModuleDefinition.cpp:84
llvm::object::Parser
Definition:COFFModuleDefinition.cpp:139
llvm::object::Parser::Parser
Parser(StringRef S, MachineTypes M, bool B, bool AU)
Definition:COFFModuleDefinition.cpp:141
llvm::object::Parser::parse
Expected< COFFModuleDefinition > parse()
Definition:COFFModuleDefinition.cpp:147
uint32_t
uint64_t
Error.h
Error.h
llvm::COFF
Definition:COFF.h:29
llvm::COFF::MachineTypes
MachineTypes
Definition:COFF.h:92
llvm::COFF::IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_I386
Definition:COFF.h:104
llvm::NVPTX::PTXLdStInstCode::V2
@ V2
Definition:NVPTX.h:163
llvm::object::createError
Error createError(const Twine &Err)
Definition:Error.h:84
llvm::object::parseCOFFModuleDefinition
Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
Definition:COFFModuleDefinition.cpp:365
llvm::object::Kind
Kind
Definition:COFFModuleDefinition.cpp:31
llvm::object::KwStacksize
@ KwStacksize
Definition:COFFModuleDefinition.cpp:48
llvm::object::Equal
@ Equal
Definition:COFFModuleDefinition.cpp:36
llvm::object::Eof
@ Eof
Definition:COFFModuleDefinition.cpp:33
llvm::object::EqualEqual
@ EqualEqual
Definition:COFFModuleDefinition.cpp:37
llvm::object::KwData
@ KwData
Definition:COFFModuleDefinition.cpp:40
llvm::object::KwPrivate
@ KwPrivate
Definition:COFFModuleDefinition.cpp:47
llvm::object::KwExportAs
@ KwExportAs
Definition:COFFModuleDefinition.cpp:42
llvm::object::KwHeapsize
@ KwHeapsize
Definition:COFFModuleDefinition.cpp:43
llvm::object::KwLibrary
@ KwLibrary
Definition:COFFModuleDefinition.cpp:44
llvm::object::KwNoname
@ KwNoname
Definition:COFFModuleDefinition.cpp:46
llvm::object::Unknown
@ Unknown
Definition:COFFModuleDefinition.cpp:32
llvm::object::KwName
@ KwName
Definition:COFFModuleDefinition.cpp:45
llvm::object::KwBase
@ KwBase
Definition:COFFModuleDefinition.cpp:38
llvm::object::Identifier
@ Identifier
Definition:COFFModuleDefinition.cpp:34
llvm::object::KwExports
@ KwExports
Definition:COFFModuleDefinition.cpp:41
llvm::object::Comma
@ Comma
Definition:COFFModuleDefinition.cpp:35
llvm::object::KwVersion
@ KwVersion
Definition:COFFModuleDefinition.cpp:49
llvm::object::KwConstant
@ KwConstant
Definition:COFFModuleDefinition.cpp:39
llvm::object::isDecorated
static bool isDecorated(StringRef Sym, bool MingwDef)
Definition:COFFModuleDefinition.cpp:58
llvm::sys::path::has_extension
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
Definition:Path.cpp:664
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::object::COFFModuleDefinition::MajorImageVersion
uint32_t MajorImageVersion
Definition:COFFModuleDefinition.h:36
llvm::object::COFFModuleDefinition::StackCommit
uint64_t StackCommit
Definition:COFFModuleDefinition.h:33
llvm::object::COFFModuleDefinition::ImportName
std::string ImportName
Definition:COFFModuleDefinition.h:30
llvm::object::COFFModuleDefinition::StackReserve
uint64_t StackReserve
Definition:COFFModuleDefinition.h:32
llvm::object::COFFModuleDefinition::OutputFile
std::string OutputFile
Definition:COFFModuleDefinition.h:29
llvm::object::COFFModuleDefinition::HeapCommit
uint64_t HeapCommit
Definition:COFFModuleDefinition.h:35
llvm::object::COFFModuleDefinition::HeapReserve
uint64_t HeapReserve
Definition:COFFModuleDefinition.h:34
llvm::object::COFFModuleDefinition::MinorImageVersion
uint32_t MinorImageVersion
Definition:COFFModuleDefinition.h:37
llvm::object::COFFModuleDefinition::ImageBase
uint64_t ImageBase
Definition:COFFModuleDefinition.h:31
llvm::object::COFFModuleDefinition::Exports
std::vector< COFFShortExport > Exports
Definition:COFFModuleDefinition.h:28
llvm::object::Token
Definition:COFFModuleDefinition.cpp:52
llvm::object::Token::K
Kind K
Definition:COFFModuleDefinition.cpp:54
llvm::object::Token::Value
StringRef Value
Definition:COFFModuleDefinition.cpp:55
llvm::object::Token::Token
Token(Kind T=Unknown, StringRef S="")
Definition:COFFModuleDefinition.cpp:53

Generated on Thu Jul 17 2025 12:34:22 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp