Skip to content

Commit 48a6f2f

Browse files
authored
[Object][Archive] Recompute headers and symbol map when switching from COFF to GNU64 (#160606)
COFF format has no 64-bit version, so we use GNU64 instead. Since this changes the headers, we need to recalculate everything. Fixes #160112.
1 parent e930644 commit 48a6f2f

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

llvm/lib/Object/ArchiveWriter.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,10 +1119,26 @@ Error writeArchiveToStream(raw_ostream &Out,
11191119
// to switch to 64-bit. Note that the file can be larger than 4GB as long as
11201120
// the last member starts before the 4GB offset.
11211121
if (*HeadersSize + LastMemberHeaderOffset >= Sym64Threshold) {
1122-
if (Kind == object::Archive::K_DARWIN)
1122+
switch (Kind) {
1123+
case object::Archive::K_COFF:
1124+
// COFF format has no 64-bit version, so we use GNU64 instead.
1125+
if (!SymMap.Map.empty() && !SymMap.ECMap.empty())
1126+
// Only the COFF format supports the ECSYMBOLS section, so don’t use
1127+
// GNU64 when two symbol maps are required.
1128+
return make_error<object::GenericBinaryError>(
1129+
"Archive is too large: ARM64X does not support archives larger "
1130+
"than 4GB");
1131+
// Since this changes the headers, we need to recalculate everything.
1132+
return writeArchiveToStream(Out, NewMembers, WriteSymtab,
1133+
object::Archive::K_GNU64, Deterministic,
1134+
Thin, IsEC, Warn);
1135+
case object::Archive::K_DARWIN:
11231136
Kind = object::Archive::K_DARWIN64;
1124-
else
1137+
break;
1138+
default:
11251139
Kind = object::Archive::K_GNU64;
1140+
break;
1141+
}
11261142
HeadersSize.reset();
11271143
}
11281144
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# RUN: yaml2obj --docnum=1 %s -o %t01234567890234567789.obj
2+
# RUN: yaml2obj --docnum=2 %s -o %t-ec.obj
3+
# RUN: env SYM64_THRESHOLD=100 llvm-lib -machine:amd64 -out:%t.lib %t01234567890234567789.obj
4+
# RUN: llvm-nm --print-armap %t.lib | FileCheck --check-prefix=ARMAP %s
5+
# ARMAP: Archive map
6+
# ARMAP-NEXT: sym
7+
8+
# RUN: env SYM64_THRESHOLD=100 not llvm-lib -machine:arm64x -out:%t-ec.lib %t-ec.obj %t01234567890234567789.obj 2>&1 | FileCheck %s
9+
# CHECK: Archive is too large: ARM64X does not support archives larger than 4GB
10+
11+
--- !COFF
12+
header:
13+
Machine: IMAGE_FILE_MACHINE_AMD64
14+
Characteristics: [ ]
15+
sections:
16+
- Name: .text
17+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
18+
Alignment: 4
19+
SectionData: ''
20+
symbols:
21+
- Name: .text
22+
Value: 0
23+
SectionNumber: 1
24+
SimpleType: IMAGE_SYM_TYPE_NULL
25+
ComplexType: IMAGE_SYM_DTYPE_NULL
26+
StorageClass: IMAGE_SYM_CLASS_STATIC
27+
SectionDefinition:
28+
Length: 0
29+
NumberOfRelocations: 0
30+
NumberOfLinenumbers: 0
31+
CheckSum: 0
32+
Number: 1
33+
- !Symbol
34+
Name: sym
35+
Value: 0
36+
SectionNumber: 1
37+
SimpleType: IMAGE_SYM_TYPE_NULL # (0)
38+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION # (2)
39+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL # (2)
40+
...
41+
42+
--- !COFF
43+
header:
44+
Machine: IMAGE_FILE_MACHINE_ARM64
45+
Characteristics: [ ]
46+
sections:
47+
- Name: .text
48+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
49+
Alignment: 4
50+
SectionData: ''
51+
symbols:
52+
- Name: .text
53+
Value: 0
54+
SectionNumber: 1
55+
SimpleType: IMAGE_SYM_TYPE_NULL
56+
ComplexType: IMAGE_SYM_DTYPE_NULL
57+
StorageClass: IMAGE_SYM_CLASS_STATIC
58+
SectionDefinition:
59+
Length: 0
60+
NumberOfRelocations: 0
61+
NumberOfLinenumbers: 0
62+
CheckSum: 0
63+
Number: 1
64+
- !Symbol
65+
Name: sym
66+
Value: 0
67+
SectionNumber: 1
68+
SimpleType: IMAGE_SYM_TYPE_NULL # (0)
69+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION # (2)
70+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL # (2)
71+
...

0 commit comments

Comments
 (0)