00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(__GNUC__)
00025 #include <stdio.h>
00026 #endif
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <libgen.h>
00030 #include <sys/stat.h>
00031 #include <sys/mman.h>
00032 #include <fcntl.h>
00033 #include <sys/dir.h>
00034 #include <sys/wait.h>
00035 #include <alloca.h>
00036 #include <signal.h>
00037 #include <limits.h>
00038 #include <errno.h>
00039 #include <string.h>
00040
00041 #include "aout/ar.h"
00042
00043 #include "bfd.h"
00044 #include "libbfd.h"
00045 #include "elf-bfd.h"
00046
00047 #include "ipa_ld.h"
00048 #include "ipa_cmdline.h"
00049
00050 char *psclp_arg = NULL;
00051
00052 int arg_count;
00053 char **arg_vector;
00054 char **environ_vars;
00055
00056
00057 unsigned int max_gpa_size = 0x100000;
00058 unsigned int used_gp_area;
00059
00060 int ipa_argc = 0;
00061 char ** ipa_argv = NULL;
00062
00063 static int orig_iargc_size = 10;
00064 static char char_opt[] = {'a','A','b','c','e','f','F','G','h','l','L','m','o','O','R','T','u','y','Y','z','0'};
00065
00066 extern string outfilename;
00067 extern void ipa_insert_whirl_obj_marker(void);
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #include <stdint.h>
00081
00082
00083 typedef uint16_t Elf32_Half;
00084 typedef uint16_t Elf64_Half;
00085
00086
00087 typedef uint32_t Elf32_Word;
00088 typedef int32_t Elf32_Sword;
00089 typedef uint32_t Elf64_Word;
00090 typedef int32_t Elf64_Sword;
00091
00092
00093 typedef uint64_t Elf32_Xword;
00094 typedef int64_t Elf32_Sxword;
00095 typedef uint64_t Elf64_Xword;
00096 typedef int64_t Elf64_Sxword;
00097
00098
00099 typedef uint32_t Elf32_Addr;
00100 typedef uint64_t Elf64_Addr;
00101
00102
00103 typedef uint32_t Elf32_Off;
00104 typedef uint64_t Elf64_Off;
00105
00106
00107 typedef uint16_t Elf32_Section;
00108 typedef uint16_t Elf64_Section;
00109
00110
00111 typedef uint32_t Elf32_Symndx;
00112 typedef uint64_t Elf64_Symndx;
00113
00114
00115
00116 #ifndef EI_NIDENT
00117 #define EI_NIDENT (16)
00118 #endif
00119
00120 typedef struct
00121 {
00122 unsigned char e_ident[EI_NIDENT];
00123 Elf32_Half e_type;
00124 Elf32_Half e_machine;
00125 Elf32_Word e_version;
00126 Elf32_Addr e_entry;
00127 Elf32_Off e_phoff;
00128 Elf32_Off e_shoff;
00129 Elf32_Word e_flags;
00130 Elf32_Half e_ehsize;
00131 Elf32_Half e_phentsize;
00132 Elf32_Half e_phnum;
00133 Elf32_Half e_shentsize;
00134 Elf32_Half e_shnum;
00135 Elf32_Half e_shstrndx;
00136 } Elf32_Ehdr;
00137
00138 typedef struct
00139 {
00140 unsigned char e_ident[EI_NIDENT];
00141 Elf64_Half e_type;
00142 Elf64_Half e_machine;
00143 Elf64_Word e_version;
00144 Elf64_Addr e_entry;
00145 Elf64_Off e_phoff;
00146 Elf64_Off e_shoff;
00147 Elf64_Word e_flags;
00148 Elf64_Half e_ehsize;
00149 Elf64_Half e_phentsize;
00150 Elf64_Half e_phnum;
00151 Elf64_Half e_shentsize;
00152 Elf64_Half e_shnum;
00153 Elf64_Half e_shstrndx;
00154 } Elf64_Ehdr;
00155
00156
00157
00158
00159
00160
00161
00162 static int
00163 ipa_opt (char **argv )
00164 {
00165 if (ipa_argc == 0) {
00166 ipa_argv = (string *) MALLOC (orig_iargc_size * sizeof (string));
00167 MALLOC_ASSERT (ipa_argv);
00168 }
00169 else if (ipa_argc >= orig_iargc_size) {
00170 orig_iargc_size *=2;
00171 ipa_argv = (string *) REALLOC (ipa_argv, (orig_iargc_size * sizeof(string)));
00172 MALLOC_ASSERT (ipa_argv);
00173 }
00174
00175 ipa_argv[ipa_argc++] = ipa_copy_of(argv[0]);
00176
00177 return 1;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 static void
00193 add_WB_opt (char **argv)
00194 {
00195 char *p = *argv;
00196
00197 if ( WB_flags == NULL ) {
00198 WB_flags = concat_names("-Wb,",&p[3]);
00199 } else {
00200 char *flg = concat_names(WB_flags,&p[3] );
00201 FREE(WB_flags);
00202 WB_flags = flg;
00203 }
00204
00205 return;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 static void
00221 add_Y_opt (char **argv)
00222 {
00223 char *p = *argv;
00224
00225 if ( Y_flags == NULL ) {
00226 Y_flags = ipa_copy_of(p);
00227 } else {
00228 char *flg;
00229
00230 flg = concat_names(Y_flags," ");
00231 FREE (Y_flags);
00232 Y_flags = flg;
00233
00234 flg = concat_names(Y_flags,p);
00235 FREE (Y_flags);
00236 Y_flags = flg;
00237 }
00238
00239 return;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 #define ET_SGI_IR (ET_LOPROC + 0)
00252 static bfd_boolean
00253 check_for_whirl(char *name, bfd_boolean *is_elf)
00254 {
00255 int fd = -1;
00256 char *raw_bits = NULL;
00257 int size,bufsize;
00258 Elf32_Ehdr *p_ehdr = NULL;
00259 struct stat statb;
00260 int test;
00261
00262 #ifdef KEY
00263 *is_elf = FALSE;
00264 #endif
00265
00266 fd = OPEN(name, O_RDONLY, 0755);
00267 if (fd < 0)
00268 return FALSE;
00269
00270 if ((test = fstat(fd, &statb) != 0)) {
00271 CLOSE(fd);
00272 return FALSE;
00273 }
00274
00275 if (statb.st_size < sizeof(Elf64_Ehdr)) {
00276 CLOSE(fd);
00277 return FALSE;
00278 }
00279
00280 bufsize = sizeof(Elf64_Ehdr);
00281
00282 raw_bits = (char *)MALLOC(bufsize*4);
00283 MALLOC_ASSERT(raw_bits);
00284
00285 size = READ(fd, raw_bits, bufsize);
00286 #if 0
00287 if (size != statb.st_size) {
00288 CLOSE(fd);
00289 FREE(raw_bits);
00290 return FALSE;
00291 }
00292 #endif
00293
00294
00295
00296
00297 p_ehdr = (Elf32_Ehdr *)raw_bits;
00298 if (p_ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
00299 p_ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
00300 p_ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
00301 p_ehdr->e_ident[EI_MAG3] != ELFMAG3) {
00302 CLOSE(fd);
00303 FREE(raw_bits);
00304 return(FALSE);
00305 }
00306
00307 #ifdef KEY
00308 *is_elf = TRUE;
00309 #endif
00310
00311 if(p_ehdr->e_ident[EI_CLASS] == ELFCLASS32){
00312 Elf32_Ehdr *p32_ehdr = (Elf32_Ehdr *)raw_bits;
00313 if (p32_ehdr->e_type == ET_SGI_IR) {
00314 CLOSE(fd);
00315 FREE(raw_bits);
00316 return TRUE;
00317 }
00318 }
00319 else {
00320 Elf64_Ehdr *p64_ehdr = (Elf64_Ehdr *)raw_bits;
00321 if (p64_ehdr->e_type == ET_SGI_IR) {
00322 CLOSE(fd);
00323 FREE(raw_bits);
00324 return TRUE;
00325 }
00326 }
00327
00328 CLOSE(fd);
00329 FREE(raw_bits);
00330 return FALSE;
00331
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 static bfd_boolean
00343 needs_argument(char *string, bfd_boolean is_double_dash)
00344 {
00345
00346 int len = strlen(string);
00347
00348 if (is_double_dash) {
00349 if ((strcmp (string, "architecture") == 0)) {
00350 return TRUE;
00351 }
00352 if ((strcmp (string, "format") == 0)) {
00353 return TRUE;
00354 }
00355 if ((strcmp (string, "mri-script") == 0)) {
00356 return TRUE;
00357 }
00358 if ((strcmp (string, "entry") == 0)) {
00359 return TRUE;
00360 }
00361 if ((strcmp (string, "auxiliary") == 0)) {
00362 return TRUE;
00363 }
00364 if ((strcmp (string, "filter") == 0)) {
00365 return TRUE;
00366 }
00367 if ((strcmp (string, "gpsize") == 0)) {
00368 return TRUE;
00369 }
00370 if ((strcmp (string, "library") == 0)) {
00371 return TRUE;
00372 }
00373 if ((strcmp (string, "library-path") == 0)) {
00374 return TRUE;
00375 }
00376 if ((strcmp (string, "output") == 0)) {
00377 return TRUE;
00378 }
00379 if ((strcmp (string, "just-symbols") == 0)) {
00380 return TRUE;
00381 }
00382 if ((strcmp (string, "script") == 0)) {
00383 return TRUE;
00384 }
00385 if ((strcmp (string, "undefined") == 0)) {
00386 return TRUE;
00387 }
00388 if ((strcmp (string, "trace-symbol") == 0)) {
00389 return TRUE;
00390 }
00391 if ((strcmp (string, "assert") == 0)) {
00392 return TRUE;
00393 }
00394 if ((strcmp (string, "defsym") == 0)) {
00395 return TRUE;
00396 }
00397 if ((strcmp (string, "dynamic-linker") == 0)) {
00398 return TRUE;
00399 }
00400 if ((strcmp (string, "Map") == 0)) {
00401 return TRUE;
00402 }
00403 if ((strcmp (string, "oformat") == 0)) {
00404 return TRUE;
00405 }
00406 if ((strcmp (string, "retain-symbols-file") == 0)) {
00407 return TRUE;
00408 }
00409 if ((strcmp (string, "rpath-link") == 0)) {
00410 return TRUE;
00411 }
00412 if ((strcmp (string, "split-by-reloc") == 0)) {
00413 return TRUE;
00414 }
00415 if ((strcmp (string, "task-link") == 0)) {
00416 return TRUE;
00417 }
00418 if ((strcmp (string, "verbose") == 0)) {
00419 return TRUE;
00420 }
00421 if ((strcmp (string, "version-script") == 0)) {
00422 return TRUE;
00423 }
00424 if ((strcmp (string, "version-exports-section") == 0)) {
00425 return TRUE;
00426 }
00427 if ((strcmp (string, "wrap") == 0)) {
00428 return TRUE;
00429 }
00430 }
00431 else {
00432 if (len == 1) {
00433 int i;
00434 int size = strlen(char_opt);
00435 for (i=0;i<size;i++) {
00436 if (char_opt[i] == *string)
00437 return TRUE;
00438 }
00439 return FALSE;
00440 }
00441 if ((strcmp (string, "soname") == 0)) {
00442 return TRUE;
00443 }
00444 if ((strcmp (string, "rpath") == 0)) {
00445 return TRUE;
00446 }
00447 if ((strcmp (string, "Tbss") == 0)) {
00448 return TRUE;
00449 }
00450 if ((strcmp (string, "Tdata") == 0)) {
00451 return TRUE;
00452 }
00453 if ((strcmp (string, "Ttext") == 0)) {
00454 return TRUE;
00455 }
00456 }
00457
00458 return FALSE;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 static void
00471 blank_arg(char **argv, int ndx)
00472 {
00473
00474 int j,len;
00475
00476 len = strlen(argv[ndx]);
00477
00478 #if 1
00479 if (len >=3)
00480 strcpy(argv[ndx],"-g");
00481 else {
00482 for(j=0;j<len;j++)
00483 argv[ndx][j] = ' ';
00484 }
00485 #else
00486 argv[ndx][0] = '\0';
00487 #endif
00488
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 bfd_boolean
00507 ipa_search_command_line(int argc,
00508 char **argv,
00509 char **envp
00510 )
00511 {
00512 int i;
00513
00514
00515
00516
00517 for (i=1;i<argc;i++) {
00518 char *string = argv[i];
00519 if (*string == '-') {
00520 if ((strncmp(string,"-IPA",4)) == 0) {
00521 is_ipa = TRUE;
00522 break;
00523 }
00524 else if ((strncmp(string,"--IPA",5)) == 0) {
00525 is_ipa = TRUE;
00526 break;
00527 }
00528 else if ((strcmp(string,"--ipa")) == 0) {
00529 is_ipa = TRUE;
00530 break;
00531 }
00532 else if ((strcmp(string,"-ipa")) == 0) {
00533 is_ipa = TRUE;
00534 break;
00535 }
00536 }
00537 }
00538
00539 if (!is_ipa)
00540 return(FALSE);
00541
00542 arg_count = argc;
00543 arg_vector = argv;
00544 environ_vars = envp;
00545
00546
00547
00548
00549
00550 ipa_set_syms();
00551 #ifdef KEY
00552 (*p_Ipalink_Set_Error_Phase)("IPA Startup");
00553 #endif
00554
00555
00556
00557
00558
00559
00560 (*p_ipa_init_link_line) (0, NULL);
00561
00562 for (i=1;i<argc;i++) {
00563 #ifdef KEY
00564 bfd_boolean is_elf;
00565 #endif
00566 char *string = argv[i];
00567 if (*string == '-' && string[1] == '-') {
00568 if ((strncmp (&string[2], "ipa", strlen ("ipa")) == 0)) {
00569 continue;
00570 }
00571 if ((strncmp (&string[2], "IPA:", strlen ("IPA:")) == 0)) {
00572 char *p = &argv[i][1];
00573 ipa_opt(&p);
00574 blank_arg(argv,i);
00575 continue;
00576 }
00577 if ((strcmp (&string[2], "keep") == 0)) {
00578 ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag = TRUE;
00579
00580 blank_arg(argv,i);
00581 continue;
00582 }
00583 else if ((needs_argument(&string[2],TRUE) == TRUE)) {
00584 (*p_ipa_add_link_flag) (argv[i++]);
00585 (*p_ipa_add_link_flag) (argv[i]);
00586 continue;
00587 }
00588 }
00589 else if (*string == '-') {
00590 if ((strncmp(string,"-WB,",4)) == 0) {
00591 add_WB_opt (&argv[i]);
00592
00593
00594 blank_arg(argv,i);
00595 continue;
00596 }
00597 else if ((strncmp(string,"-Y",2)) == 0) {
00598 add_Y_opt (&argv[i]);
00599
00600
00601 blank_arg(argv,i);
00602 continue;
00603 }
00604 if ((strncmp (string, "-ipacom", strlen ("-ipacom")) == 0)) {
00605 blank_arg(argv,i);
00606 continue;
00607 }
00608 if ((strncmp (string, "-ipa", strlen ("-ipa")) == 0)) {
00609 blank_arg(argv,i);
00610 continue;
00611 }
00612 if ((strncmp (string, "-DEFAULT:", strlen ("-DEFAULT:")) == 0)) {
00613 ipa_opt(&argv[i]);
00614 blank_arg(argv,i);
00615 continue;
00616 }
00617 if ((strncmp (string, "-IPA:", strlen ("-IPA:")) == 0)) {
00618 ipa_opt(&argv[i]);
00619 blank_arg(argv,i);
00620 continue;
00621 }
00622 if ((strncmp (string, "-INLINE:", strlen ("-INLINE:")) == 0)) {
00623 ipa_opt(&argv[i]);
00624 blank_arg(argv,i);
00625 continue;
00626 }
00627 if ((strncmp (string, "-INTERNAL:", strlen ("-INTERNAL:")) == 0)) {
00628 ipa_opt(&argv[i]);
00629 blank_arg(argv,i);
00630 continue;
00631 }
00632 if ((strncmp (string, "-OPT:", strlen ("-OPT:")) == 0)) {
00633 ipa_opt(&argv[i]);
00634 blank_arg(argv,i);
00635 continue;
00636 }
00637 if ((strncmp (string, "-TENV:", strlen ("-TENV:")) == 0)) {
00638 ipa_opt(&argv[i]);
00639 blank_arg(argv,i);
00640 continue;
00641 }
00642
00643 if ((strcmp (string, "-psclp") == 0)) {
00644 psclp_arg = malloc(10 + strlen(argv[i+1]));
00645 sprintf (psclp_arg, "-psclp %s", argv[i+1]);
00646 blank_arg(argv,i);
00647 blank_arg(argv,i+1);
00648 continue;
00649 }
00650 else if ((strcmp(string,"-keep")) == 0) {
00651 ld_ipa_opt[LD_IPA_KEEP_TEMPS].flag = TRUE;
00652
00653
00654 blank_arg(argv,i);
00655 continue;
00656 }
00657 else if ((strcmp(string,"-show")) == 0) {
00658 ld_ipa_opt[LD_IPA_SHOW].flag = TRUE;
00659
00660
00661 blank_arg(argv,i);
00662 continue;
00663 }
00664 else if ((strcmp(string,"-demangle")) == 0) {
00665 ld_ipa_opt[LD_IPA_DEMANGLE].flag = TRUE;
00666
00667
00668 blank_arg(argv,i);
00669 continue;
00670 }
00671 else if ((strcmp(string,"-o")) == 0) {
00672 outfilename = MALLOC(strlen(argv[i+1])+3);
00673 MALLOC_ASSERT(outfilename);
00674 strcpy(outfilename,"");
00675 strcat(outfilename,argv[i+1]);
00676 (*p_ipa_add_link_flag) (argv[i++]);
00677 (*p_ipa_add_link_flag) (argv[i]);
00678 continue;
00679 }
00680 else if ((strcmp(string,"-v")) == 0) {
00681 ld_ipa_opt[LD_IPA_VERBOSE].flag = TRUE;
00682 }
00683
00684 else if (string[1] == 't' && strlen(string) > 3) {
00685 ipa_opt(&argv[i]);
00686
00687
00688 blank_arg(argv,i);
00689 continue;
00690 }
00691 else if (needs_argument(&string[1],FALSE)) {
00692 (*p_ipa_add_link_flag) (argv[i++]);
00693 (*p_ipa_add_link_flag) (argv[i]);
00694 continue;
00695 }
00696 }
00697
00698 else if (check_for_whirl(argv[i], &is_elf)) {
00699 (*p_ipa_insert_whirl_marker)();
00700 continue;
00701 }
00702
00703 #ifdef KEY
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 if (is_elf == TRUE)
00716 (*p_ipa_insert_whirl_marker)();
00717 #endif
00718 (*p_ipa_add_link_flag) (argv[i]);
00719
00720 }
00721
00722 return(TRUE);
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749