diff options
author | Jez Ng <jezng@fb.com> | 2020-12-01 14:45:11 -0800 |
---|---|---|
committer | Jez Ng <jezng@fb.com> | 2020-12-01 15:05:21 -0800 |
commit | b768d57b368781e6737c403e425bd835850f3a0a (patch) | |
tree | 5aa3b66211237b32181adcfaa86e3b946de00bd1 /lld/MachO | |
parent | d0c4be42e35d8cff069f91a45b76ea24187c233d (diff) | |
download | llvm-project-b768d57b368781e6737c403e425bd835850f3a0a.tar.gz |
[lld-macho] Add archive name and file modtime to STABS output
We should also set the modtime when running LTO. That will be done in a
future diff, together with support for the `-object_path_lto` flag.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D91318
Diffstat (limited to 'lld/MachO')
-rw-r--r-- | lld/MachO/Driver.cpp | 45 | ||||
-rw-r--r-- | lld/MachO/Driver.h | 2 | ||||
-rw-r--r-- | lld/MachO/DriverUtils.cpp | 10 | ||||
-rw-r--r-- | lld/MachO/InputFiles.cpp | 14 | ||||
-rw-r--r-- | lld/MachO/InputFiles.h | 4 | ||||
-rw-r--r-- | lld/MachO/LTO.cpp | 4 | ||||
-rw-r--r-- | lld/MachO/SyntheticSections.cpp | 9 |
7 files changed, 66 insertions, 22 deletions
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 141082985b4e..295f2c412a7f 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -212,21 +212,32 @@ getFrameworkSearchPaths(opt::InputArgList &args, {"/Library/Frameworks", "/System/Library/Frameworks"}); } +namespace { +struct ArchiveMember { + MemoryBufferRef mbref; + uint32_t modTime; +}; +} // namespace + // Returns slices of MB by parsing MB as an archive file. // Each slice consists of a member file in the archive. -static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef mb) { +static std::vector<ArchiveMember> getArchiveMembers(MemoryBufferRef mb) { std::unique_ptr<Archive> file = CHECK(Archive::create(mb), mb.getBufferIdentifier() + ": failed to parse archive"); - std::vector<MemoryBufferRef> v; + std::vector<ArchiveMember> v; Error err = Error::success(); for (const Archive::Child &c : file->children(err)) { MemoryBufferRef mbref = CHECK(c.getMemoryBufferRef(), mb.getBufferIdentifier() + ": could not get the buffer for a child of the archive"); - v.push_back(mbref); + uint32_t modTime = toTimeT( + CHECK(c.getLastModified(), mb.getBufferIdentifier() + + ": could not get the modification " + "time for a child of the archive")); + v.push_back({mbref, modTime}); } if (err) fatal(mb.getBufferIdentifier() + @@ -235,6 +246,16 @@ static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef mb) { return v; } +static void forceLoadArchive(StringRef path) { + if (Optional<MemoryBufferRef> buffer = readFile(path)) { + for (const ArchiveMember &member : getArchiveMembers(*buffer)) { + auto file = make<ObjFile>(member.mbref, member.modTime); + file->archiveName = buffer->getBufferIdentifier(); + inputFiles.push_back(file); + } + } +} + static InputFile *addFile(StringRef path) { Optional<MemoryBufferRef> buffer = readFile(path); if (!buffer) @@ -251,9 +272,7 @@ static InputFile *addFile(StringRef path) { error(path + ": archive has no index; run ranlib to add one"); if (config->allLoad) { - if (Optional<MemoryBufferRef> buffer = readFile(path)) - for (MemoryBufferRef member : getArchiveMembers(*buffer)) - inputFiles.push_back(make<ObjFile>(member)); + forceLoadArchive(path); } else if (config->forceLoadObjC) { for (const object::Archive::Symbol &sym : file->symbols()) if (sym.getName().startswith(objc::klass)) @@ -264,16 +283,16 @@ static InputFile *addFile(StringRef path) { // consider creating a LazyObjFile class in order to avoid double-loading // these files here and below (as part of the ArchiveFile). if (Optional<MemoryBufferRef> buffer = readFile(path)) - for (MemoryBufferRef member : getArchiveMembers(*buffer)) - if (hasObjCSection(member)) - inputFiles.push_back(make<ObjFile>(member)); + for (const ArchiveMember &member : getArchiveMembers(*buffer)) + if (hasObjCSection(member.mbref)) + inputFiles.push_back(make<ObjFile>(member.mbref, member.modTime)); } newFile = make<ArchiveFile>(std::move(file)); break; } case file_magic::macho_object: - newFile = make<ObjFile>(mbref); + newFile = make<ObjFile>(mbref, getModTime(path)); break; case file_magic::macho_dynamically_linked_shared_lib: case file_magic::macho_dynamically_linked_shared_lib_stub: @@ -304,12 +323,6 @@ static void addFileList(StringRef path) { addFile(path); } -static void forceLoadArchive(StringRef path) { - if (Optional<MemoryBufferRef> buffer = readFile(path)) - for (MemoryBufferRef member : getArchiveMembers(*buffer)) - inputFiles.push_back(make<ObjFile>(member)); -} - static std::array<StringRef, 6> archNames{"arm", "arm64", "i386", "x86_64", "ppc", "ppc64"}; static bool isArchString(StringRef s) { diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h index c06d2f9d1b3d..d5625fd3873e 100644 --- a/lld/MachO/Driver.h +++ b/lld/MachO/Driver.h @@ -43,6 +43,8 @@ llvm::Optional<std::string> resolveDylibPath(llvm::StringRef path); llvm::Optional<DylibFile *> makeDylibFromTAPI(llvm::MemoryBufferRef mbref, DylibFile *umbrella = nullptr); +uint32_t getModTime(llvm::StringRef path); + } // namespace macho } // namespace lld diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index ec57c6898129..77f76b522d7e 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -175,3 +175,13 @@ Optional<DylibFile *> macho::makeDylibFromTAPI(MemoryBufferRef mbref, } return make<DylibFile>(**result, umbrella); } + +uint32_t macho::getModTime(StringRef path) { + fs::file_status stat; + if (!fs::status(path, stat)) + if (fs::exists(stat)) + return toTimeT(stat.getLastModificationTime()); + + warn("failed to get modification time of " + path); + return 0; +} diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index 921b69995d43..19d531cc5028 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -364,7 +364,8 @@ OpaqueFile::OpaqueFile(MemoryBufferRef mb, StringRef segName, subsections.push_back({{0, isec}}); } -ObjFile::ObjFile(MemoryBufferRef mb) : InputFile(ObjKind, mb) { +ObjFile::ObjFile(MemoryBufferRef mb, uint32_t modTime) + : InputFile(ObjKind, mb), modTime(modTime) { auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart()); auto *hdr = reinterpret_cast<const mach_header_64 *>(mb.getBufferStart()); @@ -592,7 +593,16 @@ void ArchiveFile::fetch(const object::Archive::Symbol &sym) { toString(this) + ": could not get the buffer for the member defining symbol " + sym.getName()); - auto file = make<ObjFile>(mb); + + uint32_t modTime = toTimeT( + CHECK(c.getLastModified(), toString(this) + + ": could not get the modification time " + "for the member defining symbol " + + sym.getName())); + + auto file = make<ObjFile>(mb, modTime); + file->archiveName = getName(); + symbols.insert(symbols.end(), file->symbols.begin(), file->symbols.end()); subsections.insert(subsections.end(), file->subsections.begin(), file->subsections.end()); diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h index 4356350e7c17..f7fd77dacff5 100644 --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -90,10 +90,12 @@ private: // .o file class ObjFile : public InputFile { public: - explicit ObjFile(MemoryBufferRef mb); + explicit ObjFile(MemoryBufferRef mb, uint32_t modTime); static bool classof(const InputFile *f) { return f->kind() == ObjKind; } llvm::DWARFUnit *compileUnit = nullptr; + StringRef archiveName = ""; + const uint32_t modTime; private: void parseDebugInfo(); diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp index bf0db6175690..3050e03f2f24 100644 --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -73,10 +73,12 @@ std::vector<ObjFile *> BitcodeCompiler::compile() { saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o"); } + // TODO: set modTime properly std::vector<ObjFile *> ret; for (unsigned i = 0; i != maxTasks; ++i) if (!buf[i].empty()) - ret.push_back(make<ObjFile>(MemoryBufferRef(buf[i], "lto.tmp"))); + ret.push_back( + make<ObjFile>(MemoryBufferRef(buf[i], "lto.tmp"), /*modTime=*/0)); return ret; } diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 56a095c4a7e4..ae66961310c5 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -602,13 +602,18 @@ void SymtabSection::emitEndSourceStab() { void SymtabSection::emitObjectFileStab(ObjFile *file) { StabsEntry stab(MachO::N_OSO); stab.sect = target->cpuSubtype; - SmallString<261> path(file->getName()); + SmallString<261> path(!file->archiveName.empty() ? file->archiveName + : file->getName()); std::error_code ec = sys::fs::make_absolute(path); if (ec) - fatal("failed to get absolute path for " + file->getName()); + fatal("failed to get absolute path for " + path); + + if (!file->archiveName.empty()) + path.append({"(", file->getName(), ")"}); stab.strx = stringTableSection.addString(saver.save(path.str())); stab.desc = 1; + stab.value = file->modTime; stabs.emplace_back(std::move(stab)); } |