Chromium Code Reviews| 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) | |
|
robertm
2012/04/27 19:46:15
the convention seems to be to move "*" to the left
Aleksandar Simeonov
2012/05/08 15:21:42
Will be done.
| |
| 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 |
| 2361 unsigned int | 2367 unsigned int |
| 2362 Symbol_table::set_dynsym_indexes(unsigned int index, | 2368 Symbol_table::set_dynsym_indexes(unsigned int index, |
| 2363 std::vector<Symbol*>* syms, | 2369 std::vector<Symbol*>* syms, |
| 2364 Stringpool* dynpool, | 2370 Stringpool* dynpool, |
| 2365 Versions* versions) | 2371 Versions* versions) |
| 2366 { | 2372 { |
| 2373 std::vector<Symbol *> externals; | |
|
robertm
2012/04/27 19:46:15
are these change specific to MIPS - if yes explain
Aleksandar Simeonov
2012/05/08 15:21:42
The dynamic symbol table is divided into local and
| |
| 2374 int i; | |
| 2375 | |
| 2367 for (Symbol_table_type::iterator p = this->table_.begin(); | 2376 for (Symbol_table_type::iterator p = this->table_.begin(); |
| 2368 p != this->table_.end(); | 2377 p != this->table_.end(); |
| 2369 ++p) | 2378 ++p) |
| 2370 { | 2379 { |
| 2371 Symbol* sym = p->second; | 2380 Symbol* sym = p->second; |
| 2372 | 2381 |
| 2373 // Note that SYM may already have a dynamic symbol index, since | 2382 // Note that SYM may already have a dynamic symbol index, since |
| 2374 // some symbols appear more than once in the symbol table, with | 2383 // some symbols appear more than once in the symbol table, with |
| 2375 // and without a version. | 2384 // and without a version. |
| 2376 | 2385 |
| 2377 if (!sym->should_add_dynsym_entry(this)) | 2386 if (!sym->should_add_dynsym_entry(this)) |
| 2378 sym->set_dynsym_index(-1U); | 2387 sym->set_dynsym_index(-1U); |
| 2379 else if (!sym->has_dynsym_index()) | 2388 else if((!sym->has_dynsym_index() && sym->has_got_offset(0)) |
|
robertm
2012/04/27 19:46:15
This condition is complex enough that it might be
| |
| 2389 » && (!sym->final_value_is_known() | |
| 2390 » || (parameters->options().output_is_position_independent()))) | |
| 2391 » { | |
| 2392 » externals.push_back(sym); | |
| 2393 » } | |
| 2394 else if(!sym->has_dynsym_index()) | |
| 2380 { | 2395 { |
| 2381 sym->set_dynsym_index(index); | 2396 sym->set_dynsym_index(index); |
| 2382 ++index; | 2397 ++index; |
| 2383 syms->push_back(sym); | 2398 syms->push_back(sym); |
| 2384 dynpool->add(sym->name(), false, NULL); | 2399 dynpool->add(sym->name(), false, NULL); |
| 2385 | 2400 |
| 2386 // Record any version information. | 2401 // Record any version information. |
| 2387 if (sym->version() != NULL) | 2402 if (sym->version() != NULL) |
| 2388 versions->record_version(this, dynpool, sym); | 2403 versions->record_version(this, dynpool, sym); |
| 2389 | 2404 |
| 2390 // If the symbol is defined in a dynamic object and is | 2405 // If the symbol is defined in a dynamic object and is |
| 2391 // referenced in a regular object, then mark the dynamic | 2406 // referenced in a regular object, then mark the dynamic |
| 2392 // object as needed. This is used to implement --as-needed. | 2407 // object as needed. This is used to implement --as-needed. |
| 2393 if (sym->is_from_dynobj() && sym->in_reg()) | 2408 if (sym->is_from_dynobj() && sym->in_reg()) |
| 2394 sym->object()->set_is_needed(); | 2409 sym->object()->set_is_needed(); |
| 2395 } | 2410 } |
| 2396 } | 2411 } |
| 2397 | 2412 |
| 2398 // Finish up the versions. In some cases this may add new dynamic | 2413 // At the end of dynamic symbol table place global symbols that has |
| 2399 // symbols. | 2414 // .got entry. |
| 2415 std::sort(externals.begin(), externals.end(), got_offset_compare); | |
|
robertm
2012/04/27 19:46:15
mention all the extra work you do here in the func
Aleksandar Simeonov
2012/05/08 15:21:42
Will be done.
| |
| 2416 for(i = 0; (unsigned int)i < externals.size(); i++) | |
| 2417 { | |
| 2418 Symbol* sym = externals[i]; | |
| 2419 | |
| 2420 if(sym->has_dynsym_index()) | |
| 2421 continue; | |
| 2422 | |
| 2423 // Record any version information. | |
| 2424 if (sym->version() != NULL) | |
| 2425 versions->record_version(this, dynpool, sym); | |
| 2426 } | |
| 2427 | |
| 2400 index = versions->finalize(this, index, syms); | 2428 index = versions->finalize(this, index, syms); |
| 2401 | 2429 |
| 2430 // Set index of the first external symbol that has .got entry. | |
| 2431 this->global_got_index_ = index; | |
| 2432 | |
| 2433 for(i = 0; (unsigned int)i < externals.size(); i++) | |
| 2434 { | |
| 2435 Symbol* sym = externals[i]; | |
| 2436 | |
| 2437 if(sym->has_dynsym_index()) | |
| 2438 continue; | |
| 2439 | |
| 2440 sym->set_dynsym_index(index); | |
| 2441 ++index; | |
| 2442 syms->push_back(sym); | |
| 2443 dynpool->add(sym->name(), false, NULL); | |
| 2444 | |
| 2445 // If the symbol is defined in a dynamic object and is | |
| 2446 // referenced in a regular object, then mark the dynamic | |
| 2447 // object as needed. This is used to implement --as-needed. | |
| 2448 if (sym->is_from_dynobj() && sym->in_reg()) | |
| 2449 sym->object()->set_is_needed(); | |
| 2450 } | |
| 2451 | |
| 2452 // If there are no global symbols with .got entry set value to -1. | |
| 2453 if(this->global_got_index_ == index) | |
| 2454 this->global_got_index_ = (unsigned int)-1; | |
| 2455 | |
| 2402 return index; | 2456 return index; |
| 2403 } | 2457 } |
| 2404 | 2458 |
| 2405 // Set the final values for all the symbols. The index of the first | 2459 // 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 | 2460 // global symbol in the output file is *PLOCAL_SYMCOUNT. Record the |
| 2407 // file offset OFF. Add their names to POOL. Return the new file | 2461 // file offset OFF. Add their names to POOL. Return the new file |
| 2408 // offset. Update *PLOCAL_SYMCOUNT if necessary. | 2462 // offset. Update *PLOCAL_SYMCOUNT if necessary. |
| 2409 | 2463 |
| 2410 off_t | 2464 off_t |
| 2411 Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index, | 2465 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 | 3627 |
| 3574 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) | 3628 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) |
| 3575 template | 3629 template |
| 3576 void | 3630 void |
| 3577 Symbol_table::define_with_copy_reloc<64>( | 3631 Symbol_table::define_with_copy_reloc<64>( |
| 3578 Sized_symbol<64>* sym, | 3632 Sized_symbol<64>* sym, |
| 3579 Output_data* posd, | 3633 Output_data* posd, |
| 3580 elfcpp::Elf_types<64>::Elf_Addr value); | 3634 elfcpp::Elf_types<64>::Elf_Addr value); |
| 3581 #endif | 3635 #endif |
| 3582 | 3636 |
| 3637 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) | |
| 3638 template | |
| 3639 void | |
| 3640 Sized_symbol<32>::init_output_data(const char* name, const char* version, | |
| 3641 Output_data* od, Value_type value, | |
|
robertm
2012/04/27 19:46:15
indentation is off, also convention seems to be on
Aleksandar Simeonov
2012/05/08 15:21:42
It is not sure what is convention since before the
| |
| 3642 Size_type symsize, elfcpp::STT type, | |
| 3643 elfcpp::STB binding, | |
| 3644 elfcpp::STV visibility, | |
| 3645 unsigned char nonvis, | |
| 3646 bool offset_is_from_end, | |
| 3647 bool is_predefined); | |
| 3648 #endif | |
| 3649 | |
| 3650 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) | |
| 3651 template | |
| 3652 void | |
| 3653 Sized_symbol<64>::init_output_data(const char* name, const char* version, | |
| 3654 Output_data* od, Value_type value, | |
|
robertm
2012/04/27 19:46:15
here too
Aleksandar Simeonov
2012/05/08 15:21:42
Same as above.
| |
| 3655 Size_type symsize, elfcpp::STT type, | |
| 3656 elfcpp::STB binding, | |
| 3657 elfcpp::STV visibility, | |
| 3658 unsigned char nonvis, | |
| 3659 bool offset_is_from_end, | |
| 3660 bool is_predefined); | |
| 3661 #endif | |
| 3662 | |
| 3583 #ifdef HAVE_TARGET_32_LITTLE | 3663 #ifdef HAVE_TARGET_32_LITTLE |
| 3584 template | 3664 template |
| 3585 void | 3665 void |
| 3586 Warnings::issue_warning<32, false>(const Symbol* sym, | 3666 Warnings::issue_warning<32, false>(const Symbol* sym, |
| 3587 const Relocate_info<32, false>* relinfo, | 3667 const Relocate_info<32, false>* relinfo, |
| 3588 size_t relnum, off_t reloffset) const; | 3668 size_t relnum, off_t reloffset) const; |
| 3589 #endif | 3669 #endif |
| 3590 | 3670 |
| 3591 #ifdef HAVE_TARGET_32_BIG | 3671 #ifdef HAVE_TARGET_32_BIG |
| 3592 template | 3672 template |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3606 | 3686 |
| 3607 #ifdef HAVE_TARGET_64_BIG | 3687 #ifdef HAVE_TARGET_64_BIG |
| 3608 template | 3688 template |
| 3609 void | 3689 void |
| 3610 Warnings::issue_warning<64, true>(const Symbol* sym, | 3690 Warnings::issue_warning<64, true>(const Symbol* sym, |
| 3611 const Relocate_info<64, true>* relinfo, | 3691 const Relocate_info<64, true>* relinfo, |
| 3612 size_t relnum, off_t reloffset) const; | 3692 size_t relnum, off_t reloffset) const; |
| 3613 #endif | 3693 #endif |
| 3614 | 3694 |
| 3615 } // End namespace gold. | 3695 } // End namespace gold. |
| OLD | NEW |