src/hotspot/os/linux/decoder_linux.cpp
changeset 48975 2c35fd3c5789
parent 47765 b7c7428eaab9
--- a/src/hotspot/os/linux/decoder_linux.cpp	Wed Feb 14 16:42:00 2018 +0100
+++ b/src/hotspot/os/linux/decoder_linux.cpp	Wed Feb 14 17:20:59 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 
 #include "jvm.h"
 #include "utilities/decoder_elf.hpp"
+#include "utilities/elfFile.hpp"
 
 #include <cxxabi.h>
 
@@ -50,3 +51,38 @@
   return false;
 }
 
+// Returns true if the elf file is marked NOT to require an executable stack,
+// or if the file could not be opened.
+// Returns false if the elf file requires an executable stack, the stack flag
+// is not set at all, or if the file can not be read.
+bool ElfFile::specifies_noexecstack(const char* filepath) {
+  if (filepath == NULL) return true;
+
+  FILE* file = fopen(filepath, "r");
+  if (file == NULL)  return true;
+
+  // AARCH64 defaults to noexecstack. All others default to execstack.
+  bool result = AARCH64_ONLY(true) NOT_AARCH64(false);
+
+  // Read file header
+  Elf_Ehdr head;
+  if (fread(&head, sizeof(Elf_Ehdr), 1, file) == 1 &&
+      is_elf_file(head) &&
+      fseek(file, head.e_phoff, SEEK_SET) == 0) {
+
+    // Read program header table
+    Elf_Phdr phdr;
+    for (int index = 0; index < head.e_phnum; index ++) {
+      if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, file) != 1) {
+        result = false;
+        break;
+      }
+      if (phdr.p_type == PT_GNU_STACK) {
+        result = (phdr.p_flags == (PF_R | PF_W));
+        break;
+      }
+    }
+  }
+  fclose(file);
+  return result;
+}