aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/g++spec.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/g++spec.c')
-rw-r--r--gcc/cp/g++spec.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 3a9faa9c1e9..9a107b04ae1 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
#define LIBSTDCXX_STATIC NULL
#endif
+#define VTABLE_LOAD_MODULE_INIT "--whole-archive,-lvtv_init,--no-whole-archive"
+
void
lang_specific_driver (struct cl_decoded_option **in_decoded_options,
unsigned int *in_decoded_options_count,
@@ -112,6 +114,11 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* The total number of arguments with the new stuff. */
unsigned int num_args = 1;
+ /* The command line contains a -fvtable_verify. We need to add the
+ init library if we are linking and if we are adding the stdc++
+ library. */
+ int saw_vtable_verify = 0;
+
argc = *in_decoded_options_count;
decoded_options = *in_decoded_options;
added_libraries = *in_added_libraries;
@@ -237,6 +244,13 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
}
}
break;
+
+ case OPT_fvtable_verify_:
+ if (strcmp (arg, "std") == 0)
+ saw_vtable_verify = 1;
+ else if (strcmp (arg, "preinit") == 0)
+ saw_vtable_verify = 2;
+ break;
}
}
@@ -248,6 +262,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* Add one for shared_libgcc or extra static library. */
num_args = argc + added + need_math + (library > 0) * 4 + 1;
+
+ /* Add two more linker args, '-Wl,-u_vtable_map_vars_start and
+ '-Wl,-u_vtable_map_vars_end. */
+ if (saw_vtable_verify && library > 0)
+ num_args += 2;
+
new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
i = 0;
@@ -310,6 +330,33 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
j++;
}
+ /* Add option to make sure that if we are doing 'std' vtable
+ verification then we link with the libvtv_init library. */
+
+ if (saw_vtable_verify == 1 && library > 0)
+ {
+ generate_option(OPT_Wl_, VTABLE_LOAD_MODULE_INIT, 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ }
+
+ /* If we are doing vtable verification, make sure the linker does
+ not garbage-collect the special symbols that mark the start and
+ end of the ".vtable_map_vars" section in the binary. (See
+ comments in vtv_start.c and vtv_end.c for more details). */
+
+ if (saw_vtable_verify > 0 && library > 0)
+ {
+ generate_option (OPT_Wl_,"-u_vtable_map_vars_start", 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ j++;
+
+ generate_option (OPT_Wl_,"-u_vtable_map_vars_end", 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ j++;
+ }
+
/* Add `-lstdc++' if we haven't already done so. */
if (library > 0)
{