summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/CommandGuide/llvm-ar.rst12
-rw-r--r--llvm/include/llvm/Object/Archive.h1
-rw-r--r--llvm/test/Object/archive-thin-create.test3
-rw-r--r--llvm/test/Object/archive-toc.test14
-rw-r--r--llvm/tools/llvm-ar/llvm-ar.cpp34
5 files changed, 48 insertions, 16 deletions
diff --git a/llvm/docs/CommandGuide/llvm-ar.rst b/llvm/docs/CommandGuide/llvm-ar.rst
index 1073d96cb7e..a138dcf1683 100644
--- a/llvm/docs/CommandGuide/llvm-ar.rst
+++ b/llvm/docs/CommandGuide/llvm-ar.rst
@@ -100,15 +100,15 @@ r[abu]
*files* or insert them at the end of the archive if they do not exist. If no
*files* are specified, the archive is not modified.
-t[v]
+t[vO]
Print the table of contents. Without any modifiers, this operation just prints
the names of the members to the standard output. With the *v* modifier,
**llvm-ar** also prints out the file type (B=bitcode, S=symbol
table, blank=regular file), the permission mode, the owner and group, the
- size, and the date. If any *files* are specified, the listing is only for
- those files. If no *files* are specified, the table of contents for the
- whole archive is printed.
+ size, and the date. With the :option:`O` modifier, display member offsets.
+ If any *files* are specified, the listing is only for those files. If no
+ *files* are specified, the table of contents for the whole archive is printed.
x[oP]
@@ -145,6 +145,10 @@ section (above) to determine which modifiers are applicable to which operations.
When extracting files, this option will cause **llvm-ar** to preserve the
original modification times of the files it writes.
+[O]
+
+ Display member offsets inside the archive.
+
[u]
When replacing existing files in the archive, only replace those files that have
diff --git a/llvm/include/llvm/Object/Archive.h b/llvm/include/llvm/Object/Archive.h
index 8b58eaeff41..c3f36bdd9d1 100644
--- a/llvm/include/llvm/Object/Archive.h
+++ b/llvm/include/llvm/Object/Archive.h
@@ -135,6 +135,7 @@ public:
Expected<StringRef> getBuffer() const;
uint64_t getChildOffset() const;
+ uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; }
Expected<MemoryBufferRef> getMemoryBufferRef() const;
diff --git a/llvm/test/Object/archive-thin-create.test b/llvm/test/Object/archive-thin-create.test
index 55abe0002f9..e705d0ee2b7 100644
--- a/llvm/test/Object/archive-thin-create.test
+++ b/llvm/test/Object/archive-thin-create.test
@@ -9,6 +9,9 @@ RUN: llvm-ar qcT foo/libtest.a foo/test1.o
RUN: llvm-ar qcT foo/libtest.a foo/test2.o
RUN: llvm-ar t foo/libtest.a | FileCheck --match-full-lines %s
+O (displaying member offsets) is ignored for thin archives.
+RUN: llvm-ar tO foo/libtest.a | FileCheck --match-full-lines %s
+
CHECK: foo/test1.o
CHECK: foo/test1.o
CHECK: foo/test2.o
diff --git a/llvm/test/Object/archive-toc.test b/llvm/test/Object/archive-toc.test
index fcc7fe5312a..29f0bacfc3d 100644
--- a/llvm/test/Object/archive-toc.test
+++ b/llvm/test/Object/archive-toc.test
@@ -46,3 +46,17 @@ RUN: env TZ=GMT llvm-ar tv Inputs/thin-path.a | FileCheck %s --check-prefix=THIN
THINPATH: rw-r--r-- 0/0 1224 Jan 1 00:00 1970 Inputs/test.o
THINPATH-NEXT: rw-r--r-- 0/0 1224 Jan 1 00:00 1970 Inputs/t/test2.o
+
+RUN: llvm-ar tO Inputs/GNU.a | FileCheck %s --check-prefix=GNU-O --strict-whitespace
+
+GNU-O: {{^}}evenlen 0x10c
+GNU-O-NEXT: {{^}}oddlen 0x150
+GNU-O-NEXT: {{^}}very_long_bytecode_file_name.bc 0x194
+GNU-O-NEXT: {{^}}IsNAN.o 0x78a
+
+RUN: env TZ=GMT llvm-ar tvO Inputs/GNU.a | FileCheck %s --check-prefix=GNU-VO --strict-whitespace
+
+GNU-VO: rw-r--r-- 500/500 8 Nov 19 02:57 2004 evenlen 0x10c
+GNU-VO-NEXT: rw-r--r-- 500/500 7 Nov 19 02:57 2004 oddlen 0x150
+GNU-VO-NEXT: rwxr-xr-x 500/500 1465 Nov 19 03:01 2004 very_long_bytecode_file_name.bc 0x194
+GNU-VO-NEXT: rw-r--r-- 500/500 2280 Nov 19 03:04 2004 IsNAN.o 0x78a
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index 6233c60e9bd..c9cf217f768 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -106,6 +106,7 @@ MODIFIERS:
[L] - add archive's contents
[N] - use instance [count] of name
[o] - preserve original dates
+ [O] - display member offsets
[P] - use full names when matching (implied for thin archives)
[s] - create an archive index (cf. ranlib)
[S] - do not build a symbol table
@@ -187,17 +188,18 @@ enum ArchiveOperation {
};
// Modifiers to follow operation to vary behavior
-static bool AddAfter = false; ///< 'a' modifier
-static bool AddBefore = false; ///< 'b' modifier
-static bool Create = false; ///< 'c' modifier
-static bool OriginalDates = false; ///< 'o' modifier
-static bool CompareFullPath = false; ///< 'P' modifier
-static bool OnlyUpdate = false; ///< 'u' modifier
-static bool Verbose = false; ///< 'v' modifier
-static bool Symtab = true; ///< 's' modifier
-static bool Deterministic = true; ///< 'D' and 'U' modifiers
-static bool Thin = false; ///< 'T' modifier
-static bool AddLibrary = false; ///< 'L' modifier
+static bool AddAfter = false; ///< 'a' modifier
+static bool AddBefore = false; ///< 'b' modifier
+static bool Create = false; ///< 'c' modifier
+static bool OriginalDates = false; ///< 'o' modifier
+static bool DisplayMemberOffsets = false; ///< 'O' modifier
+static bool CompareFullPath = false; ///< 'P' modifier
+static bool OnlyUpdate = false; ///< 'u' modifier
+static bool Verbose = false; ///< 'v' modifier
+static bool Symtab = true; ///< 's' modifier
+static bool Deterministic = true; ///< 'D' and 'U' modifiers
+static bool Thin = false; ///< 'T' modifier
+static bool AddLibrary = false; ///< 'L' modifier
// Relative Positional Argument (for insert/move). This variable holds
// the name of the archive member to which the 'a', 'b' or 'i' modifier
@@ -329,6 +331,9 @@ static ArchiveOperation parseCommandLine() {
case 'o':
OriginalDates = true;
break;
+ case 'O':
+ DisplayMemberOffsets = true;
+ break;
case 'P':
CompareFullPath = true;
break;
@@ -486,8 +491,13 @@ static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
if (!ParentDir.empty())
outs() << sys::path::convert_to_slash(ParentDir) << '/';
}
+ outs() << Name;
+ } else {
+ outs() << Name;
+ if (DisplayMemberOffsets)
+ outs() << " 0x" << utohexstr(C.getDataOffset(), true);
}
- outs() << Name << "\n";
+ outs() << '\n';
}
static std::string normalizePath(StringRef Path) {
OpenPOWER on IntegriCloud