@@ -99,6 +99,12 @@ cl::opt<BitnessType> Bitness(cl::desc("Choose bitness:"), cl::init(m64),
99
99
cl::values(clEnumVal(m32, " 32-bit" ),
100
100
clEnumVal(m64, " 64-bit (default)" )));
101
101
102
+ static cl::opt<bool > SafeSEH (
103
+ " safeseh" ,
104
+ cl::desc (" Mark resulting object files as either containing no "
105
+ " exception handlers or containing exception handlers that "
106
+ " are all declared with .SAFESEH. Only available in 32-bit." ));
107
+
102
108
static cl::opt<std::string>
103
109
TripleName (" triple" , cl::desc(" Target triple to assemble for, "
104
110
" see -version for available targets" ));
@@ -195,7 +201,7 @@ static int AssembleInput(const char *ProgName, const Target *TheTarget,
195
201
MCAsmInfo &MAI, MCSubtargetInfo &STI,
196
202
MCInstrInfo &MCII, MCTargetOptions &MCOptions) {
197
203
std::unique_ptr<MCAsmParser> Parser (
198
- createMCMasmParser (SrcMgr, Ctx, Str, MAI));
204
+ createMCMasmParser (SrcMgr, Ctx, Str, MAI, 0 ));
199
205
std::unique_ptr<MCTargetAsmParser> TAP (
200
206
TheTarget->createMCAsmParser (STI, *Parser, MCII, MCOptions));
201
207
@@ -240,6 +246,12 @@ int main(int argc, char **argv) {
240
246
// construct the Triple object.
241
247
Triple TheTriple (TripleName);
242
248
249
+ if (SafeSEH && !(TheTriple.isArch32Bit () && TheTriple.isX86 ())) {
250
+ WithColor::warning ()
251
+ << " /safeseh applies only to 32-bit X86 platforms; ignoring.\n " ;
252
+ SafeSEH = false ;
253
+ }
254
+
243
255
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr =
244
256
MemoryBuffer::getFileOrSTDIN (InputFilename);
245
257
if (std::error_code EC = BufferPtr.getError ()) {
@@ -354,6 +366,23 @@ int main(int argc, char **argv) {
354
366
/* DWARFMustBeAtTheEnd*/ false ));
355
367
}
356
368
369
+ if (TheTriple.isOSBinFormatCOFF ()) {
370
+ // Emit an absolute @feat.00 symbol. This is a features bitfield read by
371
+ // link.exe.
372
+ int64_t Feat00Flags = 0x2 ;
373
+ if (SafeSEH) {
374
+ // According to the PE-COFF spec, the LSB of this value marks the object
375
+ // for "registered SEH". This means that all SEH handler entry points
376
+ // must be registered in .sxdata. Use of any unregistered handlers will
377
+ // cause the process to terminate immediately.
378
+ Feat00Flags |= 0x1 ;
379
+ }
380
+ MCSymbol *Feat00Sym = Ctx.getOrCreateSymbol (" @feat.00" );
381
+ Feat00Sym->setRedefinable (true );
382
+ Str->emitSymbolAttribute (Feat00Sym, MCSA_Global);
383
+ Str->emitAssignment (Feat00Sym, MCConstantExpr::create (Feat00Flags, Ctx));
384
+ }
385
+
357
386
// Use Assembler information for parsing.
358
387
Str->setUseAssemblerInfoForParsing (true );
359
388
0 commit comments