summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/tools/dsymutil/archive-timestamp.test24
-rw-r--r--llvm/test/tools/dsymutil/yaml-object-address-rewrite.test3
-rw-r--r--llvm/tools/dsymutil/BinaryHolder.cpp26
-rw-r--r--llvm/tools/dsymutil/BinaryHolder.h18
-rw-r--r--llvm/tools/dsymutil/DebugMap.cpp19
-rw-r--r--llvm/tools/dsymutil/DebugMap.h11
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp3
-rw-r--r--llvm/tools/dsymutil/MachODebugMapParser.cpp17
8 files changed, 93 insertions, 28 deletions
diff --git a/llvm/test/tools/dsymutil/archive-timestamp.test b/llvm/test/tools/dsymutil/archive-timestamp.test
new file mode 100644
index 00000000000..11add6d0b72
--- /dev/null
+++ b/llvm/test/tools/dsymutil/archive-timestamp.test
@@ -0,0 +1,24 @@
+# RUN: llvm-dsymutil -no-output -v -oso-prepend-path=%p -y %s 2>&1 | FileCheck %s
+
+# This is the archive member part of basic-archive.macho.x86_64 debug map with corrupted timestamps.
+
+# CHECK: warning: {{.*}}libbasic.a(basic2.macho.x86_64.o): {{[Nn]o}} such file
+# CHECK: warning: {{.*}}libbasic.a(basic3.macho.x86_64.o): {{[Nn]o}} such file
+
+---
+triple: 'x86_64-unknown-unknown-macho'
+objects:
+ - filename: '/Inputs/libbasic.a(basic2.macho.x86_64.o)'
+ timestamp: 141869239
+ symbols:
+ - { sym: _foo, objAddr: 0x0000000000000020, binAddr: 0x0000000100000ED0, size: 0x00000050 }
+ - { sym: _private_int, objAddr: 0x0000000000000560, binAddr: 0x0000000100001004, size: 0x00000000 }
+ - { sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F20, size: 0x00000017 }
+ - { sym: _baz, objAddr: 0x0000000000000310, binAddr: 0x0000000100001000, size: 0x00000000 }
+ - filename: '/Inputs/libbasic.a(basic3.macho.x86_64.o)'
+ timestamp: 418692393
+ symbols:
+ - { sym: _val, objAddr: 0x0000000000000004, binAddr: 0x0000000100001008, size: 0x00000000 }
+ - { sym: _bar, objAddr: 0x0000000000000020, binAddr: 0x0000000100000F40, size: 0x00000050 }
+ - { sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F90, size: 0x00000019 }
+...
diff --git a/llvm/test/tools/dsymutil/yaml-object-address-rewrite.test b/llvm/test/tools/dsymutil/yaml-object-address-rewrite.test
index dcb39be891c..73697d4a6e5 100644
--- a/llvm/test/tools/dsymutil/yaml-object-address-rewrite.test
+++ b/llvm/test/tools/dsymutil/yaml-object-address-rewrite.test
@@ -8,9 +8,11 @@
# CHECK-NEXT: triple:{{.*}}'x86_64-unknown-unknown-macho'
# CHECK-NEXT: objects:
# CHECK-NEXT: filename:{{.*}}/Inputs/basic1.macho.x86_64.o
+# CHECK-NEXT: timestamp: 0
# CHECK-NEXT: symbols:
# CHECK-NEXT: sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000EA0, size: 0x00000024
# CHECK-NEXT: filename:{{.*}}/Inputs/./libbasic.a(basic2.macho.x86_64.o)'
+# CHECK-NEXT: timestamp: 0
# CHECK-NEXT: symbols:
# CHECK-DAG: sym: _foo, objAddr: 0x0000000000000020, binAddr: 0x0000000100000ED0, size: 0x00000050
# CHECK-DAG: sym: _private_int, objAddr: 0x0000000000000560, binAddr: 0x0000000100001004, size: 0x00000000
@@ -18,6 +20,7 @@
# CHECK-DAG: sym: _baz, objAddr: 0x0000000000000310, binAddr: 0x0000000100001000, size: 0x00000000
# CHECK-NOT: { sym:
# CHECK-NEXT: filename:{{.*}}/Inputs/./libbasic.a(basic3.macho.x86_64.o)'
+# CHECK-NEXT: timestamp: 0
# CHECK-NEXT: symbols:
# CHECK-DAG: sym: _val, objAddr: 0x0000000000000004, binAddr: 0x0000000100001008, size: 0x00000000
# CHECK-DAG: sym: _bar, objAddr: 0x0000000000000020, binAddr: 0x0000000100000F40, size: 0x00000050
diff --git a/llvm/tools/dsymutil/BinaryHolder.cpp b/llvm/tools/dsymutil/BinaryHolder.cpp
index ad66105bc24..49fe901b419 100644
--- a/llvm/tools/dsymutil/BinaryHolder.cpp
+++ b/llvm/tools/dsymutil/BinaryHolder.cpp
@@ -19,18 +19,20 @@ namespace llvm {
namespace dsymutil {
ErrorOr<MemoryBufferRef>
-BinaryHolder::GetMemoryBufferForFile(StringRef Filename) {
+BinaryHolder::GetMemoryBufferForFile(StringRef Filename,
+ sys::TimeValue Timestamp) {
if (Verbose)
outs() << "trying to open '" << Filename << "'\n";
// Try that first as it doesn't involve any filesystem access.
- if (auto ErrOrArchiveMember = GetArchiveMemberBuffer(Filename))
+ if (auto ErrOrArchiveMember = GetArchiveMemberBuffer(Filename, Timestamp))
return *ErrOrArchiveMember;
// If the name ends with a closing paren, there is a huge chance
// it is an archive member specification.
if (Filename.endswith(")"))
- if (auto ErrOrArchiveMember = MapArchiveAndGetMemberBuffer(Filename))
+ if (auto ErrOrArchiveMember =
+ MapArchiveAndGetMemberBuffer(Filename, Timestamp))
return *ErrOrArchiveMember;
// Otherwise, just try opening a standard file. If this is an
@@ -50,7 +52,8 @@ BinaryHolder::GetMemoryBufferForFile(StringRef Filename) {
}
ErrorOr<MemoryBufferRef>
-BinaryHolder::GetArchiveMemberBuffer(StringRef Filename) {
+BinaryHolder::GetArchiveMemberBuffer(StringRef Filename,
+ sys::TimeValue Timestamp) {
if (!CurrentArchive)
return make_error_code(errc::no_such_file_or_directory);
@@ -64,6 +67,12 @@ BinaryHolder::GetArchiveMemberBuffer(StringRef Filename) {
for (const auto &Child : CurrentArchive->children()) {
if (auto NameOrErr = Child.getName())
if (*NameOrErr == Filename) {
+ if (Timestamp != sys::TimeValue::PosixZeroTime() &&
+ Timestamp != Child.getLastModified()) {
+ if (Verbose)
+ outs() << "\tmember had timestamp mismatch.\n";
+ continue;
+ }
if (Verbose)
outs() << "\tfound member in current archive.\n";
return Child.getMemoryBufferRef();
@@ -74,7 +83,8 @@ BinaryHolder::GetArchiveMemberBuffer(StringRef Filename) {
}
ErrorOr<MemoryBufferRef>
-BinaryHolder::MapArchiveAndGetMemberBuffer(StringRef Filename) {
+BinaryHolder::MapArchiveAndGetMemberBuffer(StringRef Filename,
+ sys::TimeValue Timestamp) {
StringRef ArchiveFilename = Filename.substr(0, Filename.find('('));
auto ErrOrBuff = MemoryBuffer::getFileOrSTDIN(ArchiveFilename);
@@ -90,12 +100,12 @@ BinaryHolder::MapArchiveAndGetMemberBuffer(StringRef Filename) {
CurrentArchive = std::move(*ErrOrArchive);
CurrentMemoryBuffer = std::move(*ErrOrBuff);
- return GetArchiveMemberBuffer(Filename);
+ return GetArchiveMemberBuffer(Filename, Timestamp);
}
ErrorOr<const object::ObjectFile &>
-BinaryHolder::GetObjectFile(StringRef Filename) {
- auto ErrOrMemBufferRef = GetMemoryBufferForFile(Filename);
+BinaryHolder::GetObjectFile(StringRef Filename, sys::TimeValue Timestamp) {
+ auto ErrOrMemBufferRef = GetMemoryBufferForFile(Filename, Timestamp);
if (auto Err = ErrOrMemBufferRef.getError())
return Err;
diff --git a/llvm/tools/dsymutil/BinaryHolder.h b/llvm/tools/dsymutil/BinaryHolder.h
index 04871b5d585..84c07ce0c4b 100644
--- a/llvm/tools/dsymutil/BinaryHolder.h
+++ b/llvm/tools/dsymutil/BinaryHolder.h
@@ -19,6 +19,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/TimeValue.h"
namespace llvm {
namespace dsymutil {
@@ -46,12 +47,14 @@ class BinaryHolder {
/// This function performs no system calls, it just looks up a
/// potential match for the given \p Filename in the currently
/// mapped archive if there is one.
- ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename);
+ ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename,
+ sys::TimeValue Timestamp);
/// \brief Interpret Filename as an archive member specification,
/// map the corresponding archive to memory and return the
/// MemoryBufferRef corresponding to the described member.
- ErrorOr<MemoryBufferRef> MapArchiveAndGetMemberBuffer(StringRef Filename);
+ ErrorOr<MemoryBufferRef>
+ MapArchiveAndGetMemberBuffer(StringRef Filename, sys::TimeValue Timestamp);
/// \brief Return the MemoryBufferRef that holds the memory
/// mapping for the given \p Filename. This function will try to
@@ -61,7 +64,8 @@ class BinaryHolder {
/// The returned MemoryBufferRef points to a buffer owned by this
/// object. The buffer is valid until the next call to
/// GetMemoryBufferForFile() on this object.
- ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename);
+ ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename,
+ sys::TimeValue Timestamp);
public:
BinaryHolder(bool Verbose) : Verbose(Verbose) {}
@@ -72,11 +76,15 @@ public:
///
/// Calling this function invalidates the previous mapping owned by
/// the BinaryHolder.
- ErrorOr<const object::ObjectFile &> GetObjectFile(StringRef Filename);
+ ErrorOr<const object::ObjectFile &>
+ GetObjectFile(StringRef Filename,
+ sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime());
/// \brief Wraps GetObjectFile() to return a derived ObjectFile type.
template <typename ObjectFileType>
- ErrorOr<const ObjectFileType &> GetFileAs(StringRef Filename) {
+ ErrorOr<const ObjectFileType &>
+ GetFileAs(StringRef Filename,
+ sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()) {
auto ErrOrObjFile = GetObjectFile(Filename);
if (auto Err = ErrOrObjFile.getError())
return Err;
diff --git a/llvm/tools/dsymutil/DebugMap.cpp b/llvm/tools/dsymutil/DebugMap.cpp
index e5cc87b3f31..24dedfcb673 100644
--- a/llvm/tools/dsymutil/DebugMap.cpp
+++ b/llvm/tools/dsymutil/DebugMap.cpp
@@ -20,8 +20,9 @@ namespace dsymutil {
using namespace llvm::object;
-DebugMapObject::DebugMapObject(StringRef ObjectFilename)
- : Filename(ObjectFilename) {}
+DebugMapObject::DebugMapObject(StringRef ObjectFilename,
+ sys::TimeValue Timestamp)
+ : Filename(ObjectFilename), Timestamp(Timestamp) {}
bool DebugMapObject::addSymbol(StringRef Name, uint64_t ObjectAddress,
uint64_t LinkedAddress, uint32_t Size) {
@@ -58,8 +59,9 @@ void DebugMapObject::print(raw_ostream &OS) const {
void DebugMapObject::dump() const { print(errs()); }
#endif
-DebugMapObject &DebugMap::addDebugMapObject(StringRef ObjectFilePath) {
- Objects.emplace_back(new DebugMapObject(ObjectFilePath));
+DebugMapObject &DebugMap::addDebugMapObject(StringRef ObjectFilePath,
+ sys::TimeValue Timestamp) {
+ Objects.emplace_back(new DebugMapObject(ObjectFilePath, Timestamp));
return *Objects.back();
}
@@ -121,11 +123,12 @@ namespace yaml {
// Normalize/Denormalize between YAML and a DebugMapObject.
struct MappingTraits<dsymutil::DebugMapObject>::YamlDMO {
- YamlDMO(IO &io) {}
+ YamlDMO(IO &io) { Timestamp = 0; }
YamlDMO(IO &io, dsymutil::DebugMapObject &Obj);
dsymutil::DebugMapObject denormalize(IO &IO);
std::string Filename;
+ sys::TimeValue::SecondsType Timestamp;
std::vector<dsymutil::DebugMapObject::YAMLSymbolMapping> Entries;
};
@@ -141,6 +144,7 @@ void MappingTraits<dsymutil::DebugMapObject>::mapping(
IO &io, dsymutil::DebugMapObject &DMO) {
MappingNormalization<YamlDMO, dsymutil::DebugMapObject> Norm(io, DMO);
io.mapRequired("filename", Norm->Filename);
+ io.mapOptional("timestamp", Norm->Timestamp);
io.mapRequired("symbols", Norm->Entries);
}
@@ -192,6 +196,7 @@ void MappingTraits<std::unique_ptr<dsymutil::DebugMap>>::mapping(
MappingTraits<dsymutil::DebugMapObject>::YamlDMO::YamlDMO(
IO &io, dsymutil::DebugMapObject &Obj) {
Filename = Obj.Filename;
+ Timestamp = Obj.getTimestamp().toEpochTime();
Entries.reserve(Obj.Symbols.size());
for (auto &Entry : Obj.Symbols)
Entries.push_back(std::make_pair(Entry.getKey(), Entry.getValue()));
@@ -224,7 +229,9 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
}
}
- dsymutil::DebugMapObject Res(Path);
+ sys::TimeValue TV;
+ TV.fromEpochTime(Timestamp);
+ dsymutil::DebugMapObject Res(Path, TV);
for (auto &Entry : Entries) {
auto &Mapping = Entry.second;
uint64_t ObjAddress = Mapping.ObjectAddress;
diff --git a/llvm/tools/dsymutil/DebugMap.h b/llvm/tools/dsymutil/DebugMap.h
index d0edbabb404..29347ed0f50 100644
--- a/llvm/tools/dsymutil/DebugMap.h
+++ b/llvm/tools/dsymutil/DebugMap.h
@@ -29,6 +29,7 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeValue.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>
@@ -89,7 +90,8 @@ public:
/// This function adds an DebugMapObject to the list owned by this
/// debug map.
- DebugMapObject &addDebugMapObject(StringRef ObjectFilePath);
+ DebugMapObject &addDebugMapObject(StringRef ObjectFilePath,
+ sys::TimeValue Timestamp);
const Triple &getTriple() const { return BinaryTriple; }
@@ -139,6 +141,8 @@ public:
llvm::StringRef getObjectFilename() const { return Filename; }
+ sys::TimeValue getTimestamp() const { return Timestamp; }
+
iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const {
return make_range(Symbols.begin(), Symbols.end());
}
@@ -150,9 +154,10 @@ public:
private:
friend class DebugMap;
/// DebugMapObjects can only be constructed by the owning DebugMap.
- DebugMapObject(StringRef ObjectFilename);
+ DebugMapObject(StringRef ObjectFilename, sys::TimeValue Timestamp);
std::string Filename;
+ sys::TimeValue Timestamp;
StringMap<SymbolMapping> Symbols;
DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
@@ -167,12 +172,14 @@ private:
public:
DebugMapObject &operator=(DebugMapObject RHS) {
std::swap(Filename, RHS.Filename);
+ std::swap(Timestamp, RHS.Timestamp);
std::swap(Symbols, RHS.Symbols);
std::swap(AddressToMapping, RHS.AddressToMapping);
return *this;
}
DebugMapObject(DebugMapObject &&RHS) {
Filename = std::move(RHS.Filename);
+ Timestamp = std::move(RHS.Timestamp);
Symbols = std::move(RHS.Symbols);
AddressToMapping = std::move(RHS.AddressToMapping);
}
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index bbe5cfbb1c1..ba136d1d96f 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -3027,7 +3027,8 @@ bool DwarfLinker::link(const DebugMap &Map) {
if (Options.Verbose)
outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
- auto ErrOrObj = BinHolder.GetObjectFile(Obj->getObjectFilename());
+ auto ErrOrObj =
+ BinHolder.GetObjectFile(Obj->getObjectFilename(), Obj->getTimestamp());
if (std::error_code EC = ErrOrObj.getError()) {
reportWarning(Twine(Obj->getObjectFilename()) + ": " + EC.message());
continue;
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index 6c9fa9b5132..8f3ca6ca004 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -55,7 +55,7 @@ private:
const char *CurrentFunctionName;
uint64_t CurrentFunctionAddress;
- void switchToNewDebugMapObject(StringRef Filename);
+ void switchToNewDebugMapObject(StringRef Filename, sys::TimeValue Timestamp);
void resetParserState();
uint64_t getMainBinarySymbolAddress(StringRef Name);
void loadMainBinarySymbols();
@@ -84,13 +84,15 @@ void MachODebugMapParser::resetParserState() {
/// Create a new DebugMapObject. This function resets the state of the
/// parser that was referring to the last object file and sets
/// everything up to add symbols to the new one.
-void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) {
+void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename,
+ sys::TimeValue Timestamp) {
resetParserState();
SmallString<80> Path(PathPrefix);
sys::path::append(Path, Filename);
- auto MachOOrError = CurrentObjectHolder.GetFileAs<MachOObjectFile>(Path);
+ auto MachOOrError =
+ CurrentObjectHolder.GetFileAs<MachOObjectFile>(Path, Timestamp);
if (auto Error = MachOOrError.getError()) {
Warning(Twine("cannot open debug object \"") + Path.str() + "\": " +
Error.message() + "\n");
@@ -98,7 +100,7 @@ void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) {
}
loadCurrentObjectFileSymbols();
- CurrentDebugMapObject = &Result->addDebugMapObject(Path);
+ CurrentDebugMapObject = &Result->addDebugMapObject(Path, Timestamp);
}
static Triple getTriple(const object::MachOObjectFile &Obj) {
@@ -144,8 +146,11 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
const char *Name = &MainBinaryStrings.data()[StringIndex];
// An N_OSO entry represents the start of a new object file description.
- if (Type == MachO::N_OSO)
- return switchToNewDebugMapObject(Name);
+ if (Type == MachO::N_OSO) {
+ sys::TimeValue Timestamp;
+ Timestamp.fromEpochTime(Value);
+ return switchToNewDebugMapObject(Name, Timestamp);
+ }
// If the last N_OSO object file wasn't found,
// CurrentDebugMapObject will be null. Do not update anything
OpenPOWER on IntegriCloud