aboutsummaryrefslogtreecommitdiff
path: root/lld/MachO
diff options
context:
space:
mode:
authorJez Ng <jezng@fb.com>2020-12-01 14:45:11 -0800
committerJez Ng <jezng@fb.com>2020-12-01 15:05:21 -0800
commitb768d57b368781e6737c403e425bd835850f3a0a (patch)
tree5aa3b66211237b32181adcfaa86e3b946de00bd1 /lld/MachO
parentd0c4be42e35d8cff069f91a45b76ea24187c233d (diff)
downloadllvm-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.cpp45
-rw-r--r--lld/MachO/Driver.h2
-rw-r--r--lld/MachO/DriverUtils.cpp10
-rw-r--r--lld/MachO/InputFiles.cpp14
-rw-r--r--lld/MachO/InputFiles.h4
-rw-r--r--lld/MachO/LTO.cpp4
-rw-r--r--lld/MachO/SyntheticSections.cpp9
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));
}