LLVM: lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

25

26#include

27#include

28

29using namespace llvm;

32

33namespace {

34

35#define OPTTABLE_STR_TABLE_CODE

36#include "Options.inc"

37#undef OPTTABLE_STR_TABLE_CODE

38

39enum {

40 OPT_INVALID = 0,

41#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),

42#include "Options.inc"

43#undef OPTION

44};

45

46#define OPTTABLE_PREFIXES_TABLE_CODE

47#include "Options.inc"

48#undef OPTTABLE_PREFIXES_TABLE_CODE

49

52#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),

53#include "Options.inc"

54#undef OPTION

55};

56

58public:

59 DllOptTable()

60 : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,

62};

63

64

65std::unique_ptr openFile(const Twine &Path) {

67

68 if (std::error_code EC = MB.getError()) {

69 llvm::errs() << "cannot open file " << Path << ": " << EC.message() << "\n";

70 return nullptr;

71 }

72

73 return std::move(*MB);

74}

75

85}

86

88 switch (T.getArch()) {

100 default:

102 }

103}

104

107}

108

109std::optionalstd::string getPrefix(StringRef Argv0) {

111

112

113

114 ProgName = ProgName.rtrim("0123456789.-");

116 return std::nullopt;

119 return ProgName.str();

120}

121

123 bool AddUnderscores,

124 std::vector &Exports,

125 std::string &OutputFile) {

126 std::unique_ptr MB = openFile(DefFileName);

127 if (!MB)

128 return false;

129

130 if (!MB->getBufferSize()) {

131 llvm::errs() << "definition file empty\n";

132 return false;

133 }

134

136 *MB, Machine, true, AddUnderscores);

137 if (!Def) {

138 llvm::errs() << "error parsing definition\n"

140 return false;

141 }

142

143 if (OutputFile.empty())

144 OutputFile = std::move(Def->OutputFile);

145

146

147

148

149

150

152 if (E.ExtName.empty()) {

153 E.Name = E.ExtName;

154 E.ExtName.clear();

155 }

156 }

157

158 Exports = std::move(Def->Exports);

159 return true;

160}

161

163 if (E)

164 return 0;

167 });

168 return 1;

169}

170

171template

176 if (!NameOrErr)

177 return printError(NameOrErr.takeError(), Name);

179

181 if (!ChildMB)

182 return printError(ChildMB.takeError(), Name);

183

186 if (!Obj)

187 return printError(Obj.takeError(), Name);

189 return 1;

190 }

191 }

192 if (Err)

193 return printError(std::move(Err), Name);

194 return 0;

195}

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

221 std::vector &Names, bool IsMsStyleImplib) {

222 StringRef TargetName = IsMsStyleImplib ? ".idata$6" : ".idata$7";

223 for (const auto &S : Obj.sections()) {

225 if (!NameOrErr) {

226 printError(NameOrErr.takeError(), ObjName);

227 return false;

228 }

230 if (Name != TargetName)

231 continue;

232

233

234

235 if (!IsMsStyleImplib && !S.relocations().empty())

236 continue;

237

239 if (!ContentsOrErr) {

240 printError(ContentsOrErr.takeError(), ObjName);

241 return false;

242 }

243 StringRef Contents = *ContentsOrErr;

244 Contents = Contents.substr(0, Contents.find('\0'));

245 if (Contents.empty())

246 continue;

247 Names.push_back(Contents);

248 return true;

249 }

250 return true;

251}

252

253int doIdentify(StringRef File, bool IdentifyStrict) {

255 File, false, false);

256 if (!MaybeBuf)

260 return 1;

261 }

262

263 std::unique_ptr B = std::move(MaybeBuf.get());

266 if (Err)

267 return printError(std::move(Err), B->getBufferIdentifier());

268

269 bool IsMsStyleImplib = false;

271 if (S.getName() == "__NULL_IMPORT_DESCRIPTOR") {

272 IsMsStyleImplib = true;

273 break;

274 }

275 }

276 std::vector Names;

277 if (forEachCoff(Archive, B->getBufferIdentifier(),

279 return identifyImportName(Obj, ObjName, Names,

280 IsMsStyleImplib);

281 }))

282 return 1;

283

284 if (Names.empty()) {

285 llvm::errs() << "No DLL import name found in " << File << "\n";

286 return 1;

287 }

288 if (Names.size() > 1 && IdentifyStrict) {

289 llvm::errs() << File << "contains imports for two or more DLLs\n";

290 return 1;

291 }

292

295

296 return 0;

297}

298

299}

300

302 DllOptTable Table;

303 unsigned MissingIndex;

304 unsigned MissingCount;

306 Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);

307 if (MissingCount) {

308 llvm::errs() << Args.getArgString(MissingIndex) << ": missing argument\n";

309 return 1;

310 }

311

312

