[llvm-branch-commits] [lld] b768d57 - [lld-macho] Add archive name and file modtime to STABS output
Jez Ng via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 1 15:10:16 PST 2020
Author: Jez Ng
Date: 2020-12-01T15:05:21-08:00
New Revision: b768d57b368781e6737c403e425bd835850f3a0a
URL: https://github.com/llvm/llvm-project/commit/b768d57b368781e6737c403e425bd835850f3a0a
DIFF: https://github.com/llvm/llvm-project/commit/b768d57b368781e6737c403e425bd835850f3a0a.diff
LOG: [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
Added:
Modified:
lld/MachO/Driver.cpp
lld/MachO/Driver.h
lld/MachO/DriverUtils.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputFiles.h
lld/MachO/LTO.cpp
lld/MachO/SyntheticSections.cpp
lld/test/MachO/stabs.s
Removed:
################################################################################
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 @@ class InputFile {
// .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));
}
diff --git a/lld/test/MachO/stabs.s b/lld/test/MachO/stabs.s
index 2c49453dcd43..81f1ecbc1e96 100644
--- a/lld/test/MachO/stabs.s
+++ b/lld/test/MachO/stabs.s
@@ -3,22 +3,35 @@
# RUN: split-file %s %t
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo.s -o %t/foo.o
+## Set modtimes of the files for deterministic test output.
+# RUN: env TZ=UTC touch -t "197001010000.16" %t/test.o
+# RUN: env TZ=UTC touch -t "197001010000.32" %t/foo.o
+# RUN: rm -f %t/foo.a
+# RUN: llvm-ar rcsU %t/foo.a %t/foo.o
# RUN: %lld -lSystem %t/test.o %t/foo.o -o %t/test
-# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t
+# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o
+
+## Check that we emit the right modtime even when the object file is in an
+## archive.
+# RUN: %lld -lSystem %t/test.o %t/foo.a -o %t/test
+# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\)
## Check that we emit absolute paths to the object files in our OSO entries
## even if our inputs are relative paths.
# RUN: cd %t && %lld -lSystem test.o foo.o -o test
-# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t
+# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o
+
+# RUN: cd %t && %lld -lSystem %t/test.o %t/foo.a -o %t/test
+# RUN: llvm-nm -pa %t/test | FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\)
# CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp
-# CHECK-NEXT: 0000000000000000 - 03 0001 OSO [[DIR]]/test.o
+# CHECK-NEXT: 0000000000000010 - 03 0001 OSO [[DIR]]/test.o
# CHECK-NEXT: [[#%x, MAIN:]] - 01 0000 FUN _main
-# CHECK-NEXT: 0000000000000001 - 00 0000 FUN
+# CHECK-NEXT: 0000000000000006 - 00 0000 FUN
# CHECK-NEXT: 0000000000000000 - 01 0000 SO
# CHECK-NEXT: 0000000000000000 - 00 0000 SO /foo.cpp
-# CHECK-NEXT: 0000000000000000 - 03 0001 OSO [[DIR]]/foo.o
+# CHECK-NEXT: 0000000000000020 - 03 0001 OSO [[FOO_PATH]]
# CHECK-NEXT: [[#%x, FOO:]] - 01 0000 FUN _foo
# CHECK-NEXT: 0000000000000001 - 00 0000 FUN
# CHECK-NEXT: 0000000000000000 - 01 0000 SO
@@ -30,6 +43,7 @@
.globl _main
_main:
Lfunc_begin0:
+ callq _foo
retq
Lfunc_end0:
More information about the llvm-branch-commits
mailing list