diff --git a/.gitignore b/.gitignore index 69698a6..dfac6c7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ i386 binutils-2.20.51.0.10.tar.bz2 /binutils-2.20.51.0.11.tar.bz2 /binutils-2.20.51.0.12.tar.bz2 +/binutils-2.21.51.0.5.tar.bz2 diff --git a/binutils-2.20.51.0.10-ldlex-add-caret-pling.patch b/binutils-2.20.51.0.10-ldlex-add-caret-pling.patch deleted file mode 100644 index e6d49b3..0000000 --- a/binutils-2.20.51.0.10-ldlex-add-caret-pling.patch +++ /dev/null @@ -1,19 +0,0 @@ -*** ../binutils-2.20.51.0.10.orig/ld/ldlex.l 2010-08-20 15:28:06.000000000 +0100 ---- ld/ldlex.l 2010-08-20 15:35:27.000000000 +0100 -*************** CMDFILENAMECHAR1 [_a-zA-Z0-9\/\.\\_\+\$ -*** 99,105 **** - FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~] - SYMBOLCHARN [_a-zA-Z\/\.\\\$\_\~0-9] - FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~] -! WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*] - WHITE [ \t\n\r]+ - - NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] ---- 99,105 ---- - FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~] - SYMBOLCHARN [_a-zA-Z\/\.\\\$\_\~0-9] - FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~] -! WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*\^\!] - WHITE [ \t\n\r]+ - - NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] diff --git a/binutils-2.20.51.0.10-update-gold.patch b/binutils-2.20.51.0.10-update-gold.patch deleted file mode 100644 index d8f8962..0000000 --- a/binutils-2.20.51.0.10-update-gold.patch +++ /dev/null @@ -1,7999 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.10.original/elfcpp/i386.h elfcpp/i386.h -*** ../binutils-2.20.51.0.10.original/elfcpp/i386.h 2010-08-10 15:13:23.000000000 +0100 ---- elfcpp/i386.h 2010-08-10 15:14:09.000000000 +0100 -*************** -*** 1,6 **** - // i386.h -- ELF definitions specific to EM_386 -*- C++ -*- - -! // Copyright 2006, 2007, Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of elfcpp. ---- 1,6 ---- - // i386.h -- ELF definitions specific to EM_386 -*- C++ -*- - -! // Copyright 2006, 2007, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of elfcpp. -*************** enum -*** 85,90 **** ---- 85,91 ---- - R_386_TLS_DESC_CALL = 40, // Marker of call through TLS desc for relaxation - R_386_TLS_DESC = 41, // TLS descriptor containing pointer to code and - // to argument, returning TLS offset for symbol -+ R_386_IRELATIVE = 42, // Adjust indirectly by program base - // Used by Intel. - R_386_USED_BY_INTEL_200 = 200, - // GNU vtable garbage collection extensions. -diff -rcp ../binutils-2.20.51.0.10.original/elfcpp/powerpc.h elfcpp/powerpc.h -*** ../binutils-2.20.51.0.10.original/elfcpp/powerpc.h 2010-08-10 15:13:23.000000000 +0100 ---- elfcpp/powerpc.h 2010-08-10 15:14:09.000000000 +0100 -*************** -*** 1,6 **** - // powerpc.h -- ELF definitions specific to EM_PPC and EM_PPC64 -*- C++ -*- - -! // Copyright 2008, Free Software Foundation, Inc. - // Written by David S. Miller . - - // This file is part of elfcpp. ---- 1,6 ---- - // powerpc.h -- ELF definitions specific to EM_PPC and EM_PPC64 -*- C++ -*- - -! // Copyright 2008, 2010 Free Software Foundation, Inc. - // Written by David S. Miller . - - // This file is part of elfcpp. -*************** enum -*** 165,174 **** - R_PPC_EMB_RELST_HA = 114, - R_PPC_EMB_BIT_FLD = 115, - R_PPC_EMB_RELSDA = 116, -! R_PPC_RELAX32 = 245, -! R_PPC_RELAX32PC = 246, -! R_PPC_RELAX32_PLT = 247, -! R_PPC_RELAX32PC_PLT = 248, - R_PPC_REL16 = 249, - R_PPC_REL16_LO = 250, - R_PPC_REL16_HI = 251, ---- 165,172 ---- - R_PPC_EMB_RELST_HA = 114, - R_PPC_EMB_BIT_FLD = 115, - R_PPC_EMB_RELSDA = 116, -! -! R_POWERPC_IRELATIVE = 248, - R_PPC_REL16 = 249, - R_PPC_REL16_LO = 250, - R_PPC_REL16_HI = 251, -diff -rcp ../binutils-2.20.51.0.10.original/elfcpp/sparc.h elfcpp/sparc.h -*** ../binutils-2.20.51.0.10.original/elfcpp/sparc.h 2010-08-10 15:13:23.000000000 +0100 ---- elfcpp/sparc.h 2010-08-10 15:14:09.000000000 +0100 -*************** -*** 1,6 **** - // sparc.h -- ELF definitions specific to EM_SPARC -*- C++ -*- - -! // Copyright 2008, Free Software Foundation, Inc. - // Written by David S. Miller . - - // This file is part of elfcpp. ---- 1,6 ---- - // sparc.h -- ELF definitions specific to EM_SPARC -*- C++ -*- - -! // Copyright 2008, 2010 Free Software Foundation, Inc. - // Written by David S. Miller . - - // This file is part of elfcpp. -*************** enum -*** 141,146 **** ---- 141,148 ---- - R_SPARC_SIZE32 = 86, // size of symbol, 32-bit - R_SPARC_SIZE64 = 87, // size of symbol, 64-bit - -+ R_SPARC_IRELATIVE = 249, // Adjust indirectly by program base -+ - // GNU vtable garbage collection extensions. - R_SPARC_GNU_VTINHERIT = 250, - R_SPARC_GNU_VTENTRY = 251, -diff -rcp ../binutils-2.20.51.0.10.original/elfcpp/x86_64.h elfcpp/x86_64.h -*** ../binutils-2.20.51.0.10.original/elfcpp/x86_64.h 2010-08-10 15:13:23.000000000 +0100 ---- elfcpp/x86_64.h 2010-08-10 15:14:09.000000000 +0100 -*************** -*** 1,6 **** - // x86-64.h -- ELF definitions specific to EM_X86_64 -*- C++ -*- - -! // Copyright 2006, 2007, Free Software Foundation, Inc. - // Written by Andrew Chatham. - - // This file is part of elfcpp. ---- 1,6 ---- - // x86-64.h -- ELF definitions specific to EM_X86_64 -*- C++ -*- - -! // Copyright 2006, 2007, 2010 Free Software Foundation, Inc. - // Written by Andrew Chatham. - - // This file is part of elfcpp. -*************** enum -*** 90,98 **** - R_X86_64_GOTPC32_TLSDESC = 34, // 32-bit PC relative to TLS descriptor in GOT - R_X86_64_TLSDESC_CALL = 35, // Relaxable call through TLS descriptor - R_X86_64_TLSDESC = 36, // 2 by 64-bit TLS descriptor - // GNU vtable garbage collection extensions. -! R_386_GNU_VTINHERIT = 250, -! R_386_GNU_VTENTRY = 251 - }; - - } // End namespace elfcpp. ---- 90,99 ---- - R_X86_64_GOTPC32_TLSDESC = 34, // 32-bit PC relative to TLS descriptor in GOT - R_X86_64_TLSDESC_CALL = 35, // Relaxable call through TLS descriptor - R_X86_64_TLSDESC = 36, // 2 by 64-bit TLS descriptor -+ R_X86_64_IRELATIVE = 37, // Adjust indirectly by program base - // GNU vtable garbage collection extensions. -! R_X86_64_GNU_VTINHERIT = 250, -! R_X86_64_GNU_VTENTRY = 251 - }; - - } // End namespace elfcpp. -diff -rcp ../binutils-2.20.51.0.10.original/gold/archive.cc gold/archive.cc -*** ../binutils-2.20.51.0.10.original/gold/archive.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/archive.cc 2010-08-10 15:14:02.000000000 +0100 -*************** -*** 36,41 **** ---- 36,42 ---- - #include "readsyms.h" - #include "symtab.h" - #include "object.h" -+ #include "layout.h" - #include "archive.h" - #include "plugin.h" - -*************** Archive::read_symbols(off_t off) -*** 603,610 **** - } - - Archive::Should_include -! Archive::should_include_member(Symbol_table* symtab, const char* sym_name, -! Symbol** symp, std::string* why, char** tmpbufp, - size_t* tmpbuflen) - { - // In an object file, and therefore in an archive map, an ---- 604,612 ---- - } - - Archive::Should_include -! Archive::should_include_member(Symbol_table* symtab, Layout* layout, -! const char* sym_name, Symbol** symp, -! std::string* why, char** tmpbufp, - size_t* tmpbuflen) - { - // In an object file, and therefore in an archive map, an -*************** Archive::should_include_member(Symbol_ta -*** 648,660 **** - if (sym == NULL) - { - // Check whether the symbol was named in a -u option. -! if (!parameters->options().is_undefined(sym_name)) -! return Archive::SHOULD_INCLUDE_UNKNOWN; -! else - { - *why = "-u "; - *why += sym_name; - } - } - else if (!sym->is_undefined()) - return Archive::SHOULD_INCLUDE_NO; ---- 650,671 ---- - if (sym == NULL) - { - // Check whether the symbol was named in a -u option. -! if (parameters->options().is_undefined(sym_name)) - { - *why = "-u "; - *why += sym_name; - } -+ else if (layout->script_options()->is_referenced(sym_name)) -+ { -+ size_t alc = 100 + strlen(sym_name); -+ char* buf = new char[alc]; -+ snprintf(buf, alc, _("script or expression reference to %s"), -+ sym_name); -+ *why = buf; -+ delete[] buf; -+ } -+ else -+ return Archive::SHOULD_INCLUDE_UNKNOWN; - } - else if (!sym->is_undefined()) - return Archive::SHOULD_INCLUDE_NO; -*************** Archive::add_symbols(Symbol_table* symta -*** 726,733 **** - Symbol* sym; - std::string why; - Archive::Should_include t = -! Archive::should_include_member(symtab, sym_name, &sym, &why, -! &tmpbuf, &tmpbuflen); - - if (t == Archive::SHOULD_INCLUDE_NO - || t == Archive::SHOULD_INCLUDE_YES) ---- 737,744 ---- - Symbol* sym; - std::string why; - Archive::Should_include t = -! Archive::should_include_member(symtab, layout, sym_name, &sym, -! &why, &tmpbuf, &tmpbuflen); - - if (t == Archive::SHOULD_INCLUDE_NO - || t == Archive::SHOULD_INCLUDE_YES) -*************** Archive::include_member(Symbol_table* sy -*** 853,863 **** - && this->searched_for() - && obj == NULL - && unconfigured) -! { -! if (obj != NULL) -! delete obj; -! return false; -! } - - if (obj == NULL) - return true; ---- 864,870 ---- - && this->searched_for() - && obj == NULL - && unconfigured) -! return false; - - if (obj == NULL) - return true; -*************** Archive::include_member(Symbol_table* sy -*** 874,880 **** - } - - if (!input_objects->add_object(obj)) -! delete obj; - else - { - { ---- 881,893 ---- - } - - if (!input_objects->add_object(obj)) -! { -! // If this is an external member of a thin archive, unlock the -! // file. -! if (obj->offset() == 0) -! obj->unlock(this->task_); -! delete obj; -! } - else - { - { -*************** Lib_group::add_symbols(Symbol_table* sym -*** 1013,1018 **** ---- 1026,1032 ---- - && (member.sd_ == NULL || member.sd_->symbol_names != NULL)) - { - Archive::Should_include t = obj->should_include_member(symtab, -+ layout, - member.sd_, - &why); - -diff -rcp ../binutils-2.20.51.0.10.original/gold/archive.h gold/archive.h -*** ../binutils-2.20.51.0.10.original/gold/archive.h 2010-08-10 15:12:04.000000000 +0100 ---- gold/archive.h 2010-08-10 15:14:02.000000000 +0100 -*************** class Archive -*** 176,182 **** - }; - - static Should_include -! should_include_member(Symbol_table* symtab, const char* sym_name, - Symbol** symp, std::string* why, char** tmpbufp, - size_t* tmpbuflen); - ---- 176,182 ---- - }; - - static Should_include -! should_include_member(Symbol_table* symtab, Layout*, const char* sym_name, - Symbol** symp, std::string* why, char** tmpbufp, - size_t* tmpbuflen); - -diff -rcp ../binutils-2.20.51.0.10.original/gold/arm.cc gold/arm.cc -*** ../binutils-2.20.51.0.10.original/gold/arm.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/arm.cc 2010-08-10 15:14:02.000000000 +0100 -*************** class Arm_output_section : public Output -*** 1324,1330 **** - Arm_output_section(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags) - : Output_section(name, type, flags) -! { } - - ~Arm_output_section() - { } ---- 1324,1333 ---- - Arm_output_section(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags) - : Output_section(name, type, flags) -! { -! if (type == elfcpp::SHT_ARM_EXIDX) -! this->set_always_keeps_input_sections(); -! } - - ~Arm_output_section() - { } -*************** class Arm_output_section : public Output -*** 1352,1357 **** ---- 1355,1364 ---- - Symbol_table* symtab, - bool merge_exidx_entries); - -+ // Link an EXIDX section into its corresponding text section. -+ void -+ set_exidx_section_link(); -+ - private: - // For convenience. - typedef Output_section::Input_section Input_section; -*************** class Arm_exidx_input_section -*** 1376,1382 **** - Arm_exidx_input_section(Relobj* relobj, unsigned int shndx, - unsigned int link, uint32_t size, uint32_t addralign) - : relobj_(relobj), shndx_(shndx), link_(link), size_(size), -! addralign_(addralign) - { } - - ~Arm_exidx_input_section() ---- 1383,1389 ---- - Arm_exidx_input_section(Relobj* relobj, unsigned int shndx, - unsigned int link, uint32_t size, uint32_t addralign) - : relobj_(relobj), shndx_(shndx), link_(link), size_(size), -! addralign_(addralign), has_errors_(false) - { } - - ~Arm_exidx_input_section() -*************** class Arm_exidx_input_section -*** 1409,1414 **** ---- 1416,1431 ---- - addralign() const - { return this->addralign_; } - -+ // Whether there are any errors in the EXIDX input section. -+ bool -+ has_errors() const -+ { return this->has_errors_; } -+ -+ // Set has-errors flag. -+ void -+ set_has_errors() -+ { this->has_errors_ = true; } -+ - private: - // Object containing this. - Relobj* relobj_; -*************** class Arm_exidx_input_section -*** 1420,1425 **** ---- 1437,1444 ---- - uint32_t size_; - // Address alignment of this. For ARM 32-bit is sufficient. - uint32_t addralign_; -+ // Whether this has any errors. -+ bool has_errors_; - }; - - // Arm_relobj class. -*************** class Arm_relobj : public Sized_relobj<3 -*** 1581,1586 **** ---- 1600,1621 ---- - merge_flags_and_attributes() const - { return this->merge_flags_and_attributes_; } - -+ // Export list of EXIDX section indices. -+ void -+ get_exidx_shndx_list(std::vector* list) const -+ { -+ list->clear(); -+ for (Exidx_section_map::const_iterator p = this->exidx_section_map_.begin(); -+ p != this->exidx_section_map_.end(); -+ ++p) -+ { -+ if (p->second->shndx() == p->first) -+ list->push_back(p->first); -+ } -+ // Sort list to make result independent of implementation of map. -+ std::sort(list->begin(), list->end()); -+ } -+ - protected: - // Post constructor setup. - void -*************** class Arm_relobj : public Sized_relobj<3 -*** 1653,1659 **** - void - make_exidx_input_section(unsigned int shndx, - const elfcpp::Shdr<32, big_endian>& shdr, -! unsigned int text_shndx); - - // Return the output address of either a plain input section or a - // relaxed input section. SHNDX is the section index. ---- 1688,1695 ---- - void - make_exidx_input_section(unsigned int shndx, - const elfcpp::Shdr<32, big_endian>& shdr, -! unsigned int text_shndx, -! const elfcpp::Shdr<32, big_endian>& text_shdr); - - // Return the output address of either a plain input section or a - // relaxed input section. SHNDX is the section index. -*************** class Target_arm : public Sized_target<3 -*** 2764,2770 **** - - // Fix .ARM.exidx section coverage. - void -! fix_exidx_coverage(Layout*, Arm_output_section*, Symbol_table*); - - // Functors for STL set. - struct output_section_address_less_than ---- 2800,2807 ---- - - // Fix .ARM.exidx section coverage. - void -! fix_exidx_coverage(Layout*, const Input_objects*, -! Arm_output_section*, Symbol_table*); - - // Functors for STL set. - struct output_section_address_less_than -*************** Target_arm::got_section(Symb -*** 4116,4137 **** - - this->got_ = new Arm_output_data_got(symtab, layout); - -! Output_section* os; -! os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, false, false, false, -! true); - // The old GNU linker creates a .got.plt section. We just - // create another set of data in the .got section. Note that we - // always create a PLT if we create a GOT, although the PLT - // might be empty. - this->got_plt_ = new Output_data_space(4, "** GOT PLT"); -! os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, false, false, -! false, false); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 4); ---- 4153,4172 ---- - - this->got_ = new Arm_output_data_got(symtab, layout); - -! layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, ORDER_RELRO, true); -! - // The old GNU linker creates a .got.plt section. We just - // create another set of data in the .got section. Note that we - // always create a PLT if we create a GOT, although the PLT - // might be empty. - this->got_plt_ = new Output_data_space(4, "** GOT PLT"); -! layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, ORDER_DATA, false); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 4); -*************** Target_arm::rel_dyn_section( -*** 4159,4166 **** - gold_assert(layout != NULL); - this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_dyn_, true, -! false, false, false); - } - return this->rel_dyn_; - } ---- 4194,4201 ---- - gold_assert(layout != NULL); - this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_dyn_, -! ORDER_DYNAMIC_RELOCS, false); - } - return this->rel_dyn_; - } -*************** void -*** 5657,5666 **** - Arm_output_section::append_text_sections_to_list( - Text_section_list* list) - { -- // We only care about text sections. -- if ((this->flags() & elfcpp::SHF_EXECINSTR) == 0) -- return; -- - gold_assert((this->flags() & elfcpp::SHF_ALLOC) != 0); - - for (Input_section_list::const_iterator p = this->input_sections().begin(); ---- 5692,5697 ---- -*************** Arm_output_section::fix_exid -*** 5733,5741 **** - const Arm_exidx_input_section* exidx_input_section = - arm_relobj->exidx_input_section_by_link(shndx); - -! // If this text section has no EXIDX section, force an EXIDX_CANTUNWIND -! // entry pointing to the end of the last seen EXIDX section. -! if (exidx_input_section == NULL) - { - exidx_fixup.add_exidx_cantunwind_as_needed(); - continue; ---- 5764,5773 ---- - const Arm_exidx_input_section* exidx_input_section = - arm_relobj->exidx_input_section_by_link(shndx); - -! // If this text section has no EXIDX section or if the EXIDX section -! // has errors, force an EXIDX_CANTUNWIND entry pointing to the end -! // of the last seen EXIDX section. -! if (exidx_input_section == NULL || exidx_input_section->has_errors()) - { - exidx_fixup.add_exidx_cantunwind_as_needed(); - continue; -*************** Arm_output_section::fix_exid -*** 5819,5833 **** - if (processed_input_sections.find(Section_id(p->relobj(), p->shndx())) - == processed_input_sections.end()) - { -! // We only discard a known EXIDX section because its linked -! // text section has been folded by ICF. - Arm_relobj* arm_relobj = - Arm_relobj::as_arm_relobj(p->relobj()); - const Arm_exidx_input_section* exidx_input_section = - arm_relobj->exidx_input_section_by_shndx(p->shndx()); - gold_assert(exidx_input_section != NULL); -! unsigned int text_shndx = exidx_input_section->link(); -! gold_assert(symtab->is_section_folded(p->relobj(), text_shndx)); - - // Remove this from link. We also need to recount the - // local symbols. ---- 5851,5870 ---- - if (processed_input_sections.find(Section_id(p->relobj(), p->shndx())) - == processed_input_sections.end()) - { -! // We discard a known EXIDX section because its linked -! // text section has been folded by ICF. We also discard an -! // EXIDX section with error, the output does not matter in this -! // case. We do this to avoid triggering asserts. - Arm_relobj* arm_relobj = - Arm_relobj::as_arm_relobj(p->relobj()); - const Arm_exidx_input_section* exidx_input_section = - arm_relobj->exidx_input_section_by_shndx(p->shndx()); - gold_assert(exidx_input_section != NULL); -! if (!exidx_input_section->has_errors()) -! { -! unsigned int text_shndx = exidx_input_section->link(); -! gold_assert(symtab->is_section_folded(p->relobj(), text_shndx)); -! } - - // Remove this from link. We also need to recount the - // local symbols. -*************** Arm_output_section::fix_exid -*** 5846,5851 **** ---- 5883,5910 ---- - this->set_section_offsets_need_adjustment(); - } - -+ // Link EXIDX output sections to text output sections. -+ -+ template -+ void -+ Arm_output_section::set_exidx_section_link() -+ { -+ gold_assert(this->type() == elfcpp::SHT_ARM_EXIDX); -+ if (!this->input_sections().empty()) -+ { -+ Input_section_list::const_iterator p = this->input_sections().begin(); -+ Arm_relobj* arm_relobj = -+ Arm_relobj::as_arm_relobj(p->relobj()); -+ unsigned exidx_shndx = p->shndx(); -+ const Arm_exidx_input_section* exidx_input_section = -+ arm_relobj->exidx_input_section_by_shndx(exidx_shndx); -+ gold_assert(exidx_input_section != NULL); -+ unsigned int text_shndx = exidx_input_section->link(); -+ Output_section* os = arm_relobj->output_section(text_shndx); -+ this->set_link_section(os); -+ } -+ } -+ - // Arm_relobj methods. - - // Determine if an input section is scannable for stub processing. SHDR is -*************** void -*** 6447,6474 **** - Arm_relobj::make_exidx_input_section( - unsigned int shndx, - const elfcpp::Shdr<32, big_endian>& shdr, -! unsigned int text_shndx) - { -- // Issue an error and ignore this EXIDX section if it points to a text -- // section already has an EXIDX section. -- if (this->exidx_section_map_[text_shndx] != NULL) -- { -- gold_error(_("EXIDX sections %u and %u both link to text section %u " -- "in %s"), -- shndx, this->exidx_section_map_[text_shndx]->shndx(), -- text_shndx, this->name().c_str()); -- return; -- } -- - // Create an Arm_exidx_input_section object for this EXIDX section. - Arm_exidx_input_section* exidx_input_section = - new Arm_exidx_input_section(this, shndx, text_shndx, shdr.get_sh_size(), - shdr.get_sh_addralign()); -- this->exidx_section_map_[text_shndx] = exidx_input_section; - -- // Also map the EXIDX section index to this. - gold_assert(this->exidx_section_map_[shndx] == NULL); - this->exidx_section_map_[shndx] = exidx_input_section; - } - - // Read the symbol information. ---- 6506,6562 ---- - Arm_relobj::make_exidx_input_section( - unsigned int shndx, - const elfcpp::Shdr<32, big_endian>& shdr, -! unsigned int text_shndx, -! const elfcpp::Shdr<32, big_endian>& text_shdr) - { - // Create an Arm_exidx_input_section object for this EXIDX section. - Arm_exidx_input_section* exidx_input_section = - new Arm_exidx_input_section(this, shndx, text_shndx, shdr.get_sh_size(), - shdr.get_sh_addralign()); - - gold_assert(this->exidx_section_map_[shndx] == NULL); - this->exidx_section_map_[shndx] = exidx_input_section; -+ -+ if (text_shndx == elfcpp::SHN_UNDEF || text_shndx >= this->shnum()) -+ { -+ gold_error(_("EXIDX section %s(%u) links to invalid section %u in %s"), -+ this->section_name(shndx).c_str(), shndx, text_shndx, -+ this->name().c_str()); -+ exidx_input_section->set_has_errors(); -+ } -+ else if (this->exidx_section_map_[text_shndx] != NULL) -+ { -+ unsigned other_exidx_shndx = -+ this->exidx_section_map_[text_shndx]->shndx(); -+ gold_error(_("EXIDX sections %s(%u) and %s(%u) both link to text section" -+ "%s(%u) in %s"), -+ this->section_name(shndx).c_str(), shndx, -+ this->section_name(other_exidx_shndx).c_str(), -+ other_exidx_shndx, this->section_name(text_shndx).c_str(), -+ text_shndx, this->name().c_str()); -+ exidx_input_section->set_has_errors(); -+ } -+ else -+ this->exidx_section_map_[text_shndx] = exidx_input_section; -+ -+ // Check section flags of text section. -+ if ((text_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) -+ { -+ gold_error(_("EXIDX section %s(%u) links to non-allocated section %s(%u) " -+ " in %s"), -+ this->section_name(shndx).c_str(), shndx, -+ this->section_name(text_shndx).c_str(), text_shndx, -+ this->name().c_str()); -+ exidx_input_section->set_has_errors(); -+ } -+ else if ((text_shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) == 0) -+ // I would like to make this an error but currenlty ld just ignores -+ // this. -+ gold_warning(_("EXIDX section %s(%u) links to non-executable section " -+ "%s(%u) in %s"), -+ this->section_name(shndx).c_str(), shndx, -+ this->section_name(text_shndx).c_str(), text_shndx, -+ this->name().c_str()); - } - - // Read the symbol information. -*************** Arm_relobj::do_read_symbols( -*** 6538,6556 **** - else if (shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX) - { - unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link()); -! if (text_shndx >= this->shnum()) -! gold_error(_("EXIDX section %u linked to invalid section %u"), -! i, text_shndx); -! else if (text_shndx == elfcpp::SHN_UNDEF) - deferred_exidx_sections.push_back(i); - else -! this->make_exidx_input_section(i, shdr, text_shndx); - } - } - - // This is rare. - if (!must_merge_flags_and_attributes) - { - this->merge_flags_and_attributes_ = false; - return; - } ---- 6626,6646 ---- - else if (shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX) - { - unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link()); -! if (text_shndx == elfcpp::SHN_UNDEF) - deferred_exidx_sections.push_back(i); - else -! { -! elfcpp::Shdr<32, big_endian> text_shdr(pshdrs -! + text_shndx * shdr_size); -! this->make_exidx_input_section(i, shdr, text_shndx, text_shdr); -! } - } - } - - // This is rare. - if (!must_merge_flags_and_attributes) - { -+ gold_assert(deferred_exidx_sections.empty()); - this->merge_flags_and_attributes_ = false; - return; - } -*************** Arm_relobj::do_read_symbols( -*** 6606,6620 **** - { - unsigned int shndx = deferred_exidx_sections[i]; - elfcpp::Shdr<32, big_endian> shdr(pshdrs + shndx * shdr_size); -! unsigned int text_shndx; - Reloc_map::const_iterator it = reloc_map.find(shndx); -! if (it != reloc_map.end() -! && find_linked_text_section(pshdrs + it->second * shdr_size, -! psyms, &text_shndx)) -! this->make_exidx_input_section(shndx, shdr, text_shndx); -! else -! gold_error(_("EXIDX section %u has no linked text section."), -! shndx); - } - } - } ---- 6696,6709 ---- - { - unsigned int shndx = deferred_exidx_sections[i]; - elfcpp::Shdr<32, big_endian> shdr(pshdrs + shndx * shdr_size); -! unsigned int text_shndx = elfcpp::SHN_UNDEF; - Reloc_map::const_iterator it = reloc_map.find(shndx); -! if (it != reloc_map.end()) -! find_linked_text_section(pshdrs + it->second * shdr_size, -! psyms, &text_shndx); -! elfcpp::Shdr<32, big_endian> text_shdr(pshdrs -! + text_shndx * shdr_size); -! this->make_exidx_input_section(shndx, shdr, text_shndx, text_shdr); - } - } - } -*************** Output_data_plt_arm::Output_ -*** 7069,7076 **** - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_, true, false, -! false, false); - } - - template ---- 7158,7165 ---- - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - } - - template -*************** Target_arm::make_plt_entry(S -*** 7232,7238 **** - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, false, false, false, false); - } - this->plt_->add_entry(gsym); - } ---- 7321,7327 ---- - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, ORDER_PLT, false); - } - this->plt_->add_entry(gsym); - } -*************** Target_arm::gc_process_reloc -*** 8124,8130 **** - typedef Target_arm Arm; - typedef typename Target_arm::Scan Scan; - -! gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>( - symtab, - layout, - this, ---- 8213,8220 ---- - typedef Target_arm Arm; - typedef typename Target_arm::Scan Scan; - -! gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan, -! typename Target_arm::Relocatable_size_for_reloc>( - symtab, - layout, - this, -*************** Target_arm::do_finalize_sect -*** 8292,8299 **** - == NULL); - Output_segment* exidx_segment = - layout->make_output_segment(elfcpp::PT_ARM_EXIDX, elfcpp::PF_R); -! exidx_segment->add_output_section(exidx_section, elfcpp::PF_R, -! false); - } - } - ---- 8382,8389 ---- - == NULL); - Output_segment* exidx_segment = - layout->make_output_segment(elfcpp::PT_ARM_EXIDX, elfcpp::PF_R); -! exidx_segment->add_output_section_to_nonload(exidx_section, -! elfcpp::PF_R); - } - } - -*************** Target_arm::do_finalize_sect -*** 8305,8313 **** - new Output_attributes_section_data(*this->attributes_section_data_); - layout->add_output_section_data(".ARM.attributes", - elfcpp::SHT_ARM_ATTRIBUTES, 0, -! attributes_section, false, false, false, - false); - } - } - - // Return whether a direct absolute static relocation needs to be applied. ---- 8395,8414 ---- - new Output_attributes_section_data(*this->attributes_section_data_); - layout->add_output_section_data(".ARM.attributes", - elfcpp::SHT_ARM_ATTRIBUTES, 0, -! attributes_section, ORDER_INVALID, - false); - } -+ -+ // Fix up links in section EXIDX headers. -+ for (Layout::Section_list::const_iterator p = layout->section_list().begin(); -+ p != layout->section_list().end(); -+ ++p) -+ if ((*p)->type() == elfcpp::SHT_ARM_EXIDX) -+ { -+ Arm_output_section* os = -+ Arm_output_section::as_arm_output_section(*p); -+ os->set_exidx_section_link(); -+ } - } - - // Return whether a direct absolute static relocation needs to be applied. -*************** Target_arm::do_relax( -*** 10971,10982 **** - group_sections(layout, stub_group_size, stubs_always_after_branch); - - // Also fix .ARM.exidx section coverage. -! Output_section* os = layout->find_output_section(".ARM.exidx"); -! if (os != NULL && os->type() == elfcpp::SHT_ARM_EXIDX) - { -! Arm_output_section* exidx_output_section = -! Arm_output_section::as_arm_output_section(os); -! this->fix_exidx_coverage(layout, exidx_output_section, symtab); - done_exidx_fixup = true; - } - } ---- 11072,11099 ---- - group_sections(layout, stub_group_size, stubs_always_after_branch); - - // Also fix .ARM.exidx section coverage. -! Arm_output_section* exidx_output_section = NULL; -! for (Layout::Section_list::const_iterator p = -! layout->section_list().begin(); -! p != layout->section_list().end(); -! ++p) -! if ((*p)->type() == elfcpp::SHT_ARM_EXIDX) -! { -! if (exidx_output_section == NULL) -! exidx_output_section = -! Arm_output_section::as_arm_output_section(*p); -! else -! // We cannot handle this now. -! gold_error(_("multiple SHT_ARM_EXIDX sections %s and %s in a " -! "non-relocatable link"), -! exidx_output_section->name(), -! (*p)->name()); -! } -! -! if (exidx_output_section != NULL) - { -! this->fix_exidx_coverage(layout, input_objects, exidx_output_section, -! symtab); - done_exidx_fixup = true; - } - } -*************** template -*** 11427,11432 **** ---- 11544,11550 ---- - void - Target_arm::fix_exidx_coverage( - Layout* layout, -+ const Input_objects* input_objects, - Arm_output_section* exidx_section, - Symbol_table* symtab) - { -*************** Target_arm::fix_exidx_covera -*** 11439,11453 **** - typedef std::set - Sorted_output_section_list; - Sorted_output_section_list sorted_output_sections; -! Layout::Section_list section_list; -! layout->get_allocated_sections(§ion_list); -! for (Layout::Section_list::const_iterator p = section_list.begin(); -! p != section_list.end(); - ++p) - { -! // We only care about output sections that contain executable code. -! if (((*p)->flags() & elfcpp::SHF_EXECINSTR) != 0) -! sorted_output_sections.insert(*p); - } - - // Go over the output sections in ascending order of output addresses. ---- 11557,11586 ---- - typedef std::set - Sorted_output_section_list; - Sorted_output_section_list sorted_output_sections; -! -! // Find out all the output sections of input sections pointed by -! // EXIDX input sections. -! for (Input_objects::Relobj_iterator p = input_objects->relobj_begin(); -! p != input_objects->relobj_end(); - ++p) - { -! Arm_relobj* arm_relobj = -! Arm_relobj::as_arm_relobj(*p); -! std::vector shndx_list; -! arm_relobj->get_exidx_shndx_list(&shndx_list); -! for (size_t i = 0; i < shndx_list.size(); ++i) -! { -! const Arm_exidx_input_section* exidx_input_section = -! arm_relobj->exidx_input_section_by_shndx(shndx_list[i]); -! gold_assert(exidx_input_section != NULL); -! if (!exidx_input_section->has_errors()) -! { -! unsigned int text_shndx = exidx_input_section->link(); -! Output_section *os = arm_relobj->output_section(text_shndx); -! if (os != NULL && (os->flags() & elfcpp::SHF_ALLOC) != 0) -! sorted_output_sections.insert(os); -! } -! } - } - - // Go over the output sections in ascending order of output addresses. -diff -rcp ../binutils-2.20.51.0.10.original/gold/common.cc gold/common.cc -*** ../binutils-2.20.51.0.10.original/gold/common.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/common.cc 2010-08-10 15:14:02.000000000 +0100 -*************** Symbol_table::do_allocate_commons_list( -*** 298,305 **** - Output_data_space *poc = new Output_data_space(addralign, ds_name); - Output_section *os = layout->add_output_section_data(name, - elfcpp::SHT_NOBITS, -! flags, poc, false, -! false, false, false); - if (os != NULL) - { - if (commons_section_type == COMMONS_SMALL) ---- 298,306 ---- - Output_data_space *poc = new Output_data_space(addralign, ds_name); - Output_section *os = layout->add_output_section_data(name, - elfcpp::SHT_NOBITS, -! flags, poc, -! ORDER_INVALID, -! false); - if (os != NULL) - { - if (commons_section_type == COMMONS_SMALL) -diff -rcp ../binutils-2.20.51.0.10.original/gold/compressed_output.cc gold/compressed_output.cc -*** ../binutils-2.20.51.0.10.original/gold/compressed_output.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/compressed_output.cc 2010-08-10 15:14:02.000000000 +0100 -*************** -*** 1,6 **** -! // compressed_output.cc -- manage compressed output sections for gold - -! // Copyright 2007, 2008 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. ---- 1,6 ---- -! // compressed_output.cc -- manage compressed debug sections for gold - -! // Copyright 2007, 2008, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. -*************** -*** 33,38 **** ---- 33,40 ---- - namespace gold - { - -+ #ifdef HAVE_ZLIB_H -+ - // Compress UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns true - // if it successfully compressed, false if it failed for any reason - // (including not having zlib support in the library). If it returns -*************** namespace gold -*** 42,49 **** - // "ZLIB", and 8 bytes indicating the uncompressed size, in big-endian - // order. - -- #ifdef HAVE_ZLIB_H -- - static bool - zlib_compress(const unsigned char* uncompressed_data, - unsigned long uncompressed_size, ---- 44,49 ---- -*************** zlib_compress(const unsigned char* uncom -*** 81,86 **** ---- 81,129 ---- - } - } - -+ // Decompress COMPRESSED_DATA of size COMPRESSED_SIZE, into a buffer -+ // UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns TRUE if it -+ // decompressed successfully, false if it failed. The buffer, of -+ // appropriate size, is provided by the caller, and is typically part -+ // of the memory-mapped output file. -+ -+ static bool -+ zlib_decompress(const unsigned char* compressed_data, -+ unsigned long compressed_size, -+ unsigned char* uncompressed_data, -+ unsigned long uncompressed_size) -+ { -+ z_stream strm; -+ int rc; -+ -+ /* It is possible the section consists of several compressed -+ buffers concatenated together, so we uncompress in a loop. */ -+ strm.zalloc = NULL; -+ strm.zfree = NULL; -+ strm.opaque = NULL; -+ strm.avail_in = compressed_size; -+ strm.next_in = const_cast(compressed_data); -+ strm.avail_out = uncompressed_size; -+ -+ rc = inflateInit(&strm); -+ while (strm.avail_in > 0) -+ { -+ if (rc != Z_OK) -+ return false; -+ strm.next_out = ((Bytef*) uncompressed_data -+ + (uncompressed_size - strm.avail_out)); -+ rc = inflate(&strm, Z_FINISH); -+ if (rc != Z_STREAM_END) -+ return false; -+ rc = inflateReset(&strm); -+ } -+ rc = inflateEnd(&strm); -+ if (rc != Z_OK || strm.avail_out != 0) -+ return false; -+ -+ return true; -+ } -+ - #else // !defined(HAVE_ZLIB_H) - - static bool -*************** zlib_compress(const unsigned char*, unsi -*** 90,97 **** ---- 133,194 ---- - return false; - } - -+ static bool -+ zlib_decompress(const unsigned char*, unsigned long, -+ unsigned char*, unsigned long) -+ { -+ return false; -+ } -+ - #endif // !defined(HAVE_ZLIB_H) - -+ // Read the compression header of a compressed debug section and return -+ // the uncompressed size. -+ -+ uint64_t -+ get_uncompressed_size(const unsigned char* compressed_data, -+ section_size_type compressed_size) -+ { -+ const unsigned int zlib_header_size = 12; -+ -+ /* Verify the compression header. Currently, we support only zlib -+ compression, so it should be "ZLIB" followed by the uncompressed -+ section size, 8 bytes in big-endian order. */ -+ if (compressed_size >= zlib_header_size -+ && strncmp(reinterpret_cast(compressed_data), -+ "ZLIB", 4) == 0) -+ return elfcpp::Swap_unaligned<64, true>::readval(compressed_data + 4); -+ return -1ULL; -+ } -+ -+ // Decompress a compressed debug section directly into the output file. -+ -+ bool -+ decompress_input_section(const unsigned char* compressed_data, -+ unsigned long compressed_size, -+ unsigned char* uncompressed_data, -+ unsigned long uncompressed_size) -+ { -+ const unsigned int zlib_header_size = 12; -+ -+ /* Verify the compression header. Currently, we support only zlib -+ compression, so it should be "ZLIB" followed by the uncompressed -+ section size, 8 bytes in big-endian order. */ -+ if (compressed_size >= zlib_header_size -+ && strncmp(reinterpret_cast(compressed_data), -+ "ZLIB", 4) == 0) -+ { -+ unsigned long uncompressed_size_check = -+ elfcpp::Swap_unaligned<64, true>::readval(compressed_data + 4); -+ gold_assert(uncompressed_size_check == uncompressed_size); -+ return zlib_decompress(compressed_data + zlib_header_size, -+ compressed_size - zlib_header_size, -+ uncompressed_data, -+ uncompressed_size); -+ } -+ return false; -+ } -+ - // Class Output_compressed_section. - - // Set the final data size of a compressed section. This is where -diff -rcp ../binutils-2.20.51.0.10.original/gold/compressed_output.h gold/compressed_output.h -*** ../binutils-2.20.51.0.10.original/gold/compressed_output.h 2010-08-10 15:11:28.000000000 +0100 ---- gold/compressed_output.h 2010-08-10 15:14:02.000000000 +0100 -*************** -*** 1,6 **** - // compressed_output.h -- compressed output sections for gold -*- C++ -*- - -! // Copyright 2007, 2008 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. ---- 1,6 ---- - // compressed_output.h -- compressed output sections for gold -*- C++ -*- - -! // Copyright 2007, 2008, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. -*************** namespace gold -*** 37,42 **** ---- 37,54 ---- - - class General_options; - -+ // Read the compression header of a compressed debug section and return -+ // the uncompressed size. -+ -+ extern uint64_t -+ get_uncompressed_size(const unsigned char*, section_size_type); -+ -+ // Decompress a compressed debug section directly into the output file. -+ -+ extern bool -+ decompress_input_section(const unsigned char*, unsigned long, unsigned char*, -+ unsigned long); -+ - // This is used for a section whose data should be compressed. It is - // a regular Output_section which computes its contents into a buffer - // and then postprocesses it. -diff -rcp ../binutils-2.20.51.0.10.original/gold/configure.ac gold/configure.ac -*** ../binutils-2.20.51.0.10.original/gold/configure.ac 2010-08-10 15:12:03.000000000 +0100 ---- gold/configure.ac 2010-08-10 15:14:02.000000000 +0100 -*************** AC_CONFIG_SRCDIR(gold.cc) -*** 7,13 **** - - AC_CANONICAL_TARGET - -! AM_INIT_AUTOMAKE([no-dist]) - - AM_CONFIG_HEADER(config.h:config.in) - ---- 7,13 ---- - - AC_CANONICAL_TARGET - -! AM_INIT_AUTOMAKE([no-dist parallel-tests]) - - AM_CONFIG_HEADER(config.h:config.in) - -diff -rcp ../binutils-2.20.51.0.10.original/gold/copy-relocs.cc gold/copy-relocs.cc -*** ../binutils-2.20.51.0.10.original/gold/copy-relocs.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/copy-relocs.cc 2010-08-10 15:14:02.000000000 +0100 -*************** Copy_relocs:: -*** 141,148 **** - layout->add_output_section_data(".bss", - elfcpp::SHT_NOBITS, - elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, -! this->dynbss_, false, false, false, -! false); - } - - Output_data_space* dynbss = this->dynbss_; ---- 141,147 ---- - layout->add_output_section_data(".bss", - elfcpp::SHT_NOBITS, - elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, -! this->dynbss_, ORDER_BSS, false); - } - - Output_data_space* dynbss = this->dynbss_; -diff -rcp ../binutils-2.20.51.0.10.original/gold/descriptors.cc gold/descriptors.cc -*** ../binutils-2.20.51.0.10.original/gold/descriptors.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/descriptors.cc 2010-08-10 15:14:02.000000000 +0100 -*************** Descriptors::open(int descriptor, const -*** 113,120 **** - { - Hold_lock hl(*this->lock_); - -! gold_error(_("file %s was removed during the link"), -! this->open_descriptors_[descriptor].name); - } - - errno = ENOENT; ---- 113,119 ---- - { - Hold_lock hl(*this->lock_); - -! gold_error(_("file %s was removed during the link"), name); - } - - errno = ENOENT; -diff -rcp ../binutils-2.20.51.0.10.original/gold/dwarf_reader.cc gold/dwarf_reader.cc -*** ../binutils-2.20.51.0.10.original/gold/dwarf_reader.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/dwarf_reader.cc 2010-08-10 15:14:02.000000000 +0100 -*************** -*** 32,37 **** ---- 32,38 ---- - #include "reloc.h" - #include "dwarf_reader.h" - #include "int_encoding.h" -+ #include "compressed_output.h" - - namespace gold { - -*************** Sized_dwarf_line_info: -*** 80,85 **** ---- 81,101 ---- - if (this->buffer_ == NULL) - return; - -+ section_size_type uncompressed_size = 0; -+ unsigned char* uncompressed_data = NULL; -+ if (object->section_is_compressed(debug_shndx, &uncompressed_size)) -+ { -+ uncompressed_data = new unsigned char[uncompressed_size]; -+ if (!decompress_input_section(this->buffer_, -+ this->buffer_end_ - this->buffer_, -+ uncompressed_data, -+ uncompressed_size)) -+ object->error(_("could not decompress section %s"), -+ object->section_name(debug_shndx).c_str()); -+ this->buffer_ = uncompressed_data; -+ this->buffer_end_ = this->buffer_ + uncompressed_size; -+ } -+ - // Find the relocation section for ".debug_line". - // We expect these for relobjs (.o's) but not dynobjs (.so's). - bool got_relocs = false; -diff -rcp ../binutils-2.20.51.0.10.original/gold/dynobj.cc gold/dynobj.cc -*** ../binutils-2.20.51.0.10.original/gold/dynobj.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/dynobj.cc 2010-08-10 15:14:02.000000000 +0100 -*************** Sized_dynobj::do_add_s -*** 753,760 **** - - template - Archive::Should_include -! Sized_dynobj::do_should_include_member( -! Symbol_table*, Read_symbols_data*, std::string*) - { - return Archive::SHOULD_INCLUDE_YES; - } ---- 753,762 ---- - - template - Archive::Should_include -! Sized_dynobj::do_should_include_member(Symbol_table*, -! Layout*, -! Read_symbols_data*, -! std::string*) - { - return Archive::SHOULD_INCLUDE_YES; - } -diff -rcp ../binutils-2.20.51.0.10.original/gold/dynobj.h gold/dynobj.h -*** ../binutils-2.20.51.0.10.original/gold/dynobj.h 2010-08-10 15:11:43.000000000 +0100 ---- gold/dynobj.h 2010-08-10 15:14:02.000000000 +0100 -*************** class Sized_dynobj : public Dynobj -*** 178,184 **** - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Read_symbols_data*, - std::string* why); - - // Get the size of a section. ---- 178,184 ---- - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, - std::string* why); - - // Get the size of a section. -diff -rcp ../binutils-2.20.51.0.10.original/gold/fileread.cc gold/fileread.cc -*** ../binutils-2.20.51.0.10.original/gold/fileread.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/fileread.cc 2010-08-10 15:14:02.000000000 +0100 -*************** File_read::get_mtime() -*** 841,857 **** - #endif - } - -! // Try to find a file in the extra search dirs. Returns true on success. - -! static bool -! try_extra_search_path(int* pindex, const Input_file_argument* input_argument, -! std::string filename, std::string* found_name, -! std::string* namep) { - if (input_argument->extra_search_path() == NULL) - return false; - - std::string name = input_argument->extra_search_path(); -! if (!IS_DIR_SEPARATOR (name[name.length() - 1])) - name += '/'; - name += filename; - ---- 841,859 ---- - #endif - } - -! // Try to find a file in the extra search dirs. Returns true on success. - -! bool -! Input_file::try_extra_search_path(int* pindex, -! const Input_file_argument* input_argument, -! std::string filename, std::string* found_name, -! std::string* namep) -! { - if (input_argument->extra_search_path() == NULL) - return false; - - std::string name = input_argument->extra_search_path(); -! if (!IS_DIR_SEPARATOR(name[name.length() - 1])) - name += '/'; - name += filename; - -*************** try_extra_search_path(int* pindex, const -*** 873,882 **** - // In each, we look in extra_search_path + library_path to find - // the file location, rather than the current directory. - -! static bool -! find_file(const Dirsearch& dirpath, int* pindex, -! const Input_file_argument* input_argument, bool* is_in_sysroot, -! std::string* found_name, std::string* namep) - { - std::string name; - ---- 875,885 ---- - // In each, we look in extra_search_path + library_path to find - // the file location, rather than the current directory. - -! bool -! Input_file::find_file(const Dirsearch& dirpath, int* pindex, -! const Input_file_argument* input_argument, -! bool* is_in_sysroot, -! std::string* found_name, std::string* namep) - { - std::string name; - -*************** find_file(const Dirsearch& dirpath, int* -*** 914,924 **** - else - n1 = input_argument->name(); - -! if (try_extra_search_path(pindex, input_argument, n1, found_name, namep)) - return true; - -! if (!n2.empty() && try_extra_search_path(pindex, input_argument, n2, -! found_name, namep)) - return true; - - // It is not in the extra_search_path. ---- 917,929 ---- - else - n1 = input_argument->name(); - -! if (Input_file::try_extra_search_path(pindex, input_argument, n1, -! found_name, namep)) - return true; - -! if (!n2.empty() && Input_file::try_extra_search_path(pindex, -! input_argument, n2, -! found_name, namep)) - return true; - - // It is not in the extra_search_path. -*************** bool -*** 969,976 **** - Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex) - { - std::string name; -! if (!find_file(dirpath, pindex, this->input_argument_, &this->is_in_sysroot_, -! &this->found_name_, &name)) - return false; - - // Now that we've figured out where the file lives, try to open it. ---- 974,981 ---- - Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex) - { - std::string name; -! if (!Input_file::find_file(dirpath, pindex, this->input_argument_, -! &this->is_in_sysroot_, &this->found_name_, &name)) - return false; - - // Now that we've figured out where the file lives, try to open it. -diff -rcp ../binutils-2.20.51.0.10.original/gold/fileread.h gold/fileread.h -*** ../binutils-2.20.51.0.10.original/gold/fileread.h 2010-08-10 15:11:40.000000000 +0100 ---- gold/fileread.h 2010-08-10 15:14:02.000000000 +0100 -*************** class Input_file -*** 565,570 **** ---- 565,584 ---- - format() const - { return this->format_; } - -+ // Try to find a file in the extra search dirs. Returns true on success. -+ static bool -+ try_extra_search_path(int* pindex, -+ const Input_file_argument* input_argument, -+ std::string filename, std::string* found_name, -+ std::string* namep); -+ -+ // Find the actual file. -+ static bool -+ find_file(const Dirsearch& dirpath, int* pindex, -+ const Input_file_argument* input_argument, -+ bool* is_in_sysroot, -+ std::string* found_name, std::string* namep); -+ - private: - Input_file(const Input_file&); - Input_file& operator=(const Input_file&); -diff -rcp ../binutils-2.20.51.0.10.original/gold/gc.h gold/gc.h -*** ../binutils-2.20.51.0.10.original/gold/gc.h 2010-08-10 15:11:43.000000000 +0100 ---- gold/gc.h 2010-08-10 15:14:02.000000000 +0100 -*************** struct Symbols_data -*** 151,156 **** ---- 151,170 ---- - section_size_type symbol_names_size; - }; - -+ // Relocations of type SHT_REL store the addend value in their bytes. -+ // This function returns the size of the embedded addend which is -+ // nothing but the size of the relocation. -+ -+ template -+ inline unsigned int -+ get_embedded_addend_size(int sh_type, int r_type, Relobj* obj) -+ { -+ if (sh_type != elfcpp::SHT_REL) -+ return 0; -+ Classify_reloc classify_reloc; -+ return classify_reloc.get_size_for_reloc(r_type, obj); -+ } -+ - // This function implements the generic part of reloc - // processing to map a section to all the sections it - // references through relocs. It is called only during -*************** struct Symbols_data -*** 158,164 **** - // folding (--icf). - - template - inline void - gc_process_relocs( - Symbol_table* symtab, ---- 172,178 ---- - // folding (--icf). - - template - inline void - gc_process_relocs( - Symbol_table* symtab, -*************** gc_process_relocs( -*** 185,190 **** ---- 199,205 ---- - Icf::Symbol_info* symvec = NULL; - Icf::Addend_info* addendvec = NULL; - Icf::Offset_info* offsetvec = NULL; -+ Icf::Reloc_addend_size_info* reloc_addend_size_vec = NULL; - bool is_icf_tracked = false; - const char* cident_section_name = NULL; - -*************** gc_process_relocs( -*** 205,210 **** ---- 220,226 ---- - symvec = &reloc_info->symbol_info; - addendvec = &reloc_info->addend_info; - offsetvec = &reloc_info->offset_info; -+ reloc_addend_size_vec = &reloc_info->reloc_addend_size_info; - } - - check_section_for_function_pointers = -*************** gc_process_relocs( -*** 243,248 **** ---- 259,267 ---- - uint64_t reloc_offset = - convert_to_section_size_type(reloc.get_r_offset()); - (*offsetvec).push_back(reloc_offset); -+ (*reloc_addend_size_vec).push_back( -+ get_embedded_addend_size(sh_type, r_type, -+ src_obj)); - } - - // When doing safe folding, check to see if this relocation is that -*************** gc_process_relocs( -*** 316,321 **** ---- 335,343 ---- - uint64_t reloc_offset = - convert_to_section_size_type(reloc.get_r_offset()); - (*offsetvec).push_back(reloc_offset); -+ (*reloc_addend_size_vec).push_back( -+ get_embedded_addend_size(sh_type, r_type, -+ src_obj)); - } - - if (gsym->source() != Symbol::FROM_OBJECT) -diff -rcp ../binutils-2.20.51.0.10.original/gold/gold.cc gold/gold.cc -*** ../binutils-2.20.51.0.10.original/gold/gold.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/gold.cc 2010-08-10 15:14:02.000000000 +0100 -*************** queue_middle_tasks(const General_options -*** 309,315 **** - Mapfile* mapfile) - { - // Add any symbols named with -u options to the symbol table. -! symtab->add_undefined_symbols_from_command_line(); - - // If garbage collection was chosen, relocs have been read and processed - // at this point by pre_middle_tasks. Layout can then be done for all ---- 309,315 ---- - Mapfile* mapfile) - { - // Add any symbols named with -u options to the symbol table. -! symtab->add_undefined_symbols_from_command_line(layout); - - // If garbage collection was chosen, relocs have been read and processed - // at this point by pre_middle_tasks. Layout can then be done for all -*************** queue_middle_tasks(const General_options -*** 333,339 **** - } - } - // Symbols named with -u should not be considered garbage. -! symtab->gc_mark_undef_symbols(); - gold_assert(symtab->gc() != NULL); - // Do a transitive closure on all references to determine the worklist. - symtab->gc()->do_transitive_closure(); ---- 333,339 ---- - } - } - // Symbols named with -u should not be considered garbage. -! symtab->gc_mark_undef_symbols(layout); - gold_assert(symtab->gc() != NULL); - // Do a transitive closure on all references to determine the worklist. - symtab->gc()->do_transitive_closure(); -diff -rcp ../binutils-2.20.51.0.10.original/gold/i386.cc gold/i386.cc -*** ../binutils-2.20.51.0.10.original/gold/i386.cc 2010-08-10 15:11:58.000000000 +0100 ---- gold/i386.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 1,6 **** - // i386.cc -- i386 target support for gold. - -! // Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. ---- 1,6 ---- - // i386.cc -- i386 target support for gold. - -! // Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. -*************** class Target_i386 : public Target_freebs -*** 59,66 **** - - Target_i386() - : Target_freebsd<32, false>(&i386_info), -! got_(NULL), plt_(NULL), got_plt_(NULL), global_offset_table_(NULL), -! rel_dyn_(NULL), copy_relocs_(elfcpp::R_386_COPY), dynbss_(NULL), - got_mod_index_offset_(-1U), tls_base_symbol_defined_(false) - { } - ---- 59,67 ---- - - Target_i386() - : Target_freebsd<32, false>(&i386_info), -! got_(NULL), plt_(NULL), got_plt_(NULL), got_tlsdesc_(NULL), -! global_offset_table_(NULL), rel_dyn_(NULL), -! copy_relocs_(elfcpp::R_386_COPY), dynbss_(NULL), - got_mod_index_offset_(-1U), tls_base_symbol_defined_(false) - { } - -*************** class Target_i386 : public Target_freebs -*** 385,390 **** ---- 386,399 ---- - return this->got_plt_; - } - -+ // Get the GOT section for TLSDESC entries. -+ Output_data_got<32, false>* -+ got_tlsdesc_section() const -+ { -+ gold_assert(this->got_tlsdesc_ != NULL); -+ return this->got_tlsdesc_; -+ } -+ - // Create a PLT entry for a global symbol. - void - make_plt_entry(Symbol_table*, Layout*, Symbol*); -*************** class Target_i386 : public Target_freebs -*** 447,452 **** ---- 456,463 ---- - Output_data_plt_i386* plt_; - // The GOT PLT section. - Output_data_space* got_plt_; -+ // The GOT section for TLSDESC relocations. -+ Output_data_got<32, false>* got_tlsdesc_; - // The _GLOBAL_OFFSET_TABLE_ symbol. - Symbol* global_offset_table_; - // The dynamic reloc section. -*************** Target_i386::got_section(Symbol_table* s -*** 494,512 **** - - this->got_ = new Output_data_got<32, false>(); - -! Output_section* os; -! os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, false, true, true, -! false); - - this->got_plt_ = new Output_data_space(4, "** GOT PLT"); -! os = layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, false, false, false, -! true); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 4); ---- 505,521 ---- - - this->got_ = new Output_data_got<32, false>(); - -! layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, ORDER_RELRO_LAST, true); - - this->got_plt_ = new Output_data_space(4, "** GOT PLT"); -! layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, ORDER_NON_RELRO_FIRST, -! false); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 4); -*************** Target_i386::got_section(Symbol_table* s -*** 523,528 **** ---- 532,546 ---- - elfcpp::STB_LOCAL, - elfcpp::STV_HIDDEN, 0, - false, false); -+ -+ // If there are any TLSDESC relocations, they get GOT entries in -+ // .got.plt after the jump slot entries. -+ this->got_tlsdesc_ = new Output_data_got<32, false>(); -+ layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -+ (elfcpp::SHF_ALLOC -+ | elfcpp::SHF_WRITE), -+ this->got_tlsdesc_, -+ ORDER_NON_RELRO_FIRST, false); - } - - return this->got_; -*************** Target_i386::rel_dyn_section(Layout* lay -*** 538,545 **** - gold_assert(layout != NULL); - this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_dyn_, true, -! false, false, false); - } - return this->rel_dyn_; - } ---- 556,563 ---- - gold_assert(layout != NULL); - this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_dyn_, -! ORDER_DYNAMIC_RELOCS, false); - } - return this->rel_dyn_; - } -*************** Output_data_plt_i386::Output_data_plt_i3 -*** 621,628 **** - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_, true, -! false, false, false); - } - - void ---- 639,646 ---- - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, -! elfcpp::SHF_ALLOC, this->rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - } - - void -*************** Output_data_plt_i386::rel_tls_desc(Layou -*** 674,680 **** - this->tls_desc_rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, - elfcpp::SHF_ALLOC, this->tls_desc_rel_, -! true, false, false, false); - gold_assert(this->tls_desc_rel_->output_section() == - this->rel_->output_section()); - } ---- 692,698 ---- - this->tls_desc_rel_ = new Reloc_section(false); - layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, - elfcpp::SHF_ALLOC, this->tls_desc_rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - gold_assert(this->tls_desc_rel_->output_section() == - this->rel_->output_section()); - } -*************** Target_i386::make_plt_entry(Symbol_table -*** 825,831 **** - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, false, false, false, false); - } - - this->plt_->add_entry(gsym); ---- 843,849 ---- - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, ORDER_PLT, false); - } - - this->plt_->add_entry(gsym); -*************** Target_i386::Scan::local(Symbol_table* s -*** 1119,1127 **** - target->define_tls_base_symbol(symtab, layout); - if (optimized_type == tls::TLSOPT_NONE) - { -! // Create a double GOT entry with an R_386_TLS_DESC reloc. -! Output_data_got<32, false>* got -! = target->got_section(symtab, layout); - unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); - if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC)) - { ---- 1137,1149 ---- - target->define_tls_base_symbol(symtab, layout); - if (optimized_type == tls::TLSOPT_NONE) - { -! // Create a double GOT entry with an R_386_TLS_DESC -! // reloc. The R_386_TLS_DESC reloc is resolved -! // lazily, so the GOT entry needs to be in an area in -! // .got.plt, not .got. Call got_section to make sure -! // the section has been created. -! target->got_section(symtab, layout); -! Output_data_got<32, false>* got = target->got_tlsdesc_section(); - unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); - if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC)) - { -*************** Target_i386::Scan::global(Symbol_table* -*** 1503,1511 **** - target->define_tls_base_symbol(symtab, layout); - if (optimized_type == tls::TLSOPT_NONE) - { -! // Create a double GOT entry with an R_386_TLS_DESC reloc. -! Output_data_got<32, false>* got -! = target->got_section(symtab, layout); - Reloc_section* rt = target->rel_tls_desc_section(layout); - got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt, - elfcpp::R_386_TLS_DESC, 0); ---- 1525,1537 ---- - target->define_tls_base_symbol(symtab, layout); - if (optimized_type == tls::TLSOPT_NONE) - { -! // Create a double GOT entry with an R_386_TLS_DESC -! // reloc. The R_386_TLS_DESC reloc is resolved -! // lazily, so the GOT entry needs to be in an area in -! // .got.plt, not .got. Call got_section to make sure -! // the section has been created. -! target->got_section(symtab, layout); -! Output_data_got<32, false>* got = target->got_tlsdesc_section(); - Reloc_section* rt = target->rel_tls_desc_section(layout); - got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt, - elfcpp::R_386_TLS_DESC, 0); -*************** Target_i386::gc_process_relocs(Symbol_ta -*** 1626,1632 **** - const unsigned char* plocal_symbols) - { - gold::gc_process_relocs<32, false, Target_i386, elfcpp::SHT_REL, -! Target_i386::Scan>( - symtab, - layout, - this, ---- 1652,1659 ---- - const unsigned char* plocal_symbols) - { - gold::gc_process_relocs<32, false, Target_i386, elfcpp::SHT_REL, -! Target_i386::Scan, -! Target_i386::Relocatable_size_for_reloc>( - symtab, - layout, - this, -*************** Target_i386::Relocate::relocate_tls(cons -*** 2047,2064 **** - unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE - ? GOT_TYPE_TLS_NOFFSET - : GOT_TYPE_TLS_DESC); -! unsigned int got_offset; - if (gsym != NULL) - { - gold_assert(gsym->has_got_offset(got_type)); -! got_offset = gsym->got_offset(got_type) - target->got_size(); - } - else - { - unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym, got_type)); -! got_offset = (object->local_got_offset(r_sym, got_type) -! - target->got_size()); - } - if (optimized_type == tls::TLSOPT_TO_IE) - { ---- 2074,2100 ---- - unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE - ? GOT_TYPE_TLS_NOFFSET - : GOT_TYPE_TLS_DESC); -! unsigned int got_offset = 0; -! if (r_type == elfcpp::R_386_TLS_GOTDESC -! && optimized_type == tls::TLSOPT_NONE) -! { -! // We created GOT entries in the .got.tlsdesc portion of -! // the .got.plt section, but the offset stored in the -! // symbol is the offset within .got.tlsdesc. -! got_offset = (target->got_size() -! + target->got_plt_section()->data_size()); -! } - if (gsym != NULL) - { - gold_assert(gsym->has_got_offset(got_type)); -! got_offset += gsym->got_offset(got_type) - target->got_size(); - } - else - { - unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym, got_type)); -! got_offset += (object->local_got_offset(r_sym, got_type) -! - target->got_size()); - } - if (optimized_type == tls::TLSOPT_TO_IE) - { -diff -rcp ../binutils-2.20.51.0.10.original/gold/icf.cc gold/icf.cc -*** ../binutils-2.20.51.0.10.original/gold/icf.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/icf.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 145,150 **** ---- 145,152 ---- - #include "symtab.h" - #include "libiberty.h" - #include "demangle.h" -+ #include "elfcpp.h" -+ #include "int_encoding.h" - - namespace gold - { -*************** get_section_contents(bool first_iteratio -*** 269,280 **** - Icf::Addend_info a = (it_reloc_info_list->second).addend_info; - // Stores the offset of the reloc. - Icf::Offset_info o = (it_reloc_info_list->second).offset_info; - Icf::Sections_reachable_info::iterator it_v = v.begin(); - Icf::Symbol_info::iterator it_s = s.begin(); - Icf::Addend_info::iterator it_a = a.begin(); - Icf::Offset_info::iterator it_o = o.begin(); - -! for (; it_v != v.end(); ++it_v, ++it_s, ++it_a, ++it_o) - { - // ADDEND_STR stores the symbol value and addend and offset, - // each atmost 16 hex digits long. it_a points to a pair ---- 271,286 ---- - Icf::Addend_info a = (it_reloc_info_list->second).addend_info; - // Stores the offset of the reloc. - Icf::Offset_info o = (it_reloc_info_list->second).offset_info; -+ Icf::Reloc_addend_size_info reloc_addend_size_info = -+ (it_reloc_info_list->second).reloc_addend_size_info; - Icf::Sections_reachable_info::iterator it_v = v.begin(); - Icf::Symbol_info::iterator it_s = s.begin(); - Icf::Addend_info::iterator it_a = a.begin(); - Icf::Offset_info::iterator it_o = o.begin(); -+ Icf::Reloc_addend_size_info::iterator it_addend_size = -+ reloc_addend_size_info.begin(); - -! for (; it_v != v.end(); ++it_v, ++it_s, ++it_a, ++it_o, ++it_addend_size) - { - // ADDEND_STR stores the symbol value and addend and offset, - // each atmost 16 hex digits long. it_a points to a pair -*************** get_section_contents(bool first_iteratio -*** 372,377 **** ---- 378,423 ---- - if (addend < 0xffffff00) - offset = offset + addend; - -+ // For SHT_REL relocation sections, the addend is stored in the -+ // text section at the relocation offset. -+ uint64_t reloc_addend_value = 0; -+ const unsigned char* reloc_addend_ptr = -+ contents + static_cast(*it_o); -+ switch(*it_addend_size) -+ { -+ case 0: -+ { -+ break; -+ } -+ case 1: -+ { -+ reloc_addend_value = -+ read_from_pointer<8>(reloc_addend_ptr); -+ break; -+ } -+ case 2: -+ { -+ reloc_addend_value = -+ read_from_pointer<16>(reloc_addend_ptr); -+ break; -+ } -+ case 4: -+ { -+ reloc_addend_value = -+ read_from_pointer<32>(reloc_addend_ptr); -+ break; -+ } -+ case 8: -+ { -+ reloc_addend_value = -+ read_from_pointer<64>(reloc_addend_ptr); -+ break; -+ } -+ default: -+ gold_unreachable(); -+ } -+ offset = offset + reloc_addend_value; -+ - section_size_type secn_len; - const unsigned char* str_contents = - (it_v->first)->section_contents(it_v->second, -diff -rcp ../binutils-2.20.51.0.10.original/gold/icf.h gold/icf.h -*** ../binutils-2.20.51.0.10.original/gold/icf.h 2010-08-10 15:12:03.000000000 +0100 ---- gold/icf.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Icf -*** 43,48 **** ---- 43,49 ---- - typedef std::vector Symbol_info; - typedef std::vector > Addend_info; - typedef std::vector Offset_info; -+ typedef std::vector Reloc_addend_size_info; - typedef Unordered_map Uniq_secn_id_map; -*************** class Icf -*** 57,62 **** ---- 58,64 ---- - // This stores the symbol value and the addend for a reloc. - Addend_info addend_info; - Offset_info offset_info; -+ Reloc_addend_size_info reloc_addend_size_info; - } Reloc_info; - - typedef Unordered_mapinsert(destination->end(), buffer, buffer + valsize / 8); - } - -+ // Read a possibly unaligned integer of SIZE from SOURCE. -+ -+ template -+ typename elfcpp::Valtype_base::Valtype -+ read_from_pointer(const unsigned char* source) -+ { -+ typename elfcpp::Valtype_base::Valtype return_value; -+ if (parameters->target().is_big_endian()) -+ return_value = elfcpp::Swap_unaligned::readval(source); -+ else -+ return_value = elfcpp::Swap_unaligned::readval(source); -+ return return_value; -+ } -+ - // Read a possibly unaligned integer of SIZE. Update SOURCE after read. - - template -diff -rcp ../binutils-2.20.51.0.10.original/gold/layout.cc gold/layout.cc -*** ../binutils-2.20.51.0.10.original/gold/layout.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/layout.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Layout::find_output_segment(elfcpp::PT t -*** 409,417 **** - Output_section* - Layout::get_output_section(const char* name, Stringpool::Key name_key, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_interp, bool is_dynamic_linker_section, -! bool is_relro, bool is_last_relro, -! bool is_first_non_relro) - { - elfcpp::Elf_Xword lookup_flags = flags; - ---- 409,415 ---- - Output_section* - Layout::get_output_section(const char* name, Stringpool::Key name_key, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! Output_section_order order, bool is_relro) - { - elfcpp::Elf_Xword lookup_flags = flags; - -*************** Layout::get_output_section(const char* n -*** 460,468 **** - } - - if (os == NULL) -! os = this->make_output_section(name, type, flags, is_interp, -! is_dynamic_linker_section, is_relro, -! is_last_relro, is_first_non_relro); - ins.first->second = os; - return os; - } ---- 458,465 ---- - } - - if (os == NULL) -! os = this->make_output_section(name, type, flags, order, is_relro); -! - ins.first->second = os; - return os; - } -*************** Layout::get_output_section(const char* n -*** 482,490 **** - Output_section* - Layout::choose_output_section(const Relobj* relobj, const char* name, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_input_section, bool is_interp, -! bool is_dynamic_linker_section, bool is_relro, -! bool is_last_relro, bool is_first_non_relro) - { - // We should not see any input sections after we have attached - // sections to segments. ---- 479,486 ---- - Output_section* - Layout::choose_output_section(const Relobj* relobj, const char* name, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_input_section, Output_section_order order, -! bool is_relro) - { - // We should not see any input sections after we have attached - // sections to segments. -*************** Layout::choose_output_section(const Relo -*** 546,555 **** - - name = this->namepool_.add(name, false, NULL); - -! Output_section* os = -! this->make_output_section(name, type, flags, is_interp, -! is_dynamic_linker_section, is_relro, -! is_last_relro, is_first_non_relro); - os->set_found_in_sections_clause(); - - // Special handling for NOLOAD sections. ---- 542,550 ---- - - name = this->namepool_.add(name, false, NULL); - -! Output_section* os = this->make_output_section(name, type, flags, -! order, is_relro); -! - os->set_found_in_sections_clause(); - - // Special handling for NOLOAD sections. -*************** Layout::choose_output_section(const Relo -*** 591,599 **** - - // Find or make the output section. The output section is selected - // based on the section name, type, and flags. -! return this->get_output_section(name, name_key, type, flags, is_interp, -! is_dynamic_linker_section, is_relro, -! is_last_relro, is_first_non_relro); - } - - // Return the output section to use for input section SHNDX, with name ---- 586,592 ---- - - // Find or make the output section. The output section is selected - // based on the section name, type, and flags. -! return this->get_output_section(name, name_key, type, flags, order, is_relro); - } - - // Return the output section to use for input section SHNDX, with name -*************** Layout::layout(Sized_relobjnamepool_.add(name, true, NULL); -! os = this->make_output_section(name, sh_type, shdr.get_sh_flags(), false, -! false, false, false, false); - } - else - { - os = this->choose_output_section(object, name, sh_type, -! shdr.get_sh_flags(), true, false, -! false, false, false, false); - if (os == NULL) - return NULL; - } ---- 640,653 ---- - && (shdr.get_sh_flags() & elfcpp::SHF_GROUP) != 0) - { - name = this->namepool_.add(name, true, NULL); -! os = this->make_output_section(name, sh_type, shdr.get_sh_flags(), -! ORDER_INVALID, false); - } - else - { - os = this->choose_output_section(object, name, sh_type, -! shdr.get_sh_flags(), true, -! ORDER_INVALID, false); - if (os == NULL) - return NULL; - } -*************** Layout::layout_reloc(Sized_relobjoptions().relocatable() - || (data_section->flags() & elfcpp::SHF_GROUP) == 0) - os = this->choose_output_section(object, name.c_str(), sh_type, -! shdr.get_sh_flags(), false, false, -! false, false, false, false); - else - { - const char* n = this->namepool_.add(name.c_str(), true, NULL); - os = this->make_output_section(n, sh_type, shdr.get_sh_flags(), -! false, false, false, false, false); - } - - os->set_should_link_to_symtab(); ---- 702,714 ---- - if (!parameters->options().relocatable() - || (data_section->flags() & elfcpp::SHF_GROUP) == 0) - os = this->choose_output_section(object, name.c_str(), sh_type, -! shdr.get_sh_flags(), false, -! ORDER_INVALID, false); - else - { - const char* n = this->namepool_.add(name.c_str(), true, NULL); - os = this->make_output_section(n, sh_type, shdr.get_sh_flags(), -! ORDER_INVALID, false); - } - - os->set_should_link_to_symtab(); -*************** Layout::layout_group(Symbol_table* symta -*** 764,771 **** - Output_section* os = this->make_output_section(group_section_name, - elfcpp::SHT_GROUP, - shdr.get_sh_flags(), -! false, false, false, -! false, false); - - // We need to find a symbol with the signature in the symbol table. - // If we don't find one now, we need to look again later. ---- 757,763 ---- - Output_section* os = this->make_output_section(group_section_name, - elfcpp::SHT_GROUP, - shdr.get_sh_flags(), -! ORDER_INVALID, false); - - // We need to find a symbol with the signature in the symbol table. - // If we don't find one now, we need to look again later. -*************** Layout::layout_eh_frame(Sized_relobjchoose_output_section(object, -! name, - elfcpp::SHT_PROGBITS, -! elfcpp::SHF_ALLOC, -! false, false, false, -! false, false, false); - if (os == NULL) - return NULL; - ---- 807,816 ---- - gold_assert((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0); - - const char* const name = ".eh_frame"; -! Output_section* os = this->choose_output_section(object, name, - elfcpp::SHT_PROGBITS, -! elfcpp::SHF_ALLOC, false, -! ORDER_EHFRAME, false); - if (os == NULL) - return NULL; - -*************** Layout::layout_eh_frame(Sized_relobjoptions().eh_frame_hdr()) - { - Output_section* hdr_os = -! this->choose_output_section(NULL, -! ".eh_frame_hdr", - elfcpp::SHT_PROGBITS, -! elfcpp::SHF_ALLOC, -! false, false, false, -! false, false, false); - - if (hdr_os != NULL) - { ---- 822,831 ---- - if (parameters->options().eh_frame_hdr()) - { - Output_section* hdr_os = -! this->choose_output_section(NULL, ".eh_frame_hdr", - elfcpp::SHT_PROGBITS, -! elfcpp::SHF_ALLOC, false, -! ORDER_EHFRAME, false); - - if (hdr_os != NULL) - { -*************** Layout::layout_eh_frame(Sized_relobjmake_output_segment(elfcpp::PT_GNU_EH_FRAME, - elfcpp::PF_R); -! hdr_oseg->add_output_section(hdr_os, elfcpp::PF_R, false); - } - - this->eh_frame_data_->set_eh_frame_hdr(hdr_posd); ---- 840,847 ---- - Output_segment* hdr_oseg; - hdr_oseg = this->make_output_segment(elfcpp::PT_GNU_EH_FRAME, - elfcpp::PF_R); -! hdr_oseg->add_output_section_to_nonload(hdr_os, -! elfcpp::PF_R); - } - - this->eh_frame_data_->set_eh_frame_hdr(hdr_posd); -*************** Output_section* -*** 905,919 **** - Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags, - Output_section_data* posd, -! bool is_dynamic_linker_section, -! bool is_relro, bool is_last_relro, -! bool is_first_non_relro) - { - Output_section* os = this->choose_output_section(NULL, name, type, flags, -! false, false, -! is_dynamic_linker_section, -! is_relro, is_last_relro, -! is_first_non_relro); - if (os != NULL) - os->add_output_section_data(posd); - return os; ---- 894,903 ---- - Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags, - Output_section_data* posd, -! Output_section_order order, bool is_relro) - { - Output_section* os = this->choose_output_section(NULL, name, type, flags, -! false, order, is_relro); - if (os != NULL) - os->add_output_section_data(posd); - return os; -*************** Layout::section_flags_to_segment(elfcpp: -*** 944,964 **** - static bool - is_compressible_debug_section(const char* secname) - { -! return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0); - } - - // Make a new Output_section, and attach it to segments as -! // appropriate. IS_INTERP is true if this is the .interp section. -! // IS_DYNAMIC_LINKER_SECTION is true if this section is used by the -! // dynamic linker. IS_RELRO is true if this is a relro section. -! // IS_LAST_RELRO is true if this is the last relro section. -! // IS_FIRST_NON_RELRO is true if this is the first non relro section. - - Output_section* - Layout::make_output_section(const char* name, elfcpp::Elf_Word type, -! elfcpp::Elf_Xword flags, bool is_interp, -! bool is_dynamic_linker_section, bool is_relro, -! bool is_last_relro, bool is_first_non_relro) - { - Output_section* os; - if ((flags & elfcpp::SHF_ALLOC) == 0 ---- 928,954 ---- - static bool - is_compressible_debug_section(const char* secname) - { -! return (is_prefix_of(".debug", secname)); -! } -! -! // We may see compressed debug sections in input files. Return TRUE -! // if this is the name of a compressed debug section. -! -! bool -! is_compressed_debug_section(const char* secname) -! { -! return (is_prefix_of(".zdebug", secname)); - } - - // Make a new Output_section, and attach it to segments as -! // appropriate. ORDER is the order in which this section should -! // appear in the output segment. IS_RELRO is true if this is a relro -! // (read-only after relocations) section. - - Output_section* - Layout::make_output_section(const char* name, elfcpp::Elf_Word type, -! elfcpp::Elf_Xword flags, -! Output_section_order order, bool is_relro) - { - Output_section* os; - if ((flags & elfcpp::SHF_ALLOC) == 0 -*************** Layout::make_output_section(const char* -*** 991,1006 **** - os = target->make_output_section(name, type, flags); - } - -! if (is_interp) -! os->set_is_interp(); -! if (is_dynamic_linker_section) -! os->set_is_dynamic_linker_section(); - if (is_relro) - os->set_is_relro(); -! if (is_last_relro) -! os->set_is_last_relro(); -! if (is_first_non_relro) -! os->set_is_first_non_relro(); - - parameters->target().new_output_section(os); - ---- 981,1019 ---- - os = target->make_output_section(name, type, flags); - } - -! // With -z relro, we have to recognize the special sections by name. -! // There is no other way. -! bool is_relro_local = false; -! if (!this->script_options_->saw_sections_clause() -! && parameters->options().relro() -! && type == elfcpp::SHT_PROGBITS -! && (flags & elfcpp::SHF_ALLOC) != 0 -! && (flags & elfcpp::SHF_WRITE) != 0) -! { -! if (strcmp(name, ".data.rel.ro") == 0) -! is_relro = true; -! else if (strcmp(name, ".data.rel.ro.local") == 0) -! { -! is_relro = true; -! is_relro_local = true; -! } -! else if (type == elfcpp::SHT_INIT_ARRAY -! || type == elfcpp::SHT_FINI_ARRAY -! || type == elfcpp::SHT_PREINIT_ARRAY) -! is_relro = true; -! else if (strcmp(name, ".ctors") == 0 -! || strcmp(name, ".dtors") == 0 -! || strcmp(name, ".jcr") == 0) -! is_relro = true; -! } -! - if (is_relro) - os->set_is_relro(); -! -! if (order == ORDER_INVALID && (flags & elfcpp::SHF_ALLOC) != 0) -! order = this->default_section_order(os, is_relro_local); -! -! os->set_order(order); - - parameters->target().new_output_section(os); - -*************** Layout::make_output_section(const char* -*** 1016,1038 **** - || strcmp(name, ".fini_array") == 0)) - os->set_may_sort_attached_input_sections(); - -- // With -z relro, we have to recognize the special sections by name. -- // There is no other way. -- if (!this->script_options_->saw_sections_clause() -- && parameters->options().relro() -- && type == elfcpp::SHT_PROGBITS -- && (flags & elfcpp::SHF_ALLOC) != 0 -- && (flags & elfcpp::SHF_WRITE) != 0) -- { -- if (strcmp(name, ".data.rel.ro") == 0) -- os->set_is_relro(); -- else if (strcmp(name, ".data.rel.ro.local") == 0) -- { -- os->set_is_relro(); -- os->set_is_relro_local(); -- } -- } -- - // Check for .stab*str sections, as .stab* sections need to link to - // them. - if (type == elfcpp::SHT_STRTAB ---- 1029,1034 ---- -*************** Layout::make_output_section(const char* -*** 1050,1055 **** ---- 1046,1119 ---- - return os; - } - -+ // Return the default order in which a section should be placed in an -+ // output segment. This function captures a lot of the ideas in -+ // ld/scripttempl/elf.sc in the GNU linker. Note that the order of a -+ // linker created section is normally set when the section is created; -+ // this function is used for input sections. -+ -+ Output_section_order -+ Layout::default_section_order(Output_section* os, bool is_relro_local) -+ { -+ gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0); -+ bool is_write = (os->flags() & elfcpp::SHF_WRITE) != 0; -+ bool is_execinstr = (os->flags() & elfcpp::SHF_EXECINSTR) != 0; -+ bool is_bss = false; -+ -+ switch (os->type()) -+ { -+ default: -+ case elfcpp::SHT_PROGBITS: -+ break; -+ case elfcpp::SHT_NOBITS: -+ is_bss = true; -+ break; -+ case elfcpp::SHT_RELA: -+ case elfcpp::SHT_REL: -+ if (!is_write) -+ return ORDER_DYNAMIC_RELOCS; -+ break; -+ case elfcpp::SHT_HASH: -+ case elfcpp::SHT_DYNAMIC: -+ case elfcpp::SHT_SHLIB: -+ case elfcpp::SHT_DYNSYM: -+ case elfcpp::SHT_GNU_HASH: -+ case elfcpp::SHT_GNU_verdef: -+ case elfcpp::SHT_GNU_verneed: -+ case elfcpp::SHT_GNU_versym: -+ if (!is_write) -+ return ORDER_DYNAMIC_LINKER; -+ break; -+ case elfcpp::SHT_NOTE: -+ return is_write ? ORDER_RW_NOTE : ORDER_RO_NOTE; -+ } -+ -+ if ((os->flags() & elfcpp::SHF_TLS) != 0) -+ return is_bss ? ORDER_TLS_BSS : ORDER_TLS_DATA; -+ -+ if (!is_bss && !is_write) -+ { -+ if (is_execinstr) -+ { -+ if (strcmp(os->name(), ".init") == 0) -+ return ORDER_INIT; -+ else if (strcmp(os->name(), ".fini") == 0) -+ return ORDER_FINI; -+ } -+ return is_execinstr ? ORDER_TEXT : ORDER_READONLY; -+ } -+ -+ if (os->is_relro()) -+ return is_relro_local ? ORDER_RELRO_LOCAL : ORDER_RELRO; -+ -+ if (os->is_small_section()) -+ return is_bss ? ORDER_SMALL_BSS : ORDER_SMALL_DATA; -+ if (os->is_large_section()) -+ return is_bss ? ORDER_LARGE_BSS : ORDER_LARGE_DATA; -+ -+ return is_bss ? ORDER_BSS : ORDER_DATA; -+ } -+ - // Attach output sections to segments. This is called after we have - // seen all the input sections. - -*************** Layout::attach_allocated_section_to_segm -*** 1139,1145 **** - break; - } - -! (*p)->add_output_section(os, seg_flags, true); - break; - } - ---- 1203,1209 ---- - break; - } - -! (*p)->add_output_section_to_load(this, os, seg_flags); - break; - } - -*************** Layout::attach_allocated_section_to_segm -*** 1149,1155 **** - seg_flags); - if (os->is_large_data_section()) - oseg->set_is_large_data_segment(); -! oseg->add_output_section(os, seg_flags, true); - if (is_address_set) - oseg->set_addresses(addr, addr); - } ---- 1213,1219 ---- - seg_flags); - if (os->is_large_data_section()) - oseg->set_is_large_data_segment(); -! oseg->add_output_section_to_load(this, os, seg_flags); - if (is_address_set) - oseg->set_addresses(addr, addr); - } -*************** Layout::attach_allocated_section_to_segm -*** 1167,1173 **** - && (((*p)->flags() & elfcpp::PF_W) - == (seg_flags & elfcpp::PF_W))) - { -! (*p)->add_output_section(os, seg_flags, false); - break; - } - } ---- 1231,1237 ---- - && (((*p)->flags() & elfcpp::PF_W) - == (seg_flags & elfcpp::PF_W))) - { -! (*p)->add_output_section_to_nonload(os, seg_flags); - break; - } - } -*************** Layout::attach_allocated_section_to_segm -*** 1176,1182 **** - { - Output_segment* oseg = this->make_output_segment(elfcpp::PT_NOTE, - seg_flags); -! oseg->add_output_section(os, seg_flags, false); - } - } - ---- 1240,1246 ---- - { - Output_segment* oseg = this->make_output_segment(elfcpp::PT_NOTE, - seg_flags); -! oseg->add_output_section_to_nonload(os, seg_flags); - } - } - -*************** Layout::attach_allocated_section_to_segm -*** 1186,1192 **** - { - if (this->tls_segment_ == NULL) - this->make_output_segment(elfcpp::PT_TLS, seg_flags); -! this->tls_segment_->add_output_section(os, seg_flags, false); - } - - // If -z relro is in effect, and we see a relro section, we create a ---- 1250,1256 ---- - { - if (this->tls_segment_ == NULL) - this->make_output_segment(elfcpp::PT_TLS, seg_flags); -! this->tls_segment_->add_output_section_to_nonload(os, seg_flags); - } - - // If -z relro is in effect, and we see a relro section, we create a -*************** Layout::attach_allocated_section_to_segm -*** 1196,1202 **** - gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W)); - if (this->relro_segment_ == NULL) - this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags); -! this->relro_segment_->add_output_section(os, seg_flags, false); - } - } - ---- 1260,1266 ---- - gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W)); - if (this->relro_segment_ == NULL) - this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags); -! this->relro_segment_->add_output_section_to_nonload(os, seg_flags); - } - } - -*************** Layout::make_output_section_for_script( -*** 1212,1219 **** - if (section_type == Script_sections::ST_NOLOAD) - sh_flags = 0; - Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS, -! sh_flags, false, -! false, false, false, false); - os->set_found_in_sections_clause(); - if (section_type == Script_sections::ST_NOLOAD) - os->set_is_noload(); ---- 1276,1283 ---- - if (section_type == Script_sections::ST_NOLOAD) - sh_flags = 0; - Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS, -! sh_flags, ORDER_INVALID, -! false); - os->set_found_in_sections_clause(); - if (section_type == Script_sections::ST_NOLOAD) - os->set_is_noload(); -*************** Layout::create_initial_dynamic_sections( -*** 1285,1292 **** - elfcpp::SHT_DYNAMIC, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE), -! false, false, true, -! true, false, false); - - this->dynamic_symbol_ = - symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED, ---- 1349,1356 ---- - elfcpp::SHT_DYNAMIC, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE), -! false, ORDER_RELRO, -! true); - - this->dynamic_symbol_ = - symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED, -*************** Layout::relaxation_loop_body( -*** 1591,1607 **** - || this->script_options_->saw_sections_clause()); - - // If the address of the load segment we found has been set by -! // --section-start rather than by a script, then we don't want to -! // use it for the file and segment headers. - if (load_seg != NULL - && load_seg->are_addresses_set() -! && !this->script_options_->saw_sections_clause()) -! load_seg = NULL; - - // Lay out the segment headers. - if (!parameters->options().relocatable()) - { - gold_assert(segment_headers != NULL); - if (load_seg != NULL) - load_seg->add_initial_output_data(segment_headers); - if (phdr_seg != NULL) ---- 1655,1695 ---- - || this->script_options_->saw_sections_clause()); - - // If the address of the load segment we found has been set by -! // --section-start rather than by a script, then adjust the VMA and -! // LMA downward if possible to include the file and section headers. -! uint64_t header_gap = 0; - if (load_seg != NULL - && load_seg->are_addresses_set() -! && !this->script_options_->saw_sections_clause() -! && !parameters->options().relocatable()) -! { -! file_header->finalize_data_size(); -! segment_headers->finalize_data_size(); -! size_t sizeof_headers = (file_header->data_size() -! + segment_headers->data_size()); -! const uint64_t abi_pagesize = target->abi_pagesize(); -! uint64_t hdr_paddr = load_seg->paddr() - sizeof_headers; -! hdr_paddr &= ~(abi_pagesize - 1); -! uint64_t subtract = load_seg->paddr() - hdr_paddr; -! if (load_seg->paddr() < subtract || load_seg->vaddr() < subtract) -! load_seg = NULL; -! else -! { -! load_seg->set_addresses(load_seg->vaddr() - subtract, -! load_seg->paddr() - subtract); -! header_gap = subtract - sizeof_headers; -! } -! } - - // Lay out the segment headers. - if (!parameters->options().relocatable()) - { - gold_assert(segment_headers != NULL); -+ if (header_gap != 0 && load_seg != NULL) -+ { -+ Output_data_zero_fill* z = new Output_data_zero_fill(header_gap, 1); -+ load_seg->add_initial_output_data(z); -+ } - if (load_seg != NULL) - load_seg->add_initial_output_data(segment_headers); - if (phdr_seg != NULL) -*************** Layout::create_note(const char* name, in -*** 1971,1982 **** - memcpy(buffer + 3 * (size / 8), name, namesz); - - elfcpp::Elf_Xword flags = 0; - if (allocate) -! flags = elfcpp::SHF_ALLOC; - Output_section* os = this->choose_output_section(NULL, section_name, - elfcpp::SHT_NOTE, -! flags, false, false, -! false, false, false, false); - if (os == NULL) - return NULL; - ---- 2059,2073 ---- - memcpy(buffer + 3 * (size / 8), name, namesz); - - elfcpp::Elf_Xword flags = 0; -+ Output_section_order order = ORDER_INVALID; - if (allocate) -! { -! flags = elfcpp::SHF_ALLOC; -! order = ORDER_RO_NOTE; -! } - Output_section* os = this->choose_output_section(NULL, section_name, - elfcpp::SHT_NOTE, -! flags, false, order, false); - if (os == NULL) - return NULL; - -*************** Layout::create_executable_stack_info() -*** 2055,2062 **** - elfcpp::Elf_Xword flags = 0; - if (is_stack_executable) - flags |= elfcpp::SHF_EXECINSTR; -! this->make_output_section(name, elfcpp::SHT_PROGBITS, flags, false, -! false, false, false, false); - } - else - { ---- 2146,2153 ---- - elfcpp::Elf_Xword flags = 0; - if (is_stack_executable) - flags |= elfcpp::SHF_EXECINSTR; -! this->make_output_section(name, elfcpp::SHT_PROGBITS, flags, -! ORDER_INVALID, false); - } - else - { -*************** Layout::create_incremental_info_sections -*** 2217,2223 **** - Output_section* inputs_os = - this->make_output_section(incremental_inputs_name, - elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0, -! false, false, false, false, false); - Output_section_data* posd = - this->incremental_inputs_->create_incremental_inputs_section_data(); - inputs_os->add_output_section_data(posd); ---- 2308,2314 ---- - Output_section* inputs_os = - this->make_output_section(incremental_inputs_name, - elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0, -! ORDER_INVALID, false); - Output_section_data* posd = - this->incremental_inputs_->create_incremental_inputs_section_data(); - inputs_os->add_output_section_data(posd); -*************** Layout::create_incremental_info_sections -*** 2227,2234 **** - this->namepool_.add(".gnu_incremental_strtab", false, NULL); - Output_section* strtab_os = this->make_output_section(incremental_strtab_name, - elfcpp::SHT_STRTAB, -! 0, false, false, -! false, false, false); - Output_data_strtab* strtab_data = - new Output_data_strtab(this->incremental_inputs_->get_stringpool()); - strtab_os->add_output_section_data(strtab_data); ---- 2318,2325 ---- - this->namepool_.add(".gnu_incremental_strtab", false, NULL); - Output_section* strtab_os = this->make_output_section(incremental_strtab_name, - elfcpp::SHT_STRTAB, -! 0, ORDER_INVALID, -! false); - Output_data_strtab* strtab_data = - new Output_data_strtab(this->incremental_inputs_->get_stringpool()); - strtab_os->add_output_section_data(strtab_data); -*************** Layout::segment_precedes(const Output_se -*** 2321,2328 **** - if (section_count1 > 0 && section_count2 == 0) - return false; - -! uint64_t paddr1 = seg1->first_section_load_address(); -! uint64_t paddr2 = seg2->first_section_load_address(); - if (paddr1 != paddr2) - return paddr1 < paddr2; - } ---- 2412,2419 ---- - if (section_count1 > 0 && section_count2 == 0) - return false; - -! uint64_t paddr1 = seg1->paddr(); -! uint64_t paddr2 = seg2->paddr(); - if (paddr1 != paddr2) - return paddr1 < paddr2; - } -*************** Layout::create_symtab_sections(const Inp -*** 2848,2855 **** - const char* symtab_name = this->namepool_.add(".symtab", false, NULL); - Output_section* osymtab = this->make_output_section(symtab_name, - elfcpp::SHT_SYMTAB, -! 0, false, false, -! false, false, false); - this->symtab_section_ = osymtab; - - Output_section_data* pos = new Output_data_fixed_space(off - startoff, ---- 2939,2946 ---- - const char* symtab_name = this->namepool_.add(".symtab", false, NULL); - Output_section* osymtab = this->make_output_section(symtab_name, - elfcpp::SHT_SYMTAB, -! 0, ORDER_INVALID, -! false); - this->symtab_section_ = osymtab; - - Output_section_data* pos = new Output_data_fixed_space(off - startoff, -*************** Layout::create_symtab_sections(const Inp -*** 2870,2877 **** - false, NULL); - Output_section* osymtab_xindex = - this->make_output_section(symtab_xindex_name, -! elfcpp::SHT_SYMTAB_SHNDX, 0, false, -! false, false, false, false); - - size_t symcount = (off - startoff) / symsize; - this->symtab_xindex_ = new Output_symtab_xindex(symcount); ---- 2961,2968 ---- - false, NULL); - Output_section* osymtab_xindex = - this->make_output_section(symtab_xindex_name, -! elfcpp::SHT_SYMTAB_SHNDX, 0, -! ORDER_INVALID, false); - - size_t symcount = (off - startoff) / symsize; - this->symtab_xindex_ = new Output_symtab_xindex(symcount); -*************** Layout::create_symtab_sections(const Inp -*** 2893,2900 **** - const char* strtab_name = this->namepool_.add(".strtab", false, NULL); - Output_section* ostrtab = this->make_output_section(strtab_name, - elfcpp::SHT_STRTAB, -! 0, false, false, -! false, false, false); - - Output_section_data* pstr = new Output_data_strtab(&this->sympool_); - ostrtab->add_output_section_data(pstr); ---- 2984,2991 ---- - const char* strtab_name = this->namepool_.add(".strtab", false, NULL); - Output_section* ostrtab = this->make_output_section(strtab_name, - elfcpp::SHT_STRTAB, -! 0, ORDER_INVALID, -! false); - - Output_section_data* pstr = new Output_data_strtab(&this->sympool_); - ostrtab->add_output_section_data(pstr); -*************** Layout::create_shstrtab() -*** 2922,2929 **** - const char* name = this->namepool_.add(".shstrtab", false, NULL); - - Output_section* os = this->make_output_section(name, elfcpp::SHT_STRTAB, 0, -! false, false, false, false, -! false); - - if (strcmp(parameters->options().compress_debug_sections(), "none") != 0) - { ---- 3013,3019 ---- - const char* name = this->namepool_.add(".shstrtab", false, NULL); - - Output_section* os = this->make_output_section(name, elfcpp::SHT_STRTAB, 0, -! ORDER_INVALID, false); - - if (strcmp(parameters->options().compress_debug_sections(), "none") != 0) - { -*************** Layout::create_dynamic_symtab(const Inpu -*** 3040,3047 **** - Output_section* dynsym = this->choose_output_section(NULL, ".dynsym", - elfcpp::SHT_DYNSYM, - elfcpp::SHF_ALLOC, -! false, false, true, -! false, false, false); - - Output_section_data* odata = new Output_data_fixed_space(index * symsize, - align, ---- 3130,3138 ---- - Output_section* dynsym = this->choose_output_section(NULL, ".dynsym", - elfcpp::SHT_DYNSYM, - elfcpp::SHF_ALLOC, -! false, -! ORDER_DYNAMIC_LINKER, -! false); - - Output_section_data* odata = new Output_data_fixed_space(index * symsize, - align, -*************** Layout::create_dynamic_symtab(const Inpu -*** 3071,3077 **** - this->choose_output_section(NULL, ".dynsym_shndx", - elfcpp::SHT_SYMTAB_SHNDX, - elfcpp::SHF_ALLOC, -! false, false, true, false, false, false); - - this->dynsym_xindex_ = new Output_symtab_xindex(index); - ---- 3162,3168 ---- - this->choose_output_section(NULL, ".dynsym_shndx", - elfcpp::SHT_SYMTAB_SHNDX, - elfcpp::SHF_ALLOC, -! false, ORDER_DYNAMIC_LINKER, false); - - this->dynsym_xindex_ = new Output_symtab_xindex(index); - -*************** Layout::create_dynamic_symtab(const Inpu -*** 3094,3101 **** - Output_section* dynstr = this->choose_output_section(NULL, ".dynstr", - elfcpp::SHT_STRTAB, - elfcpp::SHF_ALLOC, -! false, false, true, -! false, false, false); - - Output_section_data* strdata = new Output_data_strtab(&this->dynpool_); - dynstr->add_output_section_data(strdata); ---- 3185,3193 ---- - Output_section* dynstr = this->choose_output_section(NULL, ".dynstr", - elfcpp::SHT_STRTAB, - elfcpp::SHF_ALLOC, -! false, -! ORDER_DYNAMIC_LINKER, -! false); - - Output_section_data* strdata = new Output_data_strtab(&this->dynpool_); - dynstr->add_output_section_data(strdata); -*************** Layout::create_dynamic_symtab(const Inpu -*** 3118,3129 **** - Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount, - &phash, &hashlen); - -! Output_section* hashsec = this->choose_output_section(NULL, ".hash", -! elfcpp::SHT_HASH, -! elfcpp::SHF_ALLOC, -! false, false, true, -! false, false, -! false); - - Output_section_data* hashdata = new Output_data_const_buffer(phash, - hashlen, ---- 3210,3219 ---- - Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount, - &phash, &hashlen); - -! Output_section* hashsec = -! this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH, -! elfcpp::SHF_ALLOC, false, -! ORDER_DYNAMIC_LINKER, false); - - Output_section_data* hashdata = new Output_data_const_buffer(phash, - hashlen, -*************** Layout::create_dynamic_symtab(const Inpu -*** 3145,3156 **** - Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount, - &phash, &hashlen); - -! Output_section* hashsec = this->choose_output_section(NULL, ".gnu.hash", -! elfcpp::SHT_GNU_HASH, -! elfcpp::SHF_ALLOC, -! false, false, true, -! false, false, -! false); - - Output_section_data* hashdata = new Output_data_const_buffer(phash, - hashlen, ---- 3235,3244 ---- - Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount, - &phash, &hashlen); - -! Output_section* hashsec = -! this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH, -! elfcpp::SHF_ALLOC, false, -! ORDER_DYNAMIC_LINKER, false); - - Output_section_data* hashdata = new Output_data_const_buffer(phash, - hashlen, -*************** Layout::sized_create_version_sections( -*** 3253,3260 **** - Output_section* vsec = this->choose_output_section(NULL, ".gnu.version", - elfcpp::SHT_GNU_versym, - elfcpp::SHF_ALLOC, -! false, false, true, -! false, false, false); - - unsigned char* vbuf; - unsigned int vsize; ---- 3341,3349 ---- - Output_section* vsec = this->choose_output_section(NULL, ".gnu.version", - elfcpp::SHT_GNU_versym, - elfcpp::SHF_ALLOC, -! false, -! ORDER_DYNAMIC_LINKER, -! false); - - unsigned char* vbuf; - unsigned int vsize; -*************** Layout::sized_create_version_sections( -*** 3279,3286 **** - vdsec= this->choose_output_section(NULL, ".gnu.version_d", - elfcpp::SHT_GNU_verdef, - elfcpp::SHF_ALLOC, -! false, false, true, false, false, -! false); - - unsigned char* vdbuf; - unsigned int vdsize; ---- 3368,3374 ---- - vdsec= this->choose_output_section(NULL, ".gnu.version_d", - elfcpp::SHT_GNU_verdef, - elfcpp::SHF_ALLOC, -! false, ORDER_DYNAMIC_LINKER, false); - - unsigned char* vdbuf; - unsigned int vdsize; -*************** Layout::sized_create_version_sections( -*** 3305,3312 **** - vnsec = this->choose_output_section(NULL, ".gnu.version_r", - elfcpp::SHT_GNU_verneed, - elfcpp::SHF_ALLOC, -! false, false, true, false, false, -! false); - - unsigned char* vnbuf; - unsigned int vnsize; ---- 3393,3399 ---- - vnsec = this->choose_output_section(NULL, ".gnu.version_r", - elfcpp::SHT_GNU_verneed, - elfcpp::SHF_ALLOC, -! false, ORDER_DYNAMIC_LINKER, false); - - unsigned char* vnbuf; - unsigned int vnsize; -*************** Layout::create_interp(const Target* targ -*** 3346,3360 **** - Output_section* osec = this->choose_output_section(NULL, ".interp", - elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC, -! false, true, true, -! false, false, false); - osec->add_output_section_data(odata); - - if (!this->script_options_->saw_phdrs_clause()) - { - Output_segment* oseg = this->make_output_segment(elfcpp::PT_INTERP, - elfcpp::PF_R); -! oseg->add_output_section(osec, elfcpp::PF_R, false); - } - } - ---- 3433,3447 ---- - Output_section* osec = this->choose_output_section(NULL, ".interp", - elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC, -! false, ORDER_INTERP, -! false); - osec->add_output_section_data(odata); - - if (!this->script_options_->saw_phdrs_clause()) - { - Output_segment* oseg = this->make_output_segment(elfcpp::PT_INTERP, - elfcpp::PF_R); -! oseg->add_output_section_to_nonload(osec, elfcpp::PF_R); - } - } - -*************** Layout::finish_dynamic_section(const Inp -*** 3462,3470 **** - Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC, - (elfcpp::PF_R - | elfcpp::PF_W)); -! oseg->add_output_section(this->dynamic_section_, -! elfcpp::PF_R | elfcpp::PF_W, -! false); - } - - Output_data_dynamic* const odyn = this->dynamic_data_; ---- 3549,3556 ---- - Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC, - (elfcpp::PF_R - | elfcpp::PF_W)); -! oseg->add_output_section_to_nonload(this->dynamic_section_, -! elfcpp::PF_R | elfcpp::PF_W); - } - - Output_data_dynamic* const odyn = this->dynamic_data_; -*************** Layout::finish_dynamic_section(const Inp -*** 3562,3568 **** - ++p) - { - if (((*p)->flags() & elfcpp::PF_W) == 0 -! && (*p)->dynamic_reloc_count() > 0) - { - have_textrel = true; - break; ---- 3648,3654 ---- - ++p) - { - if (((*p)->flags() & elfcpp::PF_W) == 0 -! && (*p)->has_dynamic_reloc()) - { - have_textrel = true; - break; -*************** Layout::finish_dynamic_section(const Inp -*** 3581,3587 **** - { - if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0 - && ((*p)->flags() & elfcpp::SHF_WRITE) == 0 -! && ((*p)->dynamic_reloc_count() > 0)) - { - have_textrel = true; - break; ---- 3667,3673 ---- - { - if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0 - && ((*p)->flags() & elfcpp::SHF_WRITE) == 0 -! && ((*p)->has_dynamic_reloc())) - { - have_textrel = true; - break; -*************** Layout::output_section_name(const char* -*** 3772,3777 **** ---- 3858,3877 ---- - } - } - -+ // Compressed debug sections should be mapped to the corresponding -+ // uncompressed section. -+ if (is_compressed_debug_section(name)) -+ { -+ size_t len = strlen(name); -+ char *uncompressed_name = new char[len]; -+ uncompressed_name[0] = '.'; -+ gold_assert(name[0] == '.' && name[1] == 'z'); -+ strncpy(&uncompressed_name[1], &name[2], len - 2); -+ uncompressed_name[len - 1] = '\0'; -+ *plen = len - 1; -+ return uncompressed_name; -+ } -+ - return name; - } - -diff -rcp ../binutils-2.20.51.0.10.original/gold/layout.h gold/layout.h -*** ../binutils-2.20.51.0.10.original/gold/layout.h 2010-08-10 15:12:04.000000000 +0100 ---- gold/layout.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Output_reduced_debug_info_section; -*** 59,64 **** ---- 59,68 ---- - class Eh_frame; - class Target; - -+ // Return TRUE if SECNAME is the name of a compressed debug section. -+ extern bool -+ is_compressed_debug_section(const char* secname); -+ - // This task function handles mapping the input sections to output - // sections and laying them out in memory. - -*************** class Kept_section -*** 282,287 **** ---- 286,392 ---- - } u_; - }; - -+ // The ordering for output sections. This controls how output -+ // sections are ordered within a PT_LOAD output segment. -+ -+ enum Output_section_order -+ { -+ // Unspecified. Used for non-load segments. Also used for the file -+ // and segment headers. -+ ORDER_INVALID, -+ -+ // The PT_INTERP section should come first, so that the dynamic -+ // linker can pick it up quickly. -+ ORDER_INTERP, -+ -+ // Loadable read-only note sections come next so that the PT_NOTE -+ // segment is on the first page of the executable. -+ ORDER_RO_NOTE, -+ -+ // Put read-only sections used by the dynamic linker early in the -+ // executable to minimize paging. -+ ORDER_DYNAMIC_LINKER, -+ -+ // Put reloc sections used by the dynamic linker after other -+ // sections used by the dynamic linker; otherwise, objcopy and strip -+ // get confused. -+ ORDER_DYNAMIC_RELOCS, -+ -+ // Put the PLT reloc section after the other dynamic relocs; -+ // otherwise, prelink gets confused. -+ ORDER_DYNAMIC_PLT_RELOCS, -+ -+ // The .init section. -+ ORDER_INIT, -+ -+ // The PLT. -+ ORDER_PLT, -+ -+ // The regular text sections. -+ ORDER_TEXT, -+ -+ // The .fini section. -+ ORDER_FINI, -+ -+ // The read-only sections. -+ ORDER_READONLY, -+ -+ // The exception frame sections. -+ ORDER_EHFRAME, -+ -+ // The TLS sections come first in the data section. -+ ORDER_TLS_DATA, -+ ORDER_TLS_BSS, -+ -+ // Local RELRO (read-only after relocation) sections come before -+ // non-local RELRO sections. This data will be fully resolved by -+ // the prelinker. -+ ORDER_RELRO_LOCAL, -+ -+ // Non-local RELRO sections are grouped together after local RELRO -+ // sections. All RELRO sections must be adjacent so that they can -+ // all be put into a PT_GNU_RELRO segment. -+ ORDER_RELRO, -+ -+ // We permit marking exactly one output section as the last RELRO -+ // section. We do this so that the read-only GOT can be adjacent to -+ // the writable GOT. -+ ORDER_RELRO_LAST, -+ -+ // Similarly, we permit marking exactly one output section as the -+ // first non-RELRO section. -+ ORDER_NON_RELRO_FIRST, -+ -+ // The regular data sections come after the RELRO sections. -+ ORDER_DATA, -+ -+ // Large data sections normally go in large data segments. -+ ORDER_LARGE_DATA, -+ -+ // Group writable notes so that we can have a single PT_NOTE -+ // segment. -+ ORDER_RW_NOTE, -+ -+ // The small data sections must be at the end of the data sections, -+ // so that they can be adjacent to the small BSS sections. -+ ORDER_SMALL_DATA, -+ -+ // The BSS sections start here. -+ -+ // The small BSS sections must be at the start of the BSS sections, -+ // so that they can be adjacent to the small data sections. -+ ORDER_SMALL_BSS, -+ -+ // The regular BSS sections. -+ ORDER_BSS, -+ -+ // The large BSS sections come after the other BSS sections. -+ ORDER_LARGE_BSS, -+ -+ // Maximum value. -+ ORDER_MAX -+ }; -+ - // This class handles the details of laying out input sections. - - class Layout -*************** class Layout -*** 367,384 **** - layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags); - - // Add an Output_section_data to the layout. This is used for -! // special sections like the GOT section. IS_DYNAMIC_LINKER_SECTION -! // is true for sections which are used by the dynamic linker, such -! // as dynamic reloc sections. IS_RELRO is true for relro sections. -! // IS_LAST_RELRO is true for the last relro section. -! // IS_FIRST_NON_RELRO is true for the first section after the relro -! // sections. - Output_section* - add_output_section_data(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags, -! Output_section_data*, bool is_dynamic_linker_section, -! bool is_relro, bool is_last_relro, -! bool is_first_non_relro); - - // Increase the size of the relro segment by this much. - void ---- 472,485 ---- - layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags); - - // Add an Output_section_data to the layout. This is used for -! // special sections like the GOT section. ORDER is where the -! // section should wind up in the output segment. IS_RELRO is true -! // for relro sections. - Output_section* - add_output_section_data(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags, -! Output_section_data*, Output_section_order order, -! bool is_relro); - - // Increase the size of the relro segment by this much. - void -*************** class Layout -*** 451,456 **** ---- 552,558 ---- - { - // Debugging sections can only be recognized by name. - return (strncmp(name, ".debug", sizeof(".debug") - 1) == 0 -+ || strncmp(name, ".zdebug", sizeof(".zdebug") - 1) == 0 - || strncmp(name, ".gnu.linkonce.wi.", - sizeof(".gnu.linkonce.wi.") - 1) == 0 - || strncmp(name, ".line", sizeof(".line") - 1) == 0 -*************** class Layout -*** 783,811 **** - Output_section* - get_output_section(const char* name, Stringpool::Key name_key, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_interp, bool is_dynamic_linker_section, -! bool is_relro, bool is_last_relro, -! bool is_first_non_relro); - - // Choose the output section for NAME in RELOBJ. - Output_section* - choose_output_section(const Relobj* relobj, const char* name, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_input_section, bool is_interp, -! bool is_dynamic_linker_section, bool is_relro, -! bool is_last_relro, bool is_first_non_relro); - - // Create a new Output_section. - Output_section* - make_output_section(const char* name, elfcpp::Elf_Word type, -! elfcpp::Elf_Xword flags, bool is_interp, -! bool is_dynamic_linker_section, bool is_relro, -! bool is_last_relro, bool is_first_non_relro); - - // Attach a section to a segment. - void - attach_section_to_segment(Output_section*); - - // Attach an allocated section to a segment. - void - attach_allocated_section_to_segment(Output_section*); ---- 885,913 ---- - Output_section* - get_output_section(const char* name, Stringpool::Key name_key, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! Output_section_order order, bool is_relro); - - // Choose the output section for NAME in RELOBJ. - Output_section* - choose_output_section(const Relobj* relobj, const char* name, - elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, -! bool is_input_section, Output_section_order order, -! bool is_relro); - - // Create a new Output_section. - Output_section* - make_output_section(const char* name, elfcpp::Elf_Word type, -! elfcpp::Elf_Xword flags, Output_section_order order, -! bool is_relro); - - // Attach a section to a segment. - void - attach_section_to_segment(Output_section*); - -+ // Get section order. -+ Output_section_order -+ default_section_order(Output_section*, bool is_relro_local); -+ - // Attach an allocated section to a segment. - void - attach_allocated_section_to_segment(Output_section*); -diff -rcp ../binutils-2.20.51.0.10.original/gold/Makefile.in gold/Makefile.in -*** ../binutils-2.20.51.0.10.original/gold/Makefile.in 2010-08-10 15:11:28.000000000 +0100 ---- gold/Makefile.in 2010-08-10 15:14:03.000000000 +0100 -*************** RECURSIVE_TARGETS = all-recursive check- -*** 147,157 **** - RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive - AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ -! $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS - ETAGS = etags - CTAGS = ctags - am__tty_colors = \ - red=; grn=; lgn=; blu=; std= - DIST_SUBDIRS = $(SUBDIRS) - ACLOCAL = @ACLOCAL@ - AMTAR = @AMTAR@ ---- 147,227 ---- - RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive - AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ -! $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ -! check check-html recheck recheck-html - ETAGS = etags - CTAGS = ctags - am__tty_colors = \ - red=; grn=; lgn=; blu=; std= -+ am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -+ am__vpath_adj = case $$p in \ -+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ -+ *) f=$$p;; \ -+ esac; -+ am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -+ am__install_max = 40 -+ am__nobase_strip_setup = \ -+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -+ am__nobase_strip = \ -+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -+ am__nobase_list = $(am__nobase_strip_setup); \ -+ for p in $$list; do echo "$$p $$p"; done | \ -+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ -+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ -+ if (++n[$$2] == $(am__install_max)) \ -+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ -+ END { for (dir in files) print dir, files[dir] }' -+ am__base_list = \ -+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ -+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -+ # Restructured Text title and section. -+ am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//' -+ am__rst_section = sed 'p;s/./=/g;p;g' -+ # Put stdin (possibly several lines separated by ". ") in a box. -+ am__text_box = $(AWK) '{ \ -+ n = split($$0, lines, "\\. "); max = 0; \ -+ for (i = 1; i <= n; ++i) \ -+ if (max < length(lines[i])) \ -+ max = length(lines[i]); \ -+ for (i = 0; i < max; ++i) line = line "="; \ -+ print line; \ -+ for (i = 1; i <= n; ++i) if (lines[i]) print lines[i];\ -+ print line; \ -+ }' -+ # Solaris 10 'make', and several other traditional 'make' implementations, -+ # pass "-e" to $(SHELL). This contradicts POSIX. Work around the problem -+ # by disabling -e (using the XSI extension "set +e") if it's set. -+ am__sh_e_setup = case $$- in *e*) set +e;; esac -+ # To be inserted before the command running the test. Creates the -+ # directory for the log if needed. Stores in $dir the directory -+ # containing $f, in $tst the test, in $log the log, and passes -+ # TESTS_ENVIRONMENT. Save and restore TERM around use of -+ # TESTS_ENVIRONMENT, in case that unsets it. -+ am__check_pre = \ -+ $(am__sh_e_setup); \ -+ $(am__vpath_adj_setup) $(am__vpath_adj) \ -+ srcdir=$(srcdir); export srcdir; \ -+ rm -f $@-t; \ -+ trap 'st=$$?; rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st' \ -+ 1 2 13 15; \ -+ am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \ -+ test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \ -+ if test -f "./$$f"; then dir=./; \ -+ elif test -f "$$f"; then dir=; \ -+ else dir="$(srcdir)/"; fi; \ -+ tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \ -+ $(TESTS_ENVIRONMENT) -+ RECHECK_LOGS = $(TEST_LOGS) -+ TEST_SUITE_LOG = test-suite.log -+ TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html) -+ TEST_EXTENSIONS = @EXEEXT@ .test -+ LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) -+ am__test_logs1 = $(TESTS:=.log) -+ am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -+ TEST_LOGS = $(am__test_logs2:.test.log=.log) -+ TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ -+ $(TEST_LOG_FLAGS) -+ TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t) - DIST_SUBDIRS = $(SUBDIRS) - ACLOCAL = @ACLOCAL@ - AMTAR = @AMTAR@ -*************** all: config.h -*** 453,459 **** - $(MAKE) $(AM_MAKEFLAGS) all-recursive - - .SUFFIXES: -! .SUFFIXES: .c .cc .o .obj .y - am--refresh: - @: - $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) ---- 523,529 ---- - $(MAKE) $(AM_MAKEFLAGS) all-recursive - - .SUFFIXES: -! .SUFFIXES: .c .cc .html .log .o .obj .test .test$(EXEEXT) .y - am--refresh: - @: - $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) -*************** GTAGS: -*** 774,870 **** - distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -! check-TESTS: $(TESTS) -! @failed=0; all=0; xfail=0; xpass=0; skip=0; \ -! srcdir=$(srcdir); export srcdir; \ -! list=' $(TESTS) '; \ -! $(am__tty_colors); \ -! if test -n "$$list"; then \ -! for tst in $$list; do \ -! if test -f ./$$tst; then dir=./; \ -! elif test -f $$tst; then dir=; \ -! else dir="$(srcdir)/"; fi; \ -! if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ -! all=`expr $$all + 1`; \ -! case " $(XFAIL_TESTS) " in \ -! *[\ \ ]$$tst[\ \ ]*) \ -! xpass=`expr $$xpass + 1`; \ -! failed=`expr $$failed + 1`; \ -! col=$$red; res=XPASS; \ -! ;; \ -! *) \ -! col=$$grn; res=PASS; \ -! ;; \ -! esac; \ -! elif test $$? -ne 77; then \ -! all=`expr $$all + 1`; \ -! case " $(XFAIL_TESTS) " in \ -! *[\ \ ]$$tst[\ \ ]*) \ -! xfail=`expr $$xfail + 1`; \ -! col=$$lgn; res=XFAIL; \ -! ;; \ -! *) \ -! failed=`expr $$failed + 1`; \ -! col=$$red; res=FAIL; \ -! ;; \ -! esac; \ -! else \ -! skip=`expr $$skip + 1`; \ -! col=$$blu; res=SKIP; \ -! fi; \ -! echo "$${col}$$res$${std}: $$tst"; \ -! done; \ -! if test "$$all" -eq 1; then \ -! tests="test"; \ -! All=""; \ -! else \ -! tests="tests"; \ -! All="All "; \ -! fi; \ -! if test "$$failed" -eq 0; then \ -! if test "$$xfail" -eq 0; then \ -! banner="$$All$$all $$tests passed"; \ -! else \ -! if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ -! banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ -! fi; \ -! else \ -! if test "$$xpass" -eq 0; then \ -! banner="$$failed of $$all $$tests failed"; \ -! else \ -! if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ -! banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ -! fi; \ -! fi; \ -! dashes="$$banner"; \ -! skipped=""; \ -! if test "$$skip" -ne 0; then \ -! if test "$$skip" -eq 1; then \ -! skipped="($$skip test was not run)"; \ -! else \ -! skipped="($$skip tests were not run)"; \ -! fi; \ -! test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ -! dashes="$$skipped"; \ -! fi; \ -! report=""; \ -! if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ -! report="Please report to $(PACKAGE_BUGREPORT)"; \ -! test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ -! dashes="$$report"; \ -! fi; \ -! dashes=`echo "$$dashes" | sed s/./=/g`; \ -! if test "$$failed" -eq 0; then \ -! echo "$$grn$$dashes"; \ -! else \ -! echo "$$red$$dashes"; \ -! fi; \ -! echo "$$banner"; \ -! test -z "$$skipped" || echo "$$skipped"; \ -! test -z "$$report" || echo "$$report"; \ -! echo "$$dashes$$std"; \ -! test "$$failed" -eq 0; \ -! else :; fi - check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS ---- 844,1008 ---- - distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -! # To be appended to the command running the test. Handle the stdout -! # and stderr redirection, and catch the exit status. -! am__check_post = \ -! >$@-t 2>&1; \ -! estatus=$$?; \ -! if test -n '$(DISABLE_HARD_ERRORS)' \ -! && test $$estatus -eq 99; then \ -! estatus=1; \ -! fi; \ -! TERM=$$__SAVED_TERM; export TERM; \ -! $(am__tty_colors); \ -! xfailed=PASS; \ -! case " $(XFAIL_TESTS) " in \ -! *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ -! xfailed=XFAIL;; \ -! esac; \ -! case $$estatus:$$xfailed in \ -! 0:XFAIL) col=$$red; res=XPASS;; \ -! 0:*) col=$$grn; res=PASS ;; \ -! 77:*) col=$$blu; res=SKIP ;; \ -! 99:*) col=$$red; res=FAIL ;; \ -! *:XFAIL) col=$$lgn; res=XFAIL;; \ -! *:*) col=$$red; res=FAIL ;; \ -! esac; \ -! echo "$${col}$$res$${std}: $$f"; \ -! echo "$$res: $$f (exit: $$estatus)" | \ -! $(am__rst_section) >$@; \ -! cat $@-t >>$@; \ -! rm -f $@-t -! -! $(TEST_SUITE_LOG): $(TEST_LOGS) -! @$(am__sh_e_setup); \ -! list='$(TEST_LOGS)'; \ -! results=`for f in $$list; do \ -! read line < $$f && echo "$$line" || echo FAIL; \ -! done`; \ -! all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \ -! fail=`echo "$$results" | grep -c '^FAIL'`; \ -! pass=`echo "$$results" | grep -c '^PASS'`; \ -! skip=`echo "$$results" | grep -c '^SKIP'`; \ -! xfail=`echo "$$results" | grep -c '^XFAIL'`; \ -! xpass=`echo "$$results" | grep -c '^XPASS'`; \ -! failures=`expr $$fail + $$xpass`; \ -! all=`expr $$all - $$skip`; \ -! if test "$$all" -eq 1; then tests=test; All=; \ -! else tests=tests; All="All "; fi; \ -! case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \ -! fail=0:xpass=0:xfail=0) \ -! msg="$$All$$all $$tests passed. "; \ -! exit=true;; \ -! fail=0:xpass=0:xfail=*) \ -! msg="$$All$$all $$tests behaved as expected"; \ -! if test "$$xfail" -eq 1; then xfailures=failure; \ -! else xfailures=failures; fi; \ -! msg="$$msg ($$xfail expected $$xfailures). "; \ -! exit=true;; \ -! fail=*:xpass=0:xfail=*) \ -! msg="$$fail of $$all $$tests failed. "; \ -! exit=false;; \ -! fail=*:xpass=*:xfail=*) \ -! msg="$$failures of $$all $$tests did not behave as expected"; \ -! if test "$$xpass" -eq 1; then xpasses=pass; \ -! else xpasses=passes; fi; \ -! msg="$$msg ($$xpass unexpected $$xpasses). "; \ -! exit=false;; \ -! *) \ -! echo >&2 "incorrect case"; exit 4;; \ -! esac; \ -! if test "$$skip" -ne 0; then \ -! if test "$$skip" -eq 1; then \ -! msg="$$msg($$skip test was not run). "; \ -! else \ -! msg="$$msg($$skip tests were not run). "; \ -! fi; \ -! fi; \ -! { \ -! echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ -! $(am__rst_title); \ -! echo "$$msg"; \ -! echo; \ -! echo ".. contents:: :depth: 2"; \ -! echo; \ -! for f in $$list; do \ -! read line < $$f; \ -! case $$line in \ -! PASS:*|XFAIL:*);; \ -! *) echo; cat $$f;; \ -! esac; \ -! done; \ -! } >$(TEST_SUITE_LOG).tmp; \ -! mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ -! if test "$$failures" -ne 0; then \ -! msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \ -! if test -n "$(PACKAGE_BUGREPORT)"; then \ -! msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \ -! fi; \ -! fi; \ -! test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \ -! $(am__tty_colors); \ -! if $$exit; then \ -! echo $(ECHO_N) "$$grn$(ECHO_C)"; \ -! else \ -! echo $(ECHO_N) "$$red$(ECHO_C)"; \ -! fi; \ -! echo "$$msg" | $(am__text_box); \ -! echo $(ECHO_N) "$$std$(ECHO_C)"; \ -! $$exit -! -! # Run all the tests. -! check-TESTS: -! @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list -! @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) -! @set_logs=; if test "X$(TEST_LOGS)" = X.log; then \ -! set_logs=TEST_LOGS=; \ -! fi; \ -! $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) $$set_logs -! -! .log.html: -! @list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \ -! for r2h in $$list; do \ -! if ($$r2h --version) >/dev/null 2>&1; then \ -! R2H=$$r2h; \ -! fi; \ -! done; \ -! if test -z "$$R2H"; then \ -! echo >&2 "cannot find rst2html, cannot create $@"; \ -! exit 2; \ -! fi; \ -! $$R2H $< >$@.tmp -! @mv $@.tmp $@ -! -! # Be sure to run check first, and then to convert the result. -! # Beware of concurrent executions. Run "check" not "check-TESTS", as -! # check-SCRIPTS and other dependencies are rebuilt by the former only. -! # And expect check to fail. -! check-html: -! @if $(MAKE) $(AM_MAKEFLAGS) check; then \ -! rv=0; else rv=$$?; \ -! fi; \ -! $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) || exit 4; \ -! exit $$rv -! recheck recheck-html: -! @target=`echo $@ | sed 's,^re,,'`; \ -! list='$(TEST_LOGS)'; \ -! list=`for f in $$list; do \ -! test -f $$f || continue; \ -! if read line < $$f; then \ -! case $$line in FAIL*|XPASS*) echo $$f;; esac; \ -! else echo $$f; fi; \ -! done | tr '\012\015' ' '`; \ -! $(MAKE) $(AM_MAKEFLAGS) $$target AM_MAKEFLAGS='$(AM_MAKEFLAGS) TEST_LOGS="'"$$list"'"' -! bootstrap-test.log: bootstrap-test -! @p='bootstrap-test'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) -! bootstrap-test-r.log: bootstrap-test-r -! @p='bootstrap-test-r'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) -! .test.log: -! @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) -! @am__EXEEXT_TRUE@.test$(EXEEXT).log: -! @am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) - check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -*************** install-strip: -*** 887,892 **** ---- 1025,1034 ---- - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install - mostlyclean-generic: -+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -+ -test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP) -+ -test -z "$(TEST_SUITE_HTML)" || rm -f $(TEST_SUITE_HTML) -+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - - clean-generic: - -*************** ps-am: -*** 973,983 **** - uninstall-am: - - .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ -! ctags-recursive install-am install-strip tags-recursive - - .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ -! all all-am am--refresh check check-TESTS check-am clean \ -! clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ - clean-noinstPROGRAMS ctags ctags-recursive distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-tags dvi dvi-am html html-am info info-am install \ ---- 1115,1126 ---- - uninstall-am: - - .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ -! check-html ctags-recursive install-am install-strip recheck \ -! recheck-html tags-recursive - - .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ -! all all-am am--refresh check check-TESTS check-am check-html \ -! clean clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ - clean-noinstPROGRAMS ctags ctags-recursive distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-tags dvi dvi-am html html-am info info-am install \ -*************** uninstall-am: -*** 988,995 **** - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ -! mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ -! uninstall uninstall-am - - - # Use an explicit dependency for the bison generated header file. ---- 1131,1138 ---- - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ -! mostlyclean-generic pdf pdf-am ps ps-am recheck recheck-html \ -! tags tags-recursive uninstall uninstall-am - - - # Use an explicit dependency for the bison generated header file. -diff -rcp ../binutils-2.20.51.0.10.original/gold/merge.cc gold/merge.cc -*** ../binutils-2.20.51.0.10.original/gold/merge.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/merge.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 1,6 **** - // merge.cc -- handle section merging for gold - -! // Copyright 2006, 2007, 2008 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. ---- 1,6 ---- - // merge.cc -- handle section merging for gold - -! // Copyright 2006, 2007, 2008, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. -*************** -*** 26,31 **** ---- 26,32 ---- - #include - - #include "merge.h" -+ #include "compressed_output.h" - - namespace gold - { -*************** bool -*** 404,415 **** - Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx) - { - section_size_type len; - const unsigned char* p = object->section_contents(shndx, &len, false); - - section_size_type entsize = convert_to_section_size_type(this->entsize()); - - if (len % entsize != 0) -! return false; - - this->input_count_ += len / entsize; - ---- 405,433 ---- - Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx) - { - section_size_type len; -+ section_size_type uncompressed_size = 0; -+ unsigned char* uncompressed_data = NULL; - const unsigned char* p = object->section_contents(shndx, &len, false); - -+ if (object->section_is_compressed(shndx, &uncompressed_size)) -+ { -+ uncompressed_data = new unsigned char[uncompressed_size]; -+ if (!decompress_input_section(p, len, uncompressed_data, -+ uncompressed_size)) -+ object->error(_("could not decompress section %s"), -+ object->section_name(shndx).c_str()); -+ p = uncompressed_data; -+ len = uncompressed_size; -+ } -+ - section_size_type entsize = convert_to_section_size_type(this->entsize()); - - if (len % entsize != 0) -! { -! if (uncompressed_data != NULL) -! delete[] uncompressed_data; -! return false; -! } - - this->input_count_ += len / entsize; - -*************** Output_merge_data::do_add_input_section( -*** 438,443 **** ---- 456,464 ---- - if (this->keeps_input_sections()) - record_input_section(object, shndx); - -+ if (uncompressed_data != NULL) -+ delete[] uncompressed_data; -+ - return true; - } - -*************** Output_merge_string::do_add_i -*** 495,550 **** - unsigned int shndx) - { - section_size_type len; - const unsigned char* pdata = object->section_contents(shndx, &len, false); - - const Char_type* p = reinterpret_cast(pdata); - const Char_type* pend = p + len / sizeof(Char_type); - - if (len % sizeof(Char_type) != 0) - { - object->error(_("mergeable string section length not multiple of " - "character size")); - return false; - } - - size_t count = 0; - - // The index I is in bytes, not characters. - section_size_type i = 0; -! while (i < len) - { -! const Char_type* pl; -! for (pl = p; *pl != 0; ++pl) -! { -! if (pl >= pend) -! { -! gold_warning(_("%s: last entry in mergeable string section '%s' " -! "not null terminated"), -! object->name().c_str(), -! object->section_name(shndx).c_str()); -! break; -! } -! } - - Stringpool::Key key; -! const Char_type* str = this->stringpool_.add_with_length(p, pl - p, true, -! &key); - -! section_size_type bytelen_with_null = ((pl - p) + 1) * sizeof(Char_type); -! this->merged_strings_.push_back(Merged_string(object, shndx, i, str, -! bytelen_with_null, key)); -! -! p = pl + 1; -! i += bytelen_with_null; -! ++count; - } - - this->input_count_ += count; - - // For script processing, we keep the input sections. - if (this->keeps_input_sections()) - record_input_section(object, shndx); - - return true; - } - ---- 516,613 ---- - unsigned int shndx) - { - section_size_type len; -+ section_size_type uncompressed_size = 0; -+ unsigned char* uncompressed_data = NULL; - const unsigned char* pdata = object->section_contents(shndx, &len, false); - -+ if (object->section_is_compressed(shndx, &uncompressed_size)) -+ { -+ uncompressed_data = new unsigned char[uncompressed_size]; -+ if (!decompress_input_section(pdata, len, uncompressed_data, -+ uncompressed_size)) -+ object->error(_("could not decompress section %s"), -+ object->section_name(shndx).c_str()); -+ pdata = uncompressed_data; -+ len = uncompressed_size; -+ } -+ - const Char_type* p = reinterpret_cast(pdata); - const Char_type* pend = p + len / sizeof(Char_type); -+ const Char_type* pend0 = pend; - - if (len % sizeof(Char_type) != 0) - { - object->error(_("mergeable string section length not multiple of " - "character size")); -+ if (uncompressed_data != NULL) -+ delete[] uncompressed_data; - return false; - } - -+ if (pend[-1] != 0) -+ { -+ gold_warning(_("%s: last entry in mergeable string section '%s' " -+ "not null terminated"), -+ object->name().c_str(), -+ object->section_name(shndx).c_str()); -+ // Find the end of the last NULL-terminated string in the buffer. -+ while (pend0 > p && pend0[-1] != 0) -+ --pend0; -+ } -+ -+ Merged_strings_list* merged_strings_list = -+ new Merged_strings_list(object, shndx); -+ this->merged_strings_lists_.push_back(merged_strings_list); -+ Merged_strings& merged_strings = merged_strings_list->merged_strings; -+ -+ // Count the number of strings in the section and size the list. - size_t count = 0; -+ for (const Char_type* pt = p; pt < pend0; pt += string_length(pt) + 1) -+ ++count; -+ if (pend0 < pend) -+ ++count; -+ merged_strings.reserve(count + 1); - - // The index I is in bytes, not characters. - section_size_type i = 0; -! while (p < pend0) - { -! size_t len = string_length(p); -! -! Stringpool::Key key; -! this->stringpool_.add_with_length(p, len, true, &key); -! -! merged_strings.push_back(Merged_string(i, key)); -! -! p += len + 1; -! i += (len + 1) * sizeof(Char_type); -! } -! if (p < pend) -! { -! size_t len = pend - p; - - Stringpool::Key key; -! this->stringpool_.add_with_length(p, len, true, &key); - -! merged_strings.push_back(Merged_string(i, key)); -! -! i += (len + 1) * sizeof(Char_type); - } - -+ // Record the last offset in the input section so that we can -+ // compute the length of the last string. -+ merged_strings.push_back(Merged_string(i, 0)); -+ - this->input_count_ += count; -+ this->input_size_ += len; - - // For script processing, we keep the input sections. - if (this->keeps_input_sections()) - record_input_section(object, shndx); - -+ if (uncompressed_data != NULL) -+ delete[] uncompressed_data; -+ - return true; - } - -*************** Output_merge_string::finalize -*** 557,576 **** - { - this->stringpool_.set_string_offsets(); - -! for (typename Merged_strings::const_iterator p = -! this->merged_strings_.begin(); -! p != this->merged_strings_.end(); -! ++p) -! { -! section_offset_type offset = -! this->stringpool_.get_offset_from_key(p->stringpool_key); -! this->add_mapping(p->object, p->shndx, p->offset, p->length, offset); - } - - // Save some memory. This also ensures that this function will work - // if called twice, as may happen if Layout::set_segment_offsets - // finds a better alignment. -! this->merged_strings_.clear(); - - return this->stringpool_.get_strtab_size(); - } ---- 620,653 ---- - { - this->stringpool_.set_string_offsets(); - -! for (typename Merged_strings_lists::const_iterator l = -! this->merged_strings_lists_.begin(); -! l != this->merged_strings_lists_.end(); -! ++l) -! { -! section_offset_type last_input_offset = 0; -! section_offset_type last_output_offset = 0; -! for (typename Merged_strings::const_iterator p = -! (*l)->merged_strings.begin(); -! p != (*l)->merged_strings.end(); -! ++p) -! { -! section_size_type length = p->offset - last_input_offset; -! if (length > 0) -! this->add_mapping((*l)->object, (*l)->shndx, last_input_offset, -! length, last_output_offset); -! last_input_offset = p->offset; -! if (p->stringpool_key != 0) -! last_output_offset = -! this->stringpool_.get_offset_from_key(p->stringpool_key); -! } -! delete *l; - } - - // Save some memory. This also ensures that this function will work - // if called twice, as may happen if Layout::set_segment_offsets - // finds a better alignment. -! this->merged_strings_lists_.clear(); - - return this->stringpool_.get_strtab_size(); - } -*************** Output_merge_string::do_print -*** 641,647 **** - { - char buf[200]; - snprintf(buf, sizeof buf, "%s merged %s", section_name, this->string_name()); -! fprintf(stderr, _("%s: %s input: %zu\n"), - program_name, buf, this->input_count_); - this->stringpool_.print_stats(buf); - } ---- 718,726 ---- - { - char buf[200]; - snprintf(buf, sizeof buf, "%s merged %s", section_name, this->string_name()); -! fprintf(stderr, _("%s: %s input bytes: %zu\n"), -! program_name, buf, this->input_size_); -! fprintf(stderr, _("%s: %s input strings: %zu\n"), - program_name, buf, this->input_count_); - this->stringpool_.print_stats(buf); - } -diff -rcp ../binutils-2.20.51.0.10.original/gold/merge.h gold/merge.h -*** ../binutils-2.20.51.0.10.original/gold/merge.h 2010-08-10 15:12:03.000000000 +0100 ---- gold/merge.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Output_merge_string : public Outpu -*** 462,468 **** - public: - Output_merge_string(uint64_t addralign) - : Output_merge_base(sizeof(Char_type), addralign), stringpool_(), -! merged_strings_(), input_count_(0) - { - gold_assert(addralign <= sizeof(Char_type)); - this->stringpool_.set_no_zero_null(); ---- 462,468 ---- - public: - Output_merge_string(uint64_t addralign) - : Output_merge_base(sizeof(Char_type), addralign), stringpool_(), -! merged_strings_lists_(), input_count_(0), input_size_(0) - { - gold_assert(addralign <= sizeof(Char_type)); - this->stringpool_.set_no_zero_null(); -*************** class Output_merge_string : public Outpu -*** 531,566 **** - // index and offset to strings. - struct Merged_string - { -- // The input object where the string was found. -- Relobj* object; -- // The input section in the input object. -- unsigned int shndx; - // The offset in the input section. - section_offset_type offset; -- // The string itself, a pointer into a Stringpool. -- const Char_type* string; -- // The length of the string in bytes, including the null terminator. -- size_t length; - // The key in the Stringpool. - Stringpool::Key stringpool_key; - -! Merged_string(Relobj *objecta, unsigned int shndxa, -! section_offset_type offseta, const Char_type* stringa, -! size_t lengtha, Stringpool::Key stringpool_keya) -! : object(objecta), shndx(shndxa), offset(offseta), string(stringa), -! length(lengtha), stringpool_key(stringpool_keya) - { } - }; - - typedef std::vector Merged_strings; - - // As we see the strings, we add them to a Stringpool. - Stringpool_template stringpool_; - // Map from a location in an input object to an entry in the - // Stringpool. -! Merged_strings merged_strings_; - // The number of entries seen in input files. - size_t input_count_; - }; - - } // End namespace gold. ---- 531,573 ---- - // index and offset to strings. - struct Merged_string - { - // The offset in the input section. - section_offset_type offset; - // The key in the Stringpool. - Stringpool::Key stringpool_key; - -! Merged_string(section_offset_type offseta, Stringpool::Key stringpool_keya) -! : offset(offseta), stringpool_key(stringpool_keya) - { } - }; - - typedef std::vector Merged_strings; - -+ struct Merged_strings_list -+ { -+ // The input object where the strings were found. -+ Relobj* object; -+ // The input section in the input object. -+ unsigned int shndx; -+ // The list of merged strings. -+ Merged_strings merged_strings; -+ -+ Merged_strings_list(Relobj* objecta, unsigned int shndxa) -+ : object(objecta), shndx(shndxa), merged_strings() -+ { } -+ }; -+ -+ typedef std::vector Merged_strings_lists; -+ - // As we see the strings, we add them to a Stringpool. - Stringpool_template stringpool_; - // Map from a location in an input object to an entry in the - // Stringpool. -! Merged_strings_lists merged_strings_lists_; - // The number of entries seen in input files. - size_t input_count_; -+ // The total size of input sections. -+ size_t input_size_; - }; - - } // End namespace gold. -diff -rcp ../binutils-2.20.51.0.10.original/gold/object.cc gold/object.cc -*** ../binutils-2.20.51.0.10.original/gold/object.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/object.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 39,44 **** ---- 39,45 ---- - #include "object.h" - #include "dynobj.h" - #include "plugin.h" -+ #include "compressed_output.h" - - namespace gold - { -*************** Sized_relobj::Sized_re -*** 367,373 **** - local_got_offsets_(), - kept_comdat_sections_(), - has_eh_frame_(false), -! discarded_eh_frame_shndx_(-1U) - { - } - ---- 368,377 ---- - local_got_offsets_(), - kept_comdat_sections_(), - has_eh_frame_(false), -! discarded_eh_frame_shndx_(-1U), -! deferred_layout_(), -! deferred_layout_relocs_(), -! compressed_sections_() - { - } - -*************** Sized_relobj::find_eh_ -*** 495,500 **** ---- 499,548 ---- - return false; - } - -+ // Build a table for any compressed debug sections, mapping each section index -+ // to the uncompressed size. -+ -+ template -+ Compressed_section_map* -+ build_compressed_section_map( -+ const unsigned char* pshdrs, -+ unsigned int shnum, -+ const char* names, -+ section_size_type names_size, -+ Sized_relobj* obj) -+ { -+ Compressed_section_map* uncompressed_sizes = new Compressed_section_map(); -+ const unsigned int shdr_size = elfcpp::Elf_sizes::shdr_size; -+ const unsigned char* p = pshdrs + shdr_size; -+ for (unsigned int i = 1; i < shnum; ++i, p += shdr_size) -+ { -+ typename elfcpp::Shdr shdr(p); -+ if (shdr.get_sh_type() == elfcpp::SHT_PROGBITS -+ && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) -+ { -+ if (shdr.get_sh_name() >= names_size) -+ { -+ obj->error(_("bad section name offset for section %u: %lu"), -+ i, static_cast(shdr.get_sh_name())); -+ continue; -+ } -+ -+ const char* name = names + shdr.get_sh_name(); -+ if (is_compressed_debug_section(name)) -+ { -+ section_size_type len; -+ const unsigned char* contents = -+ obj->section_contents(i, &len, false); -+ uint64_t uncompressed_size = get_uncompressed_size(contents, len); -+ if (uncompressed_size != -1ULL) -+ (*uncompressed_sizes)[i] = -+ convert_to_section_size_type(uncompressed_size); -+ } -+ } -+ } -+ return uncompressed_sizes; -+ } -+ - // Read the sections and symbols from an object file. - - template -*************** Sized_relobj::do_read_ -*** 514,519 **** ---- 562,571 ---- - if (this->find_eh_frame(pshdrs, names, sd->section_names_size)) - this->has_eh_frame_ = true; - } -+ if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL) -+ this->compressed_sections_ = -+ build_compressed_section_map(pshdrs, this->shnum(), names, -+ sd->section_names_size, this); - - sd->symbols = NULL; - sd->symbols_size = 0; -*************** Sized_relobj::do_add_s -*** 1562,1567 **** ---- 1614,1620 ---- - template - Archive::Should_include - Sized_relobj::do_should_include_member(Symbol_table* symtab, -+ Layout* layout, - Read_symbols_data* sd, - std::string* why) - { -*************** Sized_relobj::do_shoul -*** 1587,1593 **** - unsigned int st_name = sym.get_st_name(); - const char* name = sym_names + st_name; - Symbol* symbol; -! Archive::Should_include t = Archive::should_include_member(symtab, name, - &symbol, why, - &tmpbuf, - &tmpbuflen); ---- 1640,1648 ---- - unsigned int st_name = sym.get_st_name(); - const char* name = sym_names + st_name; - Symbol* symbol; -! Archive::Should_include t = Archive::should_include_member(symtab, -! layout, -! name, - &symbol, why, - &tmpbuf, - &tmpbuflen); -diff -rcp ../binutils-2.20.51.0.10.original/gold/object.h gold/object.h -*** ../binutils-2.20.51.0.10.original/gold/object.h 2010-08-10 15:11:43.000000000 +0100 ---- gold/object.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Object -*** 405,413 **** - - // Add symbol information to the global symbol table. - Archive::Should_include -! should_include_member(Symbol_table* symtab, Read_symbols_data* sd, -! std::string* why) -! { return this->do_should_include_member(symtab, sd, why); } - - // Functions and types for the elfcpp::Elf_file interface. This - // permit us to use Object as the File template parameter for ---- 405,413 ---- - - // Add symbol information to the global symbol table. - Archive::Should_include -! should_include_member(Symbol_table* symtab, Layout* layout, -! Read_symbols_data* sd, std::string* why) -! { return this->do_should_include_member(symtab, layout, sd, why); } - - // Functions and types for the elfcpp::Elf_file interface. This - // permit us to use Object as the File template parameter for -*************** class Object -*** 518,523 **** ---- 518,530 ---- - set_no_export(bool value) - { this->no_export_ = value; } - -+ // Return TRUE if the section is a compressed debug section, and set -+ // *UNCOMPRESSED_SIZE to the size of the uncompressed data. -+ bool -+ section_is_compressed(unsigned int shndx, -+ section_size_type* uncompressed_size) const -+ { return this->do_section_is_compressed(shndx, uncompressed_size); } -+ - protected: - // Returns NULL for Objects that are not plugin objects. This method - // is overridden in the Pluginobj class. -*************** class Object -*** 539,545 **** - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*) = 0; - - virtual Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Read_symbols_data*, - std::string* why) = 0; - - // Return the location of the contents of a section. Implemented by ---- 546,552 ---- - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*) = 0; - - virtual Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, - std::string* why) = 0; - - // Return the location of the contents of a section. Implemented by -*************** class Object -*** 628,633 **** ---- 635,646 ---- - bool - handle_split_stack_section(const char* name); - -+ // Return TRUE if the section is a compressed debug section, and set -+ // *UNCOMPRESSED_SIZE to the size of the uncompressed data. -+ virtual bool -+ do_section_is_compressed(unsigned int, section_size_type*) const -+ { return false; } -+ - private: - // This class may not be copied. - Object(const Object&); -*************** class Reloc_symbol_changes -*** 1406,1411 **** ---- 1419,1428 ---- - std::vector vec_; - }; - -+ // Type for mapping section index to uncompressed size. -+ -+ typedef std::map Compressed_section_map; -+ - // A regular object file. This is size and endian specific. - - template -*************** class Sized_relobj : public Relobj -*** 1606,1612 **** - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Read_symbols_data*, - std::string* why); - - // Read the relocs. ---- 1623,1629 ---- - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, - std::string* why); - - // Read the relocs. -*************** class Sized_relobj : public Relobj -*** 1781,1787 **** - void - set_output_local_symbol_count(unsigned int value) - { this->output_local_symbol_count_ = value; } -! - private: - // For convenience. - typedef Sized_relobj This; ---- 1798,1823 ---- - void - set_output_local_symbol_count(unsigned int value) - { this->output_local_symbol_count_ = value; } -! -! // Return TRUE if the section is a compressed debug section, and set -! // *UNCOMPRESSED_SIZE to the size of the uncompressed data. -! bool -! do_section_is_compressed(unsigned int shndx, -! section_size_type* uncompressed_size) const -! { -! if (this->compressed_sections_ == NULL) -! return false; -! Compressed_section_map::const_iterator p = -! this->compressed_sections_->find(shndx); -! if (p != this->compressed_sections_->end()) -! { -! if (uncompressed_size != NULL) -! *uncompressed_size = p->second; -! return true; -! } -! return false; -! } -! - private: - // For convenience. - typedef Sized_relobj This; -*************** class Sized_relobj : public Relobj -*** 2024,2029 **** ---- 2060,2067 ---- - std::vector deferred_layout_; - // The list of relocation sections whose layout was deferred. - std::vector deferred_layout_relocs_; -+ // For compressed debug sections, map section index to uncompressed size. -+ Compressed_section_map* compressed_sections_; - }; - - // A class to manage the list of all objects. -diff -rcp ../binutils-2.20.51.0.10.original/gold/output.cc gold/output.cc -*** ../binutils-2.20.51.0.10.original/gold/output.cc 2010-08-10 15:11:46.000000000 +0100 ---- gold/output.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Output_section::Output_section(const cha -*** 1917,1922 **** ---- 1917,1923 ---- - info_(0), - type_(type), - flags_(flags), -+ order_(ORDER_INVALID), - out_shndx_(-1U), - symtab_index_(0), - dynsym_index_(0), -*************** Output_section::Output_section(const cha -*** 1938,1954 **** - must_sort_attached_input_sections_(false), - attached_input_sections_are_sorted_(false), - is_relro_(false), -- is_relro_local_(false), -- is_last_relro_(false), -- is_first_non_relro_(false), - is_small_section_(false), - is_large_section_(false), -- is_interp_(false), -- is_dynamic_linker_section_(false), - generate_code_fills_at_write_(false), - is_entsize_zero_(false), - section_offsets_need_adjustment_(false), - is_noload_(false), - tls_offset_(0), - checkpoint_(NULL), - lookup_maps_(new Output_section_lookup_maps) ---- 1939,1951 ---- - must_sort_attached_input_sections_(false), - attached_input_sections_are_sorted_(false), - is_relro_(false), - is_small_section_(false), - is_large_section_(false), - generate_code_fills_at_write_(false), - is_entsize_zero_(false), - section_offsets_need_adjustment_(false), - is_noload_(false), -+ always_keeps_input_sections_(false), - tls_offset_(0), - checkpoint_(NULL), - lookup_maps_(new Output_section_lookup_maps) -*************** Output_section::add_input_section(Layout -*** 2038,2045 **** - { - // Keep information about merged input sections for rebuilding fast - // lookup maps if we have sections-script or we do relaxation. -! bool keeps_input_sections = -! have_sections_script || parameters->target().may_relax(); - if (this->add_merge_input_section(object, shndx, sh_flags, entsize, - addralign, keeps_input_sections)) - { ---- 2035,2044 ---- - { - // Keep information about merged input sections for rebuilding fast - // lookup maps if we have sections-script or we do relaxation. -! bool keeps_input_sections = (this->always_keeps_input_sections_ -! || have_sections_script -! || parameters->target().may_relax()); -! - if (this->add_merge_input_section(object, shndx, sh_flags, entsize, - addralign, keeps_input_sections)) - { -*************** Output_section::add_input_section(Layout -*** 2086,2093 **** - } - } - - this->set_current_data_size_for_child(aligned_offset_in_section -! + shdr.get_sh_size()); - - // We need to keep track of this section if we are already keeping - // track of sections, or if we are relaxing. Also, if this is a ---- 2085,2097 ---- - } - } - -+ section_size_type input_section_size = shdr.get_sh_size(); -+ section_size_type uncompressed_size; -+ if (object->section_is_compressed(shndx, &uncompressed_size)) -+ input_section_size = uncompressed_size; -+ - this->set_current_data_size_for_child(aligned_offset_in_section -! + input_section_size); - - // We need to keep track of this section if we are already keeping - // track of sections, or if we are relaxing. Also, if this is a -*************** Output_section::add_input_section(Layout -*** 2095,2101 **** - // the future, we keep track of the sections. If the - // --section-ordering-file option is used to specify the order of - // sections, we need to keep track of sections. -! if (have_sections_script - || !this->input_sections_.empty() - || this->may_sort_attached_input_sections() - || this->must_sort_attached_input_sections() ---- 2099,2106 ---- - // the future, we keep track of the sections. If the - // --section-ordering-file option is used to specify the order of - // sections, we need to keep track of sections. -! if (this->always_keeps_input_sections_ -! || have_sections_script - || !this->input_sections_.empty() - || this->may_sort_attached_input_sections() - || this->must_sort_attached_input_sections() -*************** Output_section::print_merge_stats() -*** 3400,3408 **** - // Output segment methods. - - Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags) -! : output_data_(), -! output_bss_(), -! vaddr_(0), - paddr_(0), - memsz_(0), - max_align_(0), ---- 3405,3411 ---- - // Output segment methods. - - Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags) -! : vaddr_(0), - paddr_(0), - memsz_(0), - max_align_(0), -*************** Output_segment::Output_segment(elfcpp::E -*** 3421,3713 **** - this->flags_ = elfcpp::PF_R; - } - -! // Add an Output_section to an Output_segment. - - void -! Output_segment::add_output_section(Output_section* os, -! elfcpp::Elf_Word seg_flags, -! bool do_sort) - { - gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0); - gold_assert(!this->is_max_align_known_); - gold_assert(os->is_large_data_section() == this->is_large_data_segment()); -- gold_assert(this->type() == elfcpp::PT_LOAD || !do_sort); - - this->update_flags_for_output_section(seg_flags); - -! Output_segment::Output_data_list* pdl; -! if (os->type() == elfcpp::SHT_NOBITS) -! pdl = &this->output_bss_; - else -! pdl = &this->output_data_; -! -! // Note that while there may be many input sections in an output -! // section, there are normally only a few output sections in an -! // output segment. The loops below are expected to be fast. -! -! // So that PT_NOTE segments will work correctly, we need to ensure -! // that all SHT_NOTE sections are adjacent. -! if (os->type() == elfcpp::SHT_NOTE && !pdl->empty()) -! { -! Output_segment::Output_data_list::iterator p = pdl->end(); -! do -! { -! --p; -! if ((*p)->is_section_type(elfcpp::SHT_NOTE)) -! { -! ++p; -! pdl->insert(p, os); -! return; -! } -! } -! while (p != pdl->begin()); -! } -! -! // Similarly, so that PT_TLS segments will work, we need to group -! // SHF_TLS sections. An SHF_TLS/SHT_NOBITS section is a special -! // case: we group the SHF_TLS/SHT_NOBITS sections right after the -! // SHF_TLS/SHT_PROGBITS sections. This lets us set up PT_TLS -! // correctly. SHF_TLS sections get added to both a PT_LOAD segment -! // and the PT_TLS segment; we do this grouping only for the PT_LOAD -! // segment. -! if (this->type_ != elfcpp::PT_TLS -! && (os->flags() & elfcpp::SHF_TLS) != 0) -! { -! pdl = &this->output_data_; -! if (!pdl->empty()) -! { -! bool nobits = os->type() == elfcpp::SHT_NOBITS; -! bool sawtls = false; -! Output_segment::Output_data_list::iterator p = pdl->end(); -! gold_assert(p != pdl->begin()); -! do -! { -! --p; -! bool insert; -! if ((*p)->is_section_flag_set(elfcpp::SHF_TLS)) -! { -! sawtls = true; -! // Put a NOBITS section after the first TLS section. -! // Put a PROGBITS section after the first -! // TLS/PROGBITS section. -! insert = nobits || !(*p)->is_section_type(elfcpp::SHT_NOBITS); -! } -! else -! { -! // If we've gone past the TLS sections, but we've -! // seen a TLS section, then we need to insert this -! // section now. -! insert = sawtls; -! } -! -! if (insert) -! { -! ++p; -! pdl->insert(p, os); -! return; -! } -! } -! while (p != pdl->begin()); -! } -! -! // There are no TLS sections yet; put this one at the requested -! // location in the section list. -! } -! -! if (do_sort) -! { -! // For the PT_GNU_RELRO segment, we need to group relro -! // sections, and we need to put them before any non-relro -! // sections. Any relro local sections go before relro non-local -! // sections. One section may be marked as the last relro -! // section. -! if (os->is_relro()) -! { -! gold_assert(pdl == &this->output_data_); -! Output_segment::Output_data_list::iterator p; -! for (p = pdl->begin(); p != pdl->end(); ++p) -! { -! if (!(*p)->is_section()) -! break; - -! Output_section* pos = (*p)->output_section(); -! if (!pos->is_relro() -! || (os->is_relro_local() && !pos->is_relro_local()) -! || (!os->is_last_relro() && pos->is_last_relro())) -! break; -! } -! -! pdl->insert(p, os); -! return; -! } - -! // One section may be marked as the first section which follows -! // the relro sections. -! if (os->is_first_non_relro()) -! { -! gold_assert(pdl == &this->output_data_); -! Output_segment::Output_data_list::iterator p; -! for (p = pdl->begin(); p != pdl->end(); ++p) -! { -! if (!(*p)->is_section()) -! break; - -! Output_section* pos = (*p)->output_section(); -! if (!pos->is_relro()) -! break; -! } - -! pdl->insert(p, os); -! return; -! } -! } - -! // Small data sections go at the end of the list of data sections. -! // If OS is not small, and there are small sections, we have to -! // insert it before the first small section. -! if (os->type() != elfcpp::SHT_NOBITS -! && !os->is_small_section() -! && !pdl->empty() -! && pdl->back()->is_section() -! && pdl->back()->output_section()->is_small_section()) -! { -! for (Output_segment::Output_data_list::iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) -! { -! if ((*p)->is_section() -! && (*p)->output_section()->is_small_section()) -! { -! pdl->insert(p, os); -! return; -! } -! } -! gold_unreachable(); -! } - -! // A small BSS section goes at the start of the BSS sections, after -! // other small BSS sections. -! if (os->type() == elfcpp::SHT_NOBITS && os->is_small_section()) -! { -! for (Output_segment::Output_data_list::iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) -! { -! if (!(*p)->is_section() -! || !(*p)->output_section()->is_small_section()) -! { -! pdl->insert(p, os); -! return; -! } -! } -! } - -! // A large BSS section goes at the end of the BSS sections, which -! // means that one that is not large must come before the first large -! // one. -! if (os->type() == elfcpp::SHT_NOBITS -! && !os->is_large_section() -! && !pdl->empty() -! && pdl->back()->is_section() -! && pdl->back()->output_section()->is_large_section()) - { -! for (Output_segment::Output_data_list::iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) - { -! if ((*p)->is_section() -! && (*p)->output_section()->is_large_section()) - { -! pdl->insert(p, os); - return; - } - } -- gold_unreachable(); - } -- -- // We do some further output section sorting in order to make the -- // generated program run more efficiently. We should only do this -- // when not using a linker script, so it is controled by the DO_SORT -- // parameter. -- if (do_sort) -- { -- // FreeBSD requires the .interp section to be in the first page -- // of the executable. That is a more efficient location anyhow -- // for any OS, since it means that the kernel will have the data -- // handy after it reads the program headers. -- if (os->is_interp() && !pdl->empty()) -- { -- pdl->insert(pdl->begin(), os); -- return; -- } -- -- // Put loadable non-writable notes immediately after the .interp -- // sections, so that the PT_NOTE segment is on the first page of -- // the executable. -- if (os->type() == elfcpp::SHT_NOTE -- && (os->flags() & elfcpp::SHF_WRITE) == 0 -- && !pdl->empty()) -- { -- Output_segment::Output_data_list::iterator p = pdl->begin(); -- if ((*p)->is_section() && (*p)->output_section()->is_interp()) -- ++p; -- pdl->insert(p, os); -- return; -- } -- -- // If this section is used by the dynamic linker, and it is not -- // writable, then put it first, after the .interp section and -- // any loadable notes. This makes it more likely that the -- // dynamic linker will have to read less data from the disk. -- if (os->is_dynamic_linker_section() -- && !pdl->empty() -- && (os->flags() & elfcpp::SHF_WRITE) == 0) -- { -- bool is_reloc = (os->type() == elfcpp::SHT_REL -- || os->type() == elfcpp::SHT_RELA); -- Output_segment::Output_data_list::iterator p = pdl->begin(); -- while (p != pdl->end() -- && (*p)->is_section() -- && ((*p)->output_section()->is_dynamic_linker_section() -- || (*p)->output_section()->type() == elfcpp::SHT_NOTE)) -- { -- // Put reloc sections after the other ones. Putting the -- // dynamic reloc sections first confuses BFD, notably -- // objcopy and strip. -- if (!is_reloc -- && ((*p)->output_section()->type() == elfcpp::SHT_REL -- || (*p)->output_section()->type() == elfcpp::SHT_RELA)) -- break; -- ++p; -- } -- pdl->insert(p, os); -- return; -- } -- } -- -- // If there were no constraints on the output section, just add it -- // to the end of the list. -- pdl->push_back(os); -- } -- -- // Remove an Output_section from this segment. It is an error if it -- // is not present. -- -- void -- Output_segment::remove_output_section(Output_section* os) -- { -- // We only need this for SHT_PROGBITS. -- gold_assert(os->type() == elfcpp::SHT_PROGBITS); -- for (Output_data_list::iterator p = this->output_data_.begin(); -- p != this->output_data_.end(); -- ++p) -- { -- if (*p == os) -- { -- this->output_data_.erase(p); -- return; -- } -- } - gold_unreachable(); - } - ---- 3424,3487 ---- - this->flags_ = elfcpp::PF_R; - } - -! // Add an Output_section to a PT_LOAD Output_segment. - - void -! Output_segment::add_output_section_to_load(Layout* layout, -! Output_section* os, -! elfcpp::Elf_Word seg_flags) - { -+ gold_assert(this->type() == elfcpp::PT_LOAD); - gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0); - gold_assert(!this->is_max_align_known_); - gold_assert(os->is_large_data_section() == this->is_large_data_segment()); - - this->update_flags_for_output_section(seg_flags); - -! // We don't want to change the ordering if we have a linker script -! // with a SECTIONS clause. -! Output_section_order order = os->order(); -! if (layout->script_options()->saw_sections_clause()) -! order = static_cast(0); - else -! gold_assert(order != ORDER_INVALID); - -! this->output_lists_[order].push_back(os); -! } - -! // Add an Output_section to a non-PT_LOAD Output_segment. - -! void -! Output_segment::add_output_section_to_nonload(Output_section* os, -! elfcpp::Elf_Word seg_flags) -! { -! gold_assert(this->type() != elfcpp::PT_LOAD); -! gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0); -! gold_assert(!this->is_max_align_known_); - -! this->update_flags_for_output_section(seg_flags); - -! this->output_lists_[0].push_back(os); -! } - -! // Remove an Output_section from this segment. It is an error if it -! // is not present. - -! void -! Output_segment::remove_output_section(Output_section* os) -! { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) - { -! Output_data_list* pdl = &this->output_lists_[i]; -! for (Output_data_list::iterator p = pdl->begin(); p != pdl->end(); ++p) - { -! if (*p == os) - { -! pdl->erase(p); - return; - } - } - } - gold_unreachable(); - } - -*************** void -*** 3718,3724 **** - Output_segment::add_initial_output_data(Output_data* od) - { - gold_assert(!this->is_max_align_known_); -! this->output_data_.push_front(od); - } - - // Return whether the first data section is a relro section. ---- 3492,3521 ---- - Output_segment::add_initial_output_data(Output_data* od) - { - gold_assert(!this->is_max_align_known_); -! Output_data_list::iterator p = this->output_lists_[0].begin(); -! this->output_lists_[0].insert(p, od); -! } -! -! // Return true if this segment has any sections which hold actual -! // data, rather than being a BSS section. -! -! bool -! Output_segment::has_any_data_sections() const -! { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! const Output_data_list* pdl = &this->output_lists_[i]; -! for (Output_data_list::const_iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) -! { -! if (!(*p)->is_section()) -! return true; -! if ((*p)->output_section()->type() != elfcpp::SHT_NOBITS) -! return true; -! } -! } -! return false; - } - - // Return whether the first data section is a relro section. -*************** Output_segment::add_initial_output_data( -*** 3726,3734 **** - bool - Output_segment::is_first_section_relro() const - { -! return (!this->output_data_.empty() -! && this->output_data_.front()->is_section() -! && this->output_data_.front()->output_section()->is_relro()); - } - - // Return the maximum alignment of the Output_data in Output_segment. ---- 3523,3538 ---- - bool - Output_segment::is_first_section_relro() const - { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! const Output_data_list* pdl = &this->output_lists_[i]; -! if (!pdl->empty()) -! { -! Output_data* p = pdl->front(); -! return p->is_section() && p->output_section()->is_relro(); -! } -! } -! return false; - } - - // Return the maximum alignment of the Output_data in Output_segment. -*************** Output_segment::maximum_alignment() -*** 3738,3753 **** - { - if (!this->is_max_align_known_) - { -! uint64_t addralign; -! -! addralign = Output_segment::maximum_alignment_list(&this->output_data_); -! if (addralign > this->max_align_) -! this->max_align_ = addralign; -! -! addralign = Output_segment::maximum_alignment_list(&this->output_bss_); -! if (addralign > this->max_align_) -! this->max_align_ = addralign; -! - this->is_max_align_known_ = true; - } - ---- 3542,3554 ---- - { - if (!this->is_max_align_known_) - { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! const Output_data_list* pdl = &this->output_lists_[i]; -! uint64_t addralign = Output_segment::maximum_alignment_list(pdl); -! if (addralign > this->max_align_) -! this->max_align_ = addralign; -! } - this->is_max_align_known_ = true; - } - -*************** Output_segment::maximum_alignment_list(c -*** 3771,3796 **** - return ret; - } - -! // Return the number of dynamic relocs applied to this segment. - -! unsigned int -! Output_segment::dynamic_reloc_count() const - { -! return (this->dynamic_reloc_count_list(&this->output_data_) -! + this->dynamic_reloc_count_list(&this->output_bss_)); - } - -! // Return the number of dynamic relocs applied to an Output_data_list. - -! unsigned int -! Output_segment::dynamic_reloc_count_list(const Output_data_list* pdl) const - { -- unsigned int count = 0; - for (Output_data_list::const_iterator p = pdl->begin(); - p != pdl->end(); - ++p) -! count += (*p)->dynamic_reloc_count(); -! return count; - } - - // Set the section addresses for an Output_segment. If RESET is true, ---- 3572,3599 ---- - return ret; - } - -! // Return whether this segment has any dynamic relocs. - -! bool -! Output_segment::has_dynamic_reloc() const - { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! if (this->has_dynamic_reloc_list(&this->output_lists_[i])) -! return true; -! return false; - } - -! // Return whether this Output_data_list has any dynamic relocs. - -! bool -! Output_segment::has_dynamic_reloc_list(const Output_data_list* pdl) const - { - for (Output_data_list::const_iterator p = pdl->begin(); - p != pdl->end(); - ++p) -! if ((*p)->has_dynamic_reloc()) -! return true; -! return false; - } - - // Set the section addresses for an Output_segment. If RESET is true, -*************** Output_segment::set_section_addresses(co -*** 3818,3843 **** - { - uint64_t relro_size = 0; - off_t off = *poff; -! for (Output_data_list::iterator p = this->output_data_.begin(); -! p != this->output_data_.end(); -! ++p) - { -! if (!(*p)->is_section()) -! break; -! Output_section* pos = (*p)->output_section(); -! if (!pos->is_relro()) -! break; -! gold_assert(!(*p)->is_section_flag_set(elfcpp::SHF_TLS)); -! if ((*p)->is_address_valid()) -! relro_size += (*p)->data_size(); -! else - { -! // FIXME: This could be faster. -! (*p)->set_address_and_file_offset(addr + relro_size, -! off + relro_size); -! relro_size += (*p)->data_size(); -! (*p)->reset_address_and_file_offset(); - } - } - relro_size += increase_relro; - ---- 3621,3650 ---- - { - uint64_t relro_size = 0; - off_t off = *poff; -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) - { -! Output_data_list* pdl = &this->output_lists_[i]; -! Output_data_list::iterator p; -! for (p = pdl->begin(); p != pdl->end(); ++p) - { -! if (!(*p)->is_section()) -! break; -! Output_section* pos = (*p)->output_section(); -! if (!pos->is_relro()) -! break; -! if ((*p)->is_address_valid()) -! relro_size += (*p)->data_size(); -! else -! { -! // FIXME: This could be faster. -! (*p)->set_address_and_file_offset(addr + relro_size, -! off + relro_size); -! relro_size += (*p)->data_size(); -! (*p)->reset_address_and_file_offset(); -! } - } -+ if (p != pdl->end()) -+ break; - } - relro_size += increase_relro; - -*************** Output_segment::set_section_addresses(co -*** 3868,3883 **** - - this->offset_ = orig_off; - -! addr = this->set_section_list_addresses(layout, reset, &this->output_data_, -! addr, poff, pshndx, &in_tls); -! this->filesz_ = *poff - orig_off; -! -! off_t off = *poff; -! -! uint64_t ret = this->set_section_list_addresses(layout, reset, -! &this->output_bss_, -! addr, poff, pshndx, -! &in_tls); - - // If the last section was a TLS section, align upward to the - // alignment of the TLS segment, so that the overall size of the TLS ---- 3675,3695 ---- - - this->offset_ = orig_off; - -! off_t off = 0; -! uint64_t ret; -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! addr = this->set_section_list_addresses(layout, reset, -! &this->output_lists_[i], -! addr, poff, pshndx, &in_tls); -! if (i < static_cast(ORDER_SMALL_BSS)) -! { -! this->filesz_ = *poff - orig_off; -! off = *poff; -! } -! -! ret = addr; -! } - - // If the last section was a TLS section, align upward to the - // alignment of the TLS segment, so that the overall size of the TLS -*************** Output_segment::set_offset(unsigned int -*** 4020,4026 **** - - gold_assert(!this->are_addresses_set_); - -! if (this->output_data_.empty() && this->output_bss_.empty()) - { - gold_assert(increase == 0); - this->vaddr_ = 0; ---- 3832,3842 ---- - - gold_assert(!this->are_addresses_set_); - -! // A non-load section only uses output_lists_[0]. -! -! Output_data_list* pdl = &this->output_lists_[0]; -! -! if (pdl->empty()) - { - gold_assert(increase == 0); - this->vaddr_ = 0; -*************** Output_segment::set_offset(unsigned int -*** 4033,4043 **** - return; - } - -! const Output_data* first; -! if (this->output_data_.empty()) -! first = this->output_bss_.front(); -! else -! first = this->output_data_.front(); - this->vaddr_ = first->address(); - this->paddr_ = (first->has_load_address() - ? first->load_address() ---- 3849,3880 ---- - return; - } - -! // Find the first and last section by address. -! const Output_data* first = NULL; -! const Output_data* last_data = NULL; -! const Output_data* last_bss = NULL; -! for (Output_data_list::const_iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) -! { -! if (first == NULL -! || (*p)->address() < first->address() -! || ((*p)->address() == first->address() -! && (*p)->data_size() < first->data_size())) -! first = *p; -! const Output_data** plast; -! if ((*p)->is_section() -! && (*p)->output_section()->type() == elfcpp::SHT_NOBITS) -! plast = &last_bss; -! else -! plast = &last_data; -! if (*plast == NULL -! || (*p)->address() > (*plast)->address() -! || ((*p)->address() == (*plast)->address() -! && (*p)->data_size() > (*plast)->data_size())) -! *plast = *p; -! } -! - this->vaddr_ = first->address(); - this->paddr_ = (first->has_load_address() - ? first->load_address() -*************** Output_segment::set_offset(unsigned int -*** 4045,4065 **** - this->are_addresses_set_ = true; - this->offset_ = first->offset(); - -! if (this->output_data_.empty()) - this->filesz_ = 0; - else -! { -! const Output_data* last_data = this->output_data_.back(); -! this->filesz_ = (last_data->address() -! + last_data->data_size() -! - this->vaddr_); -! } - -! const Output_data* last; -! if (this->output_bss_.empty()) -! last = this->output_data_.back(); -! else -! last = this->output_bss_.back(); - this->memsz_ = (last->address() - + last->data_size() - - this->vaddr_); ---- 3882,3895 ---- - this->are_addresses_set_ = true; - this->offset_ = first->offset(); - -! if (last_data == NULL) - this->filesz_ = 0; - else -! this->filesz_ = (last_data->address() -! + last_data->data_size() -! - this->vaddr_); - -! const Output_data* last = last_bss != NULL ? last_bss : last_data; - this->memsz_ = (last->address() - + last->data_size() - - this->vaddr_); -*************** Output_segment::set_tls_offsets() -*** 4085,4118 **** - { - gold_assert(this->type_ == elfcpp::PT_TLS); - -! for (Output_data_list::iterator p = this->output_data_.begin(); -! p != this->output_data_.end(); -! ++p) -! (*p)->set_tls_offset(this->vaddr_); -! -! for (Output_data_list::iterator p = this->output_bss_.begin(); -! p != this->output_bss_.end(); - ++p) - (*p)->set_tls_offset(this->vaddr_); - } - -! // Return the address of the first section. - - uint64_t - Output_segment::first_section_load_address() const - { -! for (Output_data_list::const_iterator p = this->output_data_.begin(); -! p != this->output_data_.end(); -! ++p) -! if ((*p)->is_section()) -! return (*p)->has_load_address() ? (*p)->load_address() : (*p)->address(); -! -! for (Output_data_list::const_iterator p = this->output_bss_.begin(); -! p != this->output_bss_.end(); -! ++p) -! if ((*p)->is_section()) -! return (*p)->has_load_address() ? (*p)->load_address() : (*p)->address(); -! - gold_unreachable(); - } - ---- 3915,3944 ---- - { - gold_assert(this->type_ == elfcpp::PT_TLS); - -! for (Output_data_list::iterator p = this->output_lists_[0].begin(); -! p != this->output_lists_[0].end(); - ++p) - (*p)->set_tls_offset(this->vaddr_); - } - -! // Return the load address of the first section. - - uint64_t - Output_segment::first_section_load_address() const - { -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! const Output_data_list* pdl = &this->output_lists_[i]; -! for (Output_data_list::const_iterator p = pdl->begin(); -! p != pdl->end(); -! ++p) -! { -! if ((*p)->is_section()) -! return ((*p)->has_load_address() -! ? (*p)->load_address() -! : (*p)->address()); -! } -! } - gold_unreachable(); - } - -*************** Output_segment::first_section_load_addre -*** 4121,4128 **** - unsigned int - Output_segment::output_section_count() const - { -! return (this->output_section_count_list(&this->output_data_) -! + this->output_section_count_list(&this->output_bss_)); - } - - // Return the number of Output_sections in an Output_data_list. ---- 3947,3956 ---- - unsigned int - Output_segment::output_section_count() const - { -! unsigned int ret = 0; -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! ret += this->output_section_count_list(&this->output_lists_[i]); -! return ret; - } - - // Return the number of Output_sections in an Output_data_list. -*************** Output_segment::section_with_lowest_load -*** 4150,4167 **** - { - Output_section* found = NULL; - uint64_t found_lma = 0; -! this->lowest_load_address_in_list(&this->output_data_, &found, &found_lma); -! -! Output_section* found_data = found; -! this->lowest_load_address_in_list(&this->output_bss_, &found, &found_lma); -! if (found != found_data && found_data != NULL) -! { -! gold_error(_("nobits section %s may not precede progbits section %s " -! "in same segment"), -! found->name(), found_data->name()); -! return NULL; -! } -! - return found; - } - ---- 3978,3986 ---- - { - Output_section* found = NULL; - uint64_t found_lma = 0; -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! this->lowest_load_address_in_list(&this->output_lists_[i], &found, -! &found_lma); - return found; - } - -*************** Output_segment::write_section_headers(co -*** 4221,4232 **** - if (this->type_ != elfcpp::PT_LOAD) - return v; - -! v = this->write_section_headers_list(layout, secnamepool, -! &this->output_data_, -! v, pshndx); -! v = this->write_section_headers_list(layout, secnamepool, -! &this->output_bss_, -! v, pshndx); - return v; - } - ---- 4040,4054 ---- - if (this->type_ != elfcpp::PT_LOAD) - return v; - -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! { -! const Output_data_list* pdl = &this->output_lists_[i]; -! v = this->write_section_headers_list(layout, -! secnamepool, -! pdl, -! v, pshndx); -! } -! - return v; - } - -*************** Output_segment::print_sections_to_mapfil -*** 4263,4270 **** - { - if (this->type() != elfcpp::PT_LOAD) - return; -! this->print_section_list_to_mapfile(mapfile, &this->output_data_); -! this->print_section_list_to_mapfile(mapfile, &this->output_bss_); - } - - // Print an output section list to the map file. ---- 4085,4092 ---- - { - if (this->type() != elfcpp::PT_LOAD) - return; -! for (int i = 0; i < static_cast(ORDER_MAX); ++i) -! this->print_section_list_to_mapfile(mapfile, &this->output_lists_[i]); - } - - // Print an output section list to the map file. -diff -rcp ../binutils-2.20.51.0.10.original/gold/output.h gold/output.h -*** ../binutils-2.20.51.0.10.original/gold/output.h 2010-08-10 15:11:28.000000000 +0100 ---- gold/output.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Output_data -*** 56,62 **** - : address_(0), data_size_(0), offset_(-1), - is_address_valid_(false), is_data_size_valid_(false), - is_offset_valid_(false), is_data_size_fixed_(false), -! dynamic_reloc_count_(0) - { } - - virtual ---- 56,62 ---- - : address_(0), data_size_(0), offset_(-1), - is_address_valid_(false), is_data_size_valid_(false), - is_offset_valid_(false), is_data_size_fixed_(false), -! has_dynamic_reloc_(false) - { } - - virtual -*************** class Output_data -*** 233,247 **** - is_layout_complete() - { return Output_data::allocated_sizes_are_fixed; } - -! // Count the number of dynamic relocations applied to this section. - void - add_dynamic_reloc() -! { ++this->dynamic_reloc_count_; } - -! // Return the number of dynamic relocations applied to this section. -! unsigned int -! dynamic_reloc_count() const -! { return this->dynamic_reloc_count_; } - - // Whether the address is valid. - bool ---- 233,247 ---- - is_layout_complete() - { return Output_data::allocated_sizes_are_fixed; } - -! // Note that a dynamic reloc has been applied to this data. - void - add_dynamic_reloc() -! { this->has_dynamic_reloc_ = true; } - -! // Return whether a dynamic reloc has been applied. -! bool -! has_dynamic_reloc() const -! { return this->has_dynamic_reloc_; } - - // Whether the address is valid. - bool -*************** class Output_data -*** 424,438 **** - // File offset of contents in output file. - off_t offset_; - // Whether address_ is valid. -! bool is_address_valid_; - // Whether data_size_ is valid. -! bool is_data_size_valid_; - // Whether offset_ is valid. -! bool is_offset_valid_; - // Whether data size is fixed. -! bool is_data_size_fixed_; -! // Count of dynamic relocations applied to this section. -! unsigned int dynamic_reloc_count_; - }; - - // Output the section headers. ---- 424,438 ---- - // File offset of contents in output file. - off_t offset_; - // Whether address_ is valid. -! bool is_address_valid_ : 1; - // Whether data_size_ is valid. -! bool is_data_size_valid_ : 1; - // Whether offset_ is valid. -! bool is_offset_valid_ : 1; - // Whether data size is fixed. -! bool is_data_size_fixed_ : 1; -! // Whether any dynamic relocs have been applied to this section. -! bool has_dynamic_reloc_ : 1; - }; - - // Output the section headers. -*************** class Output_section_lookup_maps -*** 2432,2438 **** - std::pair value(msp, pomb); - std::pair result = - this->merge_sections_by_properties_.insert(value); -! gold_assert(value.second); - } - - // Add a mapping from a merged input section in OBJECT with index SHNDX ---- 2432,2438 ---- - std::pair value(msp, pomb); - std::pair result = - this->merge_sections_by_properties_.insert(value); -! gold_assert(result.second); - } - - // Add a mapping from a merged input section in OBJECT with index SHNDX -*************** class Output_section_lookup_maps -*** 2445,2451 **** - std::pair value(csid, pomb); - std::pair result = - this->merge_sections_by_id_.insert(value); -! gold_assert(value.second); - } - - // Find a relaxed input section of OBJECT with index SHNDX. ---- 2445,2451 ---- - std::pair value(csid, pomb); - std::pair result = - this->merge_sections_by_id_.insert(value); -! gold_assert(result.second); - } - - // Find a relaxed input section of OBJECT with index SHNDX. -*************** class Output_section_lookup_maps -*** 2469,2475 **** - value(csid, poris); - std::pair result = - this->relaxed_input_sections_by_id_.insert(value); -! gold_assert(value.second); - } - - private: ---- 2469,2475 ---- - value(csid, poris); - std::pair result = - this->relaxed_input_sections_by_id_.insert(value); -! gold_assert(result.second); - } - - private: -*************** class Output_section : public Output_dat -*** 2761,2766 **** ---- 2761,2777 ---- - set_must_sort_attached_input_sections() - { this->must_sort_attached_input_sections_ = true; } - -+ // Get the order in which this section appears in the PT_LOAD output -+ // segment. -+ Output_section_order -+ order() const -+ { return this->order_; } -+ -+ // Set the order for this section. -+ void -+ set_order(Output_section_order order) -+ { this->order_ = order; } -+ - // Return whether this section holds relro data--data which has - // dynamic relocations but which may be marked read-only after the - // dynamic relocations have been completed. -*************** class Output_section : public Output_dat -*** 2778,2823 **** - clear_is_relro() - { this->is_relro_ = false; } - -- // True if this section holds relro local data--relro data for which -- // the dynamic relocations are all RELATIVE relocations. -- bool -- is_relro_local() const -- { return this->is_relro_local_; } -- -- // Record that this section holds relro local data. -- void -- set_is_relro_local() -- { this->is_relro_local_ = true; } -- -- // True if this must be the last relro section. -- bool -- is_last_relro() const -- { return this->is_last_relro_; } -- -- // Record that this must be the last relro section. -- void -- set_is_last_relro() -- { -- gold_assert(this->is_relro_); -- this->is_last_relro_ = true; -- } -- -- // True if this must be the first section following the relro sections. -- bool -- is_first_non_relro() const -- { -- gold_assert(!this->is_relro_); -- return this->is_first_non_relro_; -- } -- -- // Record that this must be the first non-relro section. -- void -- set_is_first_non_relro() -- { -- gold_assert(!this->is_relro_); -- this->is_first_non_relro_ = true; -- } -- - // True if this is a small section: a section which holds small - // variables. - bool ---- 2789,2794 ---- -*************** class Output_section : public Output_dat -*** 2845,2871 **** - is_large_data_section() - { return this->is_large_section_ && this->type_ != elfcpp::SHT_NOBITS; } - -- // True if this is the .interp section which goes into the PT_INTERP -- // segment. -- bool -- is_interp() const -- { return this->is_interp_; } -- -- // Record that this is the interp section. -- void -- set_is_interp() -- { this->is_interp_ = true; } -- -- // True if this is a section used by the dynamic linker. -- bool -- is_dynamic_linker_section() const -- { return this->is_dynamic_linker_section_; } -- -- // Record that this is a section used by the dynamic linker. -- void -- set_is_dynamic_linker_section() -- { this->is_dynamic_linker_section_ = true; } -- - // Return whether this section should be written after all the input - // sections are complete. - bool ---- 2816,2821 ---- -*************** class Output_section : public Output_dat -*** 3468,3473 **** ---- 3418,3436 ---- - input_sections() const - { return this->input_sections_; } - -+ // Whether this always keeps an input section list -+ bool -+ always_keeps_input_sections() const -+ { return this->always_keeps_input_sections_; } -+ -+ // Always keep an input section list. -+ void -+ set_always_keeps_input_sections() -+ { -+ gold_assert(this->current_data_size_for_child() == 0); -+ this->always_keeps_input_sections_ = true; -+ } -+ - private: - // We only save enough information to undo the effects of section layout. - class Checkpoint_output_section -*************** class Output_section : public Output_dat -*** 3694,3699 **** ---- 3657,3664 ---- - const elfcpp::Elf_Word type_; - // The section flags. - elfcpp::Elf_Xword flags_; -+ // The order of this section in the output segment. -+ Output_section_order order_; - // The section index. - unsigned int out_shndx_; - // If there is a STT_SECTION for this output section in the normal -*************** class Output_section : public Output_dat -*** 3761,3781 **** - bool attached_input_sections_are_sorted_ : 1; - // True if this section holds relro data. - bool is_relro_ : 1; -- // True if this section holds relro local data. -- bool is_relro_local_ : 1; -- // True if this must be the last relro section. -- bool is_last_relro_ : 1; -- // True if this must be the first section after the relro sections. -- bool is_first_non_relro_ : 1; - // True if this is a small section. - bool is_small_section_ : 1; - // True if this is a large section. - bool is_large_section_ : 1; -- // True if this is the .interp section going into the PT_INTERP -- // segment. -- bool is_interp_ : 1; -- // True if this is section is read by the dynamic linker. -- bool is_dynamic_linker_section_ : 1; - // Whether code-fills are generated at write. - bool generate_code_fills_at_write_ : 1; - // Whether the entry size field should be zero. ---- 3726,3735 ---- -*************** class Output_section : public Output_dat -*** 3784,3789 **** ---- 3738,3745 ---- - bool section_offsets_need_adjustment_ : 1; - // Whether this is a NOLOAD section. - bool is_noload_ : 1; -+ // Whether this always keeps input section. -+ bool always_keeps_input_sections_ : 1; - // For SHT_TLS sections, the offset of this section relative to the base - // of the TLS segment. - uint64_t tls_offset_; -*************** class Output_segment -*** 3859,3870 **** - uint64_t - maximum_alignment(); - -! // Add the Output_section OS to this segment. SEG_FLAGS is the -! // segment flags to use. DO_SORT is true if we should sort the -! // placement of the input section for more efficient generated code. - void -! add_output_section(Output_section* os, elfcpp::Elf_Word seg_flags, -! bool do_sort); - - // Remove an Output_section from this segment. It is an error if it - // is not present. ---- 3815,3831 ---- - uint64_t - maximum_alignment(); - -! // Add the Output_section OS to this PT_LOAD segment. SEG_FLAGS is -! // the segment flags to use. -! void -! add_output_section_to_load(Layout* layout, Output_section* os, -! elfcpp::Elf_Word seg_flags); -! -! // Add the Output_section OS to this non-PT_LOAD segment. SEG_FLAGS -! // is the segment flags to use. - void -! add_output_section_to_nonload(Output_section* os, -! elfcpp::Elf_Word seg_flags); - - // Remove an Output_section from this segment. It is an error if it - // is not present. -*************** class Output_segment -*** 3879,3890 **** - // Return true if this segment has any sections which hold actual - // data, rather than being a BSS section. - bool -! has_any_data_sections() const -! { return !this->output_data_.empty(); } - -! // Return the number of dynamic relocations applied to this segment. -! unsigned int -! dynamic_reloc_count() const; - - // Return the address of the first section. - uint64_t ---- 3840,3850 ---- - // Return true if this segment has any sections which hold actual - // data, rather than being a BSS section. - bool -! has_any_data_sections() const; - -! // Whether this segment has a dynamic relocs. -! bool -! has_dynamic_reloc() const; - - // Return the address of the first section. - uint64_t -*************** class Output_segment -*** 3977,3983 **** - print_sections_to_mapfile(Mapfile*) const; - - private: -! typedef std::list Output_data_list; - - // Find the maximum alignment in an Output_data_list. - static uint64_t ---- 3937,3943 ---- - print_sections_to_mapfile(Mapfile*) const; - - private: -! typedef std::vector Output_data_list; - - // Find the maximum alignment in an Output_data_list. - static uint64_t -*************** class Output_segment -*** 3997,4005 **** - unsigned int - output_section_count_list(const Output_data_list*) const; - -! // Return the number of dynamic relocs in an Output_data_list. -! unsigned int -! dynamic_reloc_count_list(const Output_data_list*) const; - - // Find the section with the lowest load address in an - // Output_data_list. ---- 3957,3965 ---- - unsigned int - output_section_count_list(const Output_data_list*) const; - -! // Return whether an Output_data_list has a dynamic reloc. -! bool -! has_dynamic_reloc_list(const Output_data_list*) const; - - // Find the section with the lowest load address in an - // Output_data_list. -*************** class Output_segment -*** 4008,4013 **** ---- 3968,3979 ---- - Output_section** found, - uint64_t* found_lma) const; - -+ // Find the first and last entries by address. -+ void -+ find_first_and_last_list(const Output_data_list* pdl, -+ const Output_data** pfirst, -+ const Output_data** plast) const; -+ - // Write the section headers in the list into V. - template - unsigned char* -*************** class Output_segment -*** 4022,4031 **** - // NOTE: We want to use the copy constructor. Currently, shallow copy - // works for us so we do not need to write our own copy constructor. - -! // The list of output data with contents attached to this segment. -! Output_data_list output_data_; -! // The list of output data without contents attached to this segment. -! Output_data_list output_bss_; - // The segment virtual address. - uint64_t vaddr_; - // The segment physical address. ---- 3988,3995 ---- - // NOTE: We want to use the copy constructor. Currently, shallow copy - // works for us so we do not need to write our own copy constructor. - -! // The list of output data attached to this segment. -! Output_data_list output_lists_[ORDER_MAX]; - // The segment virtual address. - uint64_t vaddr_; - // The segment physical address. -diff -rcp ../binutils-2.20.51.0.10.original/gold/plugin.cc gold/plugin.cc -*** ../binutils-2.20.51.0.10.original/gold/plugin.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/plugin.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Sized_pluginobj::do_ad -*** 705,730 **** - template - Archive::Should_include - Sized_pluginobj::do_should_include_member( -! Symbol_table* symtab, Read_symbols_data*, std::string* why) - { - char* tmpbuf = NULL; - size_t tmpbuflen = 0; - -! for (int i = 0; i < this->nsyms_; ++i) { -! const struct ld_plugin_symbol& sym = this->syms_[i]; -! const char* name = sym.name; -! Symbol* symbol; -! Archive::Should_include t = Archive::should_include_member(symtab, name, -! &symbol, why, -! &tmpbuf, -! &tmpbuflen); - if (t == Archive::SHOULD_INCLUDE_YES) - { - if (tmpbuf != NULL) - free(tmpbuf); - return t; - } -! } - if (tmpbuf != NULL) - free(tmpbuf); - return Archive::SHOULD_INCLUDE_UNKNOWN; ---- 705,736 ---- - template - Archive::Should_include - Sized_pluginobj::do_should_include_member( -! Symbol_table* symtab, -! Layout* layout, -! Read_symbols_data*, -! std::string* why) - { - char* tmpbuf = NULL; - size_t tmpbuflen = 0; - -! for (int i = 0; i < this->nsyms_; ++i) -! { -! const struct ld_plugin_symbol& sym = this->syms_[i]; -! const char* name = sym.name; -! Symbol* symbol; -! Archive::Should_include t = Archive::should_include_member(symtab, -! layout, -! name, -! &symbol, why, -! &tmpbuf, -! &tmpbuflen); - if (t == Archive::SHOULD_INCLUDE_YES) - { - if (tmpbuf != NULL) - free(tmpbuf); - return t; - } -! } - if (tmpbuf != NULL) - free(tmpbuf); - return Archive::SHOULD_INCLUDE_UNKNOWN; -*************** Sized_pluginobj::do_ge -*** 862,868 **** - } - - // Class Plugin_finish. This task runs after all replacement files have -! // been added. It calls each plugin's cleanup handler. - - class Plugin_finish : public Task - { ---- 868,877 ---- - } - - // Class Plugin_finish. This task runs after all replacement files have -! // been added. For now, it's a placeholder for a possible plugin API -! // to allow the plugin to release most of its resources. The cleanup -! // handlers must be called later, because they can remove the temporary -! // object files that are needed until the end of the link. - - class Plugin_finish : public Task - { -*************** class Plugin_finish : public Task -*** 892,900 **** - void - run(Workqueue*) - { -! Plugin_manager* plugins = parameters->options().plugins(); -! gold_assert(plugins != NULL); -! plugins->cleanup(); - } - - std::string ---- 901,907 ---- - void - run(Workqueue*) - { -! // We could call early cleanup handlers here. - } - - std::string -diff -rcp ../binutils-2.20.51.0.10.original/gold/plugin.h gold/plugin.h -*** ../binutils-2.20.51.0.10.original/gold/plugin.h 2010-08-10 15:12:04.000000000 +0100 ---- gold/plugin.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Sized_pluginobj : public Pluginobj -*** 376,382 **** - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Read_symbols_data*, - std::string* why); - - // Get the size of a section. ---- 376,382 ---- - do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); - - Archive::Should_include -! do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, - std::string* why); - - // Get the size of a section. -diff -rcp ../binutils-2.20.51.0.10.original/gold/powerpc.cc gold/powerpc.cc -*** ../binutils-2.20.51.0.10.original/gold/powerpc.cc 2010-08-10 15:11:40.000000000 +0100 ---- gold/powerpc.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Target_powerpc::got_se -*** 738,744 **** - - layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, -! this->got_, false, false, false, false); - - // Create the GOT2 or TOC in the .got section. - if (size == 32) ---- 738,744 ---- - - layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, -! this->got_, ORDER_DATA, false); - - // Create the GOT2 or TOC in the .got section. - if (size == 32) -*************** Target_powerpc::got_se -*** 747,754 **** - layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! this->got2_, false, false, false, -! false); - } - else - { ---- 747,753 ---- - layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! this->got2_, ORDER_DATA, false); - } - else - { -*************** Target_powerpc::got_se -*** 756,763 **** - layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! this->toc_, false, false, false, -! false); - } - - // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. ---- 755,761 ---- - layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! this->toc_, ORDER_DATA, false); - } - - // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. -*************** Target_powerpc::rela_d -*** 784,791 **** - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, true, -! false, false, false); - } - return this->rela_dyn_; - } ---- 782,789 ---- - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, -! ORDER_DYNAMIC_RELOCS, false); - } - return this->rela_dyn_; - } -*************** Output_data_plt_powerpcrel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, true, false, -! false, false); - } - - template ---- 843,850 ---- - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - } - - template -*************** Target_powerpc::make_p -*** 980,986 **** - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR - | elfcpp::SHF_WRITE), -! this->plt_, false, false, false, false); - - // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. - symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, ---- 978,984 ---- - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR - | elfcpp::SHF_WRITE), -! this->plt_, ORDER_PLT, false); - - // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. - symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, -*************** Target_powerpc::gc_pro -*** 1493,1499 **** - typedef Target_powerpc Powerpc; - typedef typename Target_powerpc::Scan Scan; - -! gold::gc_process_relocs( - symtab, - layout, - this, ---- 1491,1498 ---- - typedef Target_powerpc Powerpc; - typedef typename Target_powerpc::Scan Scan; - -! gold::gc_process_relocs( - symtab, - layout, - this, -*************** Target_powerpc::scan_r -*** 1543,1550 **** - Output_section* os = layout->add_output_section_data(".sdata", 0, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! sdata, false, -! false, false, false); - symtab->define_in_output_data("_SDA_BASE_", NULL, - Symbol_table::PREDEFINED, - os, ---- 1542,1550 ---- - Output_section* os = layout->add_output_section_data(".sdata", 0, - elfcpp::SHF_ALLOC - | elfcpp::SHF_WRITE, -! sdata, -! ORDER_SMALL_DATA, -! false); - symtab->define_in_output_data("_SDA_BASE_", NULL, - Symbol_table::PREDEFINED, - os, -*************** Target_powerpc::Reloca -*** 1636,1642 **** - // Get the GOT offset if needed. Unlike i386 and x86_64, our GOT - // pointer points to the beginning, not the end, of the table. - // So we just use the plain offset. -- bool have_got_offset = false; - unsigned int got_offset = 0; - unsigned int got2_offset = 0; - switch (r_type) ---- 1636,1641 ---- -*************** Target_powerpc::Reloca -*** 1668,1674 **** - gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD)); - got_offset = object->local_got_offset(r_sym, GOT_TYPE_STANDARD); - } -- have_got_offset = true; - break; - - // R_PPC_PLTREL24 is rather special. If non-zero, ---- 1667,1672 ---- -*************** Target_powerpc::Reloca -*** 1681,1687 **** - got2_offset = got2->offset(); - addend += got2_offset; - } -- have_got_offset = true; - break; - - default: ---- 1679,1684 ---- -diff -rcp ../binutils-2.20.51.0.10.original/gold/reloc.cc gold/reloc.cc -*** ../binutils-2.20.51.0.10.original/gold/reloc.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/reloc.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 32,37 **** ---- 32,38 ---- - #include "target-reloc.h" - #include "reloc.h" - #include "icf.h" -+ #include "compressed_output.h" - - namespace gold - { -*************** Sized_relobj::write_se -*** 732,741 **** ---- 733,749 ---- - - off_t view_start; - section_size_type view_size; -+ bool must_decompress = false; - if (output_offset != invalid_address) - { - view_start = output_section_offset + output_offset; - view_size = convert_to_section_size_type(shdr.get_sh_size()); -+ section_size_type uncompressed_size; -+ if (this->section_is_compressed(i, &uncompressed_size)) -+ { -+ view_size = uncompressed_size; -+ must_decompress = true; -+ } - } - else - { -*************** Sized_relobj::write_se -*** 754,760 **** - { - unsigned char* buffer = os->postprocessing_buffer(); - view = buffer + view_start; -! if (output_offset != invalid_address) - { - off_t sh_offset = shdr.get_sh_offset(); - if (!rm.empty() && rm.back().file_offset > sh_offset) ---- 762,768 ---- - { - unsigned char* buffer = os->postprocessing_buffer(); - view = buffer + view_start; -! if (output_offset != invalid_address && !must_decompress) - { - off_t sh_offset = shdr.get_sh_offset(); - if (!rm.empty() && rm.back().file_offset > sh_offset) -*************** Sized_relobj::write_se -*** 770,783 **** - else - { - view = of->get_output_view(view_start, view_size); -! off_t sh_offset = shdr.get_sh_offset(); -! if (!rm.empty() && rm.back().file_offset > sh_offset) -! is_sorted = false; -! rm.push_back(File_read::Read_multiple_entry(sh_offset, -! view_size, view)); - } - } - - pvs->view = view; - pvs->address = os->address(); - if (output_offset != invalid_address) ---- 778,804 ---- - else - { - view = of->get_output_view(view_start, view_size); -! if (!must_decompress) -! { -! off_t sh_offset = shdr.get_sh_offset(); -! if (!rm.empty() && rm.back().file_offset > sh_offset) -! is_sorted = false; -! rm.push_back(File_read::Read_multiple_entry(sh_offset, -! view_size, view)); -! } - } - } - -+ if (must_decompress) -+ { -+ // Read and decompress the section. -+ section_size_type len; -+ const unsigned char* p = this->section_contents(i, &len, false); -+ if (!decompress_input_section(p, len, view, view_size)) -+ this->error(_("could not decompress section %s"), -+ this->section_name(i).c_str()); -+ } -+ - pvs->view = view; - pvs->address = os->address(); - if (output_offset != invalid_address) -diff -rcp ../binutils-2.20.51.0.10.original/gold/resolve.cc gold/resolve.cc -*** ../binutils-2.20.51.0.10.original/gold/resolve.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/resolve.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Symbol_table::resolve(Sized_symbol -*** 335,352 **** - sym.get_st_type()); - - bool adjust_common_sizes; - typename Sized_symbol::Size_type tosize = to->symsize(); - if (Symbol_table::should_override(to, frombits, OBJECT, object, -! &adjust_common_sizes)) - { - this->override(to, sym, st_shndx, is_ordinary, object, version); - if (adjust_common_sizes && tosize > to->symsize()) - to->set_symsize(tosize); - } - else - { - if (adjust_common_sizes && sym.get_st_size() > tosize) - to->set_symsize(sym.get_st_size()); - // The ELF ABI says that even for a reference to a symbol we - // merge the visibility. - to->override_visibility(sym.get_st_visibility()); ---- 335,367 ---- - sym.get_st_type()); - - bool adjust_common_sizes; -+ bool adjust_dyndef; - typename Sized_symbol::Size_type tosize = to->symsize(); - if (Symbol_table::should_override(to, frombits, OBJECT, object, -! &adjust_common_sizes, -! &adjust_dyndef)) - { -+ elfcpp::STB tobinding = to->binding(); - this->override(to, sym, st_shndx, is_ordinary, object, version); - if (adjust_common_sizes && tosize > to->symsize()) - to->set_symsize(tosize); -+ if (adjust_dyndef) -+ { -+ // We are overriding an UNDEF or WEAK UNDEF with a DYN DEF. -+ // Remember which kind of UNDEF it was for future reference. -+ to->set_undef_binding(tobinding); -+ } - } - else - { - if (adjust_common_sizes && sym.get_st_size() > tosize) - to->set_symsize(sym.get_st_size()); -+ if (adjust_dyndef) -+ { -+ // We are keeping a DYN DEF after seeing an UNDEF or WEAK UNDEF. -+ // Remember which kind of UNDEF it was. -+ to->set_undef_binding(sym.get_st_bind()); -+ } - // The ELF ABI says that even for a reference to a symbol we - // merge the visibility. - to->override_visibility(sym.get_st_visibility()); -*************** Symbol_table::resolve(Sized_symbol -*** 381,389 **** - bool - Symbol_table::should_override(const Symbol* to, unsigned int frombits, - Defined defined, Object* object, -! bool* adjust_common_sizes) - { - *adjust_common_sizes = false; - - unsigned int tobits; - if (to->source() == Symbol::IS_UNDEFINED) ---- 396,406 ---- - bool - Symbol_table::should_override(const Symbol* to, unsigned int frombits, - Defined defined, Object* object, -! bool* adjust_common_sizes, -! bool* adjust_dyndef) - { - *adjust_common_sizes = false; -+ *adjust_dyndef = false; - - unsigned int tobits; - if (to->source() == Symbol::IS_UNDEFINED) -*************** Symbol_table::should_override(const Symb -*** 531,542 **** - return false; - - case UNDEF * 16 + DYN_DEF: -- case WEAK_UNDEF * 16 + DYN_DEF: - case DYN_UNDEF * 16 + DYN_DEF: - case DYN_WEAK_UNDEF * 16 + DYN_DEF: - // Use a dynamic definition if we have a reference. - return true; - - case COMMON * 16 + DYN_DEF: - case WEAK_COMMON * 16 + DYN_DEF: - case DYN_COMMON * 16 + DYN_DEF: ---- 548,564 ---- - return false; - - case UNDEF * 16 + DYN_DEF: - case DYN_UNDEF * 16 + DYN_DEF: - case DYN_WEAK_UNDEF * 16 + DYN_DEF: - // Use a dynamic definition if we have a reference. - return true; - -+ case WEAK_UNDEF * 16 + DYN_DEF: -+ // When overriding a weak undef by a dynamic definition, -+ // we need to remember that the original undef was weak. -+ *adjust_dyndef = true; -+ return true; -+ - case COMMON * 16 + DYN_DEF: - case WEAK_COMMON * 16 + DYN_DEF: - case DYN_COMMON * 16 + DYN_DEF: -*************** Symbol_table::should_override(const Symb -*** 554,565 **** - return false; - - case UNDEF * 16 + DYN_WEAK_DEF: -- case WEAK_UNDEF * 16 + DYN_WEAK_DEF: - case DYN_UNDEF * 16 + DYN_WEAK_DEF: - case DYN_WEAK_UNDEF * 16 + DYN_WEAK_DEF: - // Use a weak dynamic definition if we have a reference. - return true; - - case COMMON * 16 + DYN_WEAK_DEF: - case WEAK_COMMON * 16 + DYN_WEAK_DEF: - case DYN_COMMON * 16 + DYN_WEAK_DEF: ---- 576,592 ---- - return false; - - case UNDEF * 16 + DYN_WEAK_DEF: - case DYN_UNDEF * 16 + DYN_WEAK_DEF: - case DYN_WEAK_UNDEF * 16 + DYN_WEAK_DEF: - // Use a weak dynamic definition if we have a reference. - return true; - -+ case WEAK_UNDEF * 16 + DYN_WEAK_DEF: -+ // When overriding a weak undef by a dynamic definition, -+ // we need to remember that the original undef was weak. -+ *adjust_dyndef = true; -+ return true; -+ - case COMMON * 16 + DYN_WEAK_DEF: - case WEAK_COMMON * 16 + DYN_WEAK_DEF: - case DYN_COMMON * 16 + DYN_WEAK_DEF: -*************** Symbol_table::should_override(const Symb -*** 570,581 **** - - case DEF * 16 + UNDEF: - case WEAK_DEF * 16 + UNDEF: -- case DYN_DEF * 16 + UNDEF: -- case DYN_WEAK_DEF * 16 + UNDEF: - case UNDEF * 16 + UNDEF: - // A new undefined reference tells us nothing. - return false; - - case WEAK_UNDEF * 16 + UNDEF: - case DYN_UNDEF * 16 + UNDEF: - case DYN_WEAK_UNDEF * 16 + UNDEF: ---- 597,612 ---- - - case DEF * 16 + UNDEF: - case WEAK_DEF * 16 + UNDEF: - case UNDEF * 16 + UNDEF: - // A new undefined reference tells us nothing. - return false; - -+ case DYN_DEF * 16 + UNDEF: -+ case DYN_WEAK_DEF * 16 + UNDEF: -+ // For a dynamic def, we need to remember which kind of undef we see. -+ *adjust_dyndef = true; -+ return false; -+ - case WEAK_UNDEF * 16 + UNDEF: - case DYN_UNDEF * 16 + UNDEF: - case DYN_WEAK_UNDEF * 16 + UNDEF: -*************** Symbol_table::should_override(const Symb -*** 591,598 **** - - case DEF * 16 + WEAK_UNDEF: - case WEAK_DEF * 16 + WEAK_UNDEF: -- case DYN_DEF * 16 + WEAK_UNDEF: -- case DYN_WEAK_DEF * 16 + WEAK_UNDEF: - case UNDEF * 16 + WEAK_UNDEF: - case WEAK_UNDEF * 16 + WEAK_UNDEF: - case DYN_UNDEF * 16 + WEAK_UNDEF: ---- 622,627 ---- -*************** Symbol_table::should_override(const Symb -*** 604,609 **** ---- 633,644 ---- - // A new weak undefined reference tells us nothing. - return false; - -+ case DYN_DEF * 16 + WEAK_UNDEF: -+ case DYN_WEAK_DEF * 16 + WEAK_UNDEF: -+ // For a dynamic def, we need to remember which kind of undef we see. -+ *adjust_dyndef = true; -+ return false; -+ - case DEF * 16 + DYN_UNDEF: - case WEAK_DEF * 16 + DYN_UNDEF: - case DYN_DEF * 16 + DYN_UNDEF: -*************** bool -*** 811,820 **** - Symbol_table::should_override_with_special(const Symbol* to, Defined defined) - { - bool adjust_common_sizes; - unsigned int frombits = global_flag | regular_flag | def_flag; - bool ret = Symbol_table::should_override(to, frombits, defined, NULL, -! &adjust_common_sizes); -! gold_assert(!adjust_common_sizes); - return ret; - } - ---- 846,857 ---- - Symbol_table::should_override_with_special(const Symbol* to, Defined defined) - { - bool adjust_common_sizes; -+ bool adjust_dyn_def; - unsigned int frombits = global_flag | regular_flag | def_flag; - bool ret = Symbol_table::should_override(to, frombits, defined, NULL, -! &adjust_common_sizes, -! &adjust_dyn_def); -! gold_assert(!adjust_common_sizes && !adjust_dyn_def); - return ret; - } - -diff -rcp ../binutils-2.20.51.0.10.original/gold/script.cc gold/script.cc -*** ../binutils-2.20.51.0.10.original/gold/script.cc 2010-08-10 15:11:40.000000000 +0100 ---- gold/script.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Script_assertion::print(FILE* f) const -*** 1045,1052 **** - // Class Script_options. - - Script_options::Script_options() -! : entry_(), symbol_assignments_(), version_script_info_(), -! script_sections_() - { - } - ---- 1045,1052 ---- - // Class Script_options. - - Script_options::Script_options() -! : entry_(), symbol_assignments_(), symbol_definitions_(), -! symbol_references_(), version_script_info_(), script_sections_() - { - } - -*************** Script_options::add_symbol_assignment(co -*** 1071,1076 **** ---- 1071,1083 ---- - value, provide, hidden); - this->symbol_assignments_.push_back(p); - } -+ -+ if (!provide) -+ { -+ std::string n(name, length); -+ this->symbol_definitions_.insert(n); -+ this->symbol_references_.erase(n); -+ } - } - else - { -*************** Script_options::add_symbol_assignment(co -*** 1084,1089 **** ---- 1091,1109 ---- - } - } - -+ // Add a reference to a symbol. -+ -+ void -+ Script_options::add_symbol_reference(const char* name, size_t length) -+ { -+ if (length != 1 || name[0] != '.') -+ { -+ std::string n(name, length); -+ if (this->symbol_definitions_.find(n) == this->symbol_definitions_.end()) -+ this->symbol_references_.insert(n); -+ } -+ } -+ - // Add an assertion. - - void -*************** script_set_common_allocation(void* closu -*** 2679,2684 **** ---- 2699,2715 ---- - script_parse_option(closurev, arg, strlen(arg)); - } - -+ // Called by the bison parser to refer to a symbol. -+ -+ extern "C" Expression* -+ script_symbol(void *closurev, const char* name, size_t length) -+ { -+ Parser_closure* closure = static_cast(closurev); -+ if (length != 1 || name[0] != '.') -+ closure->script_options()->add_symbol_reference(name, length); -+ return script_exp_string(name, length); -+ } -+ - // Called by the bison parser to define a symbol. - - extern "C" void -diff -rcp ../binutils-2.20.51.0.10.original/gold/script-c.h gold/script-c.h -*** ../binutils-2.20.51.0.10.original/gold/script-c.h 2010-08-10 15:12:04.000000000 +0100 ---- gold/script-c.h 2010-08-10 15:14:03.000000000 +0100 -*************** script_push_lex_into_version_mode(void* -*** 303,308 **** ---- 303,316 ---- - extern void - script_pop_lex_mode(void* closure); - -+ /* Called by the bison parser to get the value of a symbol. This is -+ called for a reference to a symbol, but is not called for something -+ like "sym += 10". Uses of the special symbol "." can just call -+ script_exp_string. */ -+ -+ extern Expression_ptr -+ script_symbol(void* closure, const char*, size_t); -+ - /* Called by the bison parser to set a symbol to a value. PROVIDE is - non-zero if the symbol should be provided--only defined if there is - an undefined reference. HIDDEN is non-zero if the symbol should be -diff -rcp ../binutils-2.20.51.0.10.original/gold/script.h gold/script.h -*** ../binutils-2.20.51.0.10.original/gold/script.h 2010-08-10 15:12:03.000000000 +0100 ---- gold/script.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Script_options -*** 423,428 **** ---- 423,432 ---- - add_symbol_assignment(const char* name, size_t length, bool is_defsym, - Expression* value, bool provide, bool hidden); - -+ // Add a reference to a symbol. -+ void -+ add_symbol_reference(const char* name, size_t length); -+ - // Add an assertion. - void - add_assertion(Expression* check, const char* message, size_t messagelen); -*************** class Script_options -*** 439,444 **** ---- 443,474 ---- - void - add_symbols_to_table(Symbol_table*); - -+ // Used to iterate over symbols which are referenced in expressions -+ // but not defined. -+ typedef Unordered_set::const_iterator referenced_const_iterator; -+ -+ referenced_const_iterator -+ referenced_begin() const -+ { return this->symbol_references_.begin(); } -+ -+ referenced_const_iterator -+ referenced_end() const -+ { return this->symbol_references_.end(); } -+ -+ // Return whether a symbol is referenced but not defined. -+ bool -+ is_referenced(const std::string& name) const -+ { -+ return (this->symbol_references_.find(name) -+ != this->symbol_references_.end()); -+ } -+ -+ // Return whether there are any symbols which were referenced but -+ // not defined. -+ bool -+ any_unreferenced() const -+ { return !this->symbol_references_.empty(); } -+ - // Finalize the symbol values. Also check assertions. - void - finalize_symbols(Symbol_table*, const Layout*); -*************** class Script_options -*** 497,502 **** ---- 527,536 ---- - std::string entry_; - // Symbols to set. - Symbol_assignments symbol_assignments_; -+ // Symbols defined in an expression, for faster lookup. -+ Unordered_set symbol_definitions_; -+ // Symbols referenced in an expression. -+ Unordered_set symbol_references_; - // Assertions to check. - Assertions assertions_; - // Version information parsed from a version script. -diff -rcp ../binutils-2.20.51.0.10.original/gold/script-sections.cc gold/script-sections.cc -*** ../binutils-2.20.51.0.10.original/gold/script-sections.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/script-sections.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Script_sections::create_segments(Layout* -*** 3212,3218 **** - is_current_seg_readonly = true; - } - -! current_seg->add_output_section(*p, seg_flags, false); - - if (((*p)->flags() & elfcpp::SHF_WRITE) != 0) - is_current_seg_readonly = false; ---- 3212,3218 ---- - is_current_seg_readonly = true; - } - -! current_seg->add_output_section_to_load(layout, *p, seg_flags); - - if (((*p)->flags() & elfcpp::SHF_WRITE) != 0) - is_current_seg_readonly = false; -*************** Script_sections::create_note_and_tls_seg -*** 3291,3297 **** - Layout::section_flags_to_segment((*p)->flags()); - Output_segment* oseg = layout->make_output_segment(elfcpp::PT_NOTE, - seg_flags); -! oseg->add_output_section(*p, seg_flags, false); - - // Incorporate any subsequent SHT_NOTE sections, in the - // hopes that the script is sensible. ---- 3291,3297 ---- - Layout::section_flags_to_segment((*p)->flags()); - Output_segment* oseg = layout->make_output_segment(elfcpp::PT_NOTE, - seg_flags); -! oseg->add_output_section_to_nonload(*p, seg_flags); - - // Incorporate any subsequent SHT_NOTE sections, in the - // hopes that the script is sensible. -*************** Script_sections::create_note_and_tls_seg -*** 3300,3306 **** - && (*pnext)->type() == elfcpp::SHT_NOTE) - { - seg_flags = Layout::section_flags_to_segment((*pnext)->flags()); -! oseg->add_output_section(*pnext, seg_flags, false); - p = pnext; - ++pnext; - } ---- 3300,3306 ---- - && (*pnext)->type() == elfcpp::SHT_NOTE) - { - seg_flags = Layout::section_flags_to_segment((*pnext)->flags()); -! oseg->add_output_section_to_nonload(*pnext, seg_flags); - p = pnext; - ++pnext; - } -*************** Script_sections::create_note_and_tls_seg -*** 3315,3328 **** - Layout::section_flags_to_segment((*p)->flags()); - Output_segment* oseg = layout->make_output_segment(elfcpp::PT_TLS, - seg_flags); -! oseg->add_output_section(*p, seg_flags, false); - - Layout::Section_list::const_iterator pnext = p + 1; - while (pnext != sections->end() - && ((*pnext)->flags() & elfcpp::SHF_TLS) != 0) - { - seg_flags = Layout::section_flags_to_segment((*pnext)->flags()); -! oseg->add_output_section(*pnext, seg_flags, false); - p = pnext; - ++pnext; - } ---- 3315,3328 ---- - Layout::section_flags_to_segment((*p)->flags()); - Output_segment* oseg = layout->make_output_segment(elfcpp::PT_TLS, - seg_flags); -! oseg->add_output_section_to_nonload(*p, seg_flags); - - Layout::Section_list::const_iterator pnext = p + 1; - while (pnext != sections->end() - && ((*pnext)->flags() & elfcpp::SHF_TLS) != 0) - { - seg_flags = Layout::section_flags_to_segment((*pnext)->flags()); -! oseg->add_output_section_to_nonload(*pnext, seg_flags); - p = pnext; - ++pnext; - } -*************** Script_sections::attach_sections_using_p -*** 3477,3486 **** - - elfcpp::Elf_Word seg_flags = - Layout::section_flags_to_segment(os->flags()); -- r->second->add_output_section(os, seg_flags, false); - -! if (r->second->type() == elfcpp::PT_LOAD) - { - if (in_load_segment) - gold_error(_("section in two PT_LOAD segments")); - in_load_segment = true; ---- 3477,3488 ---- - - elfcpp::Elf_Word seg_flags = - Layout::section_flags_to_segment(os->flags()); - -! if (r->second->type() != elfcpp::PT_LOAD) -! r->second->add_output_section_to_nonload(os, seg_flags); -! else - { -+ r->second->add_output_section_to_load(layout, os, seg_flags); - if (in_load_segment) - gold_error(_("section in two PT_LOAD segments")); - in_load_segment = true; -diff -rcp ../binutils-2.20.51.0.10.original/gold/sparc.cc gold/sparc.cc -*** ../binutils-2.20.51.0.10.original/gold/sparc.cc 2010-08-10 15:11:28.000000000 +0100 ---- gold/sparc.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Target_sparc::got_sect -*** 1045,1056 **** - - this->got_ = new Output_data_got(); - -! Output_section* os; -! os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, false, true, false, -! false); - - // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. - symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, ---- 1045,1054 ---- - - this->got_ = new Output_data_got(); - -! layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, ORDER_RELRO, true); - - // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. - symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, -*************** Target_sparc::rela_dyn -*** 1076,1083 **** - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, true, -! false, false, false); - } - return this->rela_dyn_; - } ---- 1074,1081 ---- - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, -! ORDER_DYNAMIC_RELOCS, false); - } - return this->rela_dyn_; - } -*************** Output_data_plt_sparc: -*** 1179,1186 **** - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, true, -! false, false, false); - } - - template ---- 1177,1184 ---- - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - } - - template -*************** Target_sparc::make_plt -*** 1402,1408 **** - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR - | elfcpp::SHF_WRITE), -! this->plt_, false, false, false, false); - - // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. - symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, ---- 1400,1406 ---- - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR - | elfcpp::SHF_WRITE), -! this->plt_, ORDER_PLT, false); - - // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. - symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, -*************** Target_sparc::gc_proce -*** 2332,2338 **** - typedef Target_sparc Sparc; - typedef typename Target_sparc::Scan Scan; - -! gold::gc_process_relocs( - symtab, - layout, - this, ---- 2330,2337 ---- - typedef Target_sparc Sparc; - typedef typename Target_sparc::Scan Scan; - -! gold::gc_process_relocs( - symtab, - layout, - this, -*************** Target_sparc::Relocate -*** 2474,2480 **** - // Get the GOT offset if needed. Unlike i386 and x86_64, our GOT - // pointer points to the beginning, not the end, of the table. - // So we just use the plain offset. -- bool have_got_offset = false; - unsigned int got_offset = 0; - switch (r_type) - { ---- 2473,2478 ---- -*************** Target_sparc::Relocate -*** 2495,2501 **** - gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD)); - got_offset = object->local_got_offset(r_sym, GOT_TYPE_STANDARD); - } -- have_got_offset = true; - break; - - default: ---- 2493,2498 ---- -diff -rcp ../binutils-2.20.51.0.10.original/gold/stringpool.cc gold/stringpool.cc -*** ../binutils-2.20.51.0.10.original/gold/stringpool.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/stringpool.cc 2010-08-10 15:14:03.000000000 +0100 -*************** Stringpool_template::re -*** 87,114 **** - this->string_set_.swap(new_string_set); - } - -- // Return the length of a string of arbitrary character type. -- -- template -- size_t -- Stringpool_template::string_length(const Stringpool_char* p) -- { -- size_t len = 0; -- for (; *p != 0; ++p) -- ++len; -- return len; -- } -- -- // Specialize string_length for char. Maybe we could just use -- // std::char_traits<>::length? -- -- template<> -- inline size_t -- Stringpool_template::string_length(const char* p) -- { -- return strlen(p); -- } -- - // Compare two strings of arbitrary character type for equality. - - template ---- 87,92 ---- -diff -rcp ../binutils-2.20.51.0.10.original/gold/stringpool.h gold/stringpool.h -*** ../binutils-2.20.51.0.10.original/gold/stringpool.h 2010-08-10 15:11:43.000000000 +0100 ---- gold/stringpool.h 2010-08-10 15:14:03.000000000 +0100 -*************** namespace gold -*** 32,37 **** ---- 32,59 ---- - - class Output_file; - -+ // Return the length of a string in units of Char_type. -+ -+ template -+ inline size_t -+ string_length(const Char_type* p) -+ { -+ size_t len = 0; -+ for (; *p != 0; ++p) -+ ++len; -+ return len; -+ } -+ -+ // Specialize string_length for char. Maybe we could just use -+ // std::char_traits<>::length? -+ -+ template<> -+ inline size_t -+ string_length(const char* p) -+ { -+ return strlen(p); -+ } -+ - // A Stringpool is a pool of unique strings. It provides the - // following features: - -*************** class Stringpool_template -*** 266,275 **** - Stringpool_template(const Stringpool_template&); - Stringpool_template& operator=(const Stringpool_template&); - -- // Return the length of a string in units of Stringpool_char. -- static size_t -- string_length(const Stringpool_char*); -- - // Return whether two strings are equal. - static bool - string_equal(const Stringpool_char*, const Stringpool_char*); ---- 288,293 ---- -diff -rcp ../binutils-2.20.51.0.10.original/gold/symtab.cc gold/symtab.cc -*** ../binutils-2.20.51.0.10.original/gold/symtab.cc 2010-08-10 15:12:04.000000000 +0100 ---- gold/symtab.cc 2010-08-10 15:14:03.000000000 +0100 -*************** -*** 38,44 **** - #include "target.h" - #include "workqueue.h" - #include "symtab.h" -! #include "demangle.h" // needed for --dynamic-list-cpp-new - #include "plugin.h" - - namespace gold ---- 38,44 ---- - #include "target.h" - #include "workqueue.h" - #include "symtab.h" -! #include "script.h" - #include "plugin.h" - - namespace gold -*************** Symbol::init_fields(const char* name, co -*** 76,81 **** ---- 76,83 ---- - this->is_ordinary_shndx_ = false; - this->in_real_elf_ = false; - this->is_defined_in_discarded_section_ = false; -+ this->undef_binding_set_ = false; -+ this->undef_binding_weak_ = false; - } - - // Return the demangled version of the symbol's name, but only -*************** Symbol_table::is_section_folded(Object* -*** 528,534 **** - // work list to avoid gc'ing them. - - void -! Symbol_table::gc_mark_undef_symbols() - { - for (options::String_set::const_iterator p = - parameters->options().undefined_begin(); ---- 530,536 ---- - // work list to avoid gc'ing them. - - void -! Symbol_table::gc_mark_undef_symbols(Layout* layout) - { - for (options::String_set::const_iterator p = - parameters->options().undefined_begin(); -*************** Symbol_table::gc_mark_undef_symbols() -*** 551,556 **** ---- 553,579 ---- - } - } - } -+ -+ for (Script_options::referenced_const_iterator p = -+ layout->script_options()->referenced_begin(); -+ p != layout->script_options()->referenced_end(); -+ ++p) -+ { -+ Symbol* sym = this->lookup(p->c_str()); -+ gold_assert(sym != NULL); -+ if (sym->source() == Symbol::FROM_OBJECT -+ && !sym->object()->is_dynamic()) -+ { -+ Relobj* obj = static_cast(sym->object()); -+ bool is_ordinary; -+ unsigned int shndx = sym->shndx(&is_ordinary); -+ if (is_ordinary) -+ { -+ gold_assert(this->gc_ != NULL); -+ this->gc_->worklist().push(Section_id(obj, shndx)); -+ } -+ } -+ } - } - - void -*************** Symbol_table::get_copy_source(const Symb -*** 2161,2174 **** - // Add any undefined symbols named on the command line. - - void -! Symbol_table::add_undefined_symbols_from_command_line() - { -! if (parameters->options().any_undefined()) - { - if (parameters->target().get_size() == 32) - { - #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) -! this->do_add_undefined_symbols_from_command_line<32>(); - #else - gold_unreachable(); - #endif ---- 2184,2198 ---- - // Add any undefined symbols named on the command line. - - void -! Symbol_table::add_undefined_symbols_from_command_line(Layout* layout) - { -! if (parameters->options().any_undefined() -! || layout->script_options()->any_unreferenced()) - { - if (parameters->target().get_size() == 32) - { - #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) -! this->do_add_undefined_symbols_from_command_line<32>(layout); - #else - gold_unreachable(); - #endif -*************** Symbol_table::add_undefined_symbols_from -*** 2176,2182 **** - else if (parameters->target().get_size() == 64) - { - #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) -! this->do_add_undefined_symbols_from_command_line<64>(); - #else - gold_unreachable(); - #endif ---- 2200,2206 ---- - else if (parameters->target().get_size() == 64) - { - #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) -! this->do_add_undefined_symbols_from_command_line<64>(layout); - #else - gold_unreachable(); - #endif -*************** Symbol_table::add_undefined_symbols_from -*** 2188,2237 **** - - template - void -! Symbol_table::do_add_undefined_symbols_from_command_line() - { - for (options::String_set::const_iterator p = - parameters->options().undefined_begin(); - p != parameters->options().undefined_end(); - ++p) -! { -! const char* name = p->c_str(); - -! if (this->lookup(name) != NULL) -! continue; - -! const char* version = NULL; - -! Sized_symbol* sym; -! Sized_symbol* oldsym; -! bool resolve_oldsym; -! if (parameters->target().is_big_endian()) -! { - #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) -! sym = this->define_special_symbol(&name, &version, -! false, &oldsym, -! &resolve_oldsym); - #else -! gold_unreachable(); - #endif -! } -! else -! { - #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) -! sym = this->define_special_symbol(&name, &version, -! false, &oldsym, -! &resolve_oldsym); - #else -! gold_unreachable(); - #endif -! } - -! gold_assert(oldsym == NULL); - -! sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, -! elfcpp::STV_DEFAULT, 0); -! ++this->saw_undefined_; -! } - } - - // Set the dynamic symbol indexes. INDEX is the index of the first ---- 2212,2270 ---- - - template - void -! Symbol_table::do_add_undefined_symbols_from_command_line(Layout* layout) - { - for (options::String_set::const_iterator p = - parameters->options().undefined_begin(); - p != parameters->options().undefined_end(); - ++p) -! this->add_undefined_symbol_from_command_line(p->c_str()); - -! for (Script_options::referenced_const_iterator p = -! layout->script_options()->referenced_begin(); -! p != layout->script_options()->referenced_end(); -! ++p) -! this->add_undefined_symbol_from_command_line(p->c_str()); -! } -! -! template -! void -! Symbol_table::add_undefined_symbol_from_command_line(const char* name) -! { -! if (this->lookup(name) != NULL) -! return; - -! const char* version = NULL; - -! Sized_symbol* sym; -! Sized_symbol* oldsym; -! bool resolve_oldsym; -! if (parameters->target().is_big_endian()) -! { - #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) -! sym = this->define_special_symbol(&name, &version, -! false, &oldsym, -! &resolve_oldsym); - #else -! gold_unreachable(); - #endif -! } -! else -! { - #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) -! sym = this->define_special_symbol(&name, &version, -! false, &oldsym, -! &resolve_oldsym); - #else -! gold_unreachable(); - #endif -! } - -! gold_assert(oldsym == NULL); - -! sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, -! elfcpp::STV_DEFAULT, 0); -! ++this->saw_undefined_; - } - - // Set the dynamic symbol indexes. INDEX is the index of the first -*************** Symbol_table::sized_write_globals(const -*** 2697,2702 **** ---- 2730,2736 ---- - unsigned int shndx; - typename elfcpp::Elf_types::Elf_Addr sym_value = sym->value(); - typename elfcpp::Elf_types::Elf_Addr dynsym_value = sym_value; -+ elfcpp::STB binding = sym->binding(); - switch (sym->source()) - { - case Symbol::FROM_OBJECT: -*************** Symbol_table::sized_write_globals(const -*** 2720,2725 **** ---- 2754,2761 ---- - if (sym->needs_dynsym_value()) - dynsym_value = target.dynsym_value(sym); - shndx = elfcpp::SHN_UNDEF; -+ if (sym->is_undef_binding_weak()) -+ binding = elfcpp::STB_WEAK; - } - else if (symobj->pluginobj() != NULL) - shndx = elfcpp::SHN_UNDEF; -*************** Symbol_table::sized_write_globals(const -*** 2800,2806 **** - gold_assert(sym_index < output_count); - unsigned char* ps = psyms + (sym_index * sym_size); - this->sized_write_symbol(sym, sym_value, shndx, -! sympool, ps); - } - - if (dynsym_index != -1U) ---- 2836,2842 ---- - gold_assert(sym_index < output_count); - unsigned char* ps = psyms + (sym_index * sym_size); - this->sized_write_symbol(sym, sym_value, shndx, -! binding, sympool, ps); - } - - if (dynsym_index != -1U) -*************** Symbol_table::sized_write_globals(const -*** 2809,2815 **** - gold_assert(dynsym_index < dynamic_count); - unsigned char* pd = dynamic_view + (dynsym_index * sym_size); - this->sized_write_symbol(sym, dynsym_value, shndx, -! dynpool, pd); - } - } - ---- 2845,2851 ---- - gold_assert(dynsym_index < dynamic_count); - unsigned char* pd = dynamic_view + (dynsym_index * sym_size); - this->sized_write_symbol(sym, dynsym_value, shndx, -! binding, dynpool, pd); - } - } - -*************** Symbol_table::sized_write_symbol( -*** 2827,2832 **** ---- 2863,2869 ---- - Sized_symbol* sym, - typename elfcpp::Elf_types::Elf_Addr value, - unsigned int shndx, -+ elfcpp::STB binding, - const Stringpool* pool, - unsigned char* p) const - { -*************** Symbol_table::sized_write_symbol( -*** 2847,2853 **** - if (sym->is_forced_local()) - osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, type)); - else -! osym.put_st_info(elfcpp::elf_st_info(sym->binding(), type)); - osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis())); - osym.put_st_shndx(shndx); - } ---- 2884,2890 ---- - if (sym->is_forced_local()) - osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, type)); - else -! osym.put_st_info(elfcpp::elf_st_info(binding, type)); - osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis())); - osym.put_st_shndx(shndx); - } -diff -rcp ../binutils-2.20.51.0.10.original/gold/symtab.h gold/symtab.h -*** ../binutils-2.20.51.0.10.original/gold/symtab.h 2010-08-10 15:11:43.000000000 +0100 ---- gold/symtab.h 2010-08-10 15:14:03.000000000 +0100 -*************** class Symbol -*** 227,232 **** ---- 227,249 ---- - void - override_visibility(elfcpp::STV); - -+ // Set whether the symbol was originally a weak undef or a regular undef -+ // when resolved by a dynamic def. -+ inline void -+ set_undef_binding(elfcpp::STB bind) -+ { -+ if (!this->undef_binding_set_ || this->undef_binding_weak_) -+ { -+ this->undef_binding_weak_ = bind == elfcpp::STB_WEAK; -+ this->undef_binding_set_ = true; -+ } -+ } -+ -+ // Return TRUE if a weak undef was resolved by a dynamic def. -+ inline bool -+ is_undef_binding_weak() const -+ { return this->undef_binding_weak_; } -+ - // Return the non-visibility part of the st_other field. - unsigned char - nonvis() const -*************** class Symbol -*** 949,954 **** ---- 966,976 ---- - // True if this symbol is defined in a section which was discarded - // (bit 31). - bool is_defined_in_discarded_section_ : 1; -+ // True if UNDEF_BINDING_WEAK_ has been set (bit 32). -+ bool undef_binding_set_ : 1; -+ // True if this symbol was a weak undef resolved by a dynamic def -+ // (bit 33). -+ bool undef_binding_weak_ : 1; - }; - - // The parts of a symbol which are size specific. Using a template -*************** class Symbol_table -*** 1247,1253 **** - - // During garbage collection, this keeps undefined symbols. - void -! gc_mark_undef_symbols(); - - // During garbage collection, this ensures externally visible symbols - // are not treated as garbage while building shared objects. ---- 1269,1275 ---- - - // During garbage collection, this keeps undefined symbols. - void -! gc_mark_undef_symbols(Layout*); - - // During garbage collection, this ensures externally visible symbols - // are not treated as garbage while building shared objects. -*************** class Symbol_table -*** 1397,1403 **** - // Add any undefined symbols named on the command line to the symbol - // table. - void -! add_undefined_symbols_from_command_line(); - - // SYM is defined using a COPY reloc. Return the dynamic object - // where the original definition was found. ---- 1419,1425 ---- - // Add any undefined symbols named on the command line to the symbol - // table. - void -! add_undefined_symbols_from_command_line(Layout*); - - // SYM is defined using a COPY reloc. Return the dynamic object - // where the original definition was found. -*************** class Symbol_table -*** 1536,1542 **** - // Whether we should override a symbol, based on flags in - // resolve.cc. - static bool -! should_override(const Symbol*, unsigned int, Defined, Object*, bool*); - - // Report a problem in symbol resolution. - static void ---- 1558,1564 ---- - // Whether we should override a symbol, based on flags in - // resolve.cc. - static bool -! should_override(const Symbol*, unsigned int, Defined, Object*, bool*, bool*); - - // Report a problem in symbol resolution. - static void -*************** class Symbol_table -*** 1611,1617 **** - // table, sized version. - template - void -! do_add_undefined_symbols_from_command_line(); - - // Types of common symbols. - ---- 1633,1644 ---- - // table, sized version. - template - void -! do_add_undefined_symbols_from_command_line(Layout*); -! -! // Add one undefined symbol. -! template -! void -! add_undefined_symbol_from_command_line(const char* name); - - // Types of common symbols. - -*************** class Symbol_table -*** 1667,1673 **** - void - sized_write_symbol(Sized_symbol*, - typename elfcpp::Elf_types::Elf_Addr value, -! unsigned int shndx, - const Stringpool*, unsigned char* p) const; - - // Possibly warn about an undefined symbol from a dynamic object. ---- 1694,1700 ---- - void - sized_write_symbol(Sized_symbol*, - typename elfcpp::Elf_types::Elf_Addr value, -! unsigned int shndx, elfcpp::STB, - const Stringpool*, unsigned char* p) const; - - // Possibly warn about an undefined symbol from a dynamic object. -diff -rcp ../binutils-2.20.51.0.10.original/gold/version.cc gold/version.cc -*** ../binutils-2.20.51.0.10.original/gold/version.cc 2010-08-10 15:11:43.000000000 +0100 ---- gold/version.cc 2010-08-10 15:14:04.000000000 +0100 -*************** namespace gold -*** 37,43 **** - // version number from configure.ac. But it's easier to just change - // this file for now. - -! static const char* version_string = "1.9"; - - // Report version information. - ---- 37,43 ---- - // version number from configure.ac. But it's easier to just change - // this file for now. - -! static const char* version_string = "1.10"; - - // Report version information. - -diff -rcp ../binutils-2.20.51.0.10.original/gold/x86_64.cc gold/x86_64.cc -*** ../binutils-2.20.51.0.10.original/gold/x86_64.cc 2010-08-10 15:12:03.000000000 +0100 ---- gold/x86_64.cc 2010-08-10 15:14:04.000000000 +0100 -*************** -*** 1,6 **** - // x86_64.cc -- x86_64 target support for gold. - -! // Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. ---- 1,6 ---- - // x86_64.cc -- x86_64 target support for gold. - -! // Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - // Written by Ian Lance Taylor . - - // This file is part of gold. -*************** class Target_x86_64 : public Target_free -*** 64,71 **** - - Target_x86_64() - : Target_freebsd<64, false>(&x86_64_info), -! got_(NULL), plt_(NULL), got_plt_(NULL), global_offset_table_(NULL), -! rela_dyn_(NULL), copy_relocs_(elfcpp::R_X86_64_COPY), dynbss_(NULL), - got_mod_index_offset_(-1U), tlsdesc_reloc_info_(), - tls_base_symbol_defined_(false) - { } ---- 64,72 ---- - - Target_x86_64() - : Target_freebsd<64, false>(&x86_64_info), -! got_(NULL), plt_(NULL), got_plt_(NULL), got_tlsdesc_(NULL), -! global_offset_table_(NULL), rela_dyn_(NULL), -! copy_relocs_(elfcpp::R_X86_64_COPY), dynbss_(NULL), - got_mod_index_offset_(-1U), tlsdesc_reloc_info_(), - tls_base_symbol_defined_(false) - { } -*************** class Target_x86_64 : public Target_free -*** 403,408 **** ---- 404,417 ---- - return this->got_plt_; - } - -+ // Get the GOT section for TLSDESC entries. -+ Output_data_got<64, false>* -+ got_tlsdesc_section() const -+ { -+ gold_assert(this->got_tlsdesc_ != NULL); -+ return this->got_tlsdesc_; -+ } -+ - // Create the PLT section. - void - make_plt_section(Symbol_table* symtab, Layout* layout); -*************** class Target_x86_64 : public Target_free -*** 486,491 **** ---- 495,502 ---- - Output_data_plt_x86_64* plt_; - // The GOT PLT section. - Output_data_space* got_plt_; -+ // The GOT section for TLSDESC relocations. -+ Output_data_got<64, false>* got_tlsdesc_; - // The _GLOBAL_OFFSET_TABLE_ symbol. - Symbol* global_offset_table_; - // The dynamic reloc section. -*************** Target_x86_64::got_section(Symbol_table* -*** 547,565 **** - - this->got_ = new Output_data_got<64, false>(); - -! Output_section* os; -! os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, false, true, true, -! false); - - this->got_plt_ = new Output_data_space(8, "** GOT PLT"); -! os = layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, false, false, -! false, true); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 8); ---- 558,575 ---- - - this->got_ = new Output_data_got<64, false>(); - -! layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_, ORDER_RELRO_LAST, -! true); - - this->got_plt_ = new Output_data_space(8, "** GOT PLT"); -! layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -! (elfcpp::SHF_ALLOC -! | elfcpp::SHF_WRITE), -! this->got_plt_, ORDER_NON_RELRO_FIRST, -! false); - - // The first three entries are reserved. - this->got_plt_->set_current_data_size(3 * 8); -*************** Target_x86_64::got_section(Symbol_table* -*** 576,581 **** ---- 586,600 ---- - elfcpp::STB_LOCAL, - elfcpp::STV_HIDDEN, 0, - false, false); -+ -+ // If there are any TLSDESC relocations, they get GOT entries in -+ // .got.plt after the jump slot entries. -+ this->got_tlsdesc_ = new Output_data_got<64, false>(); -+ layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, -+ (elfcpp::SHF_ALLOC -+ | elfcpp::SHF_WRITE), -+ this->got_tlsdesc_, -+ ORDER_NON_RELRO_FIRST, false); - } - - return this->got_; -*************** Target_x86_64::rela_dyn_section(Layout* -*** 591,598 **** - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, true, -! false, false, false); - } - return this->rela_dyn_; - } ---- 610,617 ---- - gold_assert(layout != NULL); - this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); - layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rela_dyn_, -! ORDER_DYNAMIC_RELOCS, false); - } - return this->rela_dyn_; - } -*************** Output_data_plt_x86_64::Output_data_plt_ -*** 699,706 **** - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, true, -! false, false, false); - } - - void ---- 718,725 ---- - { - this->rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, -! elfcpp::SHF_ALLOC, this->rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - } - - void -*************** Output_data_plt_x86_64::rela_tlsdesc(Lay -*** 750,756 **** - this->tlsdesc_rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, - elfcpp::SHF_ALLOC, this->tlsdesc_rel_, -! true, false, false, false); - gold_assert(this->tlsdesc_rel_->output_section() == - this->rel_->output_section()); - } ---- 769,775 ---- - this->tlsdesc_rel_ = new Reloc_section(false); - layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, - elfcpp::SHF_ALLOC, this->tlsdesc_rel_, -! ORDER_DYNAMIC_PLT_RELOCS, false); - gold_assert(this->tlsdesc_rel_->output_section() == - this->rel_->output_section()); - } -*************** Target_x86_64::make_plt_section(Symbol_t -*** 914,920 **** - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, false, false, false, false); - } - } - ---- 933,939 ---- - layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, - (elfcpp::SHF_ALLOC - | elfcpp::SHF_EXECINSTR), -! this->plt_, ORDER_PLT, false); - } - } - -*************** Target_x86_64::Scan::local(Symbol_table* -*** 1131,1138 **** - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_386_GNU_VTINHERIT: -! case elfcpp::R_386_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: ---- 1150,1157 ---- - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_X86_64_GNU_VTINHERIT: -! case elfcpp::R_X86_64_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: -*************** Target_x86_64::Scan::local(Symbol_table* -*** 1308,1316 **** - // Create reserved PLT and GOT entries for the resolver. - target->reserve_tlsdesc_entries(symtab, layout); - -! // Generate a double GOT entry with an R_X86_64_TLSDESC reloc. -! Output_data_got<64, false>* got -! = target->got_section(symtab, layout); - unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); - if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC)) - { ---- 1327,1339 ---- - // Create reserved PLT and GOT entries for the resolver. - target->reserve_tlsdesc_entries(symtab, layout); - -! // Generate a double GOT entry with an -! // R_X86_64_TLSDESC reloc. The R_X86_64_TLSDESC reloc -! // is resolved lazily, so the GOT entry needs to be in -! // an area in .got.plt, not .got. Call got_section to -! // make sure the section has been created. -! target->got_section(symtab, layout); -! Output_data_got<64, false>* got = target->got_tlsdesc_section(); - unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); - if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC)) - { -*************** Target_x86_64::Scan::global(Symbol_table -*** 1485,1492 **** - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_386_GNU_VTINHERIT: -! case elfcpp::R_386_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: ---- 1508,1515 ---- - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_X86_64_GNU_VTINHERIT: -! case elfcpp::R_X86_64_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: -*************** Target_x86_64::Scan::global(Symbol_table -*** 1689,1697 **** - // Create reserved PLT and GOT entries for the resolver. - target->reserve_tlsdesc_entries(symtab, layout); - -! // Create a double GOT entry with an R_X86_64_TLSDESC reloc. -! Output_data_got<64, false>* got -! = target->got_section(symtab, layout); - Reloc_section *rt = target->rela_tlsdesc_section(layout); - got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_DESC, rt, - elfcpp::R_X86_64_TLSDESC, 0); ---- 1712,1724 ---- - // Create reserved PLT and GOT entries for the resolver. - target->reserve_tlsdesc_entries(symtab, layout); - -! // Create a double GOT entry with an R_X86_64_TLSDESC -! // reloc. The R_X86_64_TLSDESC reloc is resolved -! // lazily, so the GOT entry needs to be in an area in -! // .got.plt, not .got. Call got_section to make sure -! // the section has been created. -! target->got_section(symtab, layout); -! Output_data_got<64, false>* got = target->got_tlsdesc_section(); - Reloc_section *rt = target->rela_tlsdesc_section(layout); - got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_DESC, rt, - elfcpp::R_X86_64_TLSDESC, 0); -*************** Target_x86_64::gc_process_relocs(Symbol_ -*** 1783,1789 **** - } - - gold::gc_process_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA, -! Target_x86_64::Scan>( - symtab, - layout, - this, ---- 1810,1817 ---- - } - - gold::gc_process_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA, -! Target_x86_64::Scan, -! Target_x86_64::Relocatable_size_for_reloc>( - symtab, - layout, - this, -*************** Target_x86_64::Relocate::relocate(const -*** 1964,1971 **** - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_386_GNU_VTINHERIT: -! case elfcpp::R_386_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: ---- 1992,1999 ---- - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_X86_64_GNU_VTINHERIT: -! case elfcpp::R_X86_64_GNU_VTENTRY: - break; - - case elfcpp::R_X86_64_64: -*************** Target_x86_64::Relocate::relocate_tls(co -*** 2230,2247 **** - unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE - ? GOT_TYPE_TLS_OFFSET - : GOT_TYPE_TLS_DESC); -! unsigned int got_offset; - if (gsym != NULL) - { - gold_assert(gsym->has_got_offset(got_type)); -! got_offset = gsym->got_offset(got_type) - target->got_size(); - } - else - { - unsigned int r_sym = elfcpp::elf_r_sym<64>(rela.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym, got_type)); -! got_offset = (object->local_got_offset(r_sym, got_type) -! - target->got_size()); - } - if (optimized_type == tls::TLSOPT_TO_IE) - { ---- 2258,2284 ---- - unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE - ? GOT_TYPE_TLS_OFFSET - : GOT_TYPE_TLS_DESC); -! unsigned int got_offset = 0; -! if (r_type == elfcpp::R_X86_64_GOTPC32_TLSDESC -! && optimized_type == tls::TLSOPT_NONE) -! { -! // We created GOT entries in the .got.tlsdesc portion of -! // the .got.plt section, but the offset stored in the -! // symbol is the offset within .got.tlsdesc. -! got_offset = (target->got_size() -! + target->got_plt_section()->data_size()); -! } - if (gsym != NULL) - { - gold_assert(gsym->has_got_offset(got_type)); -! got_offset += gsym->got_offset(got_type) - target->got_size(); - } - else - { - unsigned int r_sym = elfcpp::elf_r_sym<64>(rela.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym, got_type)); -! got_offset += (object->local_got_offset(r_sym, got_type) -! - target->got_size()); - } - if (optimized_type == tls::TLSOPT_TO_IE) - { -*************** Target_x86_64::Relocatable_size_for_relo -*** 2643,2650 **** - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_386_GNU_VTINHERIT: -! case elfcpp::R_386_GNU_VTENTRY: - case elfcpp::R_X86_64_TLSGD: // Global-dynamic - case elfcpp::R_X86_64_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url) - case elfcpp::R_X86_64_TLSDESC_CALL: ---- 2680,2687 ---- - switch (r_type) - { - case elfcpp::R_X86_64_NONE: -! case elfcpp::R_X86_64_GNU_VTINHERIT: -! case elfcpp::R_X86_64_GNU_VTENTRY: - case elfcpp::R_X86_64_TLSGD: // Global-dynamic - case elfcpp::R_X86_64_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url) - case elfcpp::R_X86_64_TLSDESC_CALL: -diff -rcp ../binutils-2.20.51.0.10.original/gold/yyscript.y gold/yyscript.y -*** ../binutils-2.20.51.0.10.original/gold/yyscript.y 2010-08-10 15:11:40.000000000 +0100 ---- gold/yyscript.y 2010-08-10 15:14:04.000000000 +0100 -*************** exp: -*** 867,873 **** - | INTEGER - { $$ = script_exp_integer($1); } - | string -! { $$ = script_exp_string($1.value, $1.length); } - | MAX_K '(' exp ',' exp ')' - { $$ = script_exp_function_max($3, $5); } - | MIN_K '(' exp ',' exp ')' ---- 867,873 ---- - | INTEGER - { $$ = script_exp_integer($1); } - | string -! { $$ = script_symbol(closure, $1.value, $1.length); } - | MAX_K '(' exp ',' exp ')' - { $$ = script_exp_function_max($3, $5); } - | MIN_K '(' exp ',' exp ')' diff --git a/binutils-2.20.51.0.11-compress-compile.patch b/binutils-2.20.51.0.11-compress-compile.patch deleted file mode 100644 index ca455e9..0000000 --- a/binutils-2.20.51.0.11-compress-compile.patch +++ /dev/null @@ -1,19 +0,0 @@ -*** ../binutils-2.20.51.0.11.orig/bfd/compress.c 2010-09-10 10:00:37.000000000 +0100 ---- bfd/compress.c 2010-09-10 10:02:20.000000000 +0100 -*************** bfd_compress_section_contents (bfd *abfd -*** 94,100 **** - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - #else -! bfd_size_type compressed_size; - bfd_byte *compressed_buffer; - - compressed_size = compressBound (uncompressed_size) + 12; ---- 94,100 ---- - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - #else -! uLongf compressed_size; - bfd_byte *compressed_buffer; - - compressed_size = compressBound (uncompressed_size) + 12; diff --git a/binutils-2.20.51.0.2-build-id.patch b/binutils-2.20.51.0.2-build-id.patch deleted file mode 100644 index c136b30..0000000 --- a/binutils-2.20.51.0.2-build-id.patch +++ /dev/null @@ -1,67 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7.original/bfd/elfcode.h ./bfd/elfcode.h -*** ../binutils-2.20.51.0.7.original/bfd/elfcode.h 2010-04-08 15:29:32.000000000 +0100 ---- ./bfd/elfcode.h 2010-04-08 15:29:39.000000000 +0100 -*************** elf_checksum_contents (bfd *abfd, -*** 1188,1193 **** ---- 1188,1211 ---- - - if (i_shdr.contents) - (*process) (i_shdr.contents, i_shdr.sh_size, arg); -+ else -+ { -+ asection *sec; -+ -+ sec = bfd_section_from_elf_index (abfd, count); -+ if (sec != NULL) -+ { -+ if (sec->contents == NULL) -+ { -+ /* Force rereading from file. */ -+ sec->flags &= ~SEC_IN_MEMORY; -+ if (! bfd_malloc_and_get_section (abfd, sec, & sec->contents)) -+ continue; -+ } -+ if (sec->contents != NULL) -+ (*process) (sec->contents, i_shdr.sh_size, arg); -+ } -+ } - } - - return TRUE; -diff -rcp ../binutils-2.20.51.0.7.original/bfd/section.c.orig ./bfd/section.c.orig -*** ../binutils-2.20.51.0.11.orig/bfd/compress.c 2010-09-10 08:44:47.000000000 +0100 ---- bfd/compress.c 2010-09-10 08:46:16.000000000 +0100 -*************** bfd_get_full_section_contents (bfd *abfd -*** 174,180 **** - case COMPRESS_SECTION_NONE: - if (p == NULL) - { -! p = (bfd_byte *) bfd_malloc (sz); - if (p == NULL) - return FALSE; - need_free = TRUE; ---- 174,180 ---- - case COMPRESS_SECTION_NONE: - if (p == NULL) - { -! p = (bfd_byte *) bfd_zmalloc (sz); - if (p == NULL) - return FALSE; - need_free = TRUE; -*************** fail_compressed: -*** 234,240 **** - uncompressed_buffer = p; - else - { -! uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size); - if (uncompressed_buffer == NULL) - goto fail_compressed; - } ---- 234,240 ---- - uncompressed_buffer = p; - else - { -! uncompressed_buffer = (bfd_byte *) bfd_zmalloc (uncompressed_size); - if (uncompressed_buffer == NULL) - goto fail_compressed; - } diff --git a/binutils-2.20.51.0.2-envvar-revert.patch b/binutils-2.20.51.0.2-envvar-revert.patch deleted file mode 100644 index 679d961..0000000 --- a/binutils-2.20.51.0.2-envvar-revert.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7.original/ld/ldmain.c ./ld/ldmain.c -*** ../binutils-2.20.51.0.7.original/ld/ldmain.c 2010-04-08 15:03:56.000000000 +0100 ---- ./ld/ldmain.c 2010-04-08 15:05:09.000000000 +0100 -*************** main (int argc, char **argv) -*** 258,271 **** - command_line.check_section_addresses = -1; - command_line.disable_target_specific_optimizations = -1; - -- if (getenv ("LD_SYMBOLIC") != NULL) -- command_line.symbolic = symbolic; -- else if (getenv ("LD_SYMBOLIC_FUNCTIONS") != NULL) -- command_line.symbolic = symbolic_functions; -- -- if (getenv ("LD_AS_NEEDED") != NULL) -- add_DT_NEEDED_for_regular = TRUE; -- - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the - output of the linker, unless COLLECT_NO_DEMANGLE is set in the ---- 258,263 ---- -diff -rcp ../binutils-2.20.51.0.7.original/ld/ld.texinfo ./ld/ld.texinfo -*** ../binutils-2.20.51.0.7.original/ld/ld.texinfo 2010-04-08 15:03:55.000000000 +0100 ---- ./ld/ld.texinfo 2010-04-08 15:05:55.000000000 +0100 -*************** their names to the @option{--as-needed} -*** 1152,1161 **** - options. They have been replaced by @option{--copy-dt-needed-entries} - and @option{--no-copy-dt-needed-entries}. - -- If the environment variable @code{LD_AS_NEEDED} is set, the linker -- will behave as if the @option{--as-needed} option is passed to the -- linker as the first command line option. -- - @kindex -assert @var{keyword} - @item -assert @var{keyword} - This option is ignored for SunOS compatibility. ---- 1152,1157 ---- -*************** When creating a shared library, bind ref -*** 1206,1226 **** - definition within the shared library, if any. Normally, it is possible - for a program linked against a shared library to override the definition - within the shared library. This option is only meaningful on ELF -! platforms which support shared libraries. If @option{-Bsymbolic} is not -! used when linking a shared library, the linker will also turn on this -! option if the environment variable @code{LD_SYMBOLIC} is set. - - @kindex -Bsymbolic-functions - @item -Bsymbolic-functions - When creating a shared library, bind references to global function - symbols to the definition within the shared library, if any. - This option is only meaningful on ELF platforms which support shared -! libraries. If @option{-Bsymbolic-functions} is not used when linking a -! shared library, the linker will also turn on this option if the -! environment variable @code{LD_SYMBOLIC_FUNCTIONS} is set. When -! both environment variables @code{LD_SYMBOLIC} and -! @code{LD_SYMBOLIC_FUNCTIONS} are set, @code{LD_SYMBOLIC} will take -! precedent. - - @kindex --dynamic-list=@var{dynamic-list-file} - @item --dynamic-list=@var{dynamic-list-file} ---- 1202,1215 ---- - definition within the shared library, if any. Normally, it is possible - for a program linked against a shared library to override the definition - within the shared library. This option is only meaningful on ELF -! platforms which support shared libraries. - - @kindex -Bsymbolic-functions - @item -Bsymbolic-functions - When creating a shared library, bind references to global function - symbols to the definition within the shared library, if any. - This option is only meaningful on ELF platforms which support shared -! libraries. - - @kindex --dynamic-list=@var{dynamic-list-file} - @item --dynamic-list=@var{dynamic-list-file} -diff -rcp ../binutils-2.20.51.0.7.original/ld/NEWS ./ld/NEWS -*** ../binutils-2.20.51.0.7.original/ld/NEWS 2010-04-08 15:03:56.000000000 +0100 ---- ./ld/NEWS 2010-04-08 15:04:14.000000000 +0100 -*************** Changes in 2.20: -*** 73,83 **** - For the switch --enable-runtime-pseudo-reloc it uses for 32-bit - runtime pseudo relocation version one, for 64-bit the version two. - -- * ELF: Support environment variable LD_AS_NEEDED for --as-needed. -- -- * ELF: Support environment variables, LD_SYMBOLIC for -Bsymbolic and -- LD_SYMBOLIC_FUNCTIONS for -Bsymbolic-functions. -- - Changes in 2.19: - - * Linker scripts support a new INSERT command that makes it easier to ---- 73,78 ---- diff --git a/binutils-2.20.51.0.7-do-not-bind-unique-symbols-locally.patch b/binutils-2.20.51.0.7-do-not-bind-unique-symbols-locally.patch deleted file mode 100644 index a3232a0..0000000 --- a/binutils-2.20.51.0.7-do-not-bind-unique-symbols-locally.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7.original/bfd/ChangeLog ./bfd/ChangeLog -*** ../binutils-2.20.51.0.7.original/bfd/ChangeLog 2010-04-08 15:35:35.000000000 +0100 ---- ./bfd/ChangeLog 2010-04-08 15:38:09.000000000 +0100 -*************** -*** 1,3 **** ---- 1,12 ---- -+ 2010-04-07 Nick Clifton -+ -+ Import this patch from the mainline: -+ -+ 2010-03-26 H.J. Lu -+ -+ PR ld/11434 -+ * elf-bfd.h (SYMBOLIC_BIND): Don't bind unique symbols locally. -+ - 2010-03-18 H.J. Lu - - PR binutils/11396 -diff -rcp ../binutils-2.20.51.0.7.original/bfd/elf-bfd.h ./bfd/elf-bfd.h -*** ../binutils-2.20.51.0.7.original/bfd/elf-bfd.h 2010-04-08 15:35:35.000000000 +0100 ---- ./bfd/elf-bfd.h 2010-04-08 15:37:41.000000000 +0100 -*************** extern asection _bfd_elf_large_com_secti -*** 2351,2358 **** - while (0) - - /* Will a symbol be bound to the the definition within the shared -! library, if any. */ - #define SYMBOLIC_BIND(INFO, H) \ -! ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)) - - #endif /* _LIBELF_H_ */ ---- 2351,2359 ---- - while (0) - - /* Will a symbol be bound to the the definition within the shared -! library, if any. A unique symbol can never be bound locally. */ - #define SYMBOLIC_BIND(INFO, H) \ -! (! (H)->unique_global \ -! && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))) - - #endif /* _LIBELF_H_ */ diff --git a/binutils-2.20.51.0.7-dwarf4.patch b/binutils-2.20.51.0.7-dwarf4.patch deleted file mode 100644 index a7c813c..0000000 --- a/binutils-2.20.51.0.7-dwarf4.patch +++ /dev/null @@ -1,1326 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7.original/bfd/ChangeLog ./bfd/ChangeLog -*** ../binutils-2.20.51.0.7.original/bfd/ChangeLog 2010-04-08 15:40:38.000000000 +0100 ---- ./bfd/ChangeLog 2010-04-08 15:40:46.000000000 +0100 -*************** -*** 1,3 **** ---- 1,31 ---- -+ 2010-04-08 Nick Clifton -+ -+ Import these patches from the mainline: -+ -+ 2010-04-05 Jakub Jelinek -+ -+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Handle CIE version 4 -+ provided that it has the expected address size and zero segment -+ length. -+ * dwarf2.c (struct line_head): Add maximum_ops_per_insn field. -+ (struct line_info): Add op_index field, change end_sequence type to -+ unsigned char. -+ (new_line_sorts_after): For the same address compare op_index. -+ (add_line_info): Add op_index argument, store it into the structure. -+ (decode_line_info): Complain about unknown versions of .debug_line. -+ Initialize maximum_ops_per_insn. Add op_index state register and -+ track it. -+ -+ 2010-04-01 Jakub Jelinek -+ -+ * dwarf2.c (read_attribute_value): Handle CU version 4 -+ for DW_FORM_ref_addr, handle DW_FORM_sec_offset, DW_FORM_exprloc -+ and DW_FORM_flag_present. For unknown form value return NULL. -+ (scan_unit_for_symbols): For DW_AT_location handle DW_FORM_exprloc -+ like DW_FORM_block. -+ (parse_comp_unit): Allow CU version 4. -+ -+ - 2010-04-07 Nick Clifton - - Import this patch from the mainline: -diff -rcp ../binutils-2.20.51.0.7.original/bfd/dwarf2.c ./bfd/dwarf2.c -*** ../binutils-2.20.51.0.7.original/bfd/dwarf2.c 2010-04-08 15:40:38.000000000 +0100 ---- ./bfd/dwarf2.c 2010-04-08 15:47:06.000000000 +0100 -*************** struct line_head -*** 45,50 **** ---- 45,51 ---- - unsigned short version; - bfd_vma prologue_length; - unsigned char minimum_instruction_length; -+ unsigned char maximum_ops_per_insn; - unsigned char default_is_stmt; - int line_base; - unsigned char line_range; -*************** read_attribute_value (struct attribute * -*** 760,766 **** - case DW_FORM_ref_addr: - /* DW_FORM_ref_addr is an address in DWARF2, and an offset in - DWARF3. */ -! if (unit->version == 3) - { - if (unit->offset_size == 4) - attr->u.val = read_4_bytes (unit->abfd, info_ptr); ---- 761,767 ---- - case DW_FORM_ref_addr: - /* DW_FORM_ref_addr is an address in DWARF2, and an offset in - DWARF3. */ -! if (unit->version == 3 || unit->version == 4) - { - if (unit->offset_size == 4) - attr->u.val = read_4_bytes (unit->abfd, info_ptr); -*************** read_attribute_value (struct attribute * -*** 774,779 **** ---- 775,787 ---- - attr->u.val = read_address (unit, info_ptr); - info_ptr += unit->addr_size; - break; -+ case DW_FORM_sec_offset: -+ if (unit->offset_size == 4) -+ attr->u.val = read_4_bytes (unit->abfd, info_ptr); -+ else -+ attr->u.val = read_8_bytes (unit->abfd, info_ptr); -+ info_ptr += unit->offset_size; -+ break; - case DW_FORM_block2: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); -*************** read_attribute_value (struct attribute * -*** 816,821 **** ---- 824,830 ---- - attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; -+ case DW_FORM_exprloc: - case DW_FORM_block: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); -*************** read_attribute_value (struct attribute * -*** 846,851 **** ---- 855,863 ---- - attr->u.val = read_1_byte (abfd, info_ptr); - info_ptr += 1; - break; -+ case DW_FORM_flag_present: -+ attr->u.val = 1; -+ break; - case DW_FORM_sdata: - attr->u.sval = read_signed_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; -*************** read_attribute_value (struct attribute * -*** 887,892 **** ---- 899,905 ---- - (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."), - form); - bfd_set_error (bfd_error_bad_value); -+ return NULL; - } - return info_ptr; - } -*************** struct line_info -*** 916,922 **** - char *filename; - unsigned int line; - unsigned int column; -! int end_sequence; /* End of (sequential) code sequence. */ - }; - - struct fileinfo ---- 929,936 ---- - char *filename; - unsigned int line; - unsigned int column; -! unsigned char op_index; -! unsigned char end_sequence; /* End of (sequential) code sequence. */ - }; - - struct fileinfo -*************** new_line_sorts_after (struct line_info * -*** 990,996 **** - { - return (new_line->address > line->address - || (new_line->address == line->address -! && new_line->end_sequence < line->end_sequence)); - } - - ---- 1004,1012 ---- - { - return (new_line->address > line->address - || (new_line->address == line->address -! && (new_line->op_index > line->op_index -! || (new_line->op_index == line->op_index -! && new_line->end_sequence < line->end_sequence)))); - } - - -*************** new_line_sorts_after (struct line_info * -*** 1002,1007 **** ---- 1018,1024 ---- - static bfd_boolean - add_line_info (struct line_info_table *table, - bfd_vma address, -+ unsigned char op_index, - char *filename, - unsigned int line, - unsigned int column, -*************** add_line_info (struct line_info_table *t -*** 1016,1021 **** ---- 1033,1039 ---- - - /* Set member data of 'info'. */ - info->address = address; -+ info->op_index = op_index; - info->line = line; - info->column = column; - info->end_sequence = end_sequence; -*************** add_line_info (struct line_info_table *t -*** 1047,1052 **** ---- 1065,1071 ---- - - if (seq - && seq->last_line->address == address -+ && seq->last_line->op_index == op_index - && seq->last_line->end_sequence == end_sequence) - { - /* We only keep the last entry with the same address and end -*************** decode_line_info (struct comp_unit *unit -*** 1372,1377 **** ---- 1391,1403 ---- - } - line_end = line_ptr + lh.total_length; - lh.version = read_2_bytes (abfd, line_ptr); -+ if (lh.version < 2 || lh.version > 4) -+ { -+ (*_bfd_error_handler) -+ (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version); -+ bfd_set_error (bfd_error_bad_value); -+ return NULL; -+ } - line_ptr += 2; - if (offset_size == 4) - lh.prologue_length = read_4_bytes (abfd, line_ptr); -*************** decode_line_info (struct comp_unit *unit -*** 1380,1385 **** ---- 1406,1425 ---- - line_ptr += offset_size; - lh.minimum_instruction_length = read_1_byte (abfd, line_ptr); - line_ptr += 1; -+ if (lh.version >= 4) -+ { -+ lh.maximum_ops_per_insn = read_1_byte (abfd, line_ptr); -+ line_ptr += 1; -+ } -+ else -+ lh.maximum_ops_per_insn = 1; -+ if (lh.maximum_ops_per_insn == 0) -+ { -+ (*_bfd_error_handler) -+ (_("Dwarf Error: Invalid maximum operations per instruction.")); -+ bfd_set_error (bfd_error_bad_value); -+ return NULL; -+ } - lh.default_is_stmt = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.line_base = read_1_signed_byte (abfd, line_ptr); -*************** decode_line_info (struct comp_unit *unit -*** 1460,1465 **** ---- 1500,1506 ---- - { - /* State machine registers. */ - bfd_vma address = 0; -+ unsigned char op_index = 0; - char * filename = table->num_files ? concat_filename (table, 1) : NULL; - unsigned int line = 1; - unsigned int column = 0; -*************** decode_line_info (struct comp_unit *unit -*** 1483,1493 **** - { - /* Special operand. */ - adj_opcode = op_code - lh.opcode_base; -! address += (adj_opcode / lh.line_range) -! * lh.minimum_instruction_length; - line += lh.line_base + (adj_opcode % lh.line_range); - /* Append row to matrix using current values. */ -! if (!add_line_info (table, address, filename, line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; ---- 1524,1544 ---- - { - /* Special operand. */ - adj_opcode = op_code - lh.opcode_base; -! if (lh.maximum_ops_per_insn == 1) -! address += (adj_opcode / lh.line_range) -! * lh.minimum_instruction_length; -! else -! { -! address += ((op_index + (adj_opcode / lh.line_range)) -! / lh.maximum_ops_per_insn) -! * lh.minimum_instruction_length; -! op_index = (op_index + (adj_opcode / lh.line_range)) -! % lh.maximum_ops_per_insn; -! } - line += lh.line_base + (adj_opcode % lh.line_range); - /* Append row to matrix using current values. */ -! if (! add_line_info (table, address, op_index, filename, -! line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; -*************** decode_line_info (struct comp_unit *unit -*** 1506,1513 **** - { - case DW_LNE_end_sequence: - end_sequence = 1; -! if (!add_line_info (table, address, filename, line, column, -! end_sequence)) - goto line_fail; - if (address < low_pc) - low_pc = address; ---- 1557,1564 ---- - { - case DW_LNE_end_sequence: - end_sequence = 1; -! if (!add_line_info (table, address, op_index, filename, -! line, column, end_sequence)) - goto line_fail; - if (address < low_pc) - low_pc = address; -*************** decode_line_info (struct comp_unit *unit -*** 1518,1523 **** ---- 1569,1575 ---- - break; - case DW_LNE_set_address: - address = read_address (unit, line_ptr); -+ op_index = 0; - line_ptr += unit->addr_size; - break; - case DW_LNE_define_file: -*************** decode_line_info (struct comp_unit *unit -*** 1560,1566 **** - } - break; - case DW_LNS_copy: -! if (!add_line_info (table, address, filename, line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; ---- 1612,1618 ---- - } - break; - case DW_LNS_copy: -! if (!add_line_info (table, address, op_index, filename, line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; -*************** decode_line_info (struct comp_unit *unit -*** 1568,1575 **** - high_pc = address; - break; - case DW_LNS_advance_pc: -! address += lh.minimum_instruction_length -! * read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - break; - case DW_LNS_advance_line: ---- 1620,1637 ---- - high_pc = address; - break; - case DW_LNS_advance_pc: -! if (lh.maximum_ops_per_insn == 1) -! address += lh.minimum_instruction_length -! * read_unsigned_leb128 (abfd, line_ptr, -! &bytes_read); -! else -! { -! bfd_vma adjust = read_unsigned_leb128 (abfd, line_ptr, -! &bytes_read); -! address = ((op_index + adjust) / lh.maximum_ops_per_insn) -! * lh.minimum_instruction_length; -! op_index = (op_index + adjust) % lh.maximum_ops_per_insn; -! } - line_ptr += bytes_read; - break; - case DW_LNS_advance_line: -*************** decode_line_info (struct comp_unit *unit -*** 1599,1609 **** - case DW_LNS_set_basic_block: - break; - case DW_LNS_const_add_pc: -! address += lh.minimum_instruction_length -! * ((255 - lh.opcode_base) / lh.line_range); - break; - case DW_LNS_fixed_advance_pc: - address += read_2_bytes (abfd, line_ptr); - line_ptr += 2; - break; - default: ---- 1661,1680 ---- - case DW_LNS_set_basic_block: - break; - case DW_LNS_const_add_pc: -! if (lh.maximum_ops_per_insn == 1) -! address += lh.minimum_instruction_length -! * ((255 - lh.opcode_base) / lh.line_range); -! else -! { -! bfd_vma adjust = ((255 - lh.opcode_base) / lh.line_range); -! address += lh.minimum_instruction_length -! * ((op_index + adjust) / lh.maximum_ops_per_insn); -! op_index = (op_index + adjust) % lh.maximum_ops_per_insn; -! } - break; - case DW_LNS_fixed_advance_pc: - address += read_2_bytes (abfd, line_ptr); -+ op_index = 0; - line_ptr += 2; - break; - default: -*************** scan_unit_for_symbols (struct comp_unit -*** 2113,2118 **** ---- 2184,2190 ---- - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: -+ case DW_FORM_exprloc: - if (*attr.u.blk->data == DW_OP_addr) - { - var->stack = 0; -*************** parse_comp_unit (struct dwarf2_debug *st -*** 2216,2224 **** - addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; - -! if (version != 2 && version != 3) - { -! (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information."), version); - bfd_set_error (bfd_error_bad_value); - return 0; - } ---- 2288,2296 ---- - addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; - -! if (version != 2 && version != 3 && version != 4) - { -! (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."), version); - bfd_set_error (bfd_error_bad_value); - return 0; - } -diff -rcp ../binutils-2.20.51.0.7.original/bfd/elf-eh-frame.c ./bfd/elf-eh-frame.c -*** ../binutils-2.20.51.0.7.original/bfd/elf-eh-frame.c 2010-04-08 15:40:38.000000000 +0100 ---- ./bfd/elf-eh-frame.c 2010-04-08 15:40:46.000000000 +0100 -*************** _bfd_elf_parse_eh_frame (bfd *abfd, stru -*** 636,642 **** - REQUIRE (read_byte (&buf, end, &cie->version)); - - /* Cannot handle unknown versions. */ -! REQUIRE (cie->version == 1 || cie->version == 3); - REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation)); - - strcpy (cie->augmentation, (char *) buf); ---- 636,644 ---- - REQUIRE (read_byte (&buf, end, &cie->version)); - - /* Cannot handle unknown versions. */ -! REQUIRE (cie->version == 1 -! || cie->version == 3 -! || cie->version == 4); - REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation)); - - strcpy (cie->augmentation, (char *) buf); -*************** _bfd_elf_parse_eh_frame (bfd *abfd, stru -*** 651,656 **** ---- 653,665 ---- - REQUIRE (skip_bytes (&buf, end, ptr_size)); - SKIP_RELOCS (buf); - } -+ if (cie->version >= 4) -+ { -+ REQUIRE (buf + 1 < end); -+ REQUIRE (buf[0] == ptr_size); -+ REQUIRE (buf[1] == 0); -+ buf += 2; -+ } - REQUIRE (read_uleb128 (&buf, end, &cie->code_align)); - REQUIRE (read_sleb128 (&buf, end, &cie->data_align)); - if (cie->version == 1) -diff -rcp ../binutils-2.20.51.0.7.original/binutils/ChangeLog ./binutils/ChangeLog -*** ../binutils-2.20.51.0.7.original/binutils/ChangeLog 2010-04-08 15:40:38.000000000 +0100 ---- ./binutils/ChangeLog 2010-04-08 15:47:41.000000000 +0100 -*************** -*** 1,3 **** ---- 1,31 ---- -+ 2010-04-08 Nick Clifton -+ -+ Import these patches from the mainline: -+ -+ 2010-04-05 Jakub Jelinek -+ -+ * dwarf.c (struct Frame_Chunk): Add ptr_size and segment_size -+ fields. -+ (display_debug_frames): Handle CIE version 4. -+ -+ * dwarf.c (struct State_Machine_Registers): Add op_index field, -+ change end_sequence type to unsigned char. -+ (reset_state_machine): Clear op_index. -+ (process_extended_line_op): For DW_LNE_set_address clear op_index. -+ (display_debug_lines_raw): Initialize li_max_ops_per_insn. -+ Track op_index state machine register and print it if -+ li_max_ops_per_insn is != 1. -+ (display_debug_lines_decoded): Likewise. -+ -+ 2010-04-01 Jakub Jelinek -+ -+ * dwarf.c (read_and_display_attr_value): Don't reject -+ dwarf_version == 4. Handle DW_FORM_sec_offset, DW_FORM_flag_present -+ and DW_FORM_exprloc. -+ (process_debug_info): Handle cu_version == 4. -+ (display_debug_lines_raw, display_debug_lines_decoded): Handle -+ li_version == 4. -+ - 2010-03-17 Alan Modra - - * readelf.c (dump_arm_unwind): Warning fix. -diff -rcp ../binutils-2.20.51.0.7.original/binutils/dwarf.c ./binutils/dwarf.c -*** ../binutils-2.20.51.0.7.original/binutils/dwarf.c 2010-04-08 15:40:38.000000000 +0100 ---- ./binutils/dwarf.c 2010-04-08 15:56:46.000000000 +0100 -*************** typedef struct State_Machine_Registers -*** 264,270 **** - unsigned int column; - int is_stmt; - int basic_block; -! int end_sequence; - /* This variable hold the number of the last entry seen - in the File Table. */ - unsigned int last_file_entry; ---- 264,271 ---- - unsigned int column; - int is_stmt; - int basic_block; -! unsigned char op_index; -! unsigned char end_sequence; - /* This variable hold the number of the last entry seen - in the File Table. */ - unsigned int last_file_entry; -*************** static void -*** 276,281 **** ---- 277,283 ---- - reset_state_machine (int is_stmt) - { - state_machine_regs.address = 0; -+ state_machine_regs.op_index = 0; - state_machine_regs.file = 1; - state_machine_regs.line = 1; - state_machine_regs.column = 0; -*************** process_extended_line_op (unsigned char -*** 322,327 **** ---- 324,330 ---- - adr = byte_get (data, len - bytes_read - 1); - printf (_("set Address to 0x%lx\n"), adr); - state_machine_regs.address = adr; -+ state_machine_regs.op_index = 0; - break; - - case DW_LNE_define_file: -*************** read_and_display_attr_value (unsigned lo -*** 1154,1167 **** - uvalue = byte_get (data, pointer_size); - data += pointer_size; - } -! else if (dwarf_version == 3) - { - uvalue = byte_get (data, offset_size); - data += offset_size; - } - else - { -! error (_("Internal error: DWARF version is not 2 or 3.\n")); - } - break; - ---- 1157,1170 ---- - uvalue = byte_get (data, pointer_size); - data += pointer_size; - } -! else if (dwarf_version == 3 || dwarf_version == 4) - { - uvalue = byte_get (data, offset_size); - data += offset_size; - } - else - { -! error (_("Internal error: DWARF version is not 2, 3 or 4.\n")); - } - break; - -*************** read_and_display_attr_value (unsigned lo -*** 1171,1180 **** ---- 1174,1188 ---- - break; - - case DW_FORM_strp: -+ case DW_FORM_sec_offset: - uvalue = byte_get (data, offset_size); - data += offset_size; - break; - -+ case DW_FORM_flag_present: -+ uvalue = 1; -+ break; -+ - case DW_FORM_ref1: - case DW_FORM_flag: - case DW_FORM_data1: -*************** read_and_display_attr_value (unsigned lo -*** 1233,1242 **** ---- 1241,1252 ---- - - case DW_FORM_data4: - case DW_FORM_addr: -+ case DW_FORM_sec_offset: - if (!do_loc) - printf (" 0x%lx", uvalue); - break; - -+ case DW_FORM_flag_present: - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_data2: -*************** read_and_display_attr_value (unsigned lo -*** 1272,1277 **** ---- 1282,1288 ---- - break; - - case DW_FORM_block: -+ case DW_FORM_exprloc: - uvalue = read_leb128 (data, & bytes_read, 0); - block_start = data + bytes_read; - if (do_loc) -*************** read_and_display_attr_value (unsigned lo -*** 1352,1358 **** - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: -! if (form == DW_FORM_data4 || form == DW_FORM_data8) - { - /* Process location list. */ - unsigned int lmax = debug_info_p->max_loc_offsets; ---- 1363,1371 ---- - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: -! if (form == DW_FORM_data4 -! || form == DW_FORM_data8 -! || form == DW_FORM_sec_offset) - { - /* Process location list. */ - unsigned int lmax = debug_info_p->max_loc_offsets; -*************** read_and_display_attr_value (unsigned lo -*** 1381,1387 **** - break; - - case DW_AT_ranges: -! if (form == DW_FORM_data4 || form == DW_FORM_data8) - { - /* Process range list. */ - unsigned int lmax = debug_info_p->max_range_lists; ---- 1394,1402 ---- - break; - - case DW_AT_ranges: -! if (form == DW_FORM_data4 -! || form == DW_FORM_data8 -! || form == DW_FORM_sec_offset) - { - /* Process range list. */ - unsigned int lmax = debug_info_p->max_range_lists; -*************** read_and_display_attr_value (unsigned lo -*** 1591,1597 **** - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: -! if (form == DW_FORM_data4 || form == DW_FORM_data8) - printf (_("(location list)")); - /* Fall through. */ - case DW_AT_allocated: ---- 1606,1614 ---- - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: -! if (form == DW_FORM_data4 -! || form == DW_FORM_data8 -! || form == DW_FORM_sec_offset) - printf (_("(location list)")); - /* Fall through. */ - case DW_AT_allocated: -*************** process_debug_info (struct dwarf_section -*** 2038,2044 **** - tags = hdrptr; - start += compunit.cu_length + initial_length_size; - -! if (compunit.cu_version != 2 && compunit.cu_version != 3) - { - warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"), - cu_offset, compunit.cu_version); ---- 2055,2063 ---- - tags = hdrptr; - start += compunit.cu_length + initial_length_size; - -! if (compunit.cu_version != 2 -! && compunit.cu_version != 3 -! && compunit.cu_version != 4) - { - warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"), - cu_offset, compunit.cu_version); -*************** display_debug_lines_raw (struct dwarf_se -*** 2269,2277 **** - /* Check its version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; -! if (linfo.li_version != 2 && linfo.li_version != 3) - { -! warn (_("Only DWARF version 2 and 3 line info is currently supported.\n")); - return 0; - } - ---- 2288,2298 ---- - /* Check its version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; -! if (linfo.li_version != 2 -! && linfo.li_version != 3 -! && linfo.li_version != 4) - { -! warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n")); - return 0; - } - -*************** display_debug_lines_raw (struct dwarf_se -*** 2279,2284 **** ---- 2300,2317 ---- - hdrptr += offset_size; - linfo.li_min_insn_length = byte_get (hdrptr, 1); - hdrptr++; -+ if (linfo.li_version >= 4) -+ { -+ linfo.li_max_ops_per_insn = byte_get (hdrptr, 1); -+ hdrptr++; -+ if (linfo.li_max_ops_per_insn == 0) -+ { -+ warn (_("Invalid maximum operations per insn.\n")); -+ return 0; -+ } -+ } -+ else -+ linfo.li_max_ops_per_insn = 1; - linfo.li_default_is_stmt = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_base = byte_get (hdrptr, 1); -*************** display_debug_lines_raw (struct dwarf_se -*** 2297,2302 **** ---- 2330,2337 ---- - printf (_(" DWARF Version: %d\n"), linfo.li_version); - printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length); - printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length); -+ if (linfo.li_version >= 4) -+ printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn); - printf (_(" Initial value of 'is_stmt': %d\n"), linfo.li_default_is_stmt); - printf (_(" Line Base: %d\n"), linfo.li_line_base); - printf (_(" Line Range: %d\n"), linfo.li_line_range); -*************** display_debug_lines_raw (struct dwarf_se -*** 2380,2389 **** - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; -! uladv = (op_code / linfo.li_line_range) * linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"), -! op_code, uladv, state_machine_regs.address); - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; - printf (_(" and Line by %d to %d\n"), ---- 2415,2441 ---- - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; -! uladv = (op_code / linfo.li_line_range); -! if (linfo.li_max_ops_per_insn == 1) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"), -! op_code, uladv, state_machine_regs.address); -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx[%d]"), -! op_code, uladv, state_machine_regs.address, -! state_machine_regs.op_index); -! } - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; - printf (_(" and Line by %d to %d\n"), -*************** display_debug_lines_raw (struct dwarf_se -*** 2401,2411 **** - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); -- uladv *= linfo.li_min_insn_length; - data += bytes_read; -! state_machine_regs.address += uladv; -! printf (_(" Advance PC by %lu to 0x%lx\n"), uladv, -! state_machine_regs.address); - break; - - case DW_LNS_advance_line: ---- 2453,2479 ---- - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; -! if (linfo.li_max_ops_per_insn == 1) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! printf (_(" Advance PC by %lu to 0x%lx\n"), uladv, -! state_machine_regs.address); -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! printf (_(" Advance PC by %lu to 0x%lx[%d]\n"), uladv, -! state_machine_regs.address, -! state_machine_regs.op_index); -! } - break; - - case DW_LNS_advance_line: -*************** display_debug_lines_raw (struct dwarf_se -*** 2444,2460 **** - break; - - case DW_LNS_const_add_pc: -! uladv = (((255 - linfo.li_opcode_base) / linfo.li_line_range) -! * linfo.li_min_insn_length); -! state_machine_regs.address += uladv; -! printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv, -! state_machine_regs.address); - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; - printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"), - uladv, state_machine_regs.address); - break; ---- 2512,2545 ---- - break; - - case DW_LNS_const_add_pc: -! uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); -! if (linfo.li_max_ops_per_insn) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv, -! state_machine_regs.address); -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! printf (_(" Advance PC by constant %lu to 0x%lx[%d]\n"), -! uladv, state_machine_regs.address, -! state_machine_regs.op_index); -! } - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; -+ state_machine_regs.op_index = 0; - printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"), - uladv, state_machine_regs.address); - break; -*************** display_debug_lines_decoded (struct dwar -*** 2557,2565 **** - /* Get this CU's Line Number Block version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; -! if (linfo.li_version != 2 && linfo.li_version != 3) - { -! warn (_("Only DWARF version 2 and 3 line info is currently " - "supported.\n")); - return 0; - } ---- 2642,2652 ---- - /* Get this CU's Line Number Block version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; -! if (linfo.li_version != 2 -! && linfo.li_version != 3 -! && linfo.li_version != 4) - { -! warn (_("Only DWARF version 2, 3 and 4 line info is currently " - "supported.\n")); - return 0; - } -*************** display_debug_lines_decoded (struct dwar -*** 2568,2573 **** ---- 2655,2672 ---- - hdrptr += offset_size; - linfo.li_min_insn_length = byte_get (hdrptr, 1); - hdrptr++; -+ if (linfo.li_version >= 4) -+ { -+ linfo.li_max_ops_per_insn = byte_get (hdrptr, 1); -+ hdrptr++; -+ if (linfo.li_max_ops_per_insn == 0) -+ { -+ warn (_("Invalid maximum operations per insn.\n")); -+ return 0; -+ } -+ } -+ else -+ linfo.li_max_ops_per_insn = 1; - linfo.li_default_is_stmt = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_base = byte_get (hdrptr, 1); -*************** display_debug_lines_decoded (struct dwar -*** 2703,2710 **** - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; -! uladv = (op_code / linfo.li_line_range) * linfo.li_min_insn_length; -! state_machine_regs.address += uladv; - - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; ---- 2802,2823 ---- - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; -! uladv = (op_code / linfo.li_line_range); -! if (linfo.li_max_ops_per_insn == 1) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! } - - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; -*************** display_debug_lines_decoded (struct dwar -*** 2737,2742 **** ---- 2850,2856 ---- - case DW_LNE_set_address: - state_machine_regs.address = - byte_get (op_code_data, ext_op_code_len - bytes_read - 1); -+ state_machine_regs.op_index = 0; - break; - case DW_LNE_define_file: - { -*************** display_debug_lines_decoded (struct dwar -*** 2765,2773 **** - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); -- uladv *= linfo.li_min_insn_length; - data += bytes_read; -! state_machine_regs.address += uladv; - break; - - case DW_LNS_advance_line: ---- 2879,2900 ---- - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; -! if (linfo.li_max_ops_per_insn == 1) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! } - break; - - case DW_LNS_advance_line: -*************** display_debug_lines_decoded (struct dwar -*** 2812,2826 **** - break; - - case DW_LNS_const_add_pc: -! uladv = (((255 - linfo.li_opcode_base) / linfo.li_line_range) -! * linfo.li_min_insn_length); -! state_machine_regs.address += uladv; - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; - break; - - case DW_LNS_set_prologue_end: ---- 2939,2967 ---- - break; - - case DW_LNS_const_add_pc: -! uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); -! if (linfo.li_max_ops_per_insn == 1) -! { -! uladv *= linfo.li_min_insn_length; -! state_machine_regs.address += uladv; -! } -! else -! { -! state_machine_regs.address -! += ((state_machine_regs.op_index + uladv) -! / linfo.li_max_ops_per_insn) -! * linfo.li_min_insn_length; -! state_machine_regs.op_index -! = (state_machine_regs.op_index + uladv) -! % linfo.li_max_ops_per_insn; -! } - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; -+ state_machine_regs.op_index = 0; - break; - - case DW_LNS_set_prologue_end: -*************** display_debug_lines_decoded (struct dwar -*** 2874,2886 **** - - if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH)) - { -! printf (_("%-35s %11d %#18lx\n"), newFileName, -! state_machine_regs.line, state_machine_regs.address); - } - else - { -! printf (_("%s %11d %#18lx\n"), newFileName, -! state_machine_regs.line, state_machine_regs.address); - } - - if (op_code == DW_LNE_end_sequence) ---- 3015,3041 ---- - - if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH)) - { -! if (linfo.li_max_ops_per_insn == 1) -! printf (_("%-35s %11d %#18lx\n"), newFileName, -! state_machine_regs.line, -! state_machine_regs.address); -! else -! printf (_("%-35s %11d %#18lx[%d]\n"), newFileName, -! state_machine_regs.line, -! state_machine_regs.address, -! state_machine_regs.op_index); - } - else - { -! if (linfo.li_max_ops_per_insn == 1) -! printf (_("%s %11d %#18lx\n"), newFileName, -! state_machine_regs.line, -! state_machine_regs.address); -! else -! printf (_("%s %11d %#18lx[%d]\n"), newFileName, -! state_machine_regs.line, -! state_machine_regs.address, -! state_machine_regs.op_index); - } - - if (op_code == DW_LNE_end_sequence) -*************** typedef struct Frame_Chunk -*** 3751,3756 **** ---- 3906,3913 ---- - int ra; - unsigned char fde_encoding; - unsigned char cfa_exp; -+ unsigned char ptr_size; -+ unsigned char segment_size; - } - Frame_Chunk; - -*************** display_debug_frames (struct dwarf_secti -*** 3959,3964 **** ---- 4116,4122 ---- - unsigned int length_return; - int max_regs = 0; - const char *bad_reg = _("bad register: "); -+ int saved_eh_addr_size = eh_addr_size; - - printf (_("Contents of the %s section:\n"), section->name); - -*************** display_debug_frames (struct dwarf_secti -*** 3973,3979 **** - int need_col_headers = 1; - unsigned char *augmentation_data = NULL; - unsigned long augmentation_data_len = 0; -! int encoded_ptr_size = eh_addr_size; - int offset_size; - int initial_length_size; - ---- 4131,4137 ---- - int need_col_headers = 1; - unsigned char *augmentation_data = NULL; - unsigned long augmentation_data_len = 0; -! int encoded_ptr_size = saved_eh_addr_size; - int offset_size; - int initial_length_size; - -*************** display_debug_frames (struct dwarf_secti -*** 4029,4076 **** - fc->augmentation = (char *) start; - start = (unsigned char *) strchr ((char *) start, '\0') + 1; - -! if (fc->augmentation[0] == 'z') - { -! fc->code_factor = LEB (); -! fc->data_factor = SLEB (); -! if (version == 1) -! { -! fc->ra = GET (1); -! } -! else -! { -! fc->ra = LEB (); -! } -! augmentation_data_len = LEB (); -! augmentation_data = start; -! start += augmentation_data_len; - } -! else if (strcmp (fc->augmentation, "eh") == 0) - { -! start += eh_addr_size; -! fc->code_factor = LEB (); -! fc->data_factor = SLEB (); -! if (version == 1) -! { -! fc->ra = GET (1); -! } -! else -! { -! fc->ra = LEB (); -! } - } - else - { -! fc->code_factor = LEB (); -! fc->data_factor = SLEB (); -! if (version == 1) -! { -! fc->ra = GET (1); -! } -! else -! { -! fc->ra = LEB (); -! } - } - cie = fc; - ---- 4187,4222 ---- - fc->augmentation = (char *) start; - start = (unsigned char *) strchr ((char *) start, '\0') + 1; - -! if (strcmp (fc->augmentation, "eh") == 0) -! start += eh_addr_size; -! -! if (version >= 4) - { -! fc->ptr_size = GET (1); -! fc->segment_size = GET (1); -! eh_addr_size = fc->ptr_size; - } -! else - { -! fc->ptr_size = eh_addr_size; -! fc->segment_size = 0; -! } -! fc->code_factor = LEB (); -! fc->data_factor = SLEB (); -! if (version == 1) -! { -! fc->ra = GET (1); - } - else - { -! fc->ra = LEB (); -! } -! -! if (fc->augmentation[0] == 'z') -! { -! augmentation_data_len = LEB (); -! augmentation_data = start; -! start += augmentation_data_len; - } - cie = fc; - -*************** display_debug_frames (struct dwarf_secti -*** 4085,4090 **** ---- 4231,4241 ---- - (unsigned long)(saved_start - section_start), length, cie_id); - printf (" Version: %d\n", version); - printf (" Augmentation: \"%s\"\n", fc->augmentation); -+ if (version >= 4) -+ { -+ printf (" Pointer Size: %u\n", fc->ptr_size); -+ printf (" Segment Size: %u\n", fc->segment_size); -+ } - printf (" Code alignment factor: %u\n", fc->code_factor); - printf (" Data alignment factor: %d\n", fc->data_factor); - printf (" Return address column: %d\n", fc->ra); -*************** display_debug_frames (struct dwarf_secti -*** 4131,4136 **** ---- 4282,4288 ---- - { - unsigned char *look_for; - static Frame_Chunk fde_fc; -+ unsigned long segment_selector; - - fc = & fde_fc; - memset (fc, 0, sizeof (Frame_Chunk)); -*************** display_debug_frames (struct dwarf_secti -*** 4152,4157 **** ---- 4304,4311 ---- - cie = fc; - fc->augmentation = ""; - fc->fde_encoding = 0; -+ fc->ptr_size = eh_addr_size; -+ fc->segment_size = 0; - } - else - { -*************** display_debug_frames (struct dwarf_secti -*** 4161,4166 **** ---- 4315,4323 ---- - memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); - memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); - fc->augmentation = cie->augmentation; -+ fc->ptr_size = cie->ptr_size; -+ eh_addr_size = cie->ptr_size; -+ fc->segment_size = cie->segment_size; - fc->code_factor = cie->code_factor; - fc->data_factor = cie->data_factor; - fc->cfa_reg = cie->cfa_reg; -*************** display_debug_frames (struct dwarf_secti -*** 4173,4178 **** ---- 4330,4341 ---- - if (fc->fde_encoding) - encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); - -+ segment_selector = 0; -+ if (fc->segment_size) -+ { -+ segment_selector = byte_get (start, fc->segment_size); -+ start += fc->segment_size; -+ } - fc->pc_begin = get_encoded_value (start, fc->fde_encoding); - if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel) - fc->pc_begin += section->address + (start - section_start); -*************** display_debug_frames (struct dwarf_secti -*** 4187,4196 **** - start += augmentation_data_len; - } - -! printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n", - (unsigned long)(saved_start - section_start), length, cie_id, -! (unsigned long)(cie->chunk_start - section_start), -! fc->pc_begin, fc->pc_begin + fc->pc_range); - if (! do_debug_frames_interp && augmentation_data_len) - { - unsigned long i; ---- 4350,4361 ---- - start += augmentation_data_len; - } - -! printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=", - (unsigned long)(saved_start - section_start), length, cie_id, -! (unsigned long)(cie->chunk_start - section_start)); -! if (fc->segment_size) -! printf ("%04lx:", segment_selector); -! printf ("%08lx..%08lx\n", fc->pc_begin, fc->pc_begin + fc->pc_range); - if (! do_debug_frames_interp && augmentation_data_len) - { - unsigned long i; -*************** display_debug_frames (struct dwarf_secti -*** 4738,4743 **** ---- 4903,4909 ---- - frame_display_row (fc, &need_col_headers, &max_regs); - - start = block_end; -+ eh_addr_size = saved_eh_addr_size; - } - - printf ("\n"); -diff -rcp ../binutils-2.20.51.0.7.original/include/ChangeLog ./include/ChangeLog -*** ../binutils-2.20.51.0.7.original/include/ChangeLog 2010-04-08 15:40:37.000000000 +0100 ---- ./include/ChangeLog 2010-04-08 15:57:22.000000000 +0100 -*************** -*** 1,3 **** ---- 1,12 ---- -+ 2010-04-08 Nick Clifton -+ -+ Import these patches from the mainline: -+ -+ 2010-04-05 Jakub Jelinek -+ -+ * dwarf2.h (DWARF2_Internal_LineInfo): Add li_max_ops_per_insn -+ field. -+ - 2010-03-05 Rainer Orth - - * elf/common.h (VER_FLG_*): Document. -diff -rcp ../binutils-2.20.51.0.7.original/include/dwarf2.h ./include/dwarf2.h -*** ../binutils-2.20.51.0.7.original/include/dwarf2.h 2010-04-08 15:40:37.000000000 +0100 ---- ./include/dwarf2.h 2010-04-08 15:40:46.000000000 +0100 -*************** typedef struct -*** 66,71 **** ---- 66,72 ---- - unsigned short li_version; - unsigned int li_prologue_length; - unsigned char li_min_insn_length; -+ unsigned char li_max_ops_per_insn; - unsigned char li_default_is_stmt; - int li_line_base; - unsigned char li_line_range; diff --git a/binutils-2.20.51.0.7-gold-INPUT.patch b/binutils-2.20.51.0.7-gold-INPUT.patch deleted file mode 100644 index f1ccbb4..0000000 --- a/binutils-2.20.51.0.7-gold-INPUT.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7-original/gold/script.cc gold/script.cc -*** ../binutils-2.20.51.0.7-original/gold/script.cc 2010-06-09 15:18:46.000000000 +0100 ---- gold/script.cc 2010-06-09 15:20:49.000000000 +0100 -*************** script_add_file(void* closurev, const ch -*** 2589,2594 **** ---- 2589,2612 ---- - closure->inputs()->add_file(file); - } - -+ // Called by the bison parser to add a library to the link. -+ -+ extern "C" void -+ script_add_library(void* closurev, const char* name, size_t length) -+ { -+ Parser_closure* closure = static_cast(closurev); -+ std::string name_string(name, length); -+ -+ if (name_string[0] != 'l') -+ gold_error(_("library name must be prefixed with -l")); -+ -+ Input_file_argument file(name_string.c_str() + 1, -+ Input_file_argument::INPUT_FILE_TYPE_LIBRARY, -+ "", false, -+ closure->position_dependent_options()); -+ closure->inputs()->add_file(file); -+ } -+ - // Called by the bison parser to start a group. If we are already in - // a group, that means that this script was invoked within a - // --start-group --end-group sequence on the command line, or that -diff -rcp ../binutils-2.20.51.0.7-original/gold/script-c.h gold/script-c.h -*** ../binutils-2.20.51.0.7-original/gold/script-c.h 2010-06-09 15:18:47.000000000 +0100 ---- gold/script-c.h 2010-06-09 15:21:05.000000000 +0100 -*************** script_add_extern(void* closure, const c -*** 222,227 **** ---- 222,232 ---- - extern void - script_add_file(void* closure, const char*, size_t); - -+ /* Called by the bison parser to add a library to the link. */ -+ -+ extern void -+ script_add_library(void* closure, const char*, size_t); -+ - /* Called by the bison parser to start and stop a group. */ - - extern void -diff -rcp ../binutils-2.20.51.0.7-original/gold/yyscript.y gold/yyscript.y -*** ../binutils-2.20.51.0.7-original/gold/yyscript.y 2010-06-09 15:18:46.000000000 +0100 ---- gold/yyscript.y 2010-06-09 15:21:21.000000000 +0100 -*************** input_list: -*** 314,319 **** ---- 314,321 ---- - input_list_element: - string - { script_add_file(closure, $1.value, $1.length); } -+ | '-' STRING -+ { script_add_library(closure, $2.value, $2.length); } - | AS_NEEDED - { script_start_as_needed(closure); } - '(' input_list ')' diff --git a/binutils-2.20.51.0.7-unique-archive-symbols.patch b/binutils-2.20.51.0.7-unique-archive-symbols.patch deleted file mode 100644 index 7c86262..0000000 --- a/binutils-2.20.51.0.7-unique-archive-symbols.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -rcp ../binutils-2.20.51.0.7-original/bfd/archive.c ./bfd/archive.c -*** ../binutils-2.20.51.0.7-original/bfd/archive.c 2010-05-04 19:08:20.000000000 +0100 ---- ./bfd/archive.c 2010-05-04 19:09:40.000000000 +0100 -*************** _bfd_compute_and_write_armap (bfd *arch, -*** 2196,2201 **** ---- 2196,2202 ---- - if ((flags & BSF_GLOBAL - || flags & BSF_WEAK - || flags & BSF_INDIRECT -+ || flags & BSF_GNU_UNIQUE - || bfd_is_com_section (sec)) - && ! bfd_is_und_section (sec)) - { -diff -rcp ../binutils-2.20.51.0.7-original/bfd/ChangeLog ./bfd/ChangeLog -*** ../binutils-2.20.51.0.7-original/bfd/ChangeLog 2010-05-04 19:08:20.000000000 +0100 ---- ./bfd/ChangeLog 2010-05-04 19:11:04.000000000 +0100 -*************** -*** 1,3 **** ---- 1,12 ---- -+ 2010-05-04 Nick Clifton -+ -+ Import this patch: -+ -+ 2010-03-18 Matt Rice -+ -+ * archive.c (_bfd_compute_and_write_armap): Allow symbols flagged -+ as unique in the armap. -+ - 2010-04-08 Nick Clifton - - Import these patches from the mainline: diff --git a/binutils.spec b/binutils.spec index d8846c4..42586e0 100644 --- a/binutils.spec +++ b/binutils.spec @@ -16,8 +16,8 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} -Version: 2.20.51.0.12 -Release: 2%{?dist} +Version: 2.21.51.0.5 +Release: 1%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -28,10 +28,8 @@ Patch02: binutils-2.20.51.0.10-ppc64-pie.patch Patch03: binutils-2.20.51.0.2-ia64-lib64.patch Patch04: binutils-2.20.51.0.2-version.patch Patch05: binutils-2.20.51.0.2-set-long-long.patch -Patch06: binutils-2.20.51.0.2-build-id.patch -Patch07: binutils-2.20.51.0.10-copy-osabi.patch -Patch08: binutils-2.20.51.0.10-sec-merge-emit.patch -Patch09: binutils-2.20.51.0.11-compress-compile.patch +Patch06: binutils-2.20.51.0.10-copy-osabi.patch +Patch07: binutils-2.20.51.0.10-sec-merge-emit.patch %define gold_arches %ix86 x86_64 @@ -127,10 +125,8 @@ using libelf instead of BFD. %endif %patch04 -p0 -b .version~ %patch05 -p0 -b .set-long-long~ -%patch06 -p0 -b .build-id~ -%patch07 -p0 -b .copy-osabi~ -%patch08 -p0 -b .sec-merge-emit~ -%patch09 -p0 -b .compress~ +%patch06 -p0 -b .copy-osabi~ +%patch07 -p0 -b .sec-merge-emit~ # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -186,7 +182,11 @@ CFLAGS="$CFLAGS -O0 -ggdb2" --build=%{_target_platform} --host=%{_target_platform} \ --target=%{binutils_target} \ %ifarch %gold_arches - --enable-gold=%{build_gold} \ +%if "%{build_gold}" == "both" + --enable-gold=default --enable-ld \ +%else + --enable-gold \ +%endif %endif %if !%{isnative} --enable-targets=%{_host} \ @@ -415,6 +415,11 @@ exit 0 %endif # %{isnative} %changelog +* Wed Jan 5 2011 Nick Clifton - 2.21.51.0.5-1 +- Rebase on 2.21.51.0.5 tarball. +- Delete redundant patches. +- Fix gold+ld configure command line option. + * Fri Nov 4 2010 Dan HorĂ¡k - 2.20.51.0.12-2 - "no" is not valid option for --enable-gold diff --git a/sources b/sources index eef472f..64ee61f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f3a1f0535935ddae61ded2bcd3c7ce09 binutils-2.20.51.0.12.tar.bz2 +85cdd97069c230b0a8771d50e309754f binutils-2.21.51.0.5.tar.bz2