[llvm-branch-commits] [compiler-rt] f625ab2 - [sanitizer] Intercept glibc's argp_parse()

2023-03-02 Thread Ilya Leoshkevich via llvm-branch-commits

Author: Ilya Leoshkevich
Date: 2023-02-24T14:15:58+01:00
New Revision: f625ab2c6943b1c381ff17fed0f4d5abc0bc10f3

URL: 
https://github.com/llvm/llvm-project/commit/f625ab2c6943b1c381ff17fed0f4d5abc0bc10f3
DIFF: 
https://github.com/llvm/llvm-project/commit/f625ab2c6943b1c381ff17fed0f4d5abc0bc10f3.diff

LOG: [sanitizer] Intercept glibc's argp_parse()

Glibc provides the argp_parse() function for parsing command line
arguments [1].

Indicate that argc/argv are read from and arg_index is written to.
Strictly speaking, we also need to indicate that argp is read from,
but this would require describing its layout, and most people use a
static initializer there, so it's not worth the effort.

[1] https://www.gnu.org/software/libc/manual/html_node/Argp.html

Differential Revision: https://reviews.llvm.org/D143330

Added: 
compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c

Modified: 
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Removed: 




diff  --git 
a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc 
b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 9fc56238a64fc..51703a34f0e9b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -10375,6 +10375,25 @@ INTERCEPTOR(void, hexdump, const void *ptr, int 
length, const char *header, int
 #define INIT_HEXDUMP
 #endif
 
+#if SANITIZER_INTERCEPT_ARGP_PARSE
+INTERCEPTOR(int, argp_parse, const struct argp *argp, int argc, char **argv,
+unsigned flags, int *arg_index, void *input) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, argp_parse, argp, argc, argv, flags, arg_index,
+   input);
+  for (int i = 0; i < argc; i++)
+COMMON_INTERCEPTOR_READ_RANGE(ctx, argv[i], internal_strlen(argv[i]) + 1);
+  int res = REAL(argp_parse)(argp, argc, argv, flags, arg_index, input);
+  if (!res && arg_index)
+COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg_index, sizeof(int));
+  return res;
+}
+
+#define INIT_ARGP_PARSE COMMON_INTERCEPT_FUNCTION(argp_parse);
+#else
+#define INIT_ARGP_PARSE
+#endif
+
 #include "sanitizer_common_interceptors_netbsd_compat.inc"
 
 static void InitializeCommonInterceptors() {
@@ -10694,6 +10713,7 @@ static void InitializeCommonInterceptors() {
   INIT_UNAME;
   INIT___XUNAME;
   INIT_HEXDUMP;
+  INIT_ARGP_PARSE;
 
   INIT___PRINTF_CHK;
 }

diff  --git 
a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h 
b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 814ff462d1cf5..eb39fabfd5983 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -592,6 +592,7 @@
 #define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD
 #define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD
 #define SANITIZER_INTERCEPT_HEXDUMP SI_FREEBSD
+#define SANITIZER_INTERCEPT_ARGP_PARSE SI_GLIBC
 
 // This macro gives a way for downstream users to override the above
 // interceptor macros irrespective of the platform they are on. They have

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c 
b/compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
new file mode 100644
index 0..b3e57cf5c8971
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
@@ -0,0 +1,57 @@
+// RUN: %clang %s -o %t && %run %t -o baz
+
+#include 
+#include 
+#include 
+#include 
+
+struct test {
+  const char *option_value;
+};
+
+static const struct argp_option options[] = {
+{"option", 'o', "OPTION", 0, "Option", 0},
+{NULL, 0, NULL, 0, NULL, 0},
+};
+
+static error_t parser(int key, char *arg, struct argp_state *state) {
+  if (key == 'o') {
+((struct test *)(state->input))->option_value = arg;
+return 0;
+  }
+  return ARGP_ERR_UNKNOWN;
+}
+
+static struct argp argp = {.options = options, .parser = parser};
+
+void test_nulls(char *argv0) {
+  char *argv[] = {argv0, NULL};
+  int res = argp_parse(NULL, 1, argv, 0, NULL, NULL);
+  assert(res == 0);
+}
+
+void test_synthetic(char *argv0) {
+  char *argv[] = {argv0, "-o", "foo", "bar", NULL};
+  struct test t = {NULL};
+  int arg_index;
+  int res = argp_parse(&argp, 4, argv, 0, &arg_index, &t);
+  assert(res == 0);
+  assert(arg_index == 3);
+  assert(strcmp(t.option_value, "foo") == 0);
+}
+
+void test_real(int argc, char **argv) {
+  struct test t = {NULL};
+  int arg_index;
+  int res = argp_parse(&argp, argc, argv, 0, &arg_index, &t);
+  assert(res == 0);
+  assert(arg_index == 3);
+  assert(strcmp(t.option_value, "baz") == 0);
+}
+
+int main(int argc, char **argv) {
+  test_nulls(argv[0]);
+  test_synthetic(argv[0]);
+  test_real(argc, argv);
+  return EXIT_SUCCESS;
+}



___

[llvm-branch-commits] [clang] e8559b2 - endbr

2023-03-02 Thread Ilya Leoshkevich via llvm-branch-commits

Author: Ilya Leoshkevich
Date: 2023-02-24T19:09:23+01:00
New Revision: e8559b2e524b9ee0b6f3fa86643a9c05037ebcc4

URL: 
https://github.com/llvm/llvm-project/commit/e8559b2e524b9ee0b6f3fa86643a9c05037ebcc4
DIFF: 
https://github.com/llvm/llvm-project/commit/e8559b2e524b9ee0b6f3fa86643a9c05037ebcc4.diff

LOG: endbr

Added: 
llvm/lib/Target/SystemZ/SystemZEndbr.cpp

Modified: 
clang/lib/Basic/Targets/SystemZ.h
llvm/lib/Target/SystemZ/CMakeLists.txt
llvm/lib/Target/SystemZ/SystemZ.h
llvm/lib/Target/SystemZ/SystemZInstrInfo.td
llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp

Removed: 




diff  --git a/clang/lib/Basic/Targets/SystemZ.h 
b/clang/lib/Basic/Targets/SystemZ.h
index 3df4284d4c4f4..4c516a5196bf8 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -209,6 +209,11 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public 
TargetInfo {
   int getEHDataRegisterNumber(unsigned RegNo) const override {
 return RegNo < 4 ? 6 + RegNo : -1;
   }
+
+  bool
+  checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
+return true;
+  };
 };
 } // namespace targets
 } // namespace clang

