SanitizerBinaryMetadata.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
  14. #include "llvm/CodeGen/MachineFrameInfo.h"
  15. #include "llvm/CodeGen/MachineFunction.h"
  16. #include "llvm/CodeGen/MachineFunctionPass.h"
  17. #include "llvm/CodeGen/Passes.h"
  18. #include "llvm/IR/IRBuilder.h"
  19. #include "llvm/IR/MDBuilder.h"
  20. #include "llvm/InitializePasses.h"
  21. #include "llvm/Pass.h"
  22. #include <algorithm>
  23. using namespace llvm;
  24. namespace {
  25. class MachineSanitizerBinaryMetadata : public MachineFunctionPass {
  26. public:
  27. static char ID;
  28. MachineSanitizerBinaryMetadata();
  29. bool runOnMachineFunction(MachineFunction &F) override;
  30. };
  31. } // namespace
  32. INITIALIZE_PASS(MachineSanitizerBinaryMetadata, "machine-sanmd",
  33. "Machine Sanitizer Binary Metadata", false, false)
  34. char MachineSanitizerBinaryMetadata::ID = 0;
  35. char &llvm::MachineSanitizerBinaryMetadataID =
  36. MachineSanitizerBinaryMetadata::ID;
  37. MachineSanitizerBinaryMetadata::MachineSanitizerBinaryMetadata()
  38. : MachineFunctionPass(ID) {
  39. initializeMachineSanitizerBinaryMetadataPass(
  40. *PassRegistry::getPassRegistry());
  41. }
  42. bool MachineSanitizerBinaryMetadata::runOnMachineFunction(MachineFunction &MF) {
  43. MDNode *MD = MF.getFunction().getMetadata(LLVMContext::MD_pcsections);
  44. if (!MD)
  45. return false;
  46. const auto &Section = *cast<MDString>(MD->getOperand(0));
  47. if (!Section.getString().equals(kSanitizerBinaryMetadataCoveredSection))
  48. return false;
  49. auto &AuxMDs = *cast<MDTuple>(MD->getOperand(1));
  50. // Assume it currently only has features.
  51. assert(AuxMDs.getNumOperands() == 1);
  52. auto *Features = cast<ConstantAsMetadata>(AuxMDs.getOperand(0))->getValue();
  53. if (!Features->getUniqueInteger()[kSanitizerBinaryMetadataUARBit])
  54. return false;
  55. // Calculate size of stack args for the function.
  56. int64_t Size = 0;
  57. uint64_t Align = 0;
  58. const MachineFrameInfo &MFI = MF.getFrameInfo();
  59. for (int i = -1; i >= (int)-MFI.getNumFixedObjects(); --i) {
  60. Size = std::max(Size, MFI.getObjectOffset(i) + MFI.getObjectSize(i));
  61. Align = std::max(Align, MFI.getObjectAlign(i).value());
  62. }
  63. Size = (Size + Align - 1) & ~(Align - 1);
  64. auto &F = MF.getFunction();
  65. IRBuilder<> IRB(F.getContext());
  66. MDBuilder MDB(F.getContext());
  67. // Keep the features and append size of stack args to the metadata.
  68. F.setMetadata(LLVMContext::MD_pcsections,
  69. MDB.createPCSections(
  70. {{Section.getString(), {Features, IRB.getInt32(Size)}}}));
  71. return false;
  72. }