Skip to content

Commit b302bd9

Browse files
committed
[objcopy][COFF] Update WinCFGuard section contents after stripping
After deleting debug sections symbol indexes are shifted but WinCFGuard sections encode these indices into section data that is completely ignored. Update symbol indices as well.
1 parent f6d143f commit b302bd9

File tree

5 files changed

+302
-0
lines changed

5 files changed

+302
-0
lines changed

llvm/lib/ObjCopy/COFF/COFFObject.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ namespace coff {
1616
using namespace object;
1717

1818
void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
19+
size_t RawIndex = 0;
1920
for (Symbol S : NewSymbols) {
2021
S.UniqueId = NextSymbolUniqueId++;
22+
S.OriginalRawIndex = RawIndex;
23+
RawIndex += 1 + S.Sym.NumberOfAuxSymbols;
2124
Symbols.emplace_back(S);
2225
}
2326
updateSymbols();

llvm/lib/ObjCopy/COFF/COFFObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct Symbol {
8989
std::optional<size_t> WeakTargetSymbolId;
9090
size_t UniqueId;
9191
size_t RawIndex;
92+
size_t OriginalRawIndex;
9293
bool Referenced;
9394
};
9495

llvm/lib/ObjCopy/COFF/COFFWriter.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/ADT/StringRef.h"
1313
#include "llvm/BinaryFormat/COFF.h"
1414
#include "llvm/Object/COFF.h"
15+
#include "llvm/Support/CRC.h"
1516
#include "llvm/Support/Errc.h"
1617
#include "llvm/Support/ErrorHandling.h"
1718
#include <cstddef>
@@ -92,6 +93,63 @@ Error COFFWriter::finalizeSymbolContents() {
9293
return Error::success();
9394
}
9495

96+
Error COFFWriter::finalizeCFGuardContents() {
97+
DenseMap<size_t, size_t> SymIdMap;
98+
bool NeedUpdate = false;
99+
for (Symbol &Sym : Obj.getMutableSymbols()) {
100+
NeedUpdate |= Sym.OriginalRawIndex == Sym.RawIndex;
101+
SymIdMap[Sym.OriginalRawIndex] = Sym.RawIndex;
102+
}
103+
104+
if (!NeedUpdate)
105+
return Error::success();
106+
107+
for (auto &Sym : Obj.getMutableSymbols()) {
108+
if (Sym.Name != ".gljmp$y" && Sym.Name != ".giats$y" &&
109+
Sym.Name != ".gfids$y")
110+
continue;
111+
112+
auto Sec = find_if(Obj.getMutableSections(),
113+
[&Sym](Section &S) { return S.Name == Sym.Name; });
114+
115+
if (Sec == Obj.getMutableSections().end() ||
116+
Sec->UniqueId != Sym.TargetSectionId)
117+
return createStringError(object_error::invalid_symbol_index,
118+
"symbol '%s' is missing its section",
119+
Sym.Name.str().c_str());
120+
121+
if (Sym.Sym.NumberOfAuxSymbols != 1 ||
122+
Sym.Sym.StorageClass != IMAGE_SYM_CLASS_STATIC)
123+
return createStringError(object_error::invalid_symbol_index,
124+
"symbol '%s' has unexpected section format",
125+
Sym.Name.str().c_str());
126+
127+
ArrayRef<uint8_t> RawIds = Sec->getContents();
128+
// Nothing to do and also CheckSum will be -1 instead of 0 if we recalculate
129+
// it on empty input.
130+
if (RawIds.size() == 0)
131+
return Error::success();
132+
133+
// Create updated content
134+
ArrayRef<uint32_t> Ids(reinterpret_cast<const uint32_t *>(RawIds.data()),
135+
RawIds.size() / 4);
136+
std::vector<uint32_t> NewIds;
137+
for (auto Id : Ids)
138+
NewIds.push_back(SymIdMap[Id]);
139+
ArrayRef<uint8_t> NewRawIds(reinterpret_cast<uint8_t *>(NewIds.data()),
140+
RawIds.size());
141+
// Update check sum
142+
JamCRC JC(/*Init=*/0);
143+
JC.update(NewRawIds);
144+
coff_aux_section_definition *SD =
145+
reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData[0].Opaque);
146+
SD->CheckSum = JC.getCRC();
147+
// Set new content
148+
Sec->setOwnedContents(NewRawIds);
149+
}
150+
return Error::success();
151+
}
152+
95153
void COFFWriter::layoutSections() {
96154
for (auto &S : Obj.getMutableSections()) {
97155
if (S.Header.SizeOfRawData > 0)
@@ -183,6 +241,8 @@ Error COFFWriter::finalize(bool IsBigObj) {
183241
return E;
184242
if (Error E = finalizeSymbolContents())
185243
return E;
244+
if (Error E = finalizeCFGuardContents())
245+
return E;
186246

187247
size_t SizeOfHeaders = 0;
188248
FileAlignment = 1;

llvm/lib/ObjCopy/COFF/COFFWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class COFFWriter {
3434
template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
3535
Error finalizeRelocTargets();
3636
Error finalizeSymbolContents();
37+
Error finalizeCFGuardContents();
3738
void layoutSections();
3839
Expected<size_t> finalizeStringTable();
3940

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
# RUN: yaml2obj %s -o %t.in.o
2+
3+
# RUN: llvm-readobj -r -s -x '.gfids$y' -x '.giats$y' -x '.gljmp$y' %t.in.o | FileCheck %s --check-prefix=ORIG
4+
# RUN: llvm-objcopy --strip-debug %t.in.o %t.out.o
5+
# RUN: llvm-readobj -r -s -x '.gfids$y' -x '.giats$y' -x '.gljmp$y' %t.out.o | FileCheck %s --check-prefix=STRIP
6+
7+
# ORIG: Relocations [
8+
# ORIG-NEXT: Section (1) .text {
9+
# ORIG-NEXT: 0x3 IMAGE_REL_AMD64_REL32 foo (14)
10+
# ORIG-NEXT: 0xA IMAGE_REL_AMD64_REL32 bar (15)
11+
# ORIG-NEXT: 0x11 IMAGE_REL_AMD64_REL32 baz (16)
12+
# ORIG-NEXT: 0x18 IMAGE_REL_AMD64_REL32 foobar (17)
13+
# ORIG-NEXT: }
14+
# ORIG-NEXT: ]
15+
# ORIG: Symbols [
16+
# ORIG: Name: .gfids$y
17+
# ORIG: Section: .gfids$y
18+
# ORIG: AuxSymbolCount: 1
19+
# ORIG: AuxSectionDef {
20+
# ORIG: Checksum: 0x459345AD
21+
# ORIG: }
22+
# ORIG: Name: .giats$y
23+
# ORIG: Section: .giats$y
24+
# ORIG: AuxSymbolCount: 1
25+
# ORIG: AuxSectionDef {
26+
# ORIG: Checksum: 0x31852256
27+
# ORIG: }
28+
# ORIG: Name: .gljmp$y
29+
# ORIG: Section: .gljmp$y
30+
# ORIG: AuxSymbolCount: 1
31+
# ORIG: AuxSectionDef {
32+
# ORIG: Checksum: 0xC608680B
33+
# ORIG: }
34+
# ORIG: ]
35+
# ORIG: Hex dump of section '.gfids$y':
36+
# ORIG-NEXT: 0x00000000 0e000000 10000000 ........
37+
# ORIG: Hex dump of section '.giats$y':
38+
# ORIG-NEXT: 0x00000000 0f000000 11000000 ........
39+
# ORIG: Hex dump of section '.gljmp$y':
40+
# ORIG-NEXT: 0x00000000 0e000000 0f000000 10000000 11000000 ................
41+
42+
# STRIP: Relocations [
43+
# STRIP-NEXT: Section (1) .text {
44+
# STRIP-NEXT: 0x3 IMAGE_REL_AMD64_REL32 foo (12)
45+
# STRIP-NEXT: 0xA IMAGE_REL_AMD64_REL32 bar (13)
46+
# STRIP-NEXT: 0x11 IMAGE_REL_AMD64_REL32 baz (14)
47+
# STRIP-NEXT: 0x18 IMAGE_REL_AMD64_REL32 foobar (15)
48+
# STRIP-NEXT: }
49+
# STRIP-NEXT: ]
50+
# STRIP: Symbols [
51+
# STRIP: Name: .gfids$y
52+
# STRIP: Section: .gfids$y
53+
# STRIP: AuxSymbolCount: 1
54+
# STRIP: AuxSectionDef {
55+
# STRIP: Checksum: 0xB770627C
56+
# STRIP: }
57+
# STRIP: Name: .giats$y
58+
# STRIP: Section: .giats$y
59+
# STRIP: AuxSymbolCount: 1
60+
# STRIP: AuxSectionDef {
61+
# STRIP: Checksum: 0xC3660587
62+
# STRIP: }
63+
# STRIP: Name: .gljmp$y
64+
# STRIP: Section: .gljmp$y
65+
# STRIP: AuxSymbolCount: 1
66+
# STRIP: AuxSectionDef {
67+
# STRIP: Checksum: 0x7464D042
68+
# STRIP: }
69+
# STRIP: ]
70+
# STRIP: Hex dump of section '.gfids$y':
71+
# STRIP-NEXT: 0x00000000 0c000000 0e000000 ........
72+
# STRIP: Hex dump of section '.giats$y':
73+
# STRIP-NEXT: 0x00000000 0d000000 0f000000 ........
74+
# STRIP: Hex dump of section '.gljmp$y':
75+
# STRIP-NEXT: 0x00000000 0c000000 0d000000 0e000000 0f000000 ................
76+
77+
--- !COFF
78+
header:
79+
Machine: IMAGE_FILE_MACHINE_AMD64
80+
Characteristics: [ ]
81+
sections:
82+
- Name: .text
83+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
84+
Alignment: 4
85+
SectionData: 488D0500000000488D0D00000000488D0500000000488D0500000000
86+
SizeOfRawData: 28
87+
Relocations:
88+
- VirtualAddress: 3
89+
SymbolName: foo
90+
Type: IMAGE_REL_AMD64_REL32
91+
- VirtualAddress: 10
92+
SymbolName: bar
93+
Type: IMAGE_REL_AMD64_REL32
94+
- VirtualAddress: 17
95+
SymbolName: baz
96+
Type: IMAGE_REL_AMD64_REL32
97+
- VirtualAddress: 24
98+
SymbolName: foobar
99+
Type: IMAGE_REL_AMD64_REL32
100+
- Name: .data
101+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
102+
Alignment: 4
103+
SectionData: ''
104+
- Name: .bss
105+
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
106+
Alignment: 4
107+
SectionData: ''
108+
- Name: '.debug$S'
109+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
110+
Alignment: 4
111+
SectionData: 04000000F100000044656275672073656374696F6E20746F20626520737472697070656400
112+
SizeOfRawData: 37
113+
- Name: '.gfids$y'
114+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
115+
Alignment: 4
116+
SectionData: '0E00000010000000'
117+
SizeOfRawData: 8
118+
- Name: '.giats$y'
119+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
120+
Alignment: 4
121+
SectionData: 0F00000011000000
122+
SizeOfRawData: 8
123+
- Name: '.gljmp$y'
124+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
125+
Alignment: 4
126+
SectionData: 0E0000000F0000001000000011000000
127+
SizeOfRawData: 16
128+
symbols:
129+
- Name: .text
130+
Value: 0
131+
SectionNumber: 1
132+
SimpleType: IMAGE_SYM_TYPE_NULL
133+
ComplexType: IMAGE_SYM_DTYPE_NULL
134+
StorageClass: IMAGE_SYM_CLASS_STATIC
135+
SectionDefinition:
136+
Length: 28
137+
NumberOfRelocations: 4
138+
NumberOfLinenumbers: 0
139+
CheckSum: 3583480811
140+
Number: 1
141+
- Name: .data
142+
Value: 0
143+
SectionNumber: 2
144+
SimpleType: IMAGE_SYM_TYPE_NULL
145+
ComplexType: IMAGE_SYM_DTYPE_NULL
146+
StorageClass: IMAGE_SYM_CLASS_STATIC
147+
SectionDefinition:
148+
Length: 0
149+
NumberOfRelocations: 0
150+
NumberOfLinenumbers: 0
151+
CheckSum: 0
152+
Number: 2
153+
- Name: .bss
154+
Value: 0
155+
SectionNumber: 3
156+
SimpleType: IMAGE_SYM_TYPE_NULL
157+
ComplexType: IMAGE_SYM_DTYPE_NULL
158+
StorageClass: IMAGE_SYM_CLASS_STATIC
159+
SectionDefinition:
160+
Length: 0
161+
NumberOfRelocations: 0
162+
NumberOfLinenumbers: 0
163+
CheckSum: 0
164+
Number: 3
165+
- Name: '.debug$S'
166+
Value: 0
167+
SectionNumber: 4
168+
SimpleType: IMAGE_SYM_TYPE_NULL
169+
ComplexType: IMAGE_SYM_DTYPE_NULL
170+
StorageClass: IMAGE_SYM_CLASS_STATIC
171+
SectionDefinition:
172+
Length: 37
173+
NumberOfRelocations: 0
174+
NumberOfLinenumbers: 0
175+
CheckSum: 2941632545
176+
Number: 4
177+
- Name: '.gfids$y'
178+
Value: 0
179+
SectionNumber: 5
180+
SimpleType: IMAGE_SYM_TYPE_NULL
181+
ComplexType: IMAGE_SYM_DTYPE_NULL
182+
StorageClass: IMAGE_SYM_CLASS_STATIC
183+
SectionDefinition:
184+
Length: 8
185+
NumberOfRelocations: 0
186+
NumberOfLinenumbers: 0
187+
CheckSum: 1167279533
188+
Number: 5
189+
- Name: '.giats$y'
190+
Value: 0
191+
SectionNumber: 6
192+
SimpleType: IMAGE_SYM_TYPE_NULL
193+
ComplexType: IMAGE_SYM_DTYPE_NULL
194+
StorageClass: IMAGE_SYM_CLASS_STATIC
195+
SectionDefinition:
196+
Length: 8
197+
NumberOfRelocations: 0
198+
NumberOfLinenumbers: 0
199+
CheckSum: 830808662
200+
Number: 6
201+
- Name: '.gljmp$y'
202+
Value: 0
203+
SectionNumber: 7
204+
SimpleType: IMAGE_SYM_TYPE_NULL
205+
ComplexType: IMAGE_SYM_DTYPE_NULL
206+
StorageClass: IMAGE_SYM_CLASS_STATIC
207+
SectionDefinition:
208+
Length: 16
209+
NumberOfRelocations: 0
210+
NumberOfLinenumbers: 0
211+
CheckSum: 3322439691
212+
Number: 7
213+
- Name: foo
214+
Value: 0
215+
SectionNumber: 0
216+
SimpleType: IMAGE_SYM_TYPE_NULL
217+
ComplexType: IMAGE_SYM_DTYPE_NULL
218+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
219+
- Name: bar
220+
Value: 0
221+
SectionNumber: 0
222+
SimpleType: IMAGE_SYM_TYPE_NULL
223+
ComplexType: IMAGE_SYM_DTYPE_NULL
224+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
225+
- Name: baz
226+
Value: 0
227+
SectionNumber: 0
228+
SimpleType: IMAGE_SYM_TYPE_NULL
229+
ComplexType: IMAGE_SYM_DTYPE_NULL
230+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
231+
- Name: foobar
232+
Value: 0
233+
SectionNumber: 0
234+
SimpleType: IMAGE_SYM_TYPE_NULL
235+
ComplexType: IMAGE_SYM_DTYPE_NULL
236+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
237+
...

0 commit comments

Comments
 (0)