diff  --git a/llvm/lib/Target/SystemZ/CMakeLists.txt 
b/llvm/lib/Target/SystemZ/CMakeLists.txt
index ba845a74949fa..4de38ff391587 100644
--- a/llvm/lib/Target/SystemZ/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_target(SystemZCodeGen
   SystemZConstantPoolValue.cpp
   SystemZCopyPhysRegs.cpp
   SystemZElimCompare.cpp
+  SystemZEndbr.cpp
   SystemZFrameLowering.cpp
   SystemZHazardRecognizer.cpp
   SystemZISelDAGToDAG.cpp

diff  --git a/llvm/lib/Target/SystemZ/SystemZ.h 
b/llvm/lib/Target/SystemZ/SystemZ.h
index cdd2850ad8e17..4463e1231b104 100644
--- a/llvm/lib/Target/SystemZ/SystemZ.h
+++ b/llvm/lib/Target/SystemZ/SystemZ.h
@@ -197,6 +197,7 @@ FunctionPass 
*createSystemZLDCleanupPass(SystemZTargetMachine &TM);
 FunctionPass *createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM);
 FunctionPass *createSystemZPostRewritePass(SystemZTargetMachine &TM);
 FunctionPass *createSystemZTDCPass();
+FunctionPass *createSystemZEndbrPass();
 
 void initializeSystemZCopyPhysRegsPass(PassRegistry &);
 void initializeSystemZDAGToDAGISelPass(PassRegistry &);

diff  --git a/llvm/lib/Target/SystemZ/SystemZEndbr.cpp 
b/llvm/lib/Target/SystemZ/SystemZEndbr.cpp
new file mode 100644
index 0..1d6119de4cd36
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/SystemZEndbr.cpp
@@ -0,0 +1,66 @@
+//=== SystemZEndbr.cpp - 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "SystemZ.h"
+#include "SystemZSubtarget.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "systemz-endbr"
+
+namespace {
+class SystemzEndbrPass : public MachineFunctionPass {
+public:
+  SystemzEndbrPass() : MachineFunctionPass(ID) {}
+
+  StringRef getPassName() const override {
+return "SystemZ ENDBR";
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+  static char ID;
+};
+}
+
+FunctionPass *llvm::createSystemZEndbrPass() {
+  return new SystemzEndbrPass();
+}
+
+char SystemzEndbrPass::ID = 0;
+
+bool SystemzEndbrPass::runOnMachineFunction(MachineFunction &MF) {
+  if (!MF.getMMI().getModule()->getModuleFlag("cf-protection-branch"))
+return false;
+
+  SmallPtrSet JumpTableTargets;
+  if (const MachineJumpTableInfo *JTI = MF.getJumpTableInfo())
+for (const MachineJumpTableEntry &JTE : JTI->getJumpTables())
+  for (const MachineBasicBlock *MBB : JTE.MBBs)
+JumpTableTargets.insert(MBB);
+
+  const SystemZSubtarget &SubTarget = MF.getSubtarget();
+  const SystemZInstrInfo *TII = SubTarget.getInstrInfo();
+  int Count = 0;
+  for (MachineBasicBlock &MBB : MF) {
+if (&MBB == &MF.front() ||
+MBB.hasAddressTaken() ||
+MBB.isEHPad() ||
+JumpTableTargets.count(&MBB)) {
+  MachineBasicBlock::iterator I = MBB.begin();
+  BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(SystemZ::ENDBR));
+  Count++;
+}
+  }
+
+  return Count;
+}

