Skip to content

Commit 2fd0b24

Browse files
committed
[Object][Archive] Recompute headers and symbol map when switching from COFF to GNU64
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 3fa3e09 commit 2fd0b24

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-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: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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-readobj %t.lib
5+
# RUN: env SYM64_THRESHOLD=100 not llvm-lib -machine:arm64x -out:%t-ec.lib %t-ec.obj %t01234567890234567789.obj 2>&1 | FileCheck %s
6+
# CHECK: Archive is too large: ARM64X does not support archives larger than 4GB
7+
8+
--- !COFF
9+
header:
10+
Machine: IMAGE_FILE_MACHINE_AMD64
11+
Characteristics: [ ]
12+
sections:
13+
- Name: .text
14+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15+
Alignment: 4
16+
SectionData: ''
17+
symbols:
18+
- Name: .text
19+
Value: 0
20+
SectionNumber: 1
21+
SimpleType: IMAGE_SYM_TYPE_NULL
22+
ComplexType: IMAGE_SYM_DTYPE_NULL
23+
StorageClass: IMAGE_SYM_CLASS_STATIC
24+
SectionDefinition:
25+
Length: 0
26+
NumberOfRelocations: 0
27+
NumberOfLinenumbers: 0
28+
CheckSum: 0
29+
Number: 1
30+
- !Symbol
31+
Name: sym
32+
Value: 0
33+
SectionNumber: 1
34+
SimpleType: IMAGE_SYM_TYPE_NULL # (0)
35+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION # (2)
36+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL # (2)
37+
...
38+
39+
--- !COFF
40+
header:
41+
Machine: IMAGE_FILE_MACHINE_ARM64
42+
Characteristics: [ ]
43+
sections:
44+
- Name: .text
45+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
46+
Alignment: 4
47+
SectionData: ''
48+
symbols:
49+
- Name: .text
50+
Value: 0
51+
SectionNumber: 1
52+
SimpleType: IMAGE_SYM_TYPE_NULL
53+
ComplexType: IMAGE_SYM_DTYPE_NULL
54+
StorageClass: IMAGE_SYM_CLASS_STATIC
55+
SectionDefinition:
56+
Length: 0
57+
NumberOfRelocations: 0
58+
NumberOfLinenumbers: 0
59+
CheckSum: 0
60+
Number: 1
61+
- !Symbol
62+
Name: sym
63+
Value: 0
64+
SectionNumber: 1
65+
SimpleType: IMAGE_SYM_TYPE_NULL # (0)
66+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION # (2)
67+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL # (2)
68+
...

0 commit comments

Comments
 (0)