diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index a5ee070d13dc6..4a0938a1bb040 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -208,6 +208,9 @@ struct Configuration { // Used for /map. std::string mapFile; + // Used for /mapinfo. + bool mapInfo = false; + // Used for /thinlto-index-only: llvm::StringRef thinLTOIndexOnlyArg; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index b22cf686379e4..25bb7b093df63 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1922,6 +1922,16 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->lldmapFile = getMapFile(args, OPT_lldmap, OPT_lldmap_file); config->mapFile = getMapFile(args, OPT_map, OPT_map_file); + if (config->mapFile != "" && args.hasArg(OPT_map_info)) { + for (auto *arg : args.filtered(OPT_map_info)) { + std::string s = StringRef(arg->getValue()).lower(); + if (s == "exports") + config->mapInfo = true; + else + error("unknown option: /mapinfo:" + s); + } + } + if (config->lldmapFile != "" && config->lldmapFile == config->mapFile) { warn("/lldmap and /map have the same output file '" + config->mapFile + "'.\n>>> ignoring /lldmap"); diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp index 2da50af303872..797d22c8aaa83 100644 --- a/lld/COFF/MapFile.cpp +++ b/lld/COFF/MapFile.cpp @@ -315,6 +315,19 @@ void lld::coff::writeMapFile(COFFLinkerContext &ctx) { for (Defined *sym : staticSyms) os << staticSymStr[sym] << '\n'; + // Print out the exported functions + if (config->mapInfo) { + os << "\n"; + os << " Exports\n"; + os << "\n"; + os << " ordinal name\n\n"; + for (Export &e : config->exports) { + os << format(" %7d", e.ordinal) << " " << e.name << "\n"; + if (!e.extName.empty() && e.extName != e.name) + os << " exported name: " << e.extName << "\n"; + } + } + t4.stop(); t1.stop(); } diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index c728279ef5cca..a2eb551a75804 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -287,6 +287,7 @@ def lldmap : F<"lldmap">; def lldmap_file : P_priv<"lldmap">; def map : F<"map">; def map_file : P_priv<"map">; +def map_info : P<"mapinfo", "Include the specified information in a map file">; def show_timing : F<"time">; def summary : F<"summary">; diff --git a/lld/test/COFF/map.test b/lld/test/COFF/map.test index 7e229613dcd9f..d1079c1acd4f7 100644 --- a/lld/test/COFF/map.test +++ b/lld/test/COFF/map.test @@ -8,6 +8,9 @@ # RUN: lld-link /out:%t.exe /entry:main %t.obj %t-dll.lib /map /lldmap:%T/foo-lld.map # RUN: FileCheck -check-prefix=MAP -strict-whitespace %s < %t.map # RUN: FileCheck -check-prefix=LLDMAP -strict-whitespace %s < %T/foo-lld.map +# RUN: lld-link /out:%t.dll /dll %t-dll.obj /export:exportfn1 \ +# RUN: /export:foo=exportfn2 /map /mapinfo:exports +# RUN: FileCheck -check-prefix=MAPINFO -strict-whitespace %s < %t.map # MAP: {{.*}} # MAP-EMPTY: @@ -38,3 +41,12 @@ # LLDMAP-NEXT: 00001000 00000026 4096 .text # LLDMAP-NEXT: 00001000 00000008 4 {{.*}}map.test.tmp.obj:(.text) # LLDMAP-NEXT: 00001000 00000000 0 main + +# MAPINFO: Exports +# MAPINFO-EMPTY: +# MAPINFO-NEXT: ordinal name +# MAPINFO-EMPTY: +# MAPINFO-NEXT: 1 exportfn1 +# MAPINFO-NEXT: 2 exportfn3 +# MAPINFO-NEXT: 3 exportfn2 +# MAPINFO-NEXT: exported name: foo