[llvm] [llvm-ar][Object] Use K_GNU instead of K_COFF for archives with no symtab. (PR #82898)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 27 07:16:35 PST 2024
https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/82898
>From 01b7c455f9fb57c3b22deddea3368d948a267316 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Sat, 24 Feb 2024 23:34:31 +0100
Subject: [PATCH 1/4] [llvm-ar][Object] Use K_GNU instead of K_COFF for
archives with no symtab.
---
llvm/lib/Object/ArchiveWriter.cpp | 7 +++---
llvm/test/tools/llvm-ar/no-symtab.yaml | 32 ++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/tools/llvm-ar/no-symtab.yaml
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index 02f72521c8b544..9af2b6e94a270a 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -966,10 +966,12 @@ static Error writeArchiveToStream(raw_ostream &Out,
SmallString<0> StringTableBuf;
raw_svector_ostream StringTable(StringTableBuf);
SymMap SymMap;
+ bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;
// COFF symbol map uses 16-bit indexes, so we can't use it if there are too
- // many members.
- if (isCOFFArchive(Kind) && NewMembers.size() > 0xfffe)
+ // many members. COFF format also requires symbol table presence, so use
+ // GNU format when NoSymtab is requested.
+ if (isCOFFArchive(Kind) && (NewMembers.size() > 0xfffe || !ShouldWriteSymtab))
Kind = object::Archive::K_GNU;
// In the scenario when LLVMContext is populated SymbolicFile will contain a
@@ -998,7 +1000,6 @@ static Error writeArchiveToStream(raw_ostream &Out,
uint64_t LastMemberHeaderOffset = 0;
uint64_t NumSyms = 0;
uint64_t NumSyms32 = 0; // Store symbol number of 32-bit member files.
- bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;
for (const auto &M : Data) {
// Record the start of the member's offset
diff --git a/llvm/test/tools/llvm-ar/no-symtab.yaml b/llvm/test/tools/llvm-ar/no-symtab.yaml
new file mode 100644
index 00000000000000..7370c9b3235522
--- /dev/null
+++ b/llvm/test/tools/llvm-ar/no-symtab.yaml
@@ -0,0 +1,32 @@
+## Create archives with no symtab in various formats and check that we can read them.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: rm -f %t.*.a
+
+# RUN: llvm-ar --format=gnu rcS %t.gnu.a %t.o
+# RUN: llvm-ar --format=coff rcS %t.coff.a %t.o
+# RUN: llvm-ar --format=darwin rcS %t.darwin.a %t.o
+# RUN: llvm-ar --format=bsd rcS %t.bsd.a %t.o
+# RUN: llvm-ar --format=bigarchive rcS %t.bigarchive.a %t.o
+
+# RUN: llvm-nm --print-armap %t.gnu.a | FileCheck %s
+# RUN: llvm-nm --print-armap %t.coff.a | FileCheck %s
+# RUN: llvm-nm --print-armap %t.darwin.a | FileCheck %s
+# RUN: llvm-nm --print-armap %t.bsd.a | FileCheck %s
+# RUN: llvm-nm --print-armap %t.bigarchive.a | FileCheck %s
+
+# CHECK-NOT: Archive map
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+Symbols:
+ - Name: symbol
+ Binding: STB_GLOBAL
+ Section: .text
>From e0d50255da142be7b20a0a67f2adf0c1ada1e387 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 26 Feb 2024 15:08:01 +0100
Subject: [PATCH 2/4] Check for COFF files in performWriteOperation if there is
an old archive with no symbol table
---
llvm/test/tools/llvm-ar/coff-symtab.test | 8 +++++++-
llvm/tools/llvm-ar/llvm-ar.cpp | 15 +++++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/llvm/test/tools/llvm-ar/coff-symtab.test b/llvm/test/tools/llvm-ar/coff-symtab.test
index 50d08fba3b02f6..86f79144416459 100644
--- a/llvm/test/tools/llvm-ar/coff-symtab.test
+++ b/llvm/test/tools/llvm-ar/coff-symtab.test
@@ -1,6 +1,6 @@
Verify that llvm-ar uses COFF archive format by ensuring that archive map is sorted.
-RUN: rm -rf %t.dif && split-file %s %t.dir && cd %t.dir
+RUN: rm -rf %t.dir && split-file %s %t.dir && cd %t.dir
RUN: yaml2obj coff-symtab.yaml -o coff-symtab.obj
RUN: llvm-ar crs out.a coff-symtab.obj
@@ -14,6 +14,12 @@ RUN: yaml2obj elf.yaml -o coff-symtab.o
RUN: llvm-ar crs --format coff out3.a coff-symtab.o
RUN: llvm-nm --print-armap out3.a | FileCheck %s
+Create an empty archive with no symbol map, add a COFF file to it.
+
+RUN: llvm-ar rcS out4.a
+RUN: llvm-ar rs out4.a coff-symtab.obj
+RUN: llvm-nm --print-armap out4.a | FileCheck %s
+
CHECK: Archive map
CHECK-NEXT: a in coff-symtab
CHECK-NEXT: b in coff-symtab
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index c58a85c695dacf..5c74bd5589320f 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -1026,14 +1026,21 @@ static void performWriteOperation(ArchiveOperation Operation,
Kind = object::Archive::K_GNU;
else if (OldArchive) {
Kind = OldArchive->kind();
- if (Kind == object::Archive::K_BSD) {
- auto InferredKind = object::Archive::K_BSD;
+ std::optional<object::Archive::Kind> AltKind;
+ if (Kind == object::Archive::K_BSD)
+ AltKind = object::Archive::K_DARWIN;
+ else if (Kind == object::Archive::K_GNU && !OldArchive->hasSymbolTable())
+ // If there is no symbol table, we can't tell GNU from COFF format
+ // from the old archive type.
+ AltKind = object::Archive::K_COFF;
+ if (AltKind) {
+ auto InferredKind = Kind;
if (NewMembersP && !NewMembersP->empty())
InferredKind = NewMembersP->front().detectKindFromObject();
else if (!NewMembers.empty())
InferredKind = NewMembers.front().detectKindFromObject();
- if (InferredKind == object::Archive::K_DARWIN)
- Kind = object::Archive::K_DARWIN;
+ if (InferredKind == AltKind)
+ Kind = *AltKind;
}
} else if (NewMembersP)
Kind = !NewMembersP->empty() ? NewMembersP->front().detectKindFromObject()
>From e78a7e9b029807728451f2a240c8459c63ad90cb Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 26 Feb 2024 16:20:58 +0100
Subject: [PATCH 3/4] Update documentation
---
llvm/docs/CommandGuide/llvm-ar.rst | 5 +++--
llvm/docs/ReleaseNotes.rst | 4 ++++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/CommandGuide/llvm-ar.rst b/llvm/docs/CommandGuide/llvm-ar.rst
index f643b214bcc837..03d5b9e41ada38 100644
--- a/llvm/docs/CommandGuide/llvm-ar.rst
+++ b/llvm/docs/CommandGuide/llvm-ar.rst
@@ -262,8 +262,9 @@ Other
.. option:: --format=<type>
This option allows for default, gnu, darwin or bsd ``<type>`` to be selected.
- When creating an ``archive``, ``<type>`` will default to that of the host
- machine.
+ When creating an ``archive`` with the default ``<type>``, :program:``llvm-ar``
+ will attempt to infer it from the input files and fallback to the default
+ toolchain target if unable to do so.
.. option:: -h, --help
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 5be00d9d5a5899..8a3a0ec66ed874 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -143,6 +143,10 @@ Changes to the LLVM tools
files using reference types and GC are also supported (but also only for
functions, globals, and data, and only for listing symbols and names).
+* llvm-ar now utilizes LLVM_DEFAULT_TARGET_TRIPLE to determine the archive format
+ if it's not specified with the ``--format`` argument and cannot be inferred from
+ input files.
+
Changes to LLDB
---------------------------------
>From dac6fb49ab17f2a6a7125e29b435680cd4a8a96c Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 27 Feb 2024 16:14:53 +0100
Subject: [PATCH 4/4] Comment clarification
---
llvm/test/tools/llvm-ar/coff-symtab.test | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/tools/llvm-ar/coff-symtab.test b/llvm/test/tools/llvm-ar/coff-symtab.test
index 86f79144416459..4f7270d9e2c6e7 100644
--- a/llvm/test/tools/llvm-ar/coff-symtab.test
+++ b/llvm/test/tools/llvm-ar/coff-symtab.test
@@ -14,7 +14,7 @@ RUN: yaml2obj elf.yaml -o coff-symtab.o
RUN: llvm-ar crs --format coff out3.a coff-symtab.o
RUN: llvm-nm --print-armap out3.a | FileCheck %s
-Create an empty archive with no symbol map, add a COFF file to it.
+Create an empty archive with no symbol map, add a COFF file to it and check that the output archive is a COFF archive.
RUN: llvm-ar rcS out4.a
RUN: llvm-ar rs out4.a coff-symtab.obj
More information about the llvm-commits
mailing list