@@ -99,7 +99,7 @@ class AArch64AsmPrinter : public AsmPrinter {
9999 void LowerPATCHABLE_FUNCTION_EXIT (const MachineInstr &MI);
100100 void LowerPATCHABLE_TAIL_CALL (const MachineInstr &MI);
101101
102- std::map<std::pair <unsigned , uint32_t >, MCSymbol *> HwasanMemaccessSymbols;
102+ std::map<std::tuple <unsigned , bool , uint32_t >, MCSymbol *> HwasanMemaccessSymbols;
103103 void LowerHWASAN_CHECK_MEMACCESS (const MachineInstr &MI);
104104 void EmitHwasanMemaccessSymbols (Module &M);
105105
@@ -237,15 +237,19 @@ void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
237237
238238void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS (const MachineInstr &MI) {
239239 Register Reg = MI.getOperand (0 ).getReg ();
240+ bool IsShort =
241+ MI.getOpcode () == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES;
240242 uint32_t AccessInfo = MI.getOperand (1 ).getImm ();
241- MCSymbol *&Sym = HwasanMemaccessSymbols[{Reg, AccessInfo}];
243+ MCSymbol *&Sym = HwasanMemaccessSymbols[{Reg, IsShort, AccessInfo}];
242244 if (!Sym) {
243245 // FIXME: Make this work on non-ELF.
244246 if (!TM.getTargetTriple ().isOSBinFormatELF ())
245247 report_fatal_error (" llvm.hwasan.check.memaccess only supported on ELF" );
246248
247249 std::string SymName = " __hwasan_check_x" + utostr (Reg - AArch64::X0) + " _" +
248250 utostr (AccessInfo);
251+ if (IsShort)
252+ SymName += " _short" ;
249253 Sym = OutContext.getOrCreateSymbol (SymName);
250254 }
251255
@@ -263,15 +267,22 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
263267 std::unique_ptr<MCSubtargetInfo> STI (
264268 TM.getTarget ().createMCSubtargetInfo (TT.str (), " " , " " ));
265269
266- MCSymbol *HwasanTagMismatchSym =
270+ MCSymbol *HwasanTagMismatchV1Sym =
267271 OutContext.getOrCreateSymbol (" __hwasan_tag_mismatch" );
272+ MCSymbol *HwasanTagMismatchV2Sym =
273+ OutContext.getOrCreateSymbol (" __hwasan_tag_mismatch_v2" );
268274
269- const MCSymbolRefExpr *HwasanTagMismatchRef =
270- MCSymbolRefExpr::create (HwasanTagMismatchSym, OutContext);
275+ const MCSymbolRefExpr *HwasanTagMismatchV1Ref =
276+ MCSymbolRefExpr::create (HwasanTagMismatchV1Sym, OutContext);
277+ const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
278+ MCSymbolRefExpr::create (HwasanTagMismatchV2Sym, OutContext);
271279
272280 for (auto &P : HwasanMemaccessSymbols) {
273- unsigned Reg = P.first .first ;
274- uint32_t AccessInfo = P.first .second ;
281+ unsigned Reg = std::get<0 >(P.first );
282+ bool IsShort = std::get<1 >(P.first );
283+ uint32_t AccessInfo = std::get<2 >(P.first );
284+ const MCSymbolRefExpr *HwasanTagMismatchRef =
285+ IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
275286 MCSymbol *Sym = P.second ;
276287
277288 OutStreamer->SwitchSection (OutContext.getELFSection (
@@ -304,82 +315,86 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
304315 .addReg (Reg)
305316 .addImm (AArch64_AM::getShifterImm (AArch64_AM::LSR, 56 )),
306317 *STI);
307- MCSymbol *HandlePartialSym = OutContext.createTempSymbol ();
318+ MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol ();
308319 OutStreamer->EmitInstruction (
309320 MCInstBuilder (AArch64::Bcc)
310321 .addImm (AArch64CC::NE)
311- .addExpr (MCSymbolRefExpr::create (HandlePartialSym, OutContext)),
322+ .addExpr (MCSymbolRefExpr::create (HandleMismatchOrPartialSym,
323+ OutContext)),
312324 *STI);
313325 MCSymbol *ReturnSym = OutContext.createTempSymbol ();
314326 OutStreamer->EmitLabel (ReturnSym);
315327 OutStreamer->EmitInstruction (
316328 MCInstBuilder (AArch64::RET).addReg (AArch64::LR), *STI);
329+ OutStreamer->EmitLabel (HandleMismatchOrPartialSym);
317330
318- OutStreamer->EmitLabel (HandlePartialSym);
319- OutStreamer->EmitInstruction (MCInstBuilder (AArch64::SUBSWri)
320- .addReg (AArch64::WZR)
321- .addReg (AArch64::W16)
322- .addImm (15 )
323- .addImm (0 ),
324- *STI);
325- MCSymbol *HandleMismatchSym = OutContext.createTempSymbol ();
326- OutStreamer->EmitInstruction (
327- MCInstBuilder (AArch64::Bcc)
328- .addImm (AArch64CC::HI)
329- .addExpr (MCSymbolRefExpr::create (HandleMismatchSym, OutContext)),
330- *STI);
331-
332- OutStreamer->EmitInstruction (
333- MCInstBuilder (AArch64::ANDXri)
334- .addReg (AArch64::X17)
335- .addReg (Reg)
336- .addImm (AArch64_AM::encodeLogicalImmediate (0xf , 64 )),
337- *STI);
338- unsigned Size = 1 << (AccessInfo & 0xf );
339- if (Size != 1 )
340- OutStreamer->EmitInstruction (MCInstBuilder (AArch64::ADDXri)
341- .addReg (AArch64::X17)
342- .addReg (AArch64::X17)
343- .addImm (Size - 1 )
331+ if (IsShort) {
332+ OutStreamer->EmitInstruction (MCInstBuilder (AArch64::SUBSWri)
333+ .addReg (AArch64::WZR)
334+ .addReg (AArch64::W16)
335+ .addImm (15 )
344336 .addImm (0 ),
345337 *STI);
346- OutStreamer->EmitInstruction (MCInstBuilder (AArch64::SUBSWrs)
347- .addReg (AArch64::WZR)
348- .addReg (AArch64::W16)
349- .addReg (AArch64::W17)
350- .addImm (0 ),
351- *STI);
352- OutStreamer->EmitInstruction (
353- MCInstBuilder (AArch64::Bcc)
354- .addImm (AArch64CC::LS)
355- .addExpr (MCSymbolRefExpr::create (HandleMismatchSym, OutContext)),
356- *STI);
357-
358- OutStreamer->EmitInstruction (
359- MCInstBuilder (AArch64::ORRXri)
360- .addReg (AArch64::X16)
361- .addReg (Reg)
362- .addImm (AArch64_AM::encodeLogicalImmediate (0xf , 64 )),
363- *STI);
364- OutStreamer->EmitInstruction (MCInstBuilder (AArch64::LDRBBui)
365- .addReg (AArch64::W16)
366- .addReg (AArch64::X16)
367- .addImm (0 ),
368- *STI);
369- OutStreamer->EmitInstruction (
370- MCInstBuilder (AArch64::SUBSXrs)
371- .addReg (AArch64::XZR)
372- .addReg (AArch64::X16)
373- .addReg (Reg)
374- .addImm (AArch64_AM::getShifterImm (AArch64_AM::LSR, 56 )),
375- *STI);
376- OutStreamer->EmitInstruction (
377- MCInstBuilder (AArch64::Bcc)
378- .addImm (AArch64CC::EQ)
379- .addExpr (MCSymbolRefExpr::create (ReturnSym, OutContext)),
380- *STI);
338+ MCSymbol *HandleMismatchSym = OutContext.createTempSymbol ();
339+ OutStreamer->EmitInstruction (
340+ MCInstBuilder (AArch64::Bcc)
341+ .addImm (AArch64CC::HI)
342+ .addExpr (MCSymbolRefExpr::create (HandleMismatchSym, OutContext)),
343+ *STI);
344+
345+ OutStreamer->EmitInstruction (
346+ MCInstBuilder (AArch64::ANDXri)
347+ .addReg (AArch64::X17)
348+ .addReg (Reg)
349+ .addImm (AArch64_AM::encodeLogicalImmediate (0xf , 64 )),
350+ *STI);
351+ unsigned Size = 1 << (AccessInfo & 0xf );
352+ if (Size != 1 )
353+ OutStreamer->EmitInstruction (MCInstBuilder (AArch64::ADDXri)
354+ .addReg (AArch64::X17)
355+ .addReg (AArch64::X17)
356+ .addImm (Size - 1 )
357+ .addImm (0 ),
358+ *STI);
359+ OutStreamer->EmitInstruction (MCInstBuilder (AArch64::SUBSWrs)
360+ .addReg (AArch64::WZR)
361+ .addReg (AArch64::W16)
362+ .addReg (AArch64::W17)
363+ .addImm (0 ),
364+ *STI);
365+ OutStreamer->EmitInstruction (
366+ MCInstBuilder (AArch64::Bcc)
367+ .addImm (AArch64CC::LS)
368+ .addExpr (MCSymbolRefExpr::create (HandleMismatchSym, OutContext)),
369+ *STI);
370+
371+ OutStreamer->EmitInstruction (
372+ MCInstBuilder (AArch64::ORRXri)
373+ .addReg (AArch64::X16)
374+ .addReg (Reg)
375+ .addImm (AArch64_AM::encodeLogicalImmediate (0xf , 64 )),
376+ *STI);
377+ OutStreamer->EmitInstruction (MCInstBuilder (AArch64::LDRBBui)
378+ .addReg (AArch64::W16)
379+ .addReg (AArch64::X16)
380+ .addImm (0 ),
381+ *STI);
382+ OutStreamer->EmitInstruction (
383+ MCInstBuilder (AArch64::SUBSXrs)
384+ .addReg (AArch64::XZR)
385+ .addReg (AArch64::X16)
386+ .addReg (Reg)
387+ .addImm (AArch64_AM::getShifterImm (AArch64_AM::LSR, 56 )),
388+ *STI);
389+ OutStreamer->EmitInstruction (
390+ MCInstBuilder (AArch64::Bcc)
391+ .addImm (AArch64CC::EQ)
392+ .addExpr (MCSymbolRefExpr::create (ReturnSym, OutContext)),
393+ *STI);
394+
395+ OutStreamer->EmitLabel (HandleMismatchSym);
396+ }
381397
382- OutStreamer->EmitLabel (HandleMismatchSym);
383398 OutStreamer->EmitInstruction (MCInstBuilder (AArch64::STPXpre)
384399 .addReg (AArch64::SP)
385400 .addReg (AArch64::X0)
@@ -414,16 +429,16 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
414429 MCInstBuilder (AArch64::ADRP)
415430 .addReg (AArch64::X16)
416431 .addExpr (AArch64MCExpr::create (
417- HwasanTagMismatchRef,
418- AArch64MCExpr::VariantKind::VK_GOT_PAGE, OutContext)),
432+ HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
433+ OutContext)),
419434 *STI);
420435 OutStreamer->EmitInstruction (
421436 MCInstBuilder (AArch64::LDRXui)
422437 .addReg (AArch64::X16)
423438 .addReg (AArch64::X16)
424439 .addExpr (AArch64MCExpr::create (
425- HwasanTagMismatchRef,
426- AArch64MCExpr::VariantKind::VK_GOT_LO12, OutContext)),
440+ HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
441+ OutContext)),
427442 *STI);
428443 OutStreamer->EmitInstruction (
429444 MCInstBuilder (AArch64::BR).addReg (AArch64::X16), *STI);
@@ -1096,6 +1111,7 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
10961111 return ;
10971112
10981113 case AArch64::HWASAN_CHECK_MEMACCESS:
1114+ case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
10991115 LowerHWASAN_CHECK_MEMACCESS (*MI);
11001116 return ;
11011117
0 commit comments