313 if (Args.hasArgNoClaim(OPT_INPUT) ||

314 (!Args.hasArgNoClaim(OPT_d) && !Args.hasArgNoClaim(OPT_l) &&

315 !Args.hasArgNoClaim(OPT_I))) {

316 Table.printHelp(outs(), "llvm-dlltool [options] file...", "llvm-dlltool",

317 false);

319 << "\nTARGETS: i386, i386:x86-64, arm, arm64, arm64ec, r4000\n";

320 return 1;

321 }

322

323 for (auto *Arg : Args.filtered(OPT_UNKNOWN))

325 << "\n";

326

327 if (Args.hasArg(OPT_I)) {

328 return doIdentify(Args.getLastArg(OPT_I)->getValue(),

329 Args.hasArg(OPT_identify_strict));

330 }

331

332 if (!Args.hasArg(OPT_d)) {

333 llvm::errs() << "no definition file specified\n";

334 return 1;

335 }

336

338 if (std::optionalstd::string Prefix = getPrefix(ArgsArr[0])) {

342 }

343 if (auto *Arg = Args.getLastArg(OPT_m))

345

348 return 1;

349 }

350

351 bool AddUnderscores = !Args.hasArg(OPT_no_leading_underscore);

352

353 std::string OutputFile;

354 if (auto *Arg = Args.getLastArg(OPT_D))

356

357 std::vector Exports, NativeExports;

358

359 if (Args.hasArg(OPT_N)) {

361 llvm::errs() << "native .def file is supported only on arm64ec target\n";

362 return 1;

363 }

364 if (!parseModuleDefinition(Args.getLastArg(OPT_N)->getValue(),

366 NativeExports, OutputFile))

367 return 1;

368 }

369

370 if (!parseModuleDefinition(Args.getLastArg(OPT_d)->getValue(), Machine,

371 AddUnderscores, Exports, OutputFile))

372 return 1;

373

374 if (OutputFile.empty()) {

375 llvm::errs() << "no DLL name specified\n";

376 return 1;

377 }

378

381 if (!E.ImportName.empty() || (!E.Name.empty() && E.Name[0] == '?'))

382 continue;

383 E.SymbolName = E.Name;

384

385

386

387

388

389 E.Name = E.Name.substr(0, E.Name.find('@', 1));

390

391

392

393 }

394 }

395

396 std::string Path = std::string(Args.getLastArgValue(OPT_l));

397 if (!Path.empty()) {

399 true, NativeExports)) {

402 });

403 return 1;

404 }

405 }

406 return 0;

407}

Function Alias Analysis false

Defines the llvm::Arg class for parsed arguments.

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

std::unique_ptr< MemoryBuffer > openFile(const Twine &Path)

Function const char TargetMachine * Machine

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

Base class for error info classes.

virtual std::string message() const

Return the error message as a string.

Represents either an error or a value T.

std::error_code getError() const

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.

Error takeError()

Take ownership of the stored error.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

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 rtrim(char Char) const

Return string with consecutive Char characters starting from the right removed.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

bool consume_back_insensitive(StringRef Suffix)

Returns true if this StringRef has the given suffix, ignoring case, and removes that suffix.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

iterator_range< symbol_iterator > symbols() const

iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const

static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)

A concrete instance of a particular driver option.

LLVM_ABI std::string getAsString(const ArgList &Args) const

Return a formatted version of the argument and its values, for diagnostics.

const char * getValue(unsigned N=0) const

Specialization of OptTable.

@ IMAGE_FILE_MACHINE_ARM64

@ IMAGE_FILE_MACHINE_UNKNOWN

@ IMAGE_FILE_MACHINE_AMD64

@ IMAGE_FILE_MACHINE_ARM64EC

@ IMAGE_FILE_MACHINE_R4000

@ IMAGE_FILE_MACHINE_I386

@ IMAGE_FILE_MACHINE_ARMNT

bool isArm64EC(T Machine)

@ C

The default llvm calling convention, compatible with C.

llvm::unique_function< void(llvm::Expected< T >)> Callback

A Callback is a void function that accepts Expected.

LLVM_ABI Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)

LLVM_ABI Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports={})

Writes a COFF import library containing entries described by the Exports array.

NodeAddr< DefNode * > Def

LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get stem.

LLVM_ABI std::string getDefaultTargetTriple()

getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI file_magic identify_magic(StringRef magic)

Identify the type of a binary file based on how magical it is.

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

LLVM_ABI raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

LLVM_ABI int dlltoolDriverMain(ArrayRef< const char * > ArgsArr)

Definition DlltoolDriver.cpp:301

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

LLVM_ABI std::error_code errorToErrorCode(Error Err)

Helper for converting an ECError to a std::error_code.

@ archive

ar style archive file

@ coff_object

COFF object file.

Entry for a single option instance in the option data table.