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 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #include <sys/types.h>
00043 #ifdef __MINGW32__
00044 #include <WINDOWS.h>
00045 #else
00046 #include <sys/mman.h>
00047 #endif
00048 #include <sys/stat.h>
00049 #include <unistd.h>
00050 #if defined(BUILD_OS_DARWIN)
00051 #include <darwin_elf.h>
00052 #else
00053 #include <elf.h>
00054 #endif
00055 #include <fcntl.h>
00056 #include <errno.h>
00057 #include <signal.h>
00058 #include <bstring.h>
00059 #define USE_STANDARD_TYPES
00060 #include "defs.h"
00061 #include "cxx_memory.h"
00062 #include "ipa_section.h"
00063 #include "wn.h"
00064 #include "erglob.h"
00065 #include "errors.h"
00066 #include "wn_simp.h"
00067 #include "ir_reader.h"
00068 #include "strtab.h"
00069 #include "stab.h"
00070 #include "irbdata.h"
00071 #include "dwarf_DST_mem.h"
00072 #include "elf_stuff.h"
00073 #include "pu_info.h"
00074 #include "config_targ.h"
00075 #include "config_elf_targ.h"
00076 #include "ipa_lno_file.h"
00077 #include "config_debug.h"
00078 #include "ir_bcom.h"
00079 #include "ipa_lno_info.h"
00080 #include "ipl_summary.h"
00081
00082
00083
00084 #define SHT_MIPS_IPALNO (SHT_LOPROC + 42)
00085
00086 #if defined(linux) || defined(BUILD_OS_DARWIN)
00087 #define MAPPED_SIZE 0x400000
00088 #endif
00089
00090
00091 static char IPALNO_REVISION[] = "IPALNO:1.1";
00092
00093 static void (*old_sigsegv)(int);
00094 static void (*old_sigbus)(int);
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 static void Ir_Lno_Signal_Handler(int sig,
00108 int err_num)
00109 {
00110 void (*old_handler)(int) = 0;
00111
00112
00113
00114
00115
00116 errno = 0;
00117 char *err_str = strerror(err_num);
00118
00119 if (Doing_mmapped_io && errno == 0)
00120 Fatal_Error("I/O error in %s: %s", Current_Output ?
00121 Current_Output->file_name : "mmapped object", err_str);
00122
00123
00124 switch (sig) {
00125 #ifndef __MINGW32__
00126 case SIGBUS:
00127 old_handler = old_sigbus;
00128 break;
00129 #endif
00130 case SIGSEGV:
00131 old_handler = old_sigsegv;
00132 break;
00133 }
00134 if (old_handler == SIG_DFL) {
00135
00136 #ifdef __MINGW32__
00137 raise(sig);
00138 #else
00139 kill(getpid(), sig);
00140 #endif
00141 } else if (old_handler != SIG_IGN) {
00142
00143 (*old_handler)(sig);
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 Section* IPA_LNO_WRITE_FILE::Create_Or_Get_Section(Elf64_Word sh_info,
00154 const char *name)
00155 {
00156 register INT i;
00157 Elf64_Word type = SHT_MIPS_IPALNO;
00158 const INT num_sections = IPA_LNO_SECTION_COUNT;
00159 Is_True(ofl, ("Create_Section: Missing Output File"));
00160
00161 for (i = 0; i < ofl->num_of_section; i++) {
00162 if ((ofl->section_list[i].shdr.sh_info == sh_info) &&
00163 (strcmp (ofl->section_list[i].name, name) == 0)) {
00164 ofl->cur_section = ofl->section_list + i;
00165 return ofl->cur_section;
00166 }
00167 }
00168
00169 if (ofl->num_of_section == 0) {
00170 ofl->max_num_of_section = num_sections;
00171 ofl->section_list =
00172 (Section *)malloc(ofl->max_num_of_section * sizeof(Section));
00173 FmtAssert (ofl->section_list, ("No more memory"));
00174 } else if (ofl->max_num_of_section == ofl->num_of_section) {
00175 ofl->max_num_of_section *= 2;
00176 ofl->section_list = (Section *) realloc
00177 (ofl->section_list,
00178 ofl->max_num_of_section * sizeof(Section));
00179 FmtAssert (ofl->section_list, ("No more memory"));
00180 }
00181
00182 ofl->cur_section = ofl->section_list + ofl->num_of_section;
00183 ofl->num_of_section += 1;
00184 memset (ofl->cur_section, 0, sizeof(Section));
00185 ofl->cur_section->name = name;
00186 ofl->cur_section->shdr.sh_info = sh_info;
00187 ofl->cur_section->shdr.sh_type = type;
00188 return ofl->cur_section;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197 void IPA_LNO_WRITE_FILE::Create_Sections()
00198 {
00199 Is_True(ofl, ("Create_Sections: Missing Output File"));
00200 Create_Or_Get_Section(IPA_PROCEDURE, IPA_PROCEDURE_NAME);
00201 Create_Or_Get_Section(IPA_PROJECTED_REGION, IPA_PROJECTED_REGION_NAME);
00202 Create_Or_Get_Section(IPA_PROJECTED_ARRAY, IPA_PROJECTED_ARRAY_NAME);
00203 Create_Or_Get_Section(IPA_TERM_ARRAY, IPA_TERM_ARRAY_NAME);
00204 Create_Or_Get_Section(IPA_IVAR, IPA_IVAR_NAME);
00205 Create_Or_Get_Section(IPA_FORMAL, IPA_FORMAL_NAME);
00206 Create_Or_Get_Section(IPA_GLOBAL, IPA_GLOBAL_NAME);
00207 Create_Or_Get_Section(IPA_STRINGS, IPA_STRINGS_NAME);
00208 Create_Or_Get_Section(IPA_REVISION, IPA_REVISION_NAME);
00209 }
00210
00211 #define DEFAULT_TMPDIR "/usr/tmp"
00212 #define DEFAULT_TEMPLATE "/elf_wnXXXXXX"
00213
00214
00215
00216
00217
00218
00219
00220 INT IPA_LNO_WRITE_FILE::Create_Temp_File()
00221 {
00222 register const char *tmpdir;
00223 register char *path;
00224 register int fd;
00225
00226 if ((tmpdir = getenv("TMPDIR")) == 0)
00227 tmpdir = DEFAULT_TMPDIR;
00228 path = (char *) malloc(strlen(tmpdir) + strlen(DEFAULT_TEMPLATE) + 1);
00229 if (path == 0)
00230 return -1;
00231 #ifdef __MINGW32__
00232 {
00233 int mode = O_RDWR | O_CREAT | O_EXCL ;
00234 do {
00235 strcpy (path, tmpdir);
00236 strcat (path, DEFAULT_TEMPLATE);
00237 mktemp( path );
00238 } while( (fd = open(path, mode)) < 0 );
00239 }
00240 #else
00241 strcpy(path, tmpdir);
00242 strcat(path, DEFAULT_TEMPLATE);
00243 fd = mkstemp (path);
00244 #endif
00245 if (fd != -1)
00246 unlink (path);
00247 ofl->file_name = path;
00248 return fd;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 void IPA_LNO_WRITE_FILE::Open_Write_File(char *file_name)
00264 {
00265 #ifndef __MINGW32__
00266
00267
00268
00269 if (old_sigsegv == 0)
00270 old_sigsegv = signal(SIGSEGV, reinterpret_cast<void (*)(int)>
00271 (Ir_Lno_Signal_Handler));
00272
00273 if (old_sigbus == 0)
00274 old_sigbus = signal (SIGBUS, reinterpret_cast<void (*)(int)>
00275 (Ir_Lno_Signal_Handler));
00276 #endif
00277
00278
00279 ofl = (Output_File *) malloc(sizeof(Output_File));
00280 if (!ofl)
00281 return;
00282
00283
00284
00285
00286
00287 if (file_name == 0) {
00288 ofl->output_fd = Create_Temp_File();
00289 } else {
00290 ofl->file_name = file_name;
00291 ofl->output_fd = open((const char *)(file_name),
00292 (int) (O_RDWR|O_CREAT|O_TRUNC), (mode_t) 0644);
00293 }
00294 if (ofl->output_fd < 0) {
00295 ofl = NULL;
00296 return;
00297 }
00298
00299 #if defined(linux) || defined(BUILD_OS_DARWIN)
00300 ftruncate(ofl->output_fd, MAPPED_SIZE);
00301 #endif
00302
00303 ofl->section_list = NULL;
00304 ofl->cur_section = NULL;
00305 ofl->num_of_section = 0;
00306
00307
00308 if (ir_b_create_map(ofl) == (char *) (-1)) {
00309 ofl = NULL;
00310 return;
00311 }
00312
00313
00314 #ifdef __ALWAYS_USE_64BIT_ELF__
00315 ofl->file_size = sizeof(Elf64_Ehdr);
00316 #else
00317 ofl->file_size = Use_32_Bit_Pointers ?
00318 sizeof(Elf32_Ehdr) : sizeof(Elf64_Ehdr);
00319 #endif
00320
00321
00322 Create_Sections();
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332 void IPA_LNO_WRITE_FILE::Write_Section(Elf64_Word sh_info,
00333 const char* name,
00334 void* buf,
00335 INT size)
00336 {
00337 Is_True(ofl, ("Write_Section: Missing Output File"));
00338 Section *s;
00339 s = Create_Or_Get_Section(sh_info, name);
00340 ofl->file_size = ir_b_align(ofl->file_size, sizeof(mINT64), 0);
00341 s->shdr.sh_offset = ofl->file_size;
00342 INT offset = (INT) ir_b_save_buf(buf, size, sizeof(mINT64), 0, ofl);
00343 s->shdr.sh_size = ofl->file_size - s->shdr.sh_offset;
00344 s->shdr.sh_addralign = sizeof(mINT64);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 void IPA_LNO_WRITE_FILE::Write_Headers(Elf64_Off e_shoff,
00359 Elf64_Shdr* strtab_sec)
00360 {
00361 INT i;
00362 char *str;
00363 Elf64_Shdr *shdr;
00364 Elf64_Ehdr *ehdr;
00365 char *base_addr = ofl->map_addr;
00366 Is_True(ofl, ("Write_Headers: Missing Output File"));
00367
00368
00369
00370 ofl->file_size += sizeof(Elf64_Shdr) * (ofl->num_of_section + 2);
00371
00372
00373 if (ofl->file_size >= ofl->mapped_size)
00374 ir_b_grow_map(0, ofl);
00375
00376
00377 ehdr = (Elf64_Ehdr *) ofl->map_addr;
00378 strcpy((char *) ehdr->e_ident, ELFMAG);
00379 ehdr->e_ident[EI_CLASS] = ELFCLASS64;
00380 ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
00381 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
00382 ehdr->e_type = ET_IR;
00383 ehdr->e_machine = Get_Elf_Target_Machine();
00384 ehdr->e_version = EV_CURRENT;
00385 ehdr->e_shoff = e_shoff;
00386 ehdr->e_flags = Config_ELF_From_Target (
00387 ! Use_32_Bit_Pointers, FALSE, Target_ISA);
00388 ehdr->e_ehsize = sizeof(Elf64_Ehdr);
00389 ehdr->e_shentsize = sizeof(Elf64_Shdr);
00390 ehdr->e_shnum = ofl->num_of_section + 2;
00391 ehdr->e_shstrndx = ofl->num_of_section + 1;
00392
00393
00394
00395
00396
00397
00398
00399 str = base_addr + strtab_sec->sh_offset;
00400 str[0] = '\0';
00401 str++;
00402
00403 for (i = 0; i < ofl->num_of_section; i++) {
00404 strcpy(str, ofl->section_list[i].name);
00405 str += strlen(str) + 1;
00406 }
00407
00408 strcpy(str, ELF_SHSTRTAB);
00409
00410
00411
00412
00413 if ((INTPTR) str + strlen(ELF_SHSTRTAB) + 1 >
00414 e_shoff + (INTPTR) base_addr)
00415 ErrMsg (EC_IR_Scn_Write, "Section Header String Table", ofl->file_name);
00416
00417
00418 shdr = (Elf64_Shdr *) (base_addr + e_shoff);
00419
00420 memset(shdr, 0, sizeof(Elf64_Shdr));
00421 shdr++;
00422
00423 for (i = 0; i < ofl->num_of_section; i++, shdr++)
00424 memcpy(shdr, &(ofl->section_list[i].shdr), sizeof(Elf64_Shdr));
00425
00426 memcpy(shdr, strtab_sec, sizeof(Elf64_Shdr));
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 Elf64_Off IPA_LNO_WRITE_FILE::Create_String_Table_Section(
00436 Elf64_Shdr *strtab_sec)
00437 {
00438 INT i;
00439 Elf64_Off e_shoff;
00440 Elf64_Word strtab_size = 1;
00441
00442
00443
00444 for (i = 0; i < ofl->num_of_section; i++) {
00445 register Section *sec = &(ofl->section_list[i]);
00446 sec->shdr.sh_name = strtab_size;
00447 strtab_size += strlen(sec->name) + 1;
00448 }
00449
00450
00451 memset(strtab_sec, 0, sizeof(Elf64_Shdr));
00452 strtab_sec->sh_name = strtab_size;
00453 strtab_size += strlen (ELF_SHSTRTAB) + 1;
00454 strtab_sec->sh_type = SHT_STRTAB;
00455 strtab_sec->sh_size = strtab_size;
00456 strtab_sec->sh_offset = ofl->file_size;
00457 ofl->file_size += strtab_size;
00458 strtab_sec->sh_addralign = 1;
00459 strtab_sec->sh_entsize = 1;
00460
00461
00462 ofl->file_size = ir_b_align(ofl->file_size,
00463 #if defined(__GNUC__)
00464 __alignof__(Elf64_Shdr),
00465 #else
00466 __builtin_alignof(Elf64_Shdr),
00467 #endif
00468 0);
00469 e_shoff = ofl->file_size;
00470 return e_shoff;
00471 }
00472
00473
00474
00475
00476
00477
00478 void IPA_LNO_WRITE_FILE::Write_Revision()
00479 {
00480 Section *s;
00481 s = Create_Or_Get_Section(IPA_REVISION, IPA_REVISION_NAME);
00482 s->shdr.sh_offset = ofl->file_size;
00483 INT offset = (INT) ir_b_save_buf(IPALNO_REVISION, strlen(IPALNO_REVISION)
00484 + 1, 1, 0, ofl);
00485 s->shdr.sh_size = ofl->file_size - s->shdr.sh_offset;
00486 s->shdr.sh_addralign = 1;
00487 s->shdr.sh_type = SHT_MIPS_IPALNO;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496 void IPA_LNO_WRITE_FILE::Write_Cleanup()
00497 {
00498 FmtAssert(ofl != NULL, ("Write_Cleanup: Missing Output_File"));
00499 ofl->output_fd = -1;
00500 if (ofl->num_of_section > 0)
00501 free(ofl->section_list);
00502 ofl->num_of_section = 0;
00503 ofl->section_list = NULL;
00504 #ifndef __MINGW32__
00505 munmap((void *) ofl->map_addr, (size_t) ofl->mapped_size);
00506 #endif
00507 ofl->map_addr = NULL;
00508 ofl->file_size = 0;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 INT IPA_LNO_WRITE_FILE::Close_Write_File()
00520 {
00521 FmtAssert(ofl != NULL, ("Close_Write_File: Missing Output_File"));
00522 Write_Revision();
00523 Elf64_Shdr strtab_sec;
00524 Elf64_Off e_shoff = Create_String_Table_Section(&strtab_sec);
00525 Write_Headers(e_shoff, &strtab_sec);
00526 if (ftruncate(ofl->output_fd, ofl->file_size) != 0)
00527 return IPALNO_CLOSE_ERROR;
00528 close(ofl->output_fd);
00529 Write_Cleanup();
00530 return IPALNO_SUCCESS;
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 INT IPA_LNO_READ_FILE::Check_Section_Headers()
00542 {
00543 register INT i;
00544 Elf64_Ehdr *ehdr;
00545 Elf64_Shdr *shdr;
00546 char *shstrtab;
00547
00548 FmtAssert(ifl != NULL, ("Check_Sections_Headers: Missing Input_File"));
00549 char* baseaddr = (char *) ifl->mapped_address;
00550 ehdr = (Elf64_Ehdr *) baseaddr;
00551 shdr = (Elf64_Shdr *) ((char *) baseaddr + ehdr->e_shoff);
00552
00553 errno = ENOEXEC;
00554
00555 if (shdr[ehdr->e_shstrndx].sh_offset >= ifl->mapped_size ||
00556 shdr[ehdr->e_shstrndx].sh_offset +
00557 shdr[ehdr->e_shstrndx].sh_size > ifl->mapped_size)
00558 return IPALNO_FORMAT_ERROR;
00559
00560 shstrtab = baseaddr + shdr[ehdr->e_shstrndx].sh_offset;
00561
00562 for (i = 1; i < ehdr->e_shnum; i++) {
00563 register Elf64_Shdr *sec = &(shdr[i]);
00564
00565 if (sec->sh_offset >= ifl->mapped_size
00566 || sec->sh_offset + sec->sh_size > ifl->mapped_size)
00567 return IPALNO_FORMAT_ERROR;
00568 if (sec->sh_name >= shdr[ehdr->e_shstrndx].sh_size)
00569 return IPALNO_FORMAT_ERROR;
00570 if (sec->sh_link >= ehdr->e_shnum)
00571 return IPALNO_FORMAT_ERROR;
00572 if (sec->sh_addralign & (sec->sh_addralign - 1))
00573 return IPALNO_FORMAT_ERROR;
00574 if (sec->sh_addralign >1 &&
00575 (long)(baseaddr + sec->sh_offset) & ((sec->sh_addralign - 1)))
00576 return IPALNO_FORMAT_ERROR;
00577
00578
00579 if (sec->sh_type == SHT_MIPS_IPALNO &&
00580 strcmp(shstrtab + sec->sh_name, IPA_REVISION_NAME) == 0) {
00581
00582 register char *p = baseaddr + sec->sh_offset;
00583 register char *eob = p + sec->sh_size - 1;
00584
00585 register int match = 0;
00586
00587 if (*eob != 0)
00588
00589 return IPALNO_FORMAT_ERROR;
00590
00591 while (p <= eob) {
00592 if (strncmp ("IPALNO:", p, 7) == 0) {
00593 strcpy(ifl->file_revision, p);
00594 if (strcmp(IPALNO_REVISION, p) == 0) {
00595 match = 1;
00596 break;
00597 }
00598 }
00599 p += strlen (p) + 1;
00600 }
00601
00602 if (!match && DEBUG_IPALNO_Version_Check)
00603 return IPALNO_REVISION_MISMATCH;
00604 }
00605 }
00606
00607 errno = 0;
00608 return IPALNO_SUCCESS;
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 INT IPA_LNO_READ_FILE::Check_Elf_Header()
00620 {
00621 Elf64_Shdr *shdr;
00622 Elf64_Ehdr *ehdr;
00623 BOOL is_64bit;
00624 INT isa;
00625
00626 FmtAssert(ifl != NULL, ("Check_Elf_Header: Missing Input_File"));
00627 if (ifl->mapped_size < sizeof(Elf64_Ehdr))
00628 return IPALNO_FORMAT_ERROR;
00629
00630 char* baseaddr = (char *) ifl->mapped_address;
00631 ehdr = (Elf64_Ehdr *) baseaddr;
00632
00633 if (IS_ELF (*ehdr)) {
00634 if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
00635 return IPALNO_FORMAT_ERROR;
00636 if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
00637 ehdr->e_version != EV_CURRENT)
00638 return IPALNO_FORMAT_ERROR;
00639 if (ehdr->e_type != ET_IR ||
00640 ehdr->e_machine != Get_Elf_Target_Machine() ||
00641 ehdr->e_shentsize != sizeof(Elf64_Shdr))
00642 return IPALNO_FORMAT_ERROR;
00643 Config_Target_From_ELF (ehdr->e_flags, &is_64bit, &isa);
00644 if ( ! Set_Target_ABI (is_64bit, isa))
00645 return IPALNO_ABI_MISMATCH;
00646 if (ehdr->e_shstrndx >= ehdr->e_shnum)
00647 return IPALNO_FORMAT_ERROR;
00648 if (ehdr->e_shoff >= ifl->mapped_size ||
00649 ehdr->e_shoff + ehdr->e_shnum * sizeof(Elf64_Shdr) > ifl->mapped_size)
00650 return IPALNO_FORMAT_ERROR;
00651 shdr = (Elf64_Shdr *) (baseaddr + ehdr->e_shoff);
00652 #if defined(__GNUC__)
00653 if ((long) shdr & (__alignof__(Elf64_Shdr) - 1))
00654 #else
00655 if ((long) shdr & (__builtin_alignof(Elf64_Shdr) - 1))
00656 #endif
00657 return IPALNO_FORMAT_ERROR;
00658 return IPALNO_SUCCESS;
00659 }
00660
00661 return IPALNO_FORMAT_ERROR;
00662 }
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 INT IPA_LNO_READ_FILE::Check_Input()
00675 {
00676 INT st;
00677 FmtAssert(ifl != NULL, ("Check_Input: Missing Input_File"));
00678 if ((st = Check_Elf_Header()) < 0)
00679 return st;
00680 if ((st = Check_Section_Headers()) <= 0)
00681 return st;
00682 return IPALNO_SUCCESS;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 INT IPA_LNO_READ_FILE::Open_Read_File(const char input_file[])
00697 {
00698 int fd;
00699 INT st;
00700 struct stat stat_buf;
00701 register char *map_addr;
00702
00703 if (input_file == NULL) {
00704 errno = ENOENT;
00705 return IPALNO_READER_ERROR;
00706 }
00707
00708 fd = open(input_file, O_RDONLY);
00709 if (fd < 0)
00710 return IPALNO_READER_ERROR;
00711
00712 if (fstat(fd, &stat_buf) != 0)
00713 return IPALNO_READER_ERROR;
00714
00715 #ifdef __MINGW32__
00716 map_addr = NULL;
00717 HANDLE map_addr_handle = NULL;
00718 map_addr_handle =
00719 CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL,
00720 PAGE_READWRITE, 0, stat_buf.st_size, input_file);
00721 if (map_addr_handle)
00722 map_addr = (char *)MapViewOfFileEx(map_addr_handle,
00723 FILE_MAP_COPY,
00724 0, 0, stat_buf.st_size, 0);
00725
00726 if (map_addr == NULL) {
00727 close(fd);
00728 return IPALNO_READER_ERROR;
00729 }
00730
00731 #else
00732 map_addr = (char *) mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE,
00733 MAP_PRIVATE, fd, 0);
00734 if (map_addr == MAP_FAILED) {
00735 close (fd);
00736 return IPALNO_READER_ERROR;
00737 }
00738 #endif
00739
00740
00741 ifl = (Input_File *) malloc(sizeof(Input_File));
00742 ifl->mapped_address = map_addr;
00743 ifl->mapped_size = stat_buf.st_size;
00744
00745 close(fd);
00746 if ((st = Check_Input()) < 0) {
00747 #ifndef __MINGW32__
00748 munmap(map_addr, stat_buf.st_size);
00749 #endif
00750 return st;
00751 }
00752 return IPALNO_SUCCESS;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 Elf64_Shdr* IPA_LNO_READ_FILE::Section_Header(Elf64_Word info)
00762 {
00763 register INT i;
00764 FmtAssert(ifl != NULL, ("Section_Header: Missing Input_File"));
00765 void* mapped_address = ifl->mapped_address;
00766 Elf64_Ehdr *eh = (Elf64_Ehdr *) mapped_address;
00767 Elf64_Shdr *sh;
00768
00769
00770 Elf64_Word type = SHT_MIPS_IPALNO;
00771 if (mapped_address == 0) {
00772 errno = EINVAL;
00773 return NULL;
00774 }
00775 errno = 0;
00776 sh = (Elf64_Shdr *) ((char *) mapped_address + eh->e_shoff);
00777 sh += 1;
00778 for (i = 1; i < eh->e_shnum; i++) {
00779 if ((sh->sh_type == type) && (sh->sh_info == info))
00780 return sh;
00781 sh += 1;
00782 }
00783 return NULL;
00784 }
00785
00786
00787
00788
00789
00790
00791
00792 void* IPA_LNO_READ_FILE::Section_Address(Elf64_Word info)
00793 {
00794 FmtAssert(ifl != NULL, ("Section_Address: Missing Input_File"));
00795 Elf64_Shdr* shdr = Section_Header(info);
00796 if (shdr == NULL)
00797 return NULL;
00798 return (void*) ((char*) ifl->mapped_address + shdr->sh_offset);
00799 }
00800
00801
00802
00803
00804
00805
00806
00807 INT IPA_LNO_READ_FILE::Section_Size(Elf64_Word info)
00808 {
00809 FmtAssert(ifl != NULL, ("Section_Size: Missing Input_File"));
00810 Elf64_Shdr* shdr = Section_Header(info);
00811 if (shdr == NULL)
00812 return 0;
00813 return (INT) shdr->sh_size;
00814 }
00815
00816
00817
00818
00819
00820
00821 void IPA_LNO_READ_FILE::Close_Read_File()
00822 {
00823 #ifndef __MINGW32__
00824 if (ifl != NULL)
00825 munmap(ifl->mapped_address, ifl->mapped_size);
00826 #endif
00827 }
00828
00829
00830
00831
00832
00833
00834
00835 IPA_LNO_SUMMARY_PROCEDURE* IPA_LNO_READ_FILE::Procedure(INT i)
00836 {
00837 IPA_LNO_SUMMARY_PROCEDURE* sa
00838 = (IPA_LNO_SUMMARY_PROCEDURE*) Section_Address(IPA_PROCEDURE);
00839 return &sa[i];
00840 }
00841
00842
00843
00844
00845
00846
00847
00848 INT IPA_LNO_READ_FILE::Procedure_Count()
00849 {
00850 return Section_Size(IPA_PROCEDURE) / sizeof(IPA_LNO_SUMMARY_PROCEDURE);
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 PROJECTED_REGION* IPA_LNO_READ_FILE::Projected_Region(INT i)
00860 {
00861 PROJECTED_REGION* sa
00862 = (PROJECTED_REGION*) Section_Address(IPA_PROJECTED_REGION);
00863 return &sa[i];
00864 }
00865
00866
00867
00868
00869
00870
00871
00872 INT IPA_LNO_READ_FILE::Projected_Region_Count()
00873 {
00874 return Section_Size(IPA_PROJECTED_REGION) / sizeof(PROJECTED_REGION);
00875 }
00876
00877
00878
00879
00880
00881
00882
00883 PROJECTED_NODE* IPA_LNO_READ_FILE::Projected_Node(INT i)
00884 {
00885 PROJECTED_NODE* sa = (PROJECTED_NODE*) Section_Address(IPA_PROJECTED_ARRAY);
00886 return &sa[i];
00887 }
00888
00889
00890
00891
00892
00893
00894
00895 INT IPA_LNO_READ_FILE::Projected_Node_Count()
00896 {
00897 return Section_Size(IPA_PROJECTED_ARRAY) / sizeof(PROJECTED_NODE);
00898 }
00899
00900
00901
00902
00903
00904
00905 TERM* IPA_LNO_READ_FILE::Term(INT i)
00906 {
00907 TERM* sa = (TERM*) Section_Address(IPA_TERM_ARRAY);
00908 return &sa[i];
00909 }
00910
00911
00912
00913
00914
00915
00916 INT IPA_LNO_READ_FILE::Term_Count()
00917 {
00918 return Section_Size(IPA_TERM_ARRAY) / sizeof(TERM);
00919 }
00920
00921
00922
00923
00924
00925
00926 IVAR* IPA_LNO_READ_FILE::Ivar(INT i)
00927 {
00928 if (i < Original_Ivar_Count()) {
00929 IVAR* sa = (IVAR*) Section_Address(IPA_IVAR);
00930 return &sa[i];
00931 } else {
00932 return &_extra_ivars[i - Original_Ivar_Count()];
00933 }
00934 }
00935
00936
00937
00938
00939
00940
00941
00942 INT IPA_LNO_READ_FILE::Add_Translated_Ivar(const IVAR& ivar)
00943 {
00944 _extra_ivars.AddElement(ivar);
00945 return Original_Ivar_Count() + _extra_ivars.Lastidx();
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955 INT IPA_LNO_READ_FILE::Add_Translated_Ivar_Unique(const IVAR& ivar)
00956 {
00957 for (INT i = 0; i < Ivar_Count(); i++) {
00958 if (*Ivar(i) == ivar)
00959 return i;
00960 }
00961 return Add_Translated_Ivar(ivar);
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971 INT IPA_LNO_READ_FILE::Original_Ivar_Count()
00972 {
00973 return Section_Size(IPA_IVAR) / sizeof(IVAR);
00974 }
00975
00976
00977
00978
00979
00980
00981
00982 INT IPA_LNO_READ_FILE::Ivar_Count()
00983 {
00984 INT old_ivar_count = Original_Ivar_Count();
00985 INT new_ivar_count = _extra_ivars.Lastidx() + 1;
00986 return old_ivar_count + new_ivar_count;
00987 }
00988
00989
00990
00991
00992
00993
00994
00995 IPA_LNO_SUMMARY_FORMAL* IPA_LNO_READ_FILE::Formal(INT i)
00996 {
00997 IPA_LNO_SUMMARY_FORMAL* sa
00998 = (IPA_LNO_SUMMARY_FORMAL*) Section_Address(IPA_FORMAL);
00999 return &sa[i];
01000 }
01001
01002
01003
01004
01005
01006
01007
01008 INT IPA_LNO_READ_FILE::Formal_Count()
01009 {
01010 return Section_Size(IPA_FORMAL) / sizeof(IPA_LNO_SUMMARY_FORMAL);
01011 }
01012
01013
01014
01015
01016
01017
01018
01019 IPA_LNO_SUMMARY_GLOBAL* IPA_LNO_READ_FILE::Global(INT i)
01020 {
01021 IPA_LNO_SUMMARY_GLOBAL* sa
01022 = (IPA_LNO_SUMMARY_GLOBAL*) Section_Address(IPA_GLOBAL);
01023 return &sa[i];
01024 }
01025
01026
01027
01028
01029
01030
01031
01032 INT IPA_LNO_READ_FILE::Global_Count()
01033 {
01034 return Section_Size(IPA_GLOBAL) / sizeof(IPA_LNO_SUMMARY_GLOBAL);
01035 }
01036
01037
01038
01039
01040
01041
01042
01043 SUMMARY_VALUE* IPA_LNO_READ_FILE::Value(INT i)
01044 {
01045 SUMMARY_VALUE* sa = (SUMMARY_VALUE*) Section_Address(IPA_VALUE);
01046 return &sa[i];
01047 }
01048
01049
01050
01051
01052
01053
01054 INT IPA_LNO_READ_FILE::Value_Count()
01055 {
01056 return Section_Size(IPA_VALUE) / sizeof(SUMMARY_VALUE);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065 SUMMARY_EXPR* IPA_LNO_READ_FILE::Expr(INT i)
01066 {
01067 SUMMARY_EXPR* sa = (SUMMARY_EXPR*) Section_Address(IPA_EXPR);
01068 return &sa[i];
01069 }
01070
01071
01072
01073
01074
01075
01076 INT IPA_LNO_READ_FILE::Expr_Count()
01077 {
01078 return Section_Size(IPA_EXPR) / sizeof(SUMMARY_EXPR);
01079 }
01080