This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH][GOLD] Handle .ARM.exidx sections in garbage collection.
- From: Ian Lance Taylor <iant at google dot com>
- To: Doug Kwan (éæå) <dougkwan at google dot com>
- Cc: Sriraman Tallam <tmsriram at google dot com>, binutils <binutils at sourceware dot org>
- Date: Sun, 10 Jan 2010 23:00:48 -0800
- Subject: Re: [PATCH][GOLD] Handle .ARM.exidx sections in garbage collection.
- References: <498552561001102219u1c9f38e5x740151cf6bc0c9d0@mail.gmail.com>
"Doug Kwan (éæå)" <dougkwan@google.com> writes:
> 2010-01-10 Doug Kwan <dougkwan@google.com>
>
> * arm.cc (Arm_relobj::do_gc_proccess_relocs): New method.
> (Target_arm::do_finalize_sections): Only define __exidx_start and
> __exidx_end if these have not been defined already. Also use default
> visibility for these symbols to match behaviour of GNU ld.
> + // Found an .ARM.exidx section, add it to the set of reachable
> + // sections from its linked text section.
> + unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link());
> + Section_id src_id(this, text_shndx);
> + Section_id dst_id(this, i);
> + Garbage_collection::Section_ref::iterator map_it
> + = symtab->gc()->section_reloc_map().find(src_id);
> + if (map_it == symtab->gc()->section_reloc_map().end())
> + symtab->gc()->section_reloc_map()[src_id].insert(dst_id);
> + else
> + map_it->second.insert(dst_id);
Please pull this little bit of code into a function in gc.h, and have
the gc.h code call it too.
> - // Create __exidx_start and __exdix_end symbols.
> - symtab->define_in_output_data("__exidx_start", NULL,
> - Symbol_table::PREDEFINED,
> - exidx_section, 0, 0, elfcpp::STT_OBJECT,
> - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
> - false, false);
> - symtab->define_in_output_data("__exidx_end", NULL,
> - Symbol_table::PREDEFINED,
> - exidx_section, 0, 0, elfcpp::STT_OBJECT,
> - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
> - true, false);
> + // Create __exidx_start and __exdix_end symbols if they are not already
> + // defined in the output.
> + Symbol* sym = symtab->lookup("__exidx_start", NULL);
> + if (sym == NULL
> + || sym->is_undefined()
> + || sym->is_from_dynobj())
> + symtab->define_in_output_data("__exidx_start", NULL,
> + Symbol_table::PREDEFINED,
> + exidx_section, 0, 0, elfcpp::STT_OBJECT,
> + elfcpp::STB_GLOBAL, elfcpp::STV_DEFAULT,
> + 0, false, false);
> +
> + sym = symtab->lookup("__exidx_end", NULL);
> + if (sym == NULL
> + || sym->is_undefined()
> + || sym->is_from_dynobj())
> + symtab->define_in_output_data("__exidx_end", NULL,
> + Symbol_table::PREDEFINED,
> + exidx_section, 0, 0, elfcpp::STT_OBJECT,
> + elfcpp::STB_GLOBAL, elfcpp::STV_DEFAULT,
> + 0, true, false);
Would it be correct to simply pass the last argument to
define_in_output_data as true? That would only define the symbols if
something refers to them. That seems to be what the GNU linker does.
Although the GNU linker does seem to make the symbols hidden, as in
the current code, unlike in your new code.
Ian