Skip to content

Commit fc22205

Browse files
committed
Avoid explicitly passing -pie/-no-pie to GCC when not linking an executable
GCC has a weird behavior where passing -pie/-no-pie forces the compiler to produce an executable even when we are not intending to produce one (e.g., it ignores the -shared flag). This seems like a bug in GCC, but I'm too lazy to report it.
1 parent aef79b0 commit fc22205

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

tools/gcc-wrapper/main.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ static const char GCC_OPT_L[] = "-l";
6666
static const char GCC_OPT_V[] = "-v";
6767
static const char GCC_OPT_D[] = "-D";
6868
static const char GCC_OPT_O[] = "-o";
69+
static const char GCC_OPT_C[] = "-c";
70+
static const char GCC_OPT_R[] = "-r";
71+
static const char GCC_OPT_S[] = "-S";
72+
static const char GCC_OPT_E[] = "-E";
73+
static const char GCC_OPT_M[] = "-M";
74+
static const char GCC_OPT_MM[] = "-MM";
75+
static const char GCC_OPT_SHARED[] = "-shared";
76+
static const char GCC_OPT_F_SYNTAX_ONLY[] = "-fsyntax-only";
6977
static const char GCC_OPT_OS[] = "-Os";
7078
static const char GCC_OPT_L_RT[] = "-lrt";
7179
static const char GCC_OPT_FSANITIZE[] = "-fsanitize=";
@@ -617,6 +625,9 @@ int main(int argc, char* argv[], char* envp[]) {
617625

618626
int have_rt_library = 0;
619627

628+
int linking = 1;
629+
int linking_shared = 0;
630+
620631
char** args = NULL;
621632
char* arg = NULL;
622633

@@ -725,7 +736,11 @@ int main(int argc, char* argv[], char* envp[]) {
725736
for (index = 0; index < (size_t) argc; index++) {
726737
cur = argv[index];
727738

728-
if (strncmp(cur, GCC_OPT_FSANITIZE, strlen(GCC_OPT_FSANITIZE)) == 0) {
739+
if (strcmp(cur, GCC_OPT_C) == 0 || strcmp(cur, GCC_OPT_R) == 0 || strcmp(cur, GCC_OPT_S) == 0 || strcmp(cur, GCC_OPT_E) == 0 || strcmp(cur, GCC_OPT_M) == 0 || strcmp(cur, GCC_OPT_MM) == 0 || strcmp(cur, GCC_OPT_F_SYNTAX_ONLY) == 0) {
740+
linking = 0;
741+
} else if (strcmp(cur, GCC_OPT_SHARED) == 0) {
742+
linking_shared = 1;
743+
} else if (strncmp(cur, GCC_OPT_FSANITIZE, strlen(GCC_OPT_FSANITIZE)) == 0) {
729744
address_sanitizer = 1;
730745
} else if (strncmp(cur, GCC_OPT_F_USE_LD, strlen(GCC_OPT_F_USE_LD)) == 0) {
731746
override_linker = 1;
@@ -989,7 +1004,7 @@ int main(int argc, char* argv[], char* envp[]) {
9891004
These libraries rely on libgcc. If we are going to statically link with them,
9901005
we should statically link with libgcc as well.
9911006
*/
992-
if (wants_force_static && (wants_libcxx || wants_libitm || wants_libgomp) && !wants_static_libgcc) {
1007+
if ((linking && wants_force_static) && (wants_libcxx || wants_libitm || wants_libgomp) && !wants_static_libgcc) {
9931008
kargv[kargc++] = (char*) GCC_OPT_STATIC_LIBGCC;
9941009
}
9951010

@@ -1173,7 +1188,7 @@ int main(int argc, char* argv[], char* envp[]) {
11731188
11741189
- https://web.archive.org/web/0/https://source.android.com/security/enhancements/enhancements41
11751190
*/
1176-
if (LIBC_VERSION(libc_major, libc_minor) < LIBC_VERSION(16, 0)) {
1191+
if ((linking && !linking_shared) && LIBC_VERSION(libc_major, libc_minor) < LIBC_VERSION(16, 0)) {
11771192
kargv[kargc++] = (char*) GCC_OPT_NO_PIE;
11781193
}
11791194
#endif
@@ -1610,7 +1625,7 @@ int main(int argc, char* argv[], char* envp[]) {
16101625
16111626
FIXME: Figure out a way to detect when we are not being invoked by Gradle and avoid copying the libraries when we are not building APKs.
16121627
*/
1613-
if (!wants_force_static && known_clang(cc) && output_directory != NULL) {
1628+
if (linking && !wants_force_static && known_clang(cc) && output_directory != NULL) {
16141629
/* libatomic */
16151630
err = copy_shared_library(sysroot_library_directory, output_directory, LIBATOMIC_SHARED, LIBATOMIC_SHARED);
16161631

0 commit comments

Comments
 (0)