Fix some more build issues (#43)

We're now scrubbing environment variables in compile.com since gnu make
was not behaving as expected. It also appears there was a regression in
recent revisions that caused ASAN to be turned off for most binaries in
dbg mode, which has now been fixed. Cosmopolitan is fully ASAN hardened
down to the lowest level libraries and it doesn't need any interceptors
This commit is contained in:
Justine Tunney 2021-02-20 12:39:39 -08:00
parent 3e1fd1d962
commit e85aeda4ba
8 changed files with 132 additions and 91 deletions

View file

@ -63,12 +63,13 @@ FLAGS\n\
\n\
-A ACTION specifies short command name for V=0 logging\n\
-T TARGET specifies target name for V=0 logging\n\
-V NUMBER specifies compiler version\n\
-t touch target on success\n\
-n do nothing (used to prime the executable)\n\
-? print help\n\
\n"
struct Flags {
struct Args {
size_t n;
char **p;
};
@ -92,6 +93,7 @@ bool wantubsan;
bool touchtarget;
char *cmd;
char *comdbg;
char *cachedcmd;
char *originalcmd;
char *colorflag;
@ -106,9 +108,18 @@ int columns;
sigset_t mask;
sigset_t savemask;
struct Flags flags;
struct Args env;
struct Args args;
struct Command command;
const char *const kSafeEnv[] = {
"ADDR2LINE", // needed by GetAddr2linePath
"MAKEFLAGS", // needed by IsRunningUnderMake
"PWD", // just seems plain needed
"TERM", // needed by IsTerminalInarticulate
"TMPDIR", // needed by compiler
};
const char *const kGccOnlyFlags[] = {
"--nocompress-debug-sections",
"--noexecstack",
@ -173,6 +184,27 @@ char *DescribeCommand(void) {
return basename(cmd);
}
bool IsSafeEnv(const char *s) {
const char *p;
int n, m, l, r, x;
p = strchr(s, '=');
n = p ? p - s : -1;
l = 0;
r = ARRAYLEN(kSafeEnv) - 1;
while (l <= r) {
m = (l + r) >> 1;
x = strncmp(s, kSafeEnv[m], n);
if (x < 0) {
r = m - 1;
} else if (x > 0) {
l = m + 1;
} else {
return true;
}
}
return false;
}
bool IsGccOnlyFlag(const char *s) {
int m, l, r, x;
l = 0;
@ -201,10 +233,24 @@ bool IsGccOnlyFlag(const char *s) {
return false;
}
void AddFlag(char *s) {
bool FileExistsAndIsNewerThan(const char *filepath, const char *thanpath) {
struct stat st1, st2;
if (stat(filepath, &st1) == -1) return false;
if (stat(thanpath, &st2) == -1) return false;
if (st1.st_mtim.tv_sec < st2.st_mtim.tv_sec) return false;
if (st1.st_mtim.tv_sec > st2.st_mtim.tv_sec) return true;
return st1.st_mtim.tv_nsec >= st2.st_mtim.tv_nsec;
}
void AddEnv(char *s) {
env.p = realloc(env.p, ++env.n * sizeof(*env.p));
env.p[env.n - 1] = s;
}
void AddArg(char *s) {
size_t n;
flags.p = realloc(flags.p, ++flags.n * sizeof(*flags.p));
flags.p[flags.n - 1] = s;
args.p = realloc(args.p, ++args.n * sizeof(*args.p));
args.p[args.n - 1] = s;
if (s) {
n = strlen(s);
if (command.n) {
@ -229,7 +275,7 @@ int Launch(void) {
if ((pid = vfork()) == -1) exit(errno);
if (!pid) {
sigprocmask(SIG_SETMASK, &savemask, NULL);
execv(cmd, flags.p);
execve(cmd, args.p, env.p);
_exit(127);
}
while (waitpid(pid, &ws, 0) == -1) {
@ -239,14 +285,14 @@ int Launch(void) {
}
int main(int argc, char *argv[]) {
char *p;
size_t n;
char *p, **envp;
int i, ws, rc, opt;
/*
* parse prefix arguments
*/
while ((opt = getopt(argc, argv, "?hntA:T:")) != -1) {
while ((opt = getopt(argc, argv, "?hntA:T:V:")) != -1) {
switch (opt) {
case 'n':
exit(0);
@ -259,6 +305,9 @@ int main(int argc, char *argv[]) {
case 'T':
target = optarg;
break;
case 'V':
ccversion = atoi(optarg);
break;
case '?':
case 'h':
write(1, MANUAL, sizeof(MANUAL) - 1);
@ -278,39 +327,38 @@ int main(int argc, char *argv[]) {
if (!(cmd = commandv(cmd, ccpath))) exit(127);
}
ccversion = atoi(firstnonnull(emptytonull(getenv("CCVERSION")), "4"));
isgcc = !!strstr(basename(cmd), "gcc");
isclang = !!strstr(basename(cmd), "clang");
iscc = isgcc | isclang;
/*
* ingest flag arguments
* ingest arguments
*/
for (i = optind; i < argc; ++i) {
if (argv[i][0] != '-') {
AddFlag(argv[i]);
AddArg(argv[i]);
continue;
}
if (!strcmp(argv[i], "-o")) {
AddFlag(argv[i]);
AddFlag((outpath = argv[++i]));
AddArg(argv[i]);
AddArg((outpath = argv[++i]));
continue;
}
if (!iscc) {
AddFlag(argv[i]);
AddArg(argv[i]);
continue;
}
if (isclang && IsGccOnlyFlag(argv[i])) {
continue;
}
if (!strcmp(argv[i], "-w")) {
AddFlag(argv[i]);
AddFlag("-D__W__");
AddArg(argv[i]);
AddArg("-D__W__");
} else if (!strcmp(argv[i], "-Oz")) {
if (isclang) {
AddFlag(argv[i]);
AddArg(argv[i]);
} else {
AddFlag("-Os");
AddArg("-Os");
}
} else if (!strcmp(argv[i], "-pg")) {
wantpg = true;
@ -328,17 +376,17 @@ int main(int argc, char *argv[]) {
wantframe = false;
} else if (!strcmp(argv[i], "-mno-vzeroupper")) {
if (isgcc) {
AddFlag("-Wa,-msse2avx");
AddFlag("-D__MNO_VZEROUPPER__");
AddArg("-Wa,-msse2avx");
AddArg("-D__MNO_VZEROUPPER__");
} else if (isclang) {
AddFlag("-mllvm");
AddFlag("-x86-use-vzeroupper=0");
AddArg("-mllvm");
AddArg("-x86-use-vzeroupper=0");
}
} else if (!strcmp(argv[i], "-msse2avx")) {
if (isgcc) {
AddFlag(argv[i]);
AddArg(argv[i]);
} else if (isclang) {
AddFlag("-Wa,-msse2avx");
AddArg("-Wa,-msse2avx");
}
} else if (!strcmp(argv[i], "-fsanitize=address")) {
if (isgcc && ccversion >= 6) wantasan = true;
@ -353,7 +401,7 @@ int main(int argc, char *argv[]) {
wantubsan = false;
} else if (startswith(argv[i], "-fsanitize=implicit") &&
strstr(argv[i], "integer")) {
if (isgcc) AddFlag(argv[i]);
if (isgcc) AddArg(argv[i]);
} else if (startswith(argv[i], "-fvect-cost") ||
startswith(argv[i], "-mstringop") ||
startswith(argv[i], "-gz") ||
@ -362,18 +410,18 @@ int main(int argc, char *argv[]) {
startswith(argv[i], "-fvect-cost") ||
startswith(argv[i], "-fvect-cost")) {
if (isgcc && ccversion >= 6) {
AddFlag(argv[i]);
AddArg(argv[i]);
}
} else if (startswith(argv[i], "-fdiagnostic-color=")) {
colorflag = argv[i];
} else if (startswith(argv[i], "-R") ||
!strcmp(argv[i], "-fsave-optimization-record")) {
if (isclang) AddFlag(argv[i]);
if (isclang) AddArg(argv[i]);
} else if (isclang && startswith(argv[i], "--debug-prefix-map")) {
/* llvm doesn't provide a gas interface so simulate w/ clang */
AddFlag(xasprintf("-f%s", argv[i] + 2));
AddArg(xasprintf("-f%s", argv[i] + 2));
} else {
AddFlag(argv[i]);
AddArg(argv[i]);
}
}
if (!outpath) {
@ -381,51 +429,62 @@ int main(int argc, char *argv[]) {
}
/*
* append special flags
* append special args
*/
if (iscc) {
if (isclang) {
/* AddFlag("-fno-integrated-as"); */
AddFlag("-Wno-unused-command-line-argument");
AddFlag("-Wno-incompatible-pointer-types-discards-qualifiers");
/* AddArg("-fno-integrated-as"); */
AddArg("-Wno-unused-command-line-argument");
AddArg("-Wno-incompatible-pointer-types-discards-qualifiers");
}
AddFlag("-no-canonical-prefixes");
AddArg("-no-canonical-prefixes");
if (!IsTerminalInarticulate()) {
AddFlag(firstnonnull(colorflag, "-fdiagnostics-color=always"));
AddArg(firstnonnull(colorflag, "-fdiagnostics-color=always"));
}
if (wantpg && !wantnopg) {
AddFlag("-pg");
AddFlag("-D__PG__");
AddArg("-pg");
AddArg("-D__PG__");
if (wantnop && !isclang) {
AddFlag("-mnop-mcount");
AddFlag("-D__MNOP_MCOUNT__");
AddArg("-mnop-mcount");
AddArg("-D__MNOP_MCOUNT__");
}
if (wantrecord) {
AddFlag("-mrecord-mcount");
AddFlag("-D__MRECORD_MCOUNT__");
AddArg("-mrecord-mcount");
AddArg("-D__MRECORD_MCOUNT__");
}
if (wantfentry) {
AddFlag("-mfentry");
AddFlag("-D__MFENTRY__");
AddArg("-mfentry");
AddArg("-D__MFENTRY__");
}
}
if (wantasan) {
AddFlag("-fsanitize=address");
AddFlag("-D__FSANITIZE_ADDRESS__");
AddArg("-fsanitize=address");
AddArg("-D__FSANITIZE_ADDRESS__");
}
if (wantubsan) {
AddFlag("-fsanitize=undefined");
AddFlag("-fno-data-sections");
AddArg("-fsanitize=undefined");
AddArg("-fno-data-sections");
}
if (wantframe) {
AddFlag("-fno-omit-frame-pointer");
AddArg("-fno-omit-frame-pointer");
}
}
/*
* terminate argument list passed to subprocess
* terminate args
*/
AddFlag(NULL);
AddArg(NULL);
/*
* scrub environment for determinism and great justice
*/
for (envp = environ; *envp; ++envp) {
if (IsSafeEnv(*envp)) {
AddEnv(*envp);
}
}
AddEnv("LC_ALL=C");
AddEnv("SOURCE_DATE_EPOCH=0");
/*
* ensure output directory exists
@ -463,10 +522,15 @@ int main(int argc, char *argv[]) {
/*
* create temporary copy when launching APE binaries
* and we help FindDebugBinary to find debug symbols
*/
if (!IsWindows() && endswith(cmd, ".com")) {
comdbg = xasprintf("%s.dbg", cmd);
cachedcmd = xasprintf("o/%s", cmd);
if (fileexists(cachedcmd)) {
if (fileexists(comdbg)) {
AddEnv(xasprintf("COMDBG=%s", comdbg));
}
if (FileExistsAndIsNewerThan(cachedcmd, cmd)) {
cmd = cachedcmd;
} else {
if (startswith(cmd, "o/")) {
@ -478,6 +542,11 @@ int main(int argc, char *argv[]) {
}
}
/*
* terminate environment
*/
AddEnv(NULL);
/*
* launch command
*/