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 #include "common/h/Dictionary.h"
00034 #include "Object.h"
00035 #include "Object-coff.h"
00036 #include <cmplrs/demangle_string.h>
00037
00038 bool GCC_COMPILED=false;
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 static inline bool obj_read_section(SCNHDR& secthead, LDFILE *ldptr,
00120 Word *buffer) {
00121 if (!secthead.s_scnptr) return false;
00122 if (ldfseek(ldptr, secthead.s_scnptr, SEEK_SET) == -1) return false;
00123
00124 if (ldfread((void*) buffer, 1, secthead.s_size, ldptr) != secthead.s_size)
00125 return false;
00126 else
00127 return true;
00128 }
00129
00130
00131
00132 #define K_D_INDEX 0
00133 #define K_XD_INDEX 1
00134 #define K_PD_INDEX 2
00135 #define K_SD_INDEX 3
00136 #define K_RD_INDEX 4
00137 #define K_RC_INDEX 5
00138 #define K_L4_INDEX 6
00139 #define K_L8_INDEX 7
00140 #define K_LA_INDEX 8
00141
00142
00143
00144 static inline bool find_data_region(vector<Address>& all_addr,
00145 vector<long>& all_size,
00146 vector<long>& all_disk,
00147 unsigned long& data_len, Address& data_off) {
00148
00149 assert(all_addr[K_D_INDEX]); assert(all_size[K_D_INDEX]);
00150 assert(all_addr.size() == all_size.size());
00151
00152 Address current = all_addr[K_D_INDEX];
00153 Address min_adr = current;
00154 Address max_adr = current + all_size[K_D_INDEX];
00155
00156 unsigned index, max=all_addr.size();
00157
00158 bool updated=true;
00159 while (updated) {
00160 updated = false;
00161 for (index=0; index<max; index++) {
00162 if (all_addr[index] && all_size[index] && all_disk[index] &&
00163 ((all_addr[index] + all_size[index]) == current)) {
00164 current = all_addr[index];
00165 updated = true;
00166 }
00167 }
00168 }
00169 min_adr = current;
00170
00171
00172 current = max_adr;
00173 updated=true;
00174 while (updated) {
00175 updated = false;
00176 for (index=0; index<max; index++) {
00177 if (all_addr[index] && all_size[index] && all_disk[index] &&
00178 (all_addr[index] == current)) {
00179 current = all_addr[index] + all_size[index];
00180 updated = true;
00181 }
00182 }
00183 }
00184
00185 max_adr = current;
00186
00187 data_len = (max_adr - min_adr);
00188 data_off = min_adr;
00189 assert(min_adr <= all_addr[K_D_INDEX]);
00190 assert(max_adr >= all_addr[K_D_INDEX] + all_size[K_D_INDEX]);
00191 return true;
00192 }
00193
00194
00195 static inline bool read_data_region(vector<Address>& all_addr,
00196 vector<long>& all_size,
00197 vector<long>& all_disk,
00198 unsigned long& data_len, Address& data_off,
00199 Word *buffer, LDFILE *ldptr) {
00200 unsigned index, max = all_disk.size();
00201 Address max_adr = data_off + data_len;
00202 assert(all_size.size() == all_addr.size());
00203 assert(all_disk.size() == all_addr.size());
00204 for (index=0; index<max; index++) {
00205 if ((all_addr[index] >= data_off) &&
00206 ((all_addr[index] + all_size[index]) <= max_adr)) {
00207 if (ldfseek(ldptr, all_disk[index], SEEK_SET) == -1) return false;
00208 Word *buf_temp = buffer + (all_addr[index] - data_off);
00209 if (ldfread((void*) buf_temp, 1, all_size[index], ldptr) != all_size[index])
00210 return false;
00211 }
00212 }
00213 return true;
00214 }
00215
00216 void Object::load_object(bool sharedLibrary) {
00217 bool success=true, text_read=false;
00218 HDRR sym_hdr;
00219 pCHDRR sym_tab_ptr = NULL;
00220 long index=0;
00221 SYMR symbol;
00222 unsigned short sectindex=1;
00223 SCNHDR secthead;
00224 unsigned nsymbols;
00225 vector<Symbol> allSymbols;
00226 vector<Address> all_addr(9, 0);
00227 vector<long> all_size(9, 0);
00228 vector<bool> all_dex(9, false);
00229 vector<long> all_disk(9, 0);
00230
00231
00232 unsigned short fmax = fhdr.f_nscns;
00233
00234 dynamicallyLinked = false;
00235
00236
00237
00238 while (sectindex < fmax) {
00239 if (ldshread(ldptr, sectindex, §head) == SUCCESS) {
00240
00241
00242 sections_.push_back(new Dyn_Section(sectindex, secthead.s_name, secthead.s_vaddr, secthead.s_size));
00243 if (!P_strcmp(secthead.s_name, ".text")) {
00244 code_len_ = (Word) secthead.s_size;
00245 Word *buffer = new Word[code_len_+1];
00246 code_ptr_ = buffer;
00247 code_off_ = (Address) secthead.s_vaddr;
00248 if (!obj_read_section(secthead, ldptr, buffer)) {
00249 success = false;
00250
00251 ldclose(ldptr);
00252 free(file);
00253 return;
00254 }
00255 text_read = true;
00256 } else if (!P_strcmp(secthead.s_name, ".data")) {
00257 if (secthead.s_vaddr && secthead.s_scnptr) {
00258 all_addr[K_D_INDEX] = secthead.s_vaddr;
00259 all_size[K_D_INDEX] = secthead.s_size;
00260 all_dex[K_D_INDEX] = true;
00261 all_disk[K_D_INDEX] = secthead.s_scnptr;
00262 } else {
00263
00264 success = false;
00265 ldclose(ldptr);
00266 free(file);
00267 return;
00268 }
00269 } else if (!P_strcmp(secthead.s_name, ".xdata")) {
00270 if (secthead.s_vaddr && secthead.s_scnptr) {
00271 all_addr[K_XD_INDEX] = secthead.s_vaddr;
00272 all_size[K_XD_INDEX] = secthead.s_size;
00273 all_dex[K_XD_INDEX] = true;
00274 all_disk[K_XD_INDEX] = secthead.s_scnptr;
00275 }
00276 } else if (!P_strcmp(secthead.s_name, ".sdata")) {
00277 if (secthead.s_vaddr && secthead.s_scnptr) {
00278 all_addr[K_SD_INDEX] = secthead.s_vaddr;
00279 all_size[K_SD_INDEX] = secthead.s_size;
00280 all_dex[K_SD_INDEX] = true;
00281 all_disk[K_SD_INDEX] = secthead.s_scnptr;
00282 }
00283 } else if (!P_strcmp(secthead.s_name, ".rdata")) {
00284 if (secthead.s_vaddr && secthead.s_scnptr) {
00285 all_addr[K_RD_INDEX] = secthead.s_vaddr;
00286 all_size[K_RD_INDEX] = secthead.s_size;
00287 all_dex[K_RD_INDEX] = true;
00288 all_disk[K_RD_INDEX] = secthead.s_scnptr;
00289 }
00290 } else if (!P_strcmp(secthead.s_name, ".lit4")) {
00291 if (secthead.s_vaddr && secthead.s_scnptr) {
00292 all_addr[K_L4_INDEX] = secthead.s_vaddr;
00293 all_size[K_L4_INDEX] = secthead.s_size;
00294 all_dex[K_L4_INDEX] = true;
00295 all_disk[K_L4_INDEX] = secthead.s_scnptr;
00296 }
00297 } else if (!P_strcmp(secthead.s_name, ".lita")) {
00298 if (secthead.s_vaddr && secthead.s_scnptr) {
00299 all_addr[K_LA_INDEX] = secthead.s_vaddr;
00300 all_size[K_LA_INDEX] = secthead.s_size;
00301 all_dex[K_LA_INDEX] = true;
00302 all_disk[K_LA_INDEX] = secthead.s_scnptr;
00303 }
00304 } else if (!P_strcmp(secthead.s_name, ".rconst")) {
00305 if (secthead.s_vaddr && secthead.s_scnptr) {
00306 all_addr[K_RC_INDEX] = secthead.s_vaddr;
00307 all_size[K_RC_INDEX] = secthead.s_size;
00308 all_dex[K_RC_INDEX] = true;
00309 all_disk[K_RC_INDEX] = secthead.s_scnptr;
00310 }
00311 } else if (!P_strcmp(secthead.s_name, ".lit8")) {
00312 if (secthead.s_vaddr && secthead.s_scnptr) {
00313 all_addr[K_L8_INDEX] = secthead.s_vaddr;
00314 all_size[K_L8_INDEX] = secthead.s_size;
00315 all_dex[K_L8_INDEX] = true;
00316 all_disk[K_L8_INDEX] = secthead.s_scnptr;
00317 }
00318 } else if (!P_strncmp(secthead.s_name, ".dynamic", 8)) {
00319
00320 dynamicallyLinked = true;
00321 }
00322 } else {
00323 success = false;
00324
00325 ldclose(ldptr);
00326 free(file);
00327 return;
00328 }
00329 sectindex++;
00330 }
00331 no_of_sections = sectindex;
00332
00333 if (!text_read) {
00334 success = false;
00335
00336 ldclose(ldptr);
00337 free(file);
00338 return;
00339 }
00340
00341
00342
00343
00344 if (all_disk[K_D_INDEX]) {
00345 if (!find_data_region(all_addr, all_size, all_disk,
00346 data_len_, data_off_)) {
00347 success = false;
00348
00349 ldclose(ldptr);
00350 free(file);
00351 return;
00352 }
00353 }
00354
00355
00356 Word *buffer = new Word[data_len_+1];
00357 data_ptr_ = buffer;
00358 if (!read_data_region(all_addr, all_size, all_disk,
00359 data_len_, data_off_, buffer, ldptr)) {
00360 success = false;
00361
00362 ldclose(ldptr);
00363 free(file);
00364 return;
00365 }
00366
00367
00368 code_vldS_ = code_off_;
00369 code_vldE_ = code_off_ + code_len_;
00370 data_vldS_ = data_off_;
00371 data_vldE_ = data_off_ + code_len_;
00372
00373
00374 if (!(sym_tab_ptr = PSYMTAB(ldptr))) {
00375 success = false;
00376
00377 ldclose(ldptr);
00378 free(file);
00379 return;
00380 }
00381
00382
00383 sym_hdr = SYMHEADER(ldptr);
00384 if (sym_hdr.magic != magicSym) {
00385 success = false;
00386
00387 ldclose(ldptr);
00388 free(file);
00389 return;
00390 }
00391 if (!(sym_tab_ptr = SYMTAB(ldptr))) {
00392 success = false;
00393
00394 ldclose(ldptr);
00395 free(file);
00396 return;
00397 }
00398 if (LDSWAP(ldptr)) {
00399
00400
00401 assert(0);
00402 }
00403
00404 string module = "DEFAULT_MODULE";
00405 if (sharedLibrary) {
00406 module = file_;
00407 allSymbols.push_back(Symbol(module, module, Symbol::ST_MODULE,
00408 Symbol::SL_GLOBAL, (Address) 0, false,));
00409 } else {
00410 module = "DEFAULT_MODULE";
00411 }
00412
00413 string name = "DEFAULT_SYMBOL";
00414 int moduleEndIdx = -1;
00415 map<string, int> fcnNames;
00416
00417 while (ldtbread(ldptr, index, &symbol) == SUCCESS) {
00418
00419 Symbol::SymbolLinkage linkage = Symbol::SL_GLOBAL;
00420 Symbol::SymbolType type = Symbol::ST_UNKNOWN;
00421 bool st_kludge = false;
00422 bool sym_use = true;
00423 unsigned secNumber;
00424 char *name = ldgetname(ldptr, &symbol);
00425 char prettyName[1024];
00426
00427 switch(symbol.st) {
00428 case stProc:
00429 case stStaticProc:
00430
00431 MLD_demangle_string(name, prettyName, 1024,
00432 MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
00433 if (strchr(prettyName, '('))
00434 *strchr(prettyName, '(') = 0;
00435 name = prettyName;
00436
00437 if (symbol.sc == scText && (fcnNames.find(name)==fcnNames.end()))
00438 {
00439 type = Symbol::ST_FUNCTION;
00440 fcnNames[name] = 1;
00441 secNumber = findSecNumber(".text");
00442 }
00443 else
00444 sym_use = false;
00445 break;
00446
00447 case stGlobal:
00448 case stConstant:
00449 case stStatic:
00450 switch(symbol.sc) {
00451 case scData:
00452 secNumber = findSecNumber(".data");
00453 type = Symbol::ST_OBJECT;
00454 break;
00455 case scBss:
00456 secNumber = findSecNumber(".bss");
00457 type = Symbol::ST_OBJECT;
00458 break;
00459 case scSData:
00460 case scSBss:
00461 case scRData:
00462 case scRConst:
00463 case scTlsData:
00464 case scTlsBss:
00465 secNumber = findSecNumber(".sdata");
00466 type = Symbol::ST_OBJECT;
00467 break;
00468 default:
00469 sym_use = false;
00470 }
00471 break;
00472
00473 case stLocal:
00474 case stParam:
00475 linkage = Symbol::SL_LOCAL;
00476
00477 switch(symbol.sc) {
00478 case scAbs:
00479 case scRegister:
00480 case scVar:
00481 case scVarRegister:
00482 case scUnallocated:
00483 secNumber = findSecNumber(".rdata");
00484 type = Symbol::ST_OBJECT;
00485 break;
00486 case scData:
00487 secNumber = findSecNumber(".data");
00488
00489 if (symbol.st == stParam)
00490 type = Symbol::ST_OBJECT;
00491 else
00492 sym_use = false;
00493 break;
00494 case scSData:
00495 case scBss:
00496 case scSBss:
00497 case scRConst:
00498 case scRData:
00499 secNumber = findSecNumber(".rdata");
00500
00501 if (symbol.st == stParam)
00502 type = Symbol::ST_OBJECT;
00503 else
00504 sym_use = false;
00505 break;
00506
00507 default:
00508 sym_use = false;
00509 }
00510 break;
00511
00512 case stTypedef:
00513 case stBase:
00514 case stTag:
00515 secNumber = findSecNumber(".rdata");
00516 if (symbol.sc == scInfo)
00517 type = Symbol::ST_OBJECT;
00518 else
00519 sym_use = false;
00520 break;
00521
00522 case stFile:
00523 secNumber = findSecNumber(".rdata");
00524 if (!sharedLibrary) {
00525 module = ldgetname(ldptr, &symbol); assert(module.length());
00526 type = Symbol::ST_MODULE;
00527 moduleEndIdx = symbol.index - 1;
00528
00529 if (strstr(module.c_str(), "libgcc"))
00530 GCC_COMPILED = true;
00531 }
00532 break;
00533
00534 case stLabel:
00535
00536
00537
00538 if (symbol.sc == scText &&
00539 code_vldS_ <= (unsigned) symbol.value && (unsigned) symbol.value < code_vldE_ &&
00540 name && *name && (fcnNames.find(name)=fcnNames.end())) {
00541
00542
00543
00544 secNumber = findSecNumber(".text");
00545 MLD_demangle_string(name, prettyName, 1024,
00546 MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
00547 if (strchr(prettyName, '('))
00548 *strchr(prettyName, '(') = 0;
00549 name = prettyName;
00550
00551 type = Symbol::ST_FUNCTION;
00552 fcnNames[name] = 1;
00553
00554 } else {
00555 sym_use = false;
00556 }
00557 break;
00558
00559 case stEnd:
00560 if (index == moduleEndIdx)
00561 module = "DEFAULT_MODULE";
00562 sym_use = false;
00563 break;
00564
00565 default:
00566 sym_use = false;
00567 }
00568
00569
00570
00571 if (P_strchr(name, ':'))
00572 sym_use = false;
00573
00574
00575
00576 index++;
00577
00578 if (sym_use) {
00579
00580 allSymbols.push_back(Symbol(name, module, type, linkage,
00581 (Address) symbol.value, st_kludge,secNumber));
00582 }
00583
00584 }
00585
00586 sort(allSymbols.begin(),allSymbols.end(),symbol_compare());
00587
00588 nsymbols = allSymbols.size();
00589 no_of_symbols = nsymbols;
00590
00591
00592 for (unsigned u = 0; u < nsymbols; u++) {
00593 unsigned size = 0;
00594 if (allSymbols[u].type() == Symbol::ST_FUNCTION) {
00595 unsigned v = u+1;
00596 while (v < nsymbols) {
00597
00598
00599 if (allSymbols[v].addr() != allSymbols[u].addr() &&
00600 (allSymbols[v].type() == Symbol::ST_FUNCTION ||
00601 allSymbols[v].name() == ".ef"))
00602 break;
00603 v++;
00604 }
00605 if (v < nsymbols) {
00606 size = (unsigned)allSymbols[v].addr()
00607 - (unsigned)allSymbols[u].addr();
00608 } else {
00609 size = (unsigned)(code_off_+code_len_)
00610 - (unsigned)allSymbols[u].addr();
00611 }
00612 }
00613
00614 if (allSymbols[u].linkage() != Symbol::SL_LOCAL) {
00615 symbols_[allSymbols[u].name()].push_back(
00616 Symbol(allSymbols[u].name(), allSymbols[u].module(),
00617 allSymbols[u].type(), allSymbols[u].linkage(),
00618 allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), size) );
00619 }
00620 }
00621
00622
00623 for (unsigned u = 0; u < nsymbols; u++) {
00624 if ( (allSymbols[u].linkage() == Symbol::SL_LOCAL) &&
00625 (!symbols_.defines(allSymbols[u].name())) ) {
00626 symbols_[allSymbols[u].name()].push_back(
00627 Symbol(allSymbols[u].name(), allSymbols[u].module(),
00628 allSymbols[u].type(), allSymbols[u].linkage(),
00629 allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), 0) );
00630 }
00631 }
00632
00633 if (did_open && (ldclose(ldptr) == FAILURE)) {
00634 log_perror(err_func_, "close");
00635 }
00636 free(file);
00637
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 Object::Object (const string fileName, const Address ,
00650 void (*err_func)(const char *))
00651 :AObject(fileName,err_func)
00652 {
00653
00654 load_object(true);
00655 }
00656
00657 Object::Object(const fDescriptor &desc, void (*err_func)(const char *))
00658 : AObject(desc.file(), err_func)
00659 {
00660 switch(desc.type)
00661 {
00662 case 1:
00663 {
00664 char* file = strdup(file_.c_str());
00665 did_open = false;
00666 ldptr = NULL;
00667
00668 if (!(ldptr = ldopen(file, ldptr)))
00669 {
00670 log_perror(err_func_, file);
00671 success = false;
00672
00673 free(file);
00674 return;
00675 }
00676 did_open = true;
00677
00678 if (TYPE(ldptr) != ALPHAMAGIC)
00679 {
00680
00681 success = false;
00682
00683 ldclose(ldptr);
00684 free(file);
00685 return;
00686 }
00687
00688
00689 fhdr = HEADER(ldptr);
00690 unsigned flags = fhdr.f_flags;
00691 if(flags & F_EXEC )
00692 load_object(false);
00693 else
00694 load_object(true);
00695 }
00696 case 2:
00697 {
00698 }
00699 default:
00700 {
00701 log_perror(err_func_, "ELF header");
00702 return;
00703 break;
00704 }
00705 }
00706
00707 load_object(desc.isSharedObject());
00708 }
00709
00710 Object::Object(const Object& obj)
00711 : AObject(obj) {
00712 load_object(false);
00713 }
00714
00715 void Dyn_Symtab::getModuleLanguageInfo(dyn_hash_map<string, supportedLanguages> *)
00716 {
00717 }
00718
00719 bool Region::isStandardCode()
00720 {
00721 return (getRegionPermissions() == RP_RX ||
00722 getRegionPermissions() == RP_RWX);
00723 }