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

@ -206,7 +206,7 @@ depend: o/$(MODE)/depend
tags: TAGS HTAGS
o/$(MODE)/.x:
@$(MKDIR) $(@D) && touch $@
@mkdir -p $(@D) && touch $@
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))

Binary file not shown.

View file

@ -46,11 +46,6 @@ V ?= 1
LC_ALL = C
SOURCE_DATE_EPOCH = 0
DD ?= /bin/dd
CP ?= /bin/cp -f
RM ?= /bin/rm -f
SED ?= /bin/sed
MKDIR ?= /bin/mkdir -p
TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
ARFLAGS = rcsD
ZFLAGS ?=
@ -83,41 +78,14 @@ PWD := $(shell pwd)
IMAGE_BASE_VIRTUAL ?= 0x400000
HELLO := $(shell build/hello)
TMPDIR := $(shell build/findtmp)
COMPILE := $(shell build/getcompile)
CCVERSION := $(shell build/getccversion $(CC))
COMPILE := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
export ADDR2LINE
export CCVERSION
export COMPILE
export CP
export DD
export GZ
export IMAGE_BASE_VIRTUAL
export LC_ALL
export LOGFMT
export MKDIR
export MODE
export OBJDUMP
export RM
export SED
export SOURCE_DATE_EPOCH
export TMPDIR
export V
export ZFLAGS
unexport COMPILER_PATH
unexport CPATH
unexport CPLUS_INCLUDE_PATH
unexport C_INCLUDE_PATH
unexport DEPENDENCIES_OUTPUT
unexport GCC_COMPARE_DEBUG
unexport GCC_EXEC_PREFIX
unexport LANG
unexport LC_CTYPE
unexport LC_MESSAGES
unexport LIBRARY_PATH
unexport OBJC_INCLUDE_PATH
unexport SUNPRO_DEPENDENCIES
FTRACE = \
-pg

View file

@ -130,7 +130,7 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
$(EXAMPLES_OBJS): examples/examples.mk
usr/share/dict/words: usr/share/dict/words.gz
@$(MKDIR) $(dir $@)
@mkdir -p $(@D)
@$(GZ) $(ZFLAGS) -d <$< >$@
.PHONY: o/$(MODE)/examples

View file

@ -39,8 +39,8 @@ wontreturn void exit(int exitcode) {
if (weaken(__cxa_finalize)) {
weaken(__cxa_finalize)(NULL);
}
for (p = *weaken(__fini_array_end); p-- > *weaken(__fini_array_start);) {
((void (*)(void))p)();
for (p = *weaken(__fini_array_end); p > *weaken(__fini_array_start);) {
((void (*)(void))(*--p))();
}
_Exit(exitcode);
}

View file

@ -35,7 +35,9 @@ const char *FindDebugBinary(void) {
unsigned i, len;
char buf[2][PATH_MAX];
static char res[PATH_MAX];
const char *bins[4], *pwd;
const char *bins[4], *pwd, *comdbg;
if (res[0]) return res;
if ((comdbg = emptytonull(getenv("COMDBG")))) return comdbg;
if (res[0]) return res;
bins[0] = program_invocation_name;
bins[1] = (const char *)getauxval(AT_EXECFN);

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
*/

View file

@ -351,8 +351,10 @@ void OpenObject(struct Package *pkg, struct Object *obj, int mode, int prot,
CHECK_NE(-1, (fd = open(&pkg->strings.p[obj->path], (obj->mode = mode))),
"path=%`'s", &pkg->strings.p[obj->path]);
CHECK_NE(-1, fstat(fd, &st));
CHECK_NE(MAP_FAILED, (obj->elf = mmap(NULL, (obj->size = st.st_size), prot,
flags, fd, 0)));
CHECK_NE(
MAP_FAILED,
(obj->elf = mmap(NULL, (obj->size = st.st_size), prot, flags, fd, 0)),
"path=%`'s", &pkg->strings.p[obj->path]);
CHECK_NE(-1, close(fd));
CHECK(IsElf64Binary(obj->elf, obj->size), "path=%`'s",
&pkg->strings.p[obj->path]);