OLD | NEW |
---|---|
1 // symtab.cc -- the gold symbol table | 1 // symtab.cc -- the gold symbol table |
2 | 2 |
3 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. | 3 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
4 // Written by Ian Lance Taylor <iant@google.com>. | 4 // Written by Ian Lance Taylor <iant@google.com>. |
5 | 5 |
6 // This file is part of gold. | 6 // This file is part of gold. |
7 | 7 |
8 // This program is free software; you can redistribute it and/or modify | 8 // This program is free software; you can redistribute it and/or modify |
9 // it under the terms of the GNU General Public License as published by | 9 // it under the terms of the GNU General Public License as published by |
10 // the Free Software Foundation; either version 3 of the License, or | 10 // the Free Software Foundation; either version 3 of the License, or |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
523 // Class Symbol_table. | 523 // Class Symbol_table. |
524 | 524 |
525 Symbol_table::Symbol_table(unsigned int count, | 525 Symbol_table::Symbol_table(unsigned int count, |
526 const Version_script_info& version_script) | 526 const Version_script_info& version_script) |
527 : saw_undefined_(0), offset_(0), table_(count), namepool_(), | 527 : saw_undefined_(0), offset_(0), table_(count), namepool_(), |
528 forwarders_(), commons_(), tls_commons_(), small_commons_(), | 528 forwarders_(), commons_(), tls_commons_(), small_commons_(), |
529 large_commons_(), forced_locals_(), warnings_(), | 529 large_commons_(), forced_locals_(), warnings_(), |
530 version_script_(version_script), gc_(NULL), icf_(NULL) | 530 version_script_(version_script), gc_(NULL), icf_(NULL), |
531 global_got_index_((unsigned int)-1) | |
531 { | 532 { |
532 namepool_.reserve(count); | 533 namepool_.reserve(count); |
533 } | 534 } |
534 | 535 |
535 Symbol_table::~Symbol_table() | 536 Symbol_table::~Symbol_table() |
536 { | 537 { |
537 } | 538 } |
538 | 539 |
539 // The symbol table key equality function. This is called with | 540 // The symbol table key equality function. This is called with |
540 // Stringpool keys. | 541 // Stringpool keys. |
(...skipping 1805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2346 #endif | 2347 #endif |
2347 } | 2348 } |
2348 | 2349 |
2349 gold_assert(oldsym == NULL); | 2350 gold_assert(oldsym == NULL); |
2350 | 2351 |
2351 sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, | 2352 sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, |
2352 elfcpp::STV_DEFAULT, 0); | 2353 elfcpp::STV_DEFAULT, 0); |
2353 ++this->saw_undefined_; | 2354 ++this->saw_undefined_; |
2354 } | 2355 } |
2355 | 2356 |
2357 bool got_offset_compare(Symbol* sym1, Symbol* sym2) | |
2358 { | |
2359 return sym1->got_offset(0) < sym2->got_offset(0); | |
2360 } | |
2361 | |
2356 // Set the dynamic symbol indexes. INDEX is the index of the first | 2362 // Set the dynamic symbol indexes. INDEX is the index of the first |
2357 // global dynamic symbol. Pointers to the symbols are stored into the | 2363 // global dynamic symbol. Pointers to the symbols are stored into the |
2358 // vector SYMS. The names are added to DYNPOOL. This returns an | 2364 // vector SYMS. The names are added to DYNPOOL. This returns an |
2359 // updated dynamic symbol index. | 2365 // updated dynamic symbol index. |
2360 | 2366 |
2367 // [MIPS] The dynamic symbol table is divided into local and global parts. | |
2368 // The global part of the dynamic symbol table is further divided into two | |
2369 // parts: symbols that do not have GOT entries associated with them and | |
2370 // symbols that do have GOT entries associated with them. | |
2361 unsigned int | 2371 unsigned int |
2362 Symbol_table::set_dynsym_indexes(unsigned int index, | 2372 Symbol_table::set_dynsym_indexes(unsigned int index, |
2363 std::vector<Symbol*>* syms, | 2373 std::vector<Symbol*>* syms, |
2364 Stringpool* dynpool, | 2374 Stringpool* dynpool, |
2365 Versions* versions) | 2375 Versions* versions) |
2366 { | 2376 { |
2377 std::vector<Symbol *> externals; | |
robertm
2012/05/11 21:50:50
move "*" to left
| |
2378 int i; | |
2379 | |
2367 for (Symbol_table_type::iterator p = this->table_.begin(); | 2380 for (Symbol_table_type::iterator p = this->table_.begin(); |
2368 p != this->table_.end(); | 2381 p != this->table_.end(); |
2369 ++p) | 2382 ++p) |
2370 { | 2383 { |
2371 Symbol* sym = p->second; | 2384 Symbol* sym = p->second; |
2372 | 2385 |
2373 // Note that SYM may already have a dynamic symbol index, since | 2386 // Note that SYM may already have a dynamic symbol index, since |
2374 // some symbols appear more than once in the symbol table, with | 2387 // some symbols appear more than once in the symbol table, with |
2375 // and without a version. | 2388 // and without a version. |
2376 | 2389 |
2377 if (!sym->should_add_dynsym_entry(this)) | 2390 if (!sym->should_add_dynsym_entry(this)) |
2378 sym->set_dynsym_index(-1U); | 2391 sym->set_dynsym_index(-1U); |
2379 else if (!sym->has_dynsym_index()) | 2392 else if((!sym->has_dynsym_index() && sym->has_got_offset(0)) |
robertm
2012/05/11 21:50:50
This condition is complex enough that it might be
| |
2393 » && (!sym->final_value_is_known() | |
2394 » || (parameters->options().output_is_position_independent()))) | |
2395 » { | |
2396 » externals.push_back(sym); | |
2397 » } | |
2398 else if(!sym->has_dynsym_index()) | |
2380 { | 2399 { |
2381 sym->set_dynsym_index(index); | 2400 sym->set_dynsym_index(index); |
2382 ++index; | 2401 ++index; |
2383 syms->push_back(sym); | 2402 syms->push_back(sym); |
2384 dynpool->add(sym->name(), false, NULL); | 2403 dynpool->add(sym->name(), false, NULL); |
2385 | 2404 |
2386 // Record any version information. | 2405 // Record any version information. |
2387 if (sym->version() != NULL) | 2406 if (sym->version() != NULL) |
2388 versions->record_version(this, dynpool, sym); | 2407 versions->record_version(this, dynpool, sym); |
2389 | 2408 |
2390 // If the symbol is defined in a dynamic object and is | 2409 // If the symbol is defined in a dynamic object and is |
2391 // referenced in a regular object, then mark the dynamic | 2410 // referenced in a regular object, then mark the dynamic |
2392 // object as needed. This is used to implement --as-needed. | 2411 // object as needed. This is used to implement --as-needed. |
2393 if (sym->is_from_dynobj() && sym->in_reg()) | 2412 if (sym->is_from_dynobj() && sym->in_reg()) |
2394 sym->object()->set_is_needed(); | 2413 sym->object()->set_is_needed(); |
2395 } | 2414 } |
2396 } | 2415 } |
2397 | 2416 |
2398 // Finish up the versions. In some cases this may add new dynamic | 2417 // At the end of dynamic symbol table place global symbols that has |
2399 // symbols. | 2418 // .got entry. |
2419 std::sort(externals.begin(), externals.end(), got_offset_compare); | |
2420 for(i = 0; (unsigned int)i < externals.size(); i++) | |
2421 { | |
2422 Symbol* sym = externals[i]; | |
2423 | |
2424 if(sym->has_dynsym_index()) | |
2425 continue; | |
2426 | |
2427 // Record any version information. | |
2428 if (sym->version() != NULL) | |
2429 versions->record_version(this, dynpool, sym); | |
2430 } | |
2431 | |
2400 index = versions->finalize(this, index, syms); | 2432 index = versions->finalize(this, index, syms); |
2401 | 2433 |
2434 // Set index of the first external symbol that has .got entry. | |
2435 this->global_got_index_ = index; | |
2436 | |
2437 for(i = 0; (unsigned int)i < externals.size(); i++) | |
2438 { | |
2439 Symbol* sym = externals[i]; | |
2440 | |
2441 if(sym->has_dynsym_index()) | |
2442 continue; | |
2443 | |
2444 sym->set_dynsym_index(index); | |
2445 ++index; | |
2446 syms->push_back(sym); | |
2447 dynpool->add(sym->name(), false, NULL); | |
2448 | |
2449 // If the symbol is defined in a dynamic object and is | |
2450 // referenced in a regular object, then mark the dynamic | |
2451 // object as needed. This is used to implement --as-needed. | |
2452 if (sym->is_from_dynobj() && sym->in_reg()) | |
2453 sym->object()->set_is_needed(); | |
2454 } | |
2455 | |
2456 // If there are no global symbols with .got entry set value to -1. | |
2457 if(this->global_got_index_ == index) | |
2458 this->global_got_index_ = (unsigned int)-1; | |
2459 | |
2402 return index; | 2460 return index; |
2403 } | 2461 } |
2404 | 2462 |
2405 // Set the final values for all the symbols. The index of the first | 2463 // Set the final values for all the symbols. The index of the first |
2406 // global symbol in the output file is *PLOCAL_SYMCOUNT. Record the | 2464 // global symbol in the output file is *PLOCAL_SYMCOUNT. Record the |
2407 // file offset OFF. Add their names to POOL. Return the new file | 2465 // file offset OFF. Add their names to POOL. Return the new file |
2408 // offset. Update *PLOCAL_SYMCOUNT if necessary. | 2466 // offset. Update *PLOCAL_SYMCOUNT if necessary. |
2409 | 2467 |
2410 off_t | 2468 off_t |
2411 Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index, | 2469 Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index, |
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3573 | 3631 |
3574 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) | 3632 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) |
3575 template | 3633 template |
3576 void | 3634 void |
3577 Symbol_table::define_with_copy_reloc<64>( | 3635 Symbol_table::define_with_copy_reloc<64>( |
3578 Sized_symbol<64>* sym, | 3636 Sized_symbol<64>* sym, |
3579 Output_data* posd, | 3637 Output_data* posd, |
3580 elfcpp::Elf_types<64>::Elf_Addr value); | 3638 elfcpp::Elf_types<64>::Elf_Addr value); |
3581 #endif | 3639 #endif |
3582 | 3640 |
3641 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) | |
3642 template | |
3643 void | |
3644 Sized_symbol<32>::init_output_data( | |
3645 const char* name, | |
3646 const char* version, | |
3647 Output_data* od, | |
3648 Value_type value, | |
3649 Size_type symsize, | |
3650 elfcpp::STT type, | |
3651 elfcpp::STB binding, | |
3652 elfcpp::STV visibility, | |
3653 unsigned char nonvis, | |
3654 bool offset_is_from_end, | |
3655 bool is_predefined); | |
3656 #endif | |
3657 | |
3658 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) | |
3659 template | |
3660 void | |
3661 Sized_symbol<64>::init_output_data( | |
3662 const char* name, | |
3663 const char* version, | |
3664 Output_data* od, | |
3665 Value_type value, | |
3666 Size_type symsize, | |
3667 elfcpp::STT type, | |
3668 elfcpp::STB binding, | |
3669 elfcpp::STV visibility, | |
3670 unsigned char nonvis, | |
3671 bool offset_is_from_end, | |
3672 bool is_predefined); | |
3673 #endif | |
3674 | |
3583 #ifdef HAVE_TARGET_32_LITTLE | 3675 #ifdef HAVE_TARGET_32_LITTLE |
3584 template | 3676 template |
3585 void | 3677 void |
3586 Warnings::issue_warning<32, false>(const Symbol* sym, | 3678 Warnings::issue_warning<32, false>(const Symbol* sym, |
3587 const Relocate_info<32, false>* relinfo, | 3679 const Relocate_info<32, false>* relinfo, |
3588 size_t relnum, off_t reloffset) const; | 3680 size_t relnum, off_t reloffset) const; |
3589 #endif | 3681 #endif |
3590 | 3682 |
3591 #ifdef HAVE_TARGET_32_BIG | 3683 #ifdef HAVE_TARGET_32_BIG |
3592 template | 3684 template |
(...skipping 13 matching lines...) Expand all Loading... | |
3606 | 3698 |
3607 #ifdef HAVE_TARGET_64_BIG | 3699 #ifdef HAVE_TARGET_64_BIG |
3608 template | 3700 template |
3609 void | 3701 void |
3610 Warnings::issue_warning<64, true>(const Symbol* sym, | 3702 Warnings::issue_warning<64, true>(const Symbol* sym, |
3611 const Relocate_info<64, true>* relinfo, | 3703 const Relocate_info<64, true>* relinfo, |
3612 size_t relnum, off_t reloffset) const; | 3704 size_t relnum, off_t reloffset) const; |
3613 #endif | 3705 #endif |
3614 | 3706 |
3615 } // End namespace gold. | 3707 } // End namespace gold. |
OLD | NEW |