diff options
Diffstat (limited to 'gcc/cp/g++spec.c')
-rw-r--r-- | gcc/cp/g++spec.c | 47 |
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) { |