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 #include <sys/types.h>
00041 #include <sys/stat.h>
00042 #include "main.h"
00043 #include "ipc_weak.h"
00044
00045 #include "defs.h"
00046 #include "errors.h"
00047 #include "erglob.h"
00048 #include "cxx_memory.h"
00049 #include "ipc_link.h"
00050
00051 #include "lib_phase_dir.h"
00052
00053
00054
00055
00056
00057 ARGV *ld_flags_part1;
00058 ARGV *ld_flags_part2;
00059 ARGV *current_ld_flags;
00060
00061
00062
00063
00064 ARGV *comma_list;
00065 UINT32 comma_list_byte_count = 0;
00066
00067 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
00068
00069 #define LINKER_NAME "gcc"
00070 #define LINKER_NAME_WITH_SLASH "/gcc"
00071
00072 #if defined(TARG_IA64)
00073 #define DYNAMIC_LINKER "-dynamic-linker /lib/ld-linux-ia64.so.2"
00074 #endif
00075
00076 static char* concat_names(const char* a , const char* b)
00077 {
00078 char * buf;
00079 buf = (char *)malloc(strlen(a)+strlen(b)+1);
00080 strcpy(buf, a);
00081 strcat(buf, b);
00082 return (buf);
00083 }
00084
00085
00086
00087 static bool file_exists(const char* path)
00088 {
00089 if (!path || strlen(path) == 0)
00090 return false;
00091
00092 struct stat buf;
00093 return stat(path, &buf) == 0 && S_ISREG(buf.st_mode);
00094 }
00095
00096
00097 static const char* get_linker_name(int argc, char** argv)
00098 {
00099 const char * toolroot = getenv("TOOLROOT");
00100 if (!toolroot) { toolroot = "" ; }
00101
00102 char* linker_name;
00103 char *where_am_i = getenv("COMPILER_BIN");
00104
00105 if (where_am_i) {
00106 char *slash = strrchr (where_am_i, '/');
00107 #if defined(VENDOR_PSC)
00108 asprintf (&linker_name, "%.*s/../" PSC_TARGET "/bin/" LINKER_NAME,
00109 slash - where_am_i, where_am_i);
00110 #else
00111 asprintf (&linker_name, "%.*s/../" OPEN64_TARGET "/bin/" LINKER_NAME,
00112 (int)(slash - where_am_i), where_am_i);
00113 #endif
00114 if (file_exists (linker_name)) {
00115 return linker_name;
00116 }
00117 free (linker_name);
00118 }
00119
00120 linker_name = concat_names (toolroot, PHASEPATH LINKER_NAME_WITH_SLASH);
00121 if (file_exists (linker_name)) {
00122 return linker_name;
00123 }
00124 free (linker_name);
00125
00126 linker_name = concat_names (toolroot, GNUPHASEPATH LINKER_NAME_WITH_SLASH);
00127 if (file_exists (linker_name)) {
00128 return linker_name;
00129 }
00130 free (linker_name);
00131
00132 linker_name = concat_names (toolroot, BINPATH LINKER_NAME_WITH_SLASH);
00133 if (file_exists (linker_name)) {
00134 return linker_name;
00135 }
00136 free (linker_name);
00137
00138 linker_name = concat_names (toolroot, ALTBINPATH LINKER_NAME_WITH_SLASH);
00139 if (file_exists (linker_name)) {
00140 return linker_name;
00141 }
00142 free (linker_name);
00143
00144 return (LINKER_NAME);
00145 }
00146
00147 #endif
00148
00149 void
00150 ipa_init_link_line (int argc, char** argv)
00151 {
00152 ld_flags_part1 = CXX_NEW (ARGV, Malloc_Mem_Pool);
00153 ld_flags_part2 = CXX_NEW (ARGV, Malloc_Mem_Pool);
00154 comma_list = CXX_NEW (ARGV, Malloc_Mem_Pool);
00155
00156
00157 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS)
00158
00159 #if 0
00160 char *t_path = arg_vector[0];
00161 char *t_name;
00162 char *buf;
00163 int len = strlen(t_path);
00164 int i,new_len;
00165
00166 t_name = t_path + (len-1);
00167 for (i=0; i<len; i++,t_name--) {
00168 if (*t_name == '/')
00169 break;
00170 }
00171 new_len = len-i;
00172 buf = (char *)malloc(strlen(LINKER_NAME)+new_len+1);
00173
00174 strncpy(buf,t_path,new_len);
00175 strcat(buf,LINKER_NAME);
00176 ld_flags_part1->push_back (buf);
00177
00178 free(buf);
00179 #endif
00180 ld_flags_part1->push_back (get_linker_name(arg_count, arg_vector));
00181 #if defined(TARG_IA64) && defined(CROSS_COMPILATION)
00182 ld_flags_part1->push_back (DYNAMIC_LINKER);
00183 #endif
00184
00185 #else
00186 ld_flags_part1->push_back (arg_vector[0]);
00187 #endif
00188
00189
00190 for (INT i = 0; i < argc; ++i) {
00191 ld_flags_part1->push_back (argv[i]);
00192 }
00193 current_ld_flags = ld_flags_part1;
00194 }
00195
00196
00197 void
00198 ipa_add_link_flag (const char* str)
00199 {
00200 current_ld_flags->push_back (str);
00201 }
00202
00203 void
00204 ipa_modify_link_flag (char* lname, char* fname)
00205 {
00206 ARGV::iterator i;
00207 for(i = ld_flags_part1->begin(); i != ld_flags_part1->end(); i++) {
00208 if(!strcmp(lname, *i)) {
00209 ld_flags_part1->erase(i);
00210 ld_flags_part1->insert(i, fname);
00211 }
00212 }
00213 for(i = ld_flags_part2->begin(); i != ld_flags_part2->end();i++) {
00214 if(!strcmp(lname, *i)) {
00215 ld_flags_part2->erase(i);
00216 ld_flags_part2->insert(i, fname);
00217 }
00218 }
00219 }
00220
00221 #ifdef KEY
00222
00223 extern "C" char *
00224 ipa_add_parent_dir_to_relative_pathname (const char *name)
00225 {
00226 if (name[0] != '/') {
00227 const char *prefix = "../";
00228 char *buf;
00229 buf = (char *) malloc(strlen(prefix)+strlen(name)+1);
00230 strcpy(buf, prefix);
00231 strcat(buf, name);
00232 return (buf);
00233 }
00234 return (char*) name;
00235 }
00236
00237 extern "C" void
00238 ipa_erase_link_flag (const char* str)
00239 {
00240 ARGV::iterator p;
00241 bool changed;
00242
00243 do {
00244 changed = FALSE;
00245 for (p = ld_flags_part1->begin();
00246 p != ld_flags_part1->end();
00247 p++) {
00248 if (!strcmp(str, *p)) {
00249 ld_flags_part1->erase(p);
00250 changed = TRUE;
00251 break;
00252 }
00253 }
00254 } while (changed);
00255
00256 do {
00257 changed = FALSE;
00258 for (p = ld_flags_part2->begin();
00259 p != ld_flags_part2->end();
00260 p++) {
00261 if (!strcmp(str, *p)) {
00262 ld_flags_part2->erase(p);
00263 changed = TRUE;
00264 break;
00265 }
00266 }
00267 } while (changed);
00268 }
00269 #endif
00270
00271
00272
00273 void
00274 ipa_insert_whirl_obj_marker ()
00275 {
00276 current_ld_flags = ld_flags_part2;
00277 }
00278
00279
00280 extern "C" void
00281 ipa_insert_whirl_marker(void)
00282 {
00283 ipa_insert_whirl_obj_marker();
00284 }
00285
00286 void
00287 ipa_add_comma_list (const char* name)
00288 {
00289 comma_list->push_back (name);
00290 comma_list_byte_count += strlen(name) + 1;
00291 }
00292
00293 void
00294 ipa_compose_comma_list (const char* name)
00295 {
00296 if (comma_list->empty ())
00297 return;
00298
00299 char* result = (char *) MEM_POOL_Alloc (Malloc_Mem_Pool,
00300 comma_list_byte_count);
00301 ARGV::const_iterator first = comma_list->begin ();
00302
00303 strcpy (result, *first);
00304 free ((void*) *first++);
00305
00306
00307 while (first != comma_list->end ()) {
00308 strcat (result, ",");
00309 strcat (result, *first);
00310 free ((void*) *first);
00311 ++first;
00312 }
00313
00314 comma_list_byte_count = 0;
00315 comma_list->erase (comma_list->begin(), comma_list->end());
00316
00317 ipa_add_link_flag ("-ar_members");
00318 ipa_add_link_flag (result);
00319
00320 char* p = (char *) MEM_POOL_Alloc (Malloc_Mem_Pool, strlen(name) + 1);
00321 strcpy (p, name);
00322 ipa_add_link_flag (p);
00323
00324 }
00325
00326
00327 ARGV *
00328 ipa_link_line_argv (const ARGV* output_files,
00329 const char* dir,
00330 const char* symtab_base)
00331 {
00332 ARGV* argv = CXX_NEW (ARGV, Malloc_Mem_Pool);
00333
00334 argv->reserve (ld_flags_part1->size () +
00335 ld_flags_part2->size () +
00336 output_files->size () +
00337 1);
00338
00339 argv->insert (argv->end (),
00340 ld_flags_part1->begin (),
00341 ld_flags_part1->end ());
00342
00343 argv->insert (argv->end (),
00344 output_files->begin (),
00345 output_files->end ());
00346
00347 if (symtab_base && symtab_base[0] != 0) {
00348 char* symtab =
00349 static_cast<char*>(malloc(strlen(dir) + strlen(symtab_base) + 2));
00350 if (!symtab)
00351 ErrMsg (EC_No_Mem, "ipa_link_line_argv");
00352 strcpy(symtab, dir);
00353 strcat(symtab, "/");
00354 strcat(symtab, symtab_base);
00355 argv->push_back(symtab);
00356 }
00357
00358 argv->insert (argv->end (),
00359 ld_flags_part2->begin (),
00360 ld_flags_part2->end ());
00361
00362 return argv;
00363 }
00364
00365 #ifdef TODO
00366 void
00367 process_cord_obj_list (FILE *f)
00368 {
00369 int i;
00370
00371 for (i = 0; i < cur_argc; ++i) {
00372 if (arg_tag[i] == ARG_OBJ) {
00373 fputs (arg_list[i].obj->other_name ?
00374 arg_list[i].obj->other_name : arg_list[i].obj->name, f);
00375 fputc ('\n', f);
00376 }
00377 }
00378 }
00379 #endif