diff  --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td 
b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index c53cb7cadadb9..69fa5de664c23 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -124,6 +124,12 @@ def JNOP : InstAlias<"jnop\t$RI2", (BRCAsm 0, 
brtarget16:$RI2), 0>;
 // jgnop on att ; jlnop on hlasm
 def JGNOP : InstAlias<"{jgnop|jlnop}\t$RI2", (BRCL

[llvm-branch-commits] [llvm] d58f112 - Prevent FENTRY_CALL reordering

2020-12-08 Thread Ilya Leoshkevich via llvm-branch-commits

Author: Ilya Leoshkevich
Date: 2020-12-09T00:59:01+01:00
New Revision: d58f112ce03877f73200591cd3c9b38e41e46afe

URL: 
https://github.com/llvm/llvm-project/commit/d58f112ce03877f73200591cd3c9b38e41e46afe
DIFF: 
https://github.com/llvm/llvm-project/commit/d58f112ce03877f73200591cd3c9b38e41e46afe.diff

LOG: Prevent FENTRY_CALL reordering

FEntryInserter prepends FENTRY_CALL to the first basic block. In case
there are other instructions, PostRA Machine Instruction Scheduler can
move FENTRY_CALL call around. This actually occurs on SystemZ (see the
testcase). This is bad for the following reasons:

* FENTRY_CALL clobbers registers.
* Linux Kernel depends on whatever FENTRY_CALL expands to to be the very
  first instruction in the function.

Fix by adding isCall attribute to FENTRY_CALL, which prevents reordering
by making it a scheduling boundary for PostRA Machine Instruction
Scheduler.

Reviewed By: niravd

Differential Revision: https://reviews.llvm.org/D91218

Added: 
llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll

Modified: 
llvm/include/llvm/Target/Target.td
llvm/lib/CodeGen/MachineInstr.cpp

Removed: 




diff  --git a/llvm/include/llvm/Target/Target.td 
b/llvm/include/llvm/Target/Target.td
index 9664f70c7a02..1c97d70a477f 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1282,6 +1282,7 @@ def FENTRY_CALL : StandardPseudoInstruction {
   let InOperandList = (ins);
   let AsmString = "# FEntry call";
   let usesCustomInserter = true;
+  let isCall = true;
   let mayLoad = true;
   let mayStore = true;
   let hasSideEffects = true;

diff  --git a/llvm/lib/CodeGen/MachineInstr.cpp 
b/llvm/lib/CodeGen/MachineInstr.cpp
index fd658cdb41b9..900abd2b260d 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -713,6 +713,7 @@ bool MachineInstr::isCandidateForCallSiteEntry(QueryType 
Type) const {
   case TargetOpcode::PATCHPOINT:
   case TargetOpcode::STACKMAP:
   case TargetOpcode::STATEPOINT:
+  case TargetOpcode::FENTRY_CALL:
 return false;
   }
   return true;

diff  --git a/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll 
b/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
new file mode 100644
index ..e78c5aad0240
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
@@ -0,0 +1,22 @@
+; Test that compiling with fentry and debuginfo works.
+;
+; RUN: llc %s -mtriple=s390x-linux-gnu -o - -verify-machineinstrs
+
+define dso_local void @_Z1av() local_unnamed_addr #0 !dbg !7 {
+entry:
+  ret void
+}
+
+attributes #0 = { norecurse nounwind readnone "fentry-call"="true" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, 
producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, 
emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: 
None)
+!1 = !DIFile(filename: "a.cpp", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DISubprogram(name: "a", linkageName: "_Z1av", scope: !1, file: 
!1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | 
DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: 
!0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}

diff  --git a/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll 
b/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll
new file mode 100644
index ..f8a9409ed84e
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll
@@ -0,0 +1,19 @@
+; RUN: llc %s -mtriple=s390x-linux-gnu -mcpu=zEC12 -o - -verify-machineinstrs \
+; RUN:   | FileCheck %s
+
+@PawnTT = dso_local local_unnamed_addr global [2048 x i8] zeroinitializer, 
align 2
+
+define dso_local void @clear_pawn_tt() local_unnamed_addr #0 {
+entry:
+  call void @llvm.memset.p0i8.i64(i8* nonnull align 2 dereferenceable(2048) 
getelementptr inbounds ([2048 x i8], [2048 x i8]* @PawnTT, i64 0, i64 0), i8 0, 
i64 2048, i1 false)
+  ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 
immarg) #1
+
+attributes #0 = { nofree nounwind writeonly "fentry-call"="true" }
+attributes #1 = { argmemonly nofree nosync nounwind willreturn writeonly }
+
+; CHECK: clear_pawn_tt: # @clear_pawn_tt
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: brasl %r0, __fentry__@PLT



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits