Skip to content

Commit 661f9b9

Browse files
committed
[llvm-ar] Use COFF archive format for COFF targets.
Detect COFF files by default and allow specifying it with --format argument.
1 parent d877ab1 commit 661f9b9

File tree

5 files changed

+114
-15
lines changed

5 files changed

+114
-15
lines changed

llvm/include/llvm/Object/Archive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ class Archive : public Binary {
339339
Kind kind() const { return (Kind)Format; }
340340
bool isThin() const { return IsThin; }
341341
static object::Archive::Kind getDefaultKindForHost();
342+
static object::Archive::Kind getDefaultKindForTriple(Triple &T);
342343

343344
child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
344345
child_iterator child_end() const;

llvm/lib/Object/Archive.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -969,12 +969,19 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
969969
Err = Error::success();
970970
}
971971

972+
object::Archive::Kind Archive::getDefaultKindForTriple(Triple &T) {
973+
if (T.isOSDarwin())
974+
return object::Archive::K_DARWIN;
975+
if (T.isOSAIX())
976+
return object::Archive::K_AIXBIG;
977+
if (T.isOSWindows())
978+
return object::Archive::K_COFF;
979+
return object::Archive::K_GNU;
980+
}
981+
972982
object::Archive::Kind Archive::getDefaultKindForHost() {
973983
Triple HostTriple(sys::getProcessTriple());
974-
return HostTriple.isOSDarwin()
975-
? object::Archive::K_DARWIN
976-
: (HostTriple.isOSAIX() ? object::Archive::K_AIXBIG
977-
: object::Archive::K_GNU);
984+
return getDefaultKindForTriple(HostTriple);
978985
}
979986

