[lld] r197217 - [PECOFF] Parse /export optional arguments.
Rui Ueyama
ruiu at google.com
Fri Dec 13 00:42:52 PST 2013
Author: ruiu
Date: Fri Dec 13 02:42:52 2013
New Revision: 197217
URL: http://llvm.org/viewvc/llvm-project?rev=197217&view=rev
Log:
[PECOFF] Parse /export optional arguments.
/EXPORT command line option can take an ordinal, NONAME flag, and DATA flag.
This patch is to parse these optional arguments.
Modified:
lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=197217&r1=197216&r2=197217&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Fri Dec 13 02:42:52 2013
@@ -57,6 +57,14 @@ public:
int minorVersion;
};
+ struct ExportDesc {
+ ExportDesc() : ordinal(-1), noname(false), isData(false) {}
+ std::string name;
+ int ordinal;
+ bool noname;
+ bool isData;
+ };
+
/// \brief Casting support
static inline bool classof(const LinkingContext *info) { return true; }
@@ -219,8 +227,8 @@ public:
void setDosStub(ArrayRef<uint8_t> data) { _dosStub = data; }
ArrayRef<uint8_t> getDosStub() const { return _dosStub; }
- void addDllExport(StringRef sym) { _dllExports.insert(sym); }
- const std::set<std::string> &getDllExports() const { return _dllExports; }
+ void addDllExport(ExportDesc &desc) { _dllExports.push_back(desc); }
+ const std::vector<ExportDesc> &getDllExports() const { return _dllExports; }
StringRef allocate(StringRef ref) const {
char *x = _allocator.Allocate<char>(ref.size() + 1);
@@ -301,7 +309,7 @@ private:
std::map<std::string, uint32_t> _sectionClearMask;
// DLLExport'ed symbols.
- std::set<std::string> _dllExports;
+ std::vector<ExportDesc> _dllExports;
// List of files that will be removed on destruction.
std::vector<std::unique_ptr<llvm::FileRemover> > _tempFiles;
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=197217&r1=197216&r2=197217&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Fri Dec 13 02:42:52 2013
@@ -300,6 +300,41 @@ bool parseManifestUac(StringRef option,
}
}
+// Parse /export:name[, at ordinal[,NONAME]][,DATA].
+bool parseExport(StringRef option, PECOFFLinkingContext::ExportDesc &ret) {
+ StringRef name;
+ StringRef rest;
+ llvm::tie(name, rest) = option.split(",");
+ if (name.empty())
+ return false;
+ ret.name = name;
+
+ for (;;) {
+ if (rest.empty())
+ return true;
+ StringRef arg;
+ llvm::tie(arg, rest) = rest.split(",");
+ if (arg.equals_lower("noname")) {
+ if (ret.ordinal < 0)
+ return false;
+ ret.noname = true;
+ continue;
+ }
+ if (arg.equals_lower("data")) {
+ ret.isData = true;
+ continue;
+ }
+ if (arg.startswith("@")) {
+ int ordinal;
+ if (arg.substr(1).getAsInteger(0, ordinal))
+ return false;
+ ret.ordinal = ordinal;
+ continue;
+ }
+ return false;
+ }
+}
+
StringRef replaceExtension(PECOFFLinkingContext &ctx,
StringRef path, StringRef extension) {
SmallString<128> val = path;
@@ -840,9 +875,15 @@ WinLinkDriver::parse(int argc, const cha
ctx.setEntrySymbolName(ctx.allocate(inputArg->getValue()));
break;
- case OPT_export:
- ctx.addDllExport(inputArg->getValue());
+ case OPT_export: {
+ PECOFFLinkingContext::ExportDesc desc;
+ if (!parseExport(inputArg->getValue(), desc)) {
+ diagnostics << "Error: malformed /export option\n";
+ return false;
+ }
+ ctx.addDllExport(desc);
break;
+ }
case OPT_libpath:
ctx.appendInputSearchPath(ctx.allocate(inputArg->getValue()));
Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=197217&r1=197216&r2=197217&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Fri Dec 13 02:42:52 2013
@@ -30,10 +30,10 @@ static bool getExportedAtoms(const PECOF
for (const DefinedAtom *atom : file->defined())
definedAtoms[atom->name()] = atom;
- for (StringRef dllExport : ctx.getDllExports()) {
- auto it = definedAtoms.find(ctx.decorateSymbol(dllExport));
+ for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
+ auto it = definedAtoms.find(ctx.decorateSymbol(desc.name));
if (it == definedAtoms.end()) {
- llvm::errs() << "Symbol <" << dllExport
+ llvm::errs() << "Symbol <" << desc.name
<< "> is exported but not defined.\n";
return false;
}
Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=197217&r1=197216&r2=197217&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Fri Dec 13 02:42:52 2013
@@ -157,10 +157,30 @@ TEST_F(WinLinkParserTest, AlternateName)
}
TEST_F(WinLinkParserTest, Export) {
- EXPECT_TRUE(parse("link.exe", "/export:_foo", "a.out", nullptr));
- const std::set<std::string> &exports = _context.getDllExports();
- EXPECT_TRUE(exports.count("_foo") == 1);
- EXPECT_TRUE(exports.count("nosuchsym") == 0);
+ EXPECT_TRUE(parse("link.exe", "/export:foo", "a.out", nullptr));
+ const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
+ _context.getDllExports();
+ EXPECT_TRUE(exports.size() == 1);
+ EXPECT_EQ("foo", exports[0].name);
+ EXPECT_EQ(-1, exports[0].ordinal);
+ EXPECT_FALSE(exports[0].noname);
+ EXPECT_FALSE(exports[0].isData);
+}
+
+TEST_F(WinLinkParserTest, ExportWithOptions) {
+ EXPECT_TRUE(parse("link.exe", "/export:foo, at 8,noname,data",
+ "/export:bar, at 10,data", "a.out", nullptr));
+ const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
+ _context.getDllExports();
+ EXPECT_TRUE(exports.size() == 2);
+ EXPECT_EQ("foo", exports[0].name);
+ EXPECT_EQ(8, exports[0].ordinal);
+ EXPECT_TRUE(exports[0].noname);
+ EXPECT_TRUE(exports[0].isData);
+ EXPECT_EQ("bar", exports[1].name);
+ EXPECT_EQ(10, exports[1].ordinal);
+ EXPECT_FALSE(exports[1].noname);
+ EXPECT_TRUE(exports[1].isData);
}
TEST_F(WinLinkParserTest, MachineX86) {
More information about the llvm-commits
mailing list