1 //===- SanitizerBinaryMetadata.cpp 2 //----------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of SanitizerBinaryMetadata. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h" 15 #include "llvm/CodeGen/MachineFrameInfo.h" 16 #include "llvm/CodeGen/MachineFunction.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/Passes.h" 19 #include "llvm/IR/IRBuilder.h" 20 #include "llvm/IR/MDBuilder.h" 21 #include "llvm/InitializePasses.h" 22 #include "llvm/Pass.h" 23 #include <algorithm> 24 25 using namespace llvm; 26 27 class MachineSanitizerBinaryMetadata : public MachineFunctionPass { 28 public: 29 static char ID; 30 31 MachineSanitizerBinaryMetadata(); 32 bool runOnMachineFunction(MachineFunction &F) override; 33 }; 34 35 INITIALIZE_PASS(MachineSanitizerBinaryMetadata, "machine-sanmd", 36 "Machine Sanitizer Binary Metadata", false, false) 37 38 char MachineSanitizerBinaryMetadata::ID = 0; 39 char &llvm::MachineSanitizerBinaryMetadataID = 40 MachineSanitizerBinaryMetadata::ID; 41 42 MachineSanitizerBinaryMetadata::MachineSanitizerBinaryMetadata() 43 : MachineFunctionPass(ID) { 44 initializeMachineSanitizerBinaryMetadataPass( 45 *PassRegistry::getPassRegistry()); 46 } 47 48 bool MachineSanitizerBinaryMetadata::runOnMachineFunction(MachineFunction &MF) { 49 MDNode *MD = MF.getFunction().getMetadata(LLVMContext::MD_pcsections); 50 if (!MD) 51 return false; 52 const auto &Section = *cast<MDString>(MD->getOperand(0)); 53 if (!Section.getString().equals(kSanitizerBinaryMetadataCoveredSection)) 54 return false; 55 auto &AuxMDs = *cast<MDTuple>(MD->getOperand(1)); 56 // Assume it currently only has features. 57 assert(AuxMDs.getNumOperands() == 1); 58 auto *Features = cast<ConstantAsMetadata>(AuxMDs.getOperand(0))->getValue(); 59 if (!Features->getUniqueInteger()[kSanitizerBinaryMetadataUARBit]) 60 return false; 61 // Calculate size of stack args for the function. 62 int64_t Size = 0; 63 uint64_t Align = 0; 64 const MachineFrameInfo &MFI = MF.getFrameInfo(); 65 for (int i = -1; i >= (int)-MFI.getNumFixedObjects(); --i) { 66 Size = std::max(Size, MFI.getObjectOffset(i) + MFI.getObjectSize(i)); 67 Align = std::max(Align, MFI.getObjectAlign(i).value()); 68 } 69 Size = (Size + Align - 1) & ~(Align - 1); 70 auto &F = MF.getFunction(); 71 IRBuilder<> IRB(F.getContext()); 72 MDBuilder MDB(F.getContext()); 73 // Keep the features and append size of stack args to the metadata. 74 F.setMetadata(LLVMContext::MD_pcsections, 75 MDB.createPCSections( 76 {{Section.getString(), {Features, IRB.getInt32(Size)}}})); 77 return false; 78 } 79