980987
Archive::child_iterator Archive::child_begin(Error &Err,

llvm/lib/Object/ArchiveWriter.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,16 @@ object::Archive::Kind NewArchiveMember::detectKindFromObject() const {
6262
Expected<std::unique_ptr<object::ObjectFile>> OptionalObject =
6363
object::ObjectFile::createObjectFile(MemBufferRef);
6464

65-
if (OptionalObject)
66-
return isa<object::MachOObjectFile>(**OptionalObject)
67-
? object::Archive::K_DARWIN
68-
: (isa<object::XCOFFObjectFile>(**OptionalObject)
69-
? object::Archive::K_AIXBIG
70-
: object::Archive::K_GNU);
65+
if (OptionalObject) {
66+
if (isa<object::MachOObjectFile>(**OptionalObject))
67+
return object::Archive::K_DARWIN;
68+
if (isa<object::XCOFFObjectFile>(**OptionalObject))
69+
return object::Archive::K_AIXBIG;
70+
if (isa<object::COFFObjectFile>(**OptionalObject) ||
71+
isa<object::COFFImportFile>(**OptionalObject))
72+
return object::Archive::K_COFF;
73+
return object::Archive::K_GNU;
74+
}
7175

7276
// Squelch the error in case we had a non-object file.
7377
consumeError(OptionalObject.takeError());
@@ -80,10 +84,7 @@ object::Archive::Kind NewArchiveMember::detectKindFromObject() const {
8084
MemBufferRef, file_magic::bitcode, &Context)) {
8185
auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr);
8286
auto TargetTriple = Triple(IRObject.getTargetTriple());
83-
return TargetTriple.isOSDarwin()
84-
? object::Archive::K_DARWIN
85-
: (TargetTriple.isOSAIX() ? object::Archive::K_AIXBIG
86-
: object::Archive::K_GNU);
87+
return object::Archive::getDefaultKindForTriple(TargetTriple);
8788
} else {
8889
// Squelch the error in case this was not a SymbolicFile.
8990
consumeError(ObjOrErr.takeError());
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Verify that llvm-ar uses COFF archive format by ensuring that archive map is sorted.
2+
3+
RUN: rm -rf %t.dif && split-file %s %t.dir && cd %t.dir
4+
5+
RUN: yaml2obj coff-symtab.yaml -o coff-symtab.obj
6+
RUN: llvm-ar crs out.a coff-symtab.obj
7+
RUN: llvm-nm --print-armap out.a | FileCheck %s
8+
9+
RUN: llvm-as coff-symtab.ll -o coff-symtab.bc
10+
RUN: llvm-ar crs out2.a coff-symtab.bc
11+
RUN: llvm-nm --print-armap out2.a | FileCheck %s
12+
13+
RUN: yaml2obj elf.yaml -o coff-symtab.o
14+
RUN: llvm-ar crs --format coff out3.a coff-symtab.o
15+
RUN: llvm-nm --print-armap out3.a | FileCheck %s
16+
17+
CHECK: Archive map
18+
CHECK-NEXT: a in coff-symtab
19+
CHECK-NEXT: b in coff-symtab
20+
CHECK-NEXT: c in coff-symtab
21+
CHECK-EMPTY:
22+
23+
#--- coff-symtab.yaml
24+
--- !COFF
25+
header:
26+
Machine: IMAGE_FILE_MACHINE_UNKNOWN
27+
Characteristics: [ ]
28+
sections:
29+
- Name: .text
30+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
31+
Alignment: 4
32+
SectionData: ''
33+
symbols:
34+
- Name: b
35+
Value: 0
36+
SectionNumber: 1
37+
SimpleType: IMAGE_SYM_TYPE_NULL
38+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
39+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
40+
- Name: c
41+
Value: 0
42+
SectionNumber: 1
43+
SimpleType: IMAGE_SYM_TYPE_NULL
44+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
45+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
46+
- Name: a
47+
Value: 0
48+
SectionNumber: 1
49+
SimpleType: IMAGE_SYM_TYPE_NULL
50+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
51+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
52+
...
53+
54+
55+
#--- coff-symtab.ll
56+
target triple = "x86_64-unknown-windows-msvc"
57+
58+
define void @b() { ret void }
59+
define void @c() { ret void }
60+
define void @a() { ret void }
61+
62+
#--- elf.yaml
63+
--- !ELF
64+
FileHeader:
65+
Class: ELFCLASS64
66+
Data : ELFDATA2LSB
67+
Type: ET_REL
68+
Machine: EM_X86_64
69+
Sections:
70+
- Name: .text
71+
Type: SHT_PROGBITS
72+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
73+
AddressAlign: 0x0000000000000004
74+
Content: ''
75+
Symbols:
76+
- Name: b
77+
Binding: STB_GLOBAL
78+
Section: .text
79+
- Name: c
80+
Binding: STB_GLOBAL
81+
Section: .text
82+
- Name: a
83+
Binding: STB_GLOBAL
84+
Section: .text
85+
...

llvm/tools/llvm-ar/llvm-ar.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static void printArHelp(StringRef ToolName) {
8282
=darwin - darwin
8383
=bsd - bsd
8484
=bigarchive - big archive (AIX OS)
85+
=coff - coff
8586
--plugin=<string> - ignored for compatibility
8687
-h --help - display this help and exit
8788
--output - the directory to extract archive members to
@@ -193,7 +194,7 @@ static SmallVector<const char *, 256> PositionalArgs;
193194
static bool MRI;
194195

195196
namespace {
196-
enum Format { Default, GNU, BSD, DARWIN, BIGARCHIVE, Unknown };
197+
enum Format { Default, GNU, COFF, BSD, DARWIN, BIGARCHIVE, Unknown };
197198
}
198199

199200
static Format FormatType = Default;
@@ -1044,6 +1045,9 @@ static void performWriteOperation(ArchiveOperation Operation,
10441045
case GNU:
10451046
Kind = object::Archive::K_GNU;
10461047
break;
1048+
case COFF:
1049+
Kind = object::Archive::K_COFF;
1050+
break;
10471051
case BSD:
10481052
if (Thin)
10491053
fail("only the gnu format has a thin mode");
@@ -1376,6 +1380,7 @@ static int ar_main(int argc, char **argv) {
13761380
.Case("darwin", DARWIN)
13771381
.Case("bsd", BSD)
13781382
.Case("bigarchive", BIGARCHIVE)
1383+
.Case("coff", COFF)
13791384
.Default(Unknown);
13801385
if (FormatType == Unknown)
13811386
fail(std::string("Invalid format ") + Match);

0 commit comments

Comments
 (0)