summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common
diff options
context:
space:
mode:
authorDimitry Andric <dimitry@andric.com>2016-03-10 20:22:02 +0000
committerDimitry Andric <dimitry@andric.com>2016-03-10 20:22:02 +0000
commit2a381f5e3fa29e4edcf638fc5b40f35724077eb0 (patch)
treea670e0e9623e419501273920fa25d72f421ee41b /lib/sanitizer_common
parente3d48b6368b6cdb41e72122115337b84a212f7cb (diff)
Retrieve command line arguments and environment correctly on FreeBSD
Summary: Recently I saw the test `TestCases/Posix/print_cmdline.cc` failing on FreeBSD, with "expected string not found in input". This is because asan could not retrieve the command line arguments properly. In `lib/sanitizer_common/sanitizer_linux.cc`, this is taken care of by the `GetArgsAndEnv()` function, but it uses `__libc_stack_end` to get at the required data. This variable does not exist on BSDs; the regular way to retrieve the arguments and environment information is via the `kern.ps_strings` sysctl. I added this functionality in sanitizer_linux.cc, as a separate #ifdef block in `GetArgsAndEnv()`. Also, `ReadNullSepFileToArray()` becomes unused due to this change. (It won't work on FreeBSD anyway, since `/proc` is not mounted by default.) Reviewers: kcc, emaste, joerg, davide Subscribers: llvm-commits, emaste Differential Revision: http://reviews.llvm.org/D17832 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@263157 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 631cdb4d1..f1380041c 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -60,7 +60,10 @@
#include <unistd.h>
#if SANITIZER_FREEBSD
+#include <sys/exec.h>
#include <sys/sysctl.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
#include <machine/atomic.h>
extern "C" {
// <sys/umtx.h> must be included after <errno.h> and <sys/types.h> on
@@ -395,11 +398,13 @@ const char *GetEnv(const char *name) {
#endif
}
+#if !SANITIZER_FREEBSD
extern "C" {
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
}
+#endif
-#if !SANITIZER_GO
+#if !SANITIZER_GO && !SANITIZER_FREEBSD
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -425,6 +430,7 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
#endif
static void GetArgsAndEnv(char ***argv, char ***envp) {
+#if !SANITIZER_FREEBSD
#if !SANITIZER_GO
if (&__libc_stack_end) {
#endif
@@ -439,6 +445,18 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
}
#endif
+#else
+ // On FreeBSD, retrieving the argument and environment arrays is done via the
+ // kern.ps_strings sysctl, which returns a pointer to a structure containing
+ // this information. If the sysctl is not available, a "hardcoded" address,
+ // PS_STRINGS, must be used instead. See also <sys/exec.h>.
+ ps_strings *pss;
+ size_t sz = sizeof(pss);
+ if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1)
+ pss = (ps_strings*)PS_STRINGS;
+ *argv = pss->ps_argvstr;
+ *envp = pss->ps_envstr;
+#endif
}
char **GetArgv() {