00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #define __STDC_LIMIT_MACROS
00042 #include <stdint.h>
00043 #include <limits.h>
00044 #include <unistd.h>
00045 #include <fcntl.h>
00046 #include <sys/types.h>
00047 #include <sys/stat.h>
00048 #include <string.h>
00049 #include <errno.h>
00050 #include <vector>
00051
00052 #include <ext/hash_map>
00053
00054 #include <libgen.h>
00055 #include <time.h>
00056 #include <sys/param.h>
00057
00058 #include "linker.h"
00059 #include "process.h"
00060 #include "main.h"
00061 #include "ipc_weak.h"
00062
00063 #include "defs.h"
00064 #include "errors.h"
00065 #include "erglob.h"
00066 #include "glob.h"
00067 #include "tracing.h"
00068 #include "cxx_memory.h"
00069 #include "opcode.h"
00070 #include "wn_core.h"
00071 #include "pu_info.h"
00072 #include "ir_bread.h"
00073
00074 #include "dwarf_DST_mem.h"
00075 #include "ipc_file.h"
00076 #include "ipa_option.h"
00077 #include "ipc_link.h"
00078
00079 #include "lib_phase_dir.h"
00080
00081 #ifdef KEY
00082 #include "ipc_defs.h"
00083 #endif
00084
00085 #pragma weak tos_string
00086 #pragma weak outfilename
00087
00088 using std::vector;
00089 using __gnu_cxx::hash_map;
00090
00091 #if defined(__linux__) || defined(BUILD_OS_DARWIN)
00092 #define _USE_GNU_MAKE_
00093 #endif
00094
00095 #ifdef _USE_GNU_MAKE_
00096 #define TARGET_DELIMITER " : "
00097 #else
00098 #define TARGET_DELIMITER " ! "
00099 #endif
00100
00101 #ifdef KEY
00102 extern char *psclp_arg;
00103 #endif
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static char* makefile_name = 0;
00136 static FILE* makefile = 0;
00137
00138 static vector<const char*>* infiles = 0;
00139 static vector<const char*>* outfiles = 0;
00140 static vector<const char*>* outfiles_fullpath = 0;
00141 static vector<const char*>* commands = 0;
00142 static vector<UINT32>* ProMP_Idx = 0;
00143 static vector<vector<const char*> >* comments = 0;
00144
00145
00146 static char input_symtab_name[PATH_MAX] = "";
00147
00148
00149
00150 static char whirl_symtab_name[PATH_MAX] = "";
00151
00152
00153 static char elf_symtab_name[PATH_MAX] = "";
00154
00155
00156 static const char* symtab_command_line = 0;
00157 static const char* symtab_extra_args = 0;
00158
00159
00160
00161
00162
00163 namespace {
00164 struct eqstr {
00165 bool operator()(const char* s1, const char* s2) const
00166 { return strcmp(s1, s2) == 0; }
00167 };
00168 typedef __gnu_cxx::hash_map<const char*, const char*, __gnu_cxx::hash<const char*>, eqstr>
00169 COMMAND_MAP_TYPE;
00170 }
00171
00172 static COMMAND_MAP_TYPE* command_map;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 static const char* get_extra_args(const char* ipaa_filename);
00187 static const char* get_extra_symtab_args(const ARGV&);
00188 static void exec_smake(char* cmdfile_name);
00189
00190
00191
00192
00193
00194 static const char*ipa_basename(char *name){
00195 const char *bname = basename(name);
00196
00197 while (*bname == '/')
00198 bname++;
00199 return bname;
00200 }
00201
00202
00203
00204
00205
00206 static char* proper_name(char *name){
00207 for(char *i = name; *i; i++) {
00208 if ( *i == '-' ) *i = '_';
00209 }
00210 return name;
00211 }
00212
00213 static const char* abi()
00214 {
00215 #ifdef TARG_MIPS
00216
00217
00218 return IPA_Target_Type == IP_64_bit_ABI ? "-64" : "-n32";
00219 #endif
00220
00221 #ifdef TARG_IA64
00222 return "-i64";
00223 #endif
00224
00225 #ifdef TARG_IA32
00226 return "-i32";
00227 #endif
00228
00229 #ifdef TARG_X8664
00230 return IPA_Target_Type == IP_64_bit_ABI ? "-m64" : "-m32";
00231 #endif
00232
00233 return "-n32";
00234 }
00235
00236 namespace {
00237
00238
00239 bool file_exists(const char* path)
00240 {
00241 if (!path || strlen(path) == 0)
00242 return false;
00243
00244 struct stat buf;
00245 return stat(path, &buf) == 0 && S_ISREG(buf.st_mode);
00246 }
00247
00248 }
00249
00250 #ifdef KEY
00251 static inline bool
00252 looks_like(const char *path, const char *base)
00253 {
00254 int p = strlen(path), b = strlen(base);
00255
00256 return (strcmp(path + p - b, base) == 0 &&
00257 (path[p - b - 1] == '-' || path[p - b - 1] == '/'));
00258 }
00259 #endif
00260
00261 extern "C" void
00262 ipa_compile_init ()
00263 {
00264 Is_True(tmpdir, ("no IPA temp. directory"));
00265
00266 Is_True(infiles == 0 && outfiles == 0 && commands == 0 && comments == 0
00267 && makefile_name == 0 && makefile == 0 && command_map == 0,
00268 ("ipa_compile_init already initialized"));
00269
00270 infiles = CXX_NEW (vector<const char*>, Malloc_Mem_Pool);
00271 outfiles = CXX_NEW (vector<const char*>, Malloc_Mem_Pool);
00272 outfiles_fullpath = CXX_NEW (vector<const char*>, Malloc_Mem_Pool);
00273 commands = CXX_NEW (vector<const char*>, Malloc_Mem_Pool);
00274 comments = CXX_NEW (vector<vector<const char*> >, Malloc_Mem_Pool);
00275
00276 if (infiles == 0 || outfiles == 0 || outfiles_fullpath == 0 ||
00277 commands == 0 || comments == 0)
00278 ErrMsg (EC_No_Mem, "ipa_compile_init");
00279
00280 if (ProMP_Listing)
00281 ProMP_Idx = CXX_NEW (vector<UINT32>, Malloc_Mem_Pool);
00282
00283 char name_buffer[256];
00284 sprintf(name_buffer, "makefile.ipa%ld", (long) getpid());
00285
00286 makefile_name = create_unique_file(name_buffer, 0);
00287 add_to_tmp_file_list (makefile_name);
00288
00289 makefile = fopen(makefile_name, "w");
00290 if (makefile == 0)
00291 ErrMsg (EC_Ipa_Open, makefile_name, strerror(errno));
00292 chmod(makefile_name, 0644);
00293
00294 command_map = CXX_NEW(COMMAND_MAP_TYPE, Malloc_Mem_Pool);
00295 if (command_map == 0)
00296 ErrMsg (EC_No_Mem, "ipa_compile_init");
00297
00298 const char* toolroot = getenv("TOOLROOT");
00299
00300 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
00301
00302 static char* smake_base = ALTBINPATH "/usr/bin/make";
00303
00304 #if defined(VENDOR_PSC)
00305 #include "pathscale_defs.h"
00306 static const char* tmp_cc_name_base = PSC_INSTALL_PREFIX "/bin/" PSC_NAME_PREFIX "cc";
00307 #elif defined(VENDOR_OSP)
00308 static const char* tmp_cc_name_base = "/usr/ia64-sgi-linux/bin/sgicc";
00309 #else
00310 static const char* tmp_cc_name_base;
00311 #endif
00312 static const char* cc_name_base = tmp_cc_name_base;
00313 static const char* cord_name_base= "/usr/bin/gen_cord";
00314 static char my_cc[MAXPATHLEN];
00315 char *where_am_i = getenv("COMPILER_BIN");
00316 int retval;
00317
00318 if (where_am_i) {
00319 tmp_cc_name_base = where_am_i;
00320 cc_name_base = where_am_i;
00321 }
00322
00323 if (my_cc[0] == '\0' &&
00324 (retval = readlink ("/proc/self/exe", my_cc, sizeof(my_cc))) >= 0) {
00325
00326 my_cc[retval] = '\0';
00327
00328 #if !defined(TARG_SL) && !defined(TARG_MIPS)
00329 if (looks_like (my_cc, OPEN64_NAME_PREFIX "cc") ||
00330 looks_like (my_cc, OPEN64_NAME_PREFIX "CC") ||
00331 looks_like (my_cc, OPEN64_NAME_PREFIX "f90")) {
00332 #else
00333 #define SLCC_NAME_PREFIX "sl"
00334 if (looks_like (my_cc, SLCC_NAME_PREFIX "cc") ||
00335 looks_like (my_cc, SLCC_NAME_PREFIX "CC") ||
00336 looks_like (my_cc, SLCC_NAME_PREFIX "f90")) {
00337 #endif
00338 tmp_cc_name_base = my_cc;
00339 cc_name_base = my_cc;
00340 } else if (looks_like (my_cc, "ipa_link")) {
00341 char *s = strrchr(my_cc, '/');
00342 if (s) {
00343 #ifndef TARG_SL
00344 *s = '\0';
00345 s = strrchr(my_cc, '/');
00346 (s) ? *s = '\0' : 0;
00347 s = strrchr(my_cc, '/');
00348 (s) ? *s = '\0' : 0;
00349 s = strrchr(my_cc, '/');
00350 (s) ? *s = '\0' : 0;
00351 s = strrchr(my_cc, '/');
00352 #endif
00353
00354 if (s) {
00355
00356
00357 const char *compiler_name_suffix;
00358 if (!strcmp(IPA_lang, "F77") ||
00359 !strcmp(IPA_lang, "F90")) {
00360 compiler_name_suffix = "f95";
00361 } else if (!strcmp(IPA_lang, "C")) {
00362 compiler_name_suffix = "cc";
00363 } else if (!strcmp(IPA_lang, "CC")) {
00364 compiler_name_suffix = "CC";
00365 } else {
00366 Fail_FmtAssertion ("ipa: unknown language");
00367 }
00368 #if defined(VENDOR_PSC)
00369 strcpy(++s, "bin/" PSC_NAME_PREFIX);
00370 s += strlen("bin/" PSC_NAME_PREFIX);
00371 #elif defined(VENDOR_SL)
00372 strcpy(++s, SLCC_NAME_PREFIX);
00373 s += strlen(SLCC_NAME_PREFIX);
00374 #elif !defined(TARG_MIPS)
00375 strcpy(++s, "bin/" OPEN64_NAME_PREFIX);
00376 s += strlen("bin/" OPEN64_NAME_PREFIX);
00377 #endif
00378 strcpy(s, compiler_name_suffix);
00379
00380 if (file_exists (my_cc)) {
00381 tmp_cc_name_base = my_cc;
00382 cc_name_base = my_cc;
00383 }
00384 }
00385 }
00386 }
00387 }
00388
00389
00390 #define MAKE_STRING "make"
00391
00392 #else
00393
00394 static char* smake_base = "/usr/sbin/smake";
00395 static char* tmp_cc_name_base = "/usr/bin/cc";
00396 static char* cc_name_base = "/usr/bin/cc";
00397 static char* cord_name_base= "/usr/bin/gen_cord";
00398 #define MAKE_STRING "smake"
00399
00400 #endif
00401
00402 (*command_map)["cord"] = cord_name_base;
00403
00404 if (toolroot) {
00405 static char* new_cc_name_base = concat_names((const string)toolroot, (const string)tmp_cc_name_base);
00406 if (file_exists(new_cc_name_base))
00407 (*command_map)["cc"] = new_cc_name_base;
00408 else
00409 (*command_map)["cc"] = cc_name_base;
00410 }
00411 else
00412 (*command_map)["cc"] = cc_name_base;
00413
00414
00415
00416
00417
00418 static const char* smake_name = 0;
00419 {
00420 if (toolroot != 0) {
00421 const char* tmp = concat_names((const string)toolroot, (const string)smake_base);
00422 if (file_exists(tmp))
00423 smake_name = tmp;
00424 }
00425
00426 if (smake_name == 0) {
00427 if (file_exists(smake_base))
00428 smake_name = smake_base;
00429 else
00430 smake_name = MAKE_STRING;
00431 }
00432 }
00433
00434 (*command_map)[MAKE_STRING] = smake_name;
00435
00436 #ifdef TODO
00437 if (IPA_Enable_Cord) {
00438 cord_output_file_name = create_tmp_file ("cord_script");
00439 call_graph_file_name = create_tmp_file ("ipa_cg");
00440 add_to_tmp_file_list (call_graph_file_name);
00441 Call_graph_file = FOPEN (call_graph_file_name, "w");
00442 if (Call_graph_file == 0)
00443 #ifdef TARG_IA64
00444 {
00445 perror(call_graph_file_name);
00446 exit(1);
00447 }
00448 #else
00449 msg (ER_FATAL, ERN_IO_FATAL, call_graph_file_name,
00450 strerror(errno));
00451 #endif
00452 }
00453 #else
00454 DevWarn ("TODO: support ipa-cord");
00455 #endif
00456 }
00457
00458
00459
00460
00461 static void
00462 get_command_line (const IP_FILE_HDR& hdr, ARGV& argv, const char* inpath,
00463 const char* outpath)
00464 {
00465 char* base_addr = (char*)
00466 WN_get_section_base (IP_FILE_HDR_input_map_addr (hdr), WT_COMP_FLAGS);
00467
00468 if (base_addr == (char*) -1)
00469 ErrMsg (EC_IR_Scn_Read, "command line", IP_FILE_HDR_file_name (hdr));
00470
00471 Elf64_Word argc = *((Elf64_Word *) base_addr);
00472 Elf64_Word* args = (Elf64_Word *) (base_addr + sizeof(Elf64_Word));
00473
00474
00475
00476
00477
00478 Is_True(command_map != 0
00479 && command_map->find("cc") != command_map->end()
00480 && (*command_map)["cc"] != 0
00481 && strlen((*command_map)["cc"]) != 0,
00482 ("Full pathname for cc not set up"));
00483
00484 if (argc > 0) {
00485 argv.push_back((*command_map)["cc"]);
00486 #if 0
00487
00488
00489 char* command = base_addr + args[0];
00490
00491
00492
00493 if (command_map->find(command) == command_map->end()) {
00494 char* toolroot = getenv("TOOLROOT");
00495 if (toolroot == 0 || strchr(command, '/') != 0)
00496 (*command_map)[command] = command;
00497 else {
00498 int len = strlen(toolroot) + strlen(command) + 116;
00499 char* buf = static_cast<char*>(malloc(len));
00500 if (!buf)
00501 ErrMsg (EC_No_Mem, "get_command_line");
00502 strcpy(buf, toolroot);
00503
00504 strcat(buf, LIBPATH "/");
00505 strcat(buf, command);
00506
00507 if (!file_exists(buf)) {
00508 BZERO(buf, strlen(buf));
00509 strcpy(buf, toolroot);
00510 strcat(buf, BINPATH "/");
00511 strcat(buf, command);
00512 }
00513
00514 if (!file_exists(buf)) {
00515 BZERO(buf, strlen(buf));
00516 strcpy(buf, toolroot);
00517 strcat(buf, ALTBINPATH "/");
00518 }
00519 (*command_map)[command] = buf;
00520 }
00521 }
00522
00523 Is_True(command_map->find(command) != command_map->end()
00524 && (*command_map)[command] != 0
00525 && strlen((*command_map)[command]) != 0,
00526 ("Full pathname for %s not found in command map", command));
00527 argv.push_back((*command_map)[command]);
00528 #endif
00529
00530 for (INT i = 1; i < argc; ++i) {
00531 argv.push_back (base_addr + args[i]);
00532 }
00533 }
00534 else {
00535 argv.push_back ((*command_map)["cc"]);
00536 argv.push_back ("-c");
00537 }
00538
00539 argv.push_back(abi());
00540
00541 argv.push_back (inpath);
00542 argv.push_back ("-o");
00543 argv.push_back (outpath);
00544 argv.push_back ("-c");
00545
00546 if (ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag)
00547 argv.push_back ("-keep");
00548
00549 }
00550
00551
00552
00553
00554 #include "ipc_symtab_merge.h"
00555 static const IP_FILE_HDR&
00556 get_ip_file_hdr (const PU_Info *pu)
00557 {
00558 ST_IDX st_idx = PU_Info_proc_sym (pu);
00559 PU_IDX pu_idx = ST_pu (St_Table[st_idx]);
00560 return *AUX_PU_file_hdr (Aux_Pu_Table[pu_idx]);
00561 }
00562
00563 extern "C" void
00564 ipacom_process_symtab (char* symtab_file)
00565 {
00566
00567 Is_True(infiles != 0 && outfiles != 0 && outfiles_fullpath != 0 &&
00568 commands != 0 && comments != 0,
00569 ("ipacom_process_symtab: ipacom not yet initialized"));
00570
00571 Is_True(strlen(input_symtab_name) == 0 &&
00572 strlen(whirl_symtab_name) == 0 &&
00573 strlen(elf_symtab_name) == 0 &&
00574 symtab_command_line == 0,
00575 ("ipacom_process_symtab: symtab already initialized"));
00576
00577 char* output_file = create_unique_file (symtab_file, 'o');
00578 add_to_tmp_file_list (output_file);
00579 #ifdef _USE_GNU_MAKE_
00580 unlink (output_file);
00581 #endif
00582
00583 const char* input_base = ipa_basename(symtab_file);
00584 const char* output_base = ipa_basename(output_file);
00585
00586
00587 strcpy(input_symtab_name, input_base);
00588 strcpy(elf_symtab_name, output_base);
00589 strcpy(whirl_symtab_name, output_base);
00590 whirl_symtab_name[strlen(whirl_symtab_name) - 1] = 'G';
00591
00592
00593 char buf[3*PATH_MAX + 64];
00594
00595 Is_True(command_map != 0
00596 && command_map->find("cc") != command_map->end()
00597 && (*command_map)["cc"] != 0
00598 && strlen((*command_map)["cc"]) != 0,
00599 ("Full pathname for cc not set up"));
00600
00601 char* toolroot = getenv("TOOLROOT");
00602
00603 #if defined(VENDOR_OSP) || defined(VENDOR_SL)
00604 sprintf(buf, "%s -c %s %s -o %s %s -TENV:emit_global_data=%s %s",
00605 #else
00606 sprintf(buf, "%s%s -c %s %s -o %s %s -TENV:emit_global_data=%s %s",
00607 (toolroot != 0) ? toolroot : "",
00608 #endif
00609 (*command_map)["cc"],
00610 abi(),
00611 input_symtab_name,
00612 elf_symtab_name,
00613 ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag ? "-keep":"",
00614 whirl_symtab_name,
00615 IPA_Enable_AutoGnum?"-Gspace 0":"");
00616
00617
00618 char* cmd = static_cast<char*>(malloc(strlen(buf) + 1));
00619 if (!cmd)
00620 ErrMsg (EC_No_Mem, "ipacom_process_symtab");
00621
00622 strcpy(cmd, buf);
00623 symtab_command_line = cmd;
00624
00625 Is_True(strlen(input_symtab_name) != 0 &&
00626 strlen(whirl_symtab_name) != 0 &&
00627 strlen(elf_symtab_name) != 0 &&
00628 symtab_command_line != 0,
00629 ("ipacom_process_symtab: initialization failed"));
00630
00631 }
00632
00633
00634 extern "C"
00635 size_t ipacom_process_file (char* input_file,
00636 const PU_Info* pu, UINT32 ProMP_id)
00637 {
00638 Is_True(infiles != 0 && outfiles_fullpath != 0 && commands != 0 &&
00639 comments != 0,
00640 ("ipacom_process_file: ipacom not initialized"));
00641
00642 Is_True(strlen(input_symtab_name) != 0 &&
00643 strlen(whirl_symtab_name) != 0 &&
00644 strlen(elf_symtab_name) != 0 &&
00645 symtab_command_line != 0,
00646 ("ipacom_process_file: symtab not initialized"));
00647
00648 if (ProMP_Listing) {
00649 Is_True (ProMP_Idx != 0,
00650 ("ipacom_process_file: ipacom not initialized"));
00651 ProMP_Idx->push_back (ProMP_id);
00652 }
00653
00654 char* output_file = create_unique_file (input_file, 'o');
00655
00656 add_to_tmp_file_list (output_file);
00657
00658 const char* input_base = ipa_basename (input_file);
00659 const char* output_base = ipa_basename (output_file);
00660
00661 infiles->push_back(input_base);
00662 outfiles->push_back(output_base);
00663 outfiles_fullpath->push_back(output_file);
00664
00665
00666
00667 ARGV argv;
00668 get_command_line (get_ip_file_hdr (pu), argv, input_base, output_base);
00669
00670 char* str = (char*) malloc(2 * PATH_MAX + 64);
00671 sprintf(str, "-TENV:ipa_ident=%ld -TENV:read_global_data=%s %s",
00672 time(0),
00673 whirl_symtab_name,
00674 IPA_Enable_AutoGnum?"-Gspace 0":"");
00675
00676
00677 argv.push_back(str);
00678
00679 #ifdef KEY
00680
00681 if (psclp_arg != NULL) {
00682 char* str = static_cast<char*>(strdup(psclp_arg));
00683 argv.push_back(str);
00684 }
00685 #endif
00686
00687 if (ProMP_Listing) {
00688 char* str = static_cast<char*>(malloc(64));
00689 sprintf(str, "-PROMP:=ON -PROMP:next_id=%lu", (unsigned long) ProMP_id);
00690 argv.push_back(str);
00691 }
00692
00693
00694
00695
00696
00697 #ifdef TODO
00698 if (gspace_size) {
00699 WRITE_STRING("-Gspace", argv->argv[i]);
00700 sprintf(str, "%d", gspace_size);
00701 WRITE_STRING(str, argv->argv[++i]);
00702 }
00703 #else
00704 static bool reported = false;
00705 if (!reported) {
00706 reported = true;
00707 DevWarn ("TODO: implement gspace_size command file");
00708 }
00709 if (IPA_Enable_Array_Sections)
00710 argv.push_back("-LNO:ipa");
00711 #endif
00712
00713
00714 size_t cmdline_length = 0;
00715 ARGV::const_iterator i;
00716
00717 for (i = argv.begin(); i != argv.end(); ++i)
00718 cmdline_length += strlen(*i) + 1;
00719
00720 char* cmdline = static_cast<char*>(malloc(cmdline_length + 1));
00721 if (!cmdline)
00722 ErrMsg (EC_No_Mem, "ipacom_process_file");
00723
00724 cmdline[0] = '\0';
00725
00726 for (i = argv.begin(); i != argv.end(); ++i) {
00727 strcat(cmdline, *i);
00728 strcat(cmdline, " ");
00729 }
00730
00731 commands->push_back(cmdline);
00732
00733
00734 #ifdef KEY // porting to GNU 3.*
00735 vector<const char*>* emptyvector = CXX_NEW(vector<const char*>,
00736 Malloc_Mem_Pool);
00737 comments->push_back(*emptyvector);
00738 #else
00739 comments->push_back();
00740 #endif
00741
00742 Is_True (infiles->size() > 0 &&
00743 infiles->size() == outfiles->size() &&
00744 infiles->size() == outfiles_fullpath->size() &&
00745 infiles->size() == commands->size() &&
00746 infiles->size() == comments->size(),
00747 ("ipacom_process_file: inconsistent vector sizes"));
00748
00749
00750 if (!symtab_extra_args)
00751 symtab_extra_args = get_extra_symtab_args(argv);
00752
00753 return infiles->size() - 1;
00754
00755 }
00756
00757
00758
00759
00760 extern "C"
00761 void ipacom_add_comment(size_t n, const char* comment)
00762 {
00763 Is_True(infiles != 0 && outfiles != 0 && outfiles_fullpath != 0 &&
00764 commands != 0 && comments != 0,
00765 ("ipacom_add_comment: ipacom not initialized"));
00766
00767 Is_True(comments->size() >= n + 1,
00768 ("ipacom_add_comment: invalid index %ld, max is %ld",
00769 n, comments->size()));
00770
00771 Is_True(comment != 0, ("ipacom_add_comment: argument is a null pointer"));
00772
00773 char* tmp = static_cast<char*>(malloc(strlen(comment) + 1));
00774 if (!tmp)
00775 ErrMsg (EC_No_Mem, "ipacom_add_commend");
00776 strcpy(tmp, comment);
00777
00778 (*comments)[n].push_back(tmp);
00779 }
00780
00781 namespace {
00782
00783 char* ipc_copy_of (char *str)
00784 {
00785 register int len;
00786 register char *p;
00787
00788 len = strlen(str) + 1;
00789 p = (char *) MALLOC (len);
00790 MALLOC_ASSERT (p);
00791 BCOPY (str, p, len);
00792 return p;
00793 }
00794
00795 void print_obj_listfiles(const char* dirname, FILE* listfile)
00796 {
00797
00798 for (vector<const char*>::iterator i = outfiles->begin();
00799 i != outfiles->end();
00800 ++i)
00801 fprintf(listfile, "%s/%s \n", dirname, *i);
00802
00803 if (strlen(elf_symtab_name) != 0)
00804 fprintf(listfile, "%s/%s \n", dirname, elf_symtab_name);
00805 }
00806
00807 void print_all_outfiles(const char* dirname)
00808 {
00809
00810 for (vector<const char*>::iterator i = outfiles->begin();
00811 i != outfiles->end();
00812 ++i)
00813 fprintf(makefile, "%s%s/%s \\\n", " ", dirname, *i);
00814
00815 if (strlen(elf_symtab_name) != 0)
00816 fprintf(makefile, "%s%s/%s \n", " ", dirname, elf_symtab_name);
00817 }
00818
00819 }
00820
00821 static
00822 const char*
00823 Get_Annotation_Filename_With_Path (void) {
00824 static char buf[MAXPATHLEN];
00825
00826 if (!Annotation_Filename) { buf[0] = '\0'; }
00827 else if (*Annotation_Filename == '/') {
00828 strcpy (buf, Annotation_Filename);
00829 }else {
00830 #ifdef KEY
00831 strcpy (buf, "$$dir/");
00832 #else
00833 strcpy (buf, "../");
00834 #endif
00835 strcat (buf, Annotation_Filename);
00836 }
00837
00838 return &buf[0];
00839 }
00840
00841 extern "C"
00842 void ipacom_doit (const char* ipaa_filename)
00843 {
00844 Is_True(infiles != 0 && outfiles != 0 && outfiles_fullpath != 0 &&
00845 commands != 0 && comments != 0 && makefile != 0,
00846 ("ipacom_doit: ipacom not yet initialized"));
00847 Is_True(infiles->size() == outfiles->size() &&
00848 infiles->size() == outfiles_fullpath->size() &&
00849 infiles->size() == commands->size() &&
00850 infiles->size() == comments->size(),
00851 ("ipacom_doit: vectors are inconsistent"));
00852
00853
00854 if (infiles->size() > 0) {
00855 Is_True(strlen(input_symtab_name) != 0 &&
00856 strlen(whirl_symtab_name) != 0 &&
00857 strlen(elf_symtab_name) != 0 &&
00858 symtab_command_line != 0,
00859 ("ipacom_doit: symtab not initialized"));
00860 }
00861
00862 #ifdef TODO
00863 if (IPA_Enable_Cord) {
00864 FCLOSE (Call_graph_file);
00865 if (IPA_Enable_final_link)
00866 process_cord_cmd ();
00867 }
00868 #endif
00869
00870
00871 const char* extra_args = get_extra_args(ipaa_filename);
00872
00873 const char* tmpdir_macro_name = "IPA_TMPDIR";
00874 const char* tmpdir_macro = "$(IPA_TMPDIR)";
00875 fprintf(makefile, "%s = %s\n\n", tmpdir_macro_name, tmpdir);
00876
00877 char* link_cmdfile_name = 0;
00878
00879
00880
00881
00882 if (IPA_Enable_final_link) {
00883
00884 const char* executable = outfilename;
00885 const char* executable_macro_name = "IPA_OUTFILENAME";
00886 const char* executable_macro = "$(IPA_OUTFILENAME)";
00887
00888 fprintf(makefile, "%s = %s\n\n", executable_macro_name, executable);
00889 fprintf(makefile, "default: %s\n\n", executable_macro);
00890 fprintf(makefile, ".IGNORE: %s\n\n", executable_macro);
00891 #ifdef KEY
00892
00893
00894 fprintf(makefile, "%s%s%s\n", executable_macro, TARGET_DELIMITER,
00895 outfiles->size() || strlen(elf_symtab_name) ? "\\" : "");
00896 #else
00897 fprintf(makefile, "%s%s\\\n", executable_macro, TARGET_DELIMITER);
00898 #endif
00899
00900 #ifdef TODO
00901 if (IPA_Enable_Cord)
00902 fprintf(makefile, "%s%s \\\n", " ", cord_output_file_name);
00903 #endif
00904
00905 print_all_outfiles(tmpdir_macro);
00906
00907 #if 0
00908 fputs("\n", makefile);
00909 #endif
00910
00911
00912
00913
00914
00915 char cmdfile_buf[256];
00916 sprintf(cmdfile_buf, "linkopt.%ld", (long) getpid());
00917 link_cmdfile_name = create_unique_file(cmdfile_buf, 0);
00918 FILE* cmdfile = fopen(link_cmdfile_name, "w");
00919 if (cmdfile == 0)
00920 ErrMsg (EC_Ipa_Open, link_cmdfile_name, strerror(errno));
00921 chmod(link_cmdfile_name, 0644);
00922
00923
00924 const ARGV* link_line = ipa_link_line_argv (outfiles_fullpath,
00925 tmpdir,
00926 elf_symtab_name);
00927 Is_True(link_line->size() > 1, ("Invalid link line ARGV vector"));
00928
00929
00930 ARGV::const_iterator i = link_line->begin();
00931
00932
00933
00934 const char* linker = strrchr(*i, '/');
00935 BOOL no_crt = TRUE;
00936 if (linker && (!strcmp (linker, "/ld") || !strcmp (linker, "/collect")) ||
00937 !linker && (!strcmp (*i, "ld") || !strcmp (*i, "collect"))) {
00938 no_crt = FALSE;
00939 }
00940
00941 for (++i; i != link_line->end(); ++i) {
00942 #ifdef KEY
00943
00944
00945 char *p;
00946 #ifndef TARG_SL // jczhang: use slcc specific crt*.o
00947 if (((p = strstr(*i, "/crt1.o")) && p[7] == '\0') ||
00948 ((p = strstr(*i, "/crti.o")) && p[7] == '\0') ||
00949 ((p = strstr(*i, "/crtbegin.o")) && p[11] == '\0') ||
00950 ((p = strstr(*i, "/crtend.o")) && p[9] == '\0') ||
00951 ((p = strstr(*i, "/crtn.o")) && p[7] == '\0')) {
00952 continue;
00953 }
00954 #endif
00955 #endif
00956
00957
00958
00959 if (strcmp(*i, "-rpath") == 0) {
00960 fputs("-Wl,-rpath,", cmdfile);
00961 ++i;
00962 }
00963 if (strcmp(*i, "-rpath-link") == 0) {
00964 fputs("-Wl,-rpath-link,", cmdfile);
00965 ++i;
00966 }
00967 if (strcmp(*i, "-whole-archive") == 0) {
00968 fputs("-Wl,-whole-archive", cmdfile);
00969 fputs(" \n", cmdfile);
00970 continue;
00971 }
00972 if (strcmp(*i, "-no-whole-archive") == 0) {
00973 fputs("-Wl,-no-whole-archive", cmdfile);
00974 fputs(" \n", cmdfile);
00975 continue;
00976 }
00977 if (strncmp(*i, "-soname=", 8) == 0) {
00978 fputs("-Wl,", cmdfile);
00979 fputs(*i, cmdfile);
00980 fputs(" \n", cmdfile);
00981 continue;
00982 }
00983 fputs(*i, cmdfile);
00984 fputs(" \n", cmdfile);
00985 }
00986
00987 #ifdef TODO
00988 if (IPA_Enable_Cord) {
00989 fputs("-T", cmdfile);
00990 fprintf(cmdfile, " %s\n", cord_output_file_name);
00991 }
00992 #endif
00993
00994 fputs("\n", cmdfile);
00995 fclose(cmdfile);
00996
00997
00998 if (ld_ipa_opt[LD_IPA_SHOW].flag) {
00999 fprintf(makefile, "\techo -n %s ' ' ; cat %s\n",
01000 link_line->front(), link_cmdfile_name);
01001 #ifndef _USE_GNU_MAKE_
01002 fprintf(makefile, "\t...\n");
01003 #endif
01004 }
01005
01006
01007 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
01008
01009
01010
01011
01012
01013
01014
01015
01016 const char *outfile_basename = ipa_basename(outfilename);
01017 char *symlinksdir = (char *) alloca(20 + strlen(outfile_basename));
01018 sprintf(symlinksdir, "/tmp/%s.ipaXXXXXX", outfile_basename);
01019 symlinksdir = mktemp(symlinksdir);
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030 fprintf(makefile, "\tmkdir %s\n", symlinksdir);
01031 fprintf(makefile, "\td=`pwd` ; \\\n");
01032 fprintf(makefile, "\tfor i in `grep ^%s/.\\*.o %s`; do ln -s %s$$i %s; done\n",
01033 tmpdir, link_cmdfile_name,
01034 tmpdir[0] == '/' ? "" : "$$d/",
01035 symlinksdir);
01036 #ifdef TARG_SL //jczhang: link with SL's ld instead of gcc
01037 char *toolroot = getenv("TOOLROOT");
01038 fprintf(makefile, "\t%s%s `sed 's:%s:%s:' %s`\n",
01039 toolroot, BINPATH"/ld", tmpdir, symlinksdir, link_cmdfile_name);
01040 #else
01041 fprintf(makefile, "\t%s `sed 's:%s:%s:' %s`\n",
01042 link_line->front(),
01043 tmpdir, symlinksdir, link_cmdfile_name);
01044 #endif // TARG_SL
01045 fprintf(makefile, "\trm -r %s\n", symlinksdir);
01046 #else
01047 fprintf(makefile, "\t%s -from %s\n",
01048 link_line->front(),
01049 link_cmdfile_name);
01050 #endif
01051
01052
01053 if (ProMP_Listing) {
01054 const char* toolroot = getenv("TOOLROOT");
01055 static const char* script_base = "/usr/lib32/cmplrs/pfa_reshuffle";
01056 const char* script_name = toolroot ? concat_names((const string)toolroot, (const string)script_base)
01057 : script_base;
01058 struct stat dummy;
01059 if (stat("/bin/perl5", &dummy) == 0 && stat(script_name, &dummy) == 0) {
01060 fprintf(makefile, "\t/bin/perl5 %s", script_name);
01061 vector<const char*>::const_iterator i = outfiles_fullpath->begin();
01062 for ( ; i != outfiles_fullpath->end(); ++i)
01063 fprintf(makefile, " %s", *i);
01064 fprintf(makefile, "\n");
01065 }
01066 else {
01067 if (stat("/bin/perl5", &dummy) != 0) {
01068 DevWarn("Can't find perl5 to run the ProMP reshuffle script");
01069 }
01070 if (stat(script_name, &dummy) != 0) {
01071 DevWarn("Can't find the ProMP reshuffle script");
01072 }
01073 }
01074
01075
01076
01077
01078 fprintf(makefile, "\tif [ -f %s.list ] ; then 'rm' -f %s.list ; fi\n",
01079 executable_macro, executable_macro);
01080 fprintf(makefile, "\t'cat' %s/*.list > %s.list\n",
01081 tmpdir_macro, executable_macro);
01082 }
01083
01084
01085
01086 bool tlogs_enabled = Get_Trace(TP_PTRACE1, 0xffffffff) ||
01087 Get_Trace(TP_PTRACE2, 0xffffffff);
01088 bool t_enabled = TFile != stdout;
01089
01090 if (tlogs_enabled) {
01091 fprintf(makefile, "\tif [ -f %s/*.tlog ] ; then ",
01092 tmpdir);
01093 fprintf(makefile, "'cat' %s/*.tlog >> %s.tlog ; true ; fi\n",
01094 tmpdir, executable);
01095 }
01096 if (t_enabled) {
01097 fprintf(makefile, "\tif [ -f %s/*.t ] ; then ",
01098 tmpdir);
01099 fprintf(makefile, "'cat' %s/*.t >> %s.t ; true ; fi\n",
01100 tmpdir, executable);
01101 }
01102 }
01103 else {
01104 fprintf(makefile, "\ndefault: \\\n");
01105 print_all_outfiles(tmpdir_macro);
01106 }
01107
01108 fputs("\n", makefile);
01109
01110
01111 if (strlen(elf_symtab_name) != 0) {
01112 char* toolroot = getenv("TOOLROOT");
01113 Is_True(strlen(input_symtab_name) != 0 &&
01114 strlen(whirl_symtab_name) != 0 &&
01115 symtab_command_line != 0 && strlen(symtab_command_line) != 0,
01116 ("ipacom_doit: symtab not initialized"));
01117
01118 if (!symtab_extra_args)
01119 symtab_extra_args = get_extra_args(0);
01120
01121 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
01122
01123 if (IPA_Enable_Cord) {
01124 const char * obj_listfile_name = create_tmp_file((const string)"obj_file_list");
01125 FILE* listfile = fopen(obj_listfile_name, "w");
01126 print_obj_listfiles(tmpdir, listfile);
01127 fclose(listfile);
01128
01129 fprintf(makefile, "%s%s \\\n", cord_output_file_name, TARGET_DELIMITER);
01130 print_all_outfiles(tmpdir_macro);
01131 fprintf(makefile, "\t%s%s -o %s %s %s\n",(toolroot != 0) ? toolroot : "",(*command_map)["cord"], cord_output_file_name, call_graph_file_name, obj_listfile_name);
01132 }
01133
01134
01135 fprintf(makefile, "%s/%s" TARGET_DELIMITER "\n",
01136 tmpdir_macro, "dummy");
01137
01138 char *tmpname = (char *) malloc (strlen (outfilename) + 1);
01139 strcpy (tmpname, outfilename);
01140 if (Feedback_Filename) {
01141 fprintf(makefile, "\tcd %s; %s -Wb,-OPT:procedure_reorder=on -fb_create %s %s -Wb,-CG:enable_feedback=off -TENV:object_name=_%s\n\n",
01142 tmpdir_macro, symtab_command_line, Feedback_Filename, symtab_extra_args, proper_name((const string)ipa_basename(outfilename)));
01143 } else if (Annotation_Filename) {
01144 fprintf (makefile, "\t"
01145 #ifdef KEY
01146 "dir=`pwd`; "
01147 #endif
01148 "cd %s; %s -Wb,-OPT:procedure_reorder=on -fb_opt %s %s -TENV:object_name=_%s "
01149 #ifdef KEY
01150 "-Wb,-CG:enable_feedback=on\n\n",
01151 #else
01152 "-Wb,-CG:enable_feedback=off\n\n",
01153 #endif
01154 tmpdir_macro, symtab_command_line,
01155 Get_Annotation_Filename_With_Path (),
01156 symtab_extra_args, proper_name((const string)ipa_basename(outfilename)));
01157 } else {
01158 fprintf(makefile, "\tcd %s; %s -Wb,-OPT:procedure_reorder=on %s -Wb,-CG:enable_feedback=off -TENV:object_name=_%s\n\n",
01159 tmpdir_macro, symtab_command_line, symtab_extra_args, proper_name((const string)ipa_basename(outfilename)));
01160 }
01161 fprintf(makefile, "%s/%s" TARGET_DELIMITER "%s/%s %s/%s\n\n",
01162 tmpdir_macro, elf_symtab_name,
01163 tmpdir_macro, input_symtab_name,
01164 tmpdir_macro, "dummy");
01165
01166 fprintf(makefile, "%s/%s" TARGET_DELIMITER "%s/%s %s/%s\n\n",
01167 tmpdir_macro, whirl_symtab_name,
01168 tmpdir_macro, elf_symtab_name,
01169 tmpdir_macro, "dummy");
01170 #endif
01171
01172 #ifdef _TARG_MIPS
01173
01174 fprintf(makefile, "%s/%s" TARGET_DELIMITER "%s/%s\n",
01175 tmpdir_macro, elf_symtab_name,
01176 tmpdir_macro, input_symtab_name);
01177
01178 fprintf(makefile, "\tcd -P %s; %s %s\n\n",
01179 tmpdir_macro, symtab_command_line, symtab_extra_args);
01180
01181 fprintf(makefile, "%s/%s" TARGET_DELIMITER "%s/%s\n\n",
01182 tmpdir_macro, whirl_symtab_name,
01183 tmpdir_macro, elf_symtab_name);
01184
01185 #endif
01186
01187 }
01188
01189
01190 for (size_t i = 0; i < infiles->size(); ++i) {
01191 fprintf(makefile, "%s/%s" TARGET_DELIMITER "%s/%s %s/%s %s/%s\n",
01192 tmpdir_macro, (*outfiles)[i],
01193 tmpdir_macro, elf_symtab_name,
01194 tmpdir_macro, whirl_symtab_name,
01195 tmpdir_macro, (*infiles)[i]);
01196 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
01197 if (Feedback_Filename) {
01198 fprintf(makefile, "\tcd %s; %s -Wb,-OPT:procedure_reorder=on -fb_create %s %s -Wb,-CG:enable_feedback=off\n",
01199 tmpdir_macro, (*commands)[i], Feedback_Filename, extra_args);
01200 } else if (Annotation_Filename) {
01201 fprintf(makefile, "\t"
01202 #ifdef KEY
01203 "dir=`pwd`; "
01204 #endif
01205 "cd %s; %s -Wb,-OPT:procedure_reorder=on -fb_opt %s %s "
01206 #ifdef KEY
01207 "-Wb,-CG:enable_feedback=on\n",
01208 #else
01209 "-Wb,-CG:enable_feedback=off\n",
01210 #endif
01211 tmpdir_macro, (*commands)[i],
01212 Get_Annotation_Filename_With_Path () , extra_args);
01213 } else {
01214 fprintf(makefile, "\tcd %s; %s -Wb,-OPT:procedure_reorder=on %s -Wb,-CG:enable_feedback=off\n",
01215 tmpdir_macro, (*commands)[i], extra_args);
01216 }
01217 #else
01218 if (Feedback_Filename) {
01219 fprintf(makefile, "\tcd %s; %s -Wb,-OPT:procedure_reorder=on -fb_create %s %s -Wb,-CG:enable_feedback=off\n",
01220 tmpdir_macro, (*commands)[i], Feedback_Filename, extra_args);
01221 } else if (Annotation_Filename) {
01222 fprintf(makefile, "\tcd %s; "
01223 #ifdef KEY
01224 "dir=`pwd`; "
01225 #endif
01226 "%s -Wb,-OPT:procedure_reorder=on -fb_opt %s %s -Wb,-CG:enable_feedback=off \n",
01227 tmpdir_macro, (*commands)[i],
01228 Get_Annotation_Filename_With_Path (),extra_args);
01229 } else {
01230 fprintf(makefile, "\tcd -P %s; %s -Wb,-OPT:procedure_reorder=on %s -Wb,-CG:enable_feedback=off\n",
01231 tmpdir_macro, (*commands)[i], extra_args);
01232 }
01233 #endif
01234
01235 const vector<const char*>& com = (*comments)[i];
01236 for (vector<const char*>::const_iterator it = com.begin();
01237 it != com.end();
01238 ++it)
01239 fprintf(makefile, "## %s\n", *it);
01240 fputs("\n", makefile);
01241 }
01242
01243 fclose(makefile);
01244 if (Tlog_File_Name) {
01245 fclose (Tlog_File);
01246 }
01247
01248
01249
01250 char sh_cmdfile_buf[256];
01251 sprintf(sh_cmdfile_buf, "cmdfile.%ld", (long) getpid());
01252 char* sh_cmdfile_name = create_unique_file(sh_cmdfile_buf, 0);
01253
01254 FILE* sh_cmdfile = fopen(sh_cmdfile_name, "w");
01255 if (sh_cmdfile == 0)
01256 ErrMsg (EC_Ipa_Open, sh_cmdfile_name, strerror(errno));
01257 chmod(sh_cmdfile_name, 0644);
01258
01259
01260 if (!ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag) {
01261 fprintf(sh_cmdfile, "cleanup() {\n");
01262
01263 vector<const char*>::iterator i;
01264 for (i = infiles->begin(); i != infiles->end(); ++i)
01265 fprintf(sh_cmdfile, "if [ -f %s/%s ] ; then 'rm' -f %s/%s ; fi\n",
01266 tmpdir, *i, tmpdir, *i);
01267 for (i = outfiles->begin(); i != outfiles->end(); ++i)
01268 fprintf(sh_cmdfile, "if [ -f %s/%s ] ; then 'rm' -f %s/%s ; fi\n",
01269 tmpdir, *i, tmpdir, *i);
01270
01271 if (strlen(input_symtab_name) != 0) {
01272 Is_True(strlen(whirl_symtab_name) != 0 && strlen(elf_symtab_name) != 0,
01273 ("Inconsistent symtab names: input, whirl, elf = %d %d %d\n",
01274 strlen(input_symtab_name),
01275 strlen(whirl_symtab_name),
01276 strlen(elf_symtab_name)));
01277
01278 fprintf(sh_cmdfile, "if [ -f %s/%s ] ; then 'rm' -f %s/%s ; fi\n",
01279 tmpdir, input_symtab_name, tmpdir, input_symtab_name);
01280 fprintf(sh_cmdfile, "if [ -f %s/%s ] ; then 'rm' -f %s/%s ; fi\n",
01281 tmpdir, whirl_symtab_name, tmpdir, whirl_symtab_name);
01282 fprintf(sh_cmdfile, "if [ -f %s/%s ] ; then 'rm' -f %s/%s ; fi\n",
01283 tmpdir, elf_symtab_name, tmpdir, elf_symtab_name);
01284 }
01285
01286 if (link_cmdfile_name)
01287 fprintf(sh_cmdfile, "if [ -f %s ] ; then 'rm' -f %s ; fi\n",
01288 link_cmdfile_name, link_cmdfile_name);
01289
01290 fprintf(sh_cmdfile,
01291 "'rm' %s > /dev/null 2>&1 ; true\n", makefile_name);
01292 #ifndef KEY
01293 fprintf(sh_cmdfile,
01294 "'rm' %s > /dev/null 2>&1 ; true\n", sh_cmdfile_name);
01295 #endif
01296
01297
01298
01299 fprintf(sh_cmdfile, "'mv' %s/* . > /dev/null 2>&1 ; true\n", tmpdir);
01300
01301
01302 fprintf(sh_cmdfile, "'rm' -rf %s > /dev/null 2>&1 ; true\n", tmpdir);
01303 #ifdef KEY
01304
01305 fprintf(sh_cmdfile,
01306 "'rm' %s > /dev/null 2>&1 ; true\n", sh_cmdfile_buf);
01307 #endif
01308 fprintf(sh_cmdfile, "}\n\n");
01309
01310
01311
01312
01313 fprintf(sh_cmdfile, "trap 'cleanup; exit 2' ");
01314 #if !defined(TARG_IA64) && !defined(TARG_X8664) && !defined(TARG_MIPS) && !defined(TARG_SL)
01315 fprintf(sh_cmdfile, "ABRT EMT SYS POLL ");
01316 #endif
01317 fprintf(sh_cmdfile, "HUP INT QUIT ILL TRAP FPE ");
01318 fprintf(sh_cmdfile, "KILL BUS PIPE ALRM TERM ");
01319 fprintf(sh_cmdfile, "USR1 USR2 IO VTALRM PROF XCPU XFSZ\n\n\n");
01320 }
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 fprintf(sh_cmdfile,"#! /bin/sh -f \n");
01332 fprintf(sh_cmdfile,"MAKEFLAGS=\nexport MAKEFLAGS\n");
01333
01334
01335 Is_True(command_map != 0
01336 && command_map->find(MAKE_STRING) != command_map->end()
01337 && (*command_map)[MAKE_STRING] != 0
01338 && strlen((*command_map)[MAKE_STRING]) != 0,
01339 ("Full pathname for smake not set up"));
01340 const char* smake_name = (*command_map)[MAKE_STRING];
01341 #ifdef KEY // bug 2487
01342 fprintf(sh_cmdfile, "rm -f %s\n", outfilename);
01343 #endif
01344 fprintf(sh_cmdfile, "%s -f %s ", smake_name, makefile_name);
01345
01346 #if 1
01347 if (!ld_ipa_opt[LD_IPA_SHOW].flag)
01348 #else
01349 if (!IPA_Echo_Commands)
01350 #endif
01351 fprintf(sh_cmdfile, "-s ");
01352
01353 #ifdef KEY
01354 if (IPA_Max_Jobs > 1)
01355 fprintf(sh_cmdfile, "-j %u ", IPA_Max_Jobs);
01356 #else
01357 if (IPA_Max_Jobs_Set)
01358 fprintf(sh_cmdfile, "-J %u ", IPA_Max_Jobs);
01359 #endif
01360
01361 fprintf(sh_cmdfile, "\nretval=$?\n");
01362
01363
01364
01365 if (!ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag) {
01366 fprintf(sh_cmdfile, "cleanup; ");
01367 }
01368 fprintf(sh_cmdfile, "exit $retval\n");
01369
01370 fclose(sh_cmdfile);
01371
01372 #ifdef KEY
01373
01374 if (IPA_old_ld_library_path != NULL) {
01375 int i;
01376 int path_len = strlen(IPA_old_ld_library_path);
01377
01378
01379 for (i=0; i<path_len; i++)
01380 if (IPA_old_ld_library_path[i] == ';')
01381 IPA_old_ld_library_path[i] = ':';
01382
01383 char *env = (char *) alloca (path_len + strlen("LD_LIBRARY_PATH=") + 5);
01384 sprintf (env, "LD_LIBRARY_PATH=%s", IPA_old_ld_library_path);
01385 putenv (env);
01386 }
01387 #endif
01388
01389 exec_smake(sh_cmdfile_name);
01390 }
01391
01392
01393
01394 static void escape_char (char *str)
01395 {
01396 char *p = str + 1;
01397
01398 do {
01399 *str++ = *p++;
01400 } while (*str != 0);
01401 }
01402
01403
01404
01405
01406
01407 static const char* get_extra_args(const char* ipaa_filename)
01408 {
01409 vector<const char*> args;
01410 args.reserve(16);
01411
01412 switch (ld_ipa_opt[LD_IPA_SHARABLE].flag) {
01413 case F_MAKE_SHARABLE:
01414 #ifdef KEY
01415 args.push_back("-TENV:PIC");
01416 #else
01417 args.push_back("-pic2");
01418 #endif
01419 break;
01420 case F_CALL_SHARED:
01421 case F_CALL_SHARED_RELOC:
01422 #ifndef TARG_MIPS
01423 #if !defined(TARG_SL)
01424 args.push_back("-pic1");
01425 #endif
01426 #endif
01427 break;
01428 case F_NON_SHARED:
01429 args.push_back("-non_shared");
01430 break;
01431 case F_RELOCATABLE:
01432 if (IPA_Enable_Relocatable_Opt == TRUE)
01433 args.push_back("-pic1");
01434 break;
01435 }
01436
01437 #if 1
01438
01439
01440 if (ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag && !IPA_Enable_Keeplight)
01441 args.push_back("-keep");
01442 #endif
01443
01444 if (ld_ipa_opt[LD_IPA_SHOW].flag)
01445 args.push_back("-show");
01446
01447
01448
01449 if (ipaa_filename) {
01450 char* buf = (char*) malloc(strlen(ipaa_filename) + 32);
01451 if (!buf)
01452 ErrMsg (EC_No_Mem, "extra_args");
01453
01454 sprintf(buf, "-WOPT:ipaa:ipaa_file=%s", ipaa_filename );
01455 args.push_back(buf);
01456 }
01457
01458
01459
01460
01461
01462 if (WB_flags) {
01463 string p = ipc_copy_of (WB_flags);
01464 while (*p) {
01465 args.push_back(p);
01466 #if 1
01467 while (*p) {
01468 if (*p == ',') {
01469 if (p[1] != ',') {
01470 *p++ = 0;
01471 break;
01472 }
01473 else
01474 escape_char(p);
01475 }
01476 else if (p[0] == '\\' && p[1] != 0)
01477 escape_char (p);
01478 p++;
01479 }
01480 #endif
01481 }
01482 }
01483
01484
01485
01486
01487 vector<char*> space_ptr;
01488 if (Y_flags) {
01489 char* p = Y_flags;
01490 while (*p) {
01491 args.push_back(p);
01492 while (*p) {
01493 if (*p == ' ') {
01494 space_ptr.push_back(p);
01495 *p++ = 0;
01496 break;
01497 }
01498 else if (p[0] == '\\')
01499 escape_char (p);
01500 p++;
01501 }
01502 }
01503 }
01504
01505 #ifdef _TARG_MIPS
01506
01507 if (ld_ipa_opt[LD_IPA_ISA].set) {
01508 switch(ld_ipa_opt[LD_IPA_ISA].flag) {
01509 case 3:
01510 args.push_back("-mips3");
01511 break;
01512 case 4:
01513 args.push_back("-mips4");
01514 break;
01515 default:
01516 break;
01517 }
01518 }
01519 #endif
01520
01521 size_t len = 0;
01522 vector<const char*>::const_iterator i;
01523
01524 for (i = args.begin(); i != args.end(); ++i)
01525 len += strlen(*i) + 1;
01526
01527 char* result = (char*) malloc(len + 1);
01528 if (!result)
01529 ErrMsg (EC_No_Mem, "extra_args");
01530
01531 result[0] = '\0';
01532
01533 for (i = args.begin(); i != args.end(); ++i) {
01534 strcat(result, *i);
01535 strcat(result, " ");
01536 }
01537
01538
01539 for (size_t idx = 0; idx < space_ptr.size(); idx++) {
01540 Is_True(*space_ptr[idx] == 0, ("space_ptr must point to 0"));
01541 *space_ptr[idx] = ' ';
01542 }
01543
01544 return result;
01545 }
01546
01547 static const char* get_extra_symtab_args(const ARGV& argv)
01548 {
01549 const char* result = get_extra_args(0);
01550
01551 for (ARGV::const_iterator i = argv.begin(); i != argv.end(); ++i) {
01552 const char* const debug_flag = "-DEBUG";
01553 const char* const G_flag = "-G";
01554 const char* const TARG_flag = "-TARG";
01555 const char* const OPT_flag = "-OPT";
01556 const int debug_len = 6;
01557 const int G_len = 2;
01558 const int TARG_len = 5;
01559 const int OPT_len = 4;
01560 bool flag_found = false;
01561
01562
01563
01564
01565
01566 if (ld_ipa_opt[LD_IPA_SHARABLE].flag == F_RELOCATABLE &&
01567 IPA_Enable_Relocatable_Opt != TRUE) {
01568 const char* const non_shared_flag = "-non_shared";
01569 if (strcmp(*i, non_shared_flag) == 0)
01570 flag_found = true;
01571 }
01572
01573 if ((strncmp(*i, debug_flag, debug_len) == 0) ||
01574 (strncmp(*i, G_flag, G_len) == 0) ||
01575 (strncmp(*i, OPT_flag, OPT_len) == 0) ||
01576 (strncmp(*i, TARG_flag, TARG_len) == 0))
01577
01578 flag_found = true;
01579
01580 if (flag_found == true) {
01581 char* buf = static_cast<char*>(malloc(strlen(result) +
01582 strlen(*i) + 2));
01583 if (!buf)
01584 ErrMsg (EC_No_Mem, "extra_symtab_args");
01585 strcpy(buf, result);
01586 strcat(buf, " ");
01587 strcat(buf, *i);
01588 free(const_cast<char*>(result));
01589 result = buf;
01590 }
01591 }
01592
01593 return result;
01594 }
01595
01596 static void exec_smake (char* sh_cmdfile_name)
01597 {
01598
01599 Set_Trace_File ( NULL );
01600
01601 #ifdef _OPENMP
01602
01603
01604
01605
01606
01607
01608 mp_destroy_();
01609 #endif
01610
01611
01612 const char* sh_name = "/bin/sh";
01613
01614 const int argc = 2;
01615 char* argv[argc+1];
01616 argv[0] = const_cast<char*>(sh_name);
01617 argv[1] = sh_cmdfile_name;
01618 argv[2] = 0;
01619
01620 execve (sh_name, argv, environ_vars);
01621
01622
01623 execvp ("sh", argv);
01624
01625 Fail_FmtAssertion ("ipa: exec sh failed");
01626 }
01627
01628 #ifdef KEY
01629 extern "C" {
01630
01631
01632 void
01633 Ipalink_Set_Error_Phase (char *name)
01634 {
01635 Set_Error_Phase (name);
01636 }
01637
01638 void
01639 Ipalink_ErrMsg_EC_infile (char *name)
01640 {
01641 ErrMsg(EC_Ipa_Infile, name);
01642 }
01643
01644 void
01645 Ipalink_ErrMsg_EC_outfile (char *name)
01646 {
01647 ErrMsg(EC_Ipa_Outfile, name);
01648 }
01649
01650 }
01651 #endif