aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link.cpp36
-rw-r--r--src/target.cpp8
-rw-r--r--src/target.hpp1
3 files changed, 34 insertions, 11 deletions
diff --git a/src/link.cpp b/src/link.cpp
index 41fb2ca415..07258943ca 100644
--- a/src/link.cpp
+++ b/src/link.cpp
@@ -1653,6 +1653,10 @@ static void construct_linker_job_elf(LinkJob *lj) {
soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
}
+ if (target_requires_pie(g->zig_target) && !is_dyn_lib) {
+ lj->args.append("-pie");
+ }
+
lj->args.append("-o");
lj->args.append(buf_ptr(&g->output_file_path));
@@ -1660,8 +1664,14 @@ static void construct_linker_job_elf(LinkJob *lj) {
const char *crt1o;
if (g->zig_target->os == OsNetBSD) {
crt1o = "crt0.o";
+ } else if (target_is_android(g->zig_target)) {
+ crt1o = "crtbegin_dynamic.o";
} else if (!g->have_dynamic_link) {
- crt1o = "crt1.o";
+ if (target_is_android(g->zig_target)) {
+ crt1o = "crtbegin.o";
+ } else {
+ crt1o = "crt1.o";
+ }
} else {
crt1o = "Scrt1.o";
}
@@ -1768,21 +1778,27 @@ static void construct_linker_job_elf(LinkJob *lj) {
if (!g->have_dynamic_link) {
lj->args.append("--start-group");
lj->args.append("-lgcc");
- lj->args.append("-lgcc_eh");
+ if (!target_is_android(g->zig_target)) {
+ lj->args.append("-lgcc_eh");
+ }
lj->args.append("-lc");
lj->args.append("-lm");
lj->args.append("--end-group");
} else {
lj->args.append("-lgcc");
- lj->args.append("--as-needed");
- lj->args.append("-lgcc_s");
- lj->args.append("--no-as-needed");
+ if (!target_is_android(g->zig_target)) {
+ lj->args.append("--as-needed");
+ lj->args.append("-lgcc_s");
+ lj->args.append("--no-as-needed");
+ }
lj->args.append("-lc");
lj->args.append("-lm");
lj->args.append("-lgcc");
- lj->args.append("--as-needed");
- lj->args.append("-lgcc_s");
- lj->args.append("--no-as-needed");
+ if (!target_is_android(g->zig_target)) {
+ lj->args.append("--as-needed");
+ lj->args.append("-lgcc_s");
+ lj->args.append("--no-as-needed");
+ }
}
if (g->zig_target->os == OsFreeBSD) {
@@ -1805,7 +1821,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
}
// crt end
- if (lj->link_in_crt && target_libc_needs_crti_crtn(g->zig_target)) {
+ if (target_is_android(g->zig_target) && g->have_dynamic_link) {
+ lj->args.append(get_libc_crt_file(g, "crtend_android.o"));
+ } else if (lj->link_in_crt && target_libc_needs_crti_crtn(g->zig_target)) {
lj->args.append(get_libc_crt_file(g, "crtn.o"));
}
diff --git a/src/target.cpp b/src/target.cpp
index 3f7bd75011..e2d0874945 100644
--- a/src/target.cpp
+++ b/src/target.cpp
@@ -1590,10 +1590,14 @@ bool target_supports_stack_probing(const ZigTarget *target) {
bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
// This function returns whether non-pic code is completely invalid on the given target.
- return target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) ||
+ return target_is_android(target) || target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) ||
(linking_libc && target_is_glibc(target));
}
+bool target_requires_pie(const ZigTarget *target) {
+ return target_is_android(target);
+}
+
bool target_is_glibc(const ZigTarget *target) {
return target->os == OsLinux && target_abi_is_gnu(target->abi);
}
@@ -1876,7 +1880,7 @@ bool target_supports_libunwind(const ZigTarget *target) {
}
bool target_libc_needs_crti_crtn(const ZigTarget *target) {
- if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64) {
+ if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64 || target_is_android(target)) {
return false;
}
return true;
diff --git a/src/target.hpp b/src/target.hpp
index c157b40011..c5c285a8db 100644
--- a/src/target.hpp
+++ b/src/target.hpp
@@ -182,6 +182,7 @@ const char *target_libc_generic_name(const ZigTarget *target);
bool target_is_libc_lib_name(const ZigTarget *target, const char *name);
bool target_supports_fpic(const ZigTarget *target);
bool target_requires_pic(const ZigTarget *target, bool linking_libc);
+bool target_requires_pie(const ZigTarget *target);
bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi);
bool target_abi_is_musl(ZigLLVM_EnvironmentType abi);
bool target_is_glibc(const ZigTarget *target);