This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PowerPC64 gold --gc-sections error
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Cc: Cary Coutant <ccoutant at google dot com>
- Date: Thu, 27 Jun 2013 12:40:39 +0930
- Subject: PowerPC64 gold --gc-sections error
This fixes some errors in gold triggered by invalid powerpc64 objects.
See http://sourceware.org/bugzilla/show_bug.cgi?id=15687
2013-06-27 Cary Coutant
* powerpc.cc (Target_powerpc::symval_for_branch): Don't assert
on garbage collected .opd section.
2013-06-27 Alan Modra
* powerpc.cc (Target_powerpc::do_gc_add_reference): Test dst_shndx
is non-zero.
(Target_powerpc::do_gc_mark_symbols): Likewise for sym->shndx().
(Target_powerpc::do_function_location): Likewise for loc->shndx.
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.91
diff -u -p -r1.91 powerpc.cc
--- gold/powerpc.cc 27 Apr 2013 00:53:16 -0000 1.91
+++ gold/powerpc.cc 27 Jun 2013 02:43:20 -0000
@@ -5827,7 +5827,7 @@ Target_powerpc<size, big_endian>::do_gc_
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(dst_obj);
- if (dst_shndx == ppc_object->opd_shndx())
+ if (dst_shndx != 0 && dst_shndx == ppc_object->opd_shndx())
{
if (ppc_object->opd_valid())
{
@@ -5859,7 +5859,7 @@ Target_powerpc<size, big_endian>::do_gc_
= static_cast<Powerpc_relobj<size, big_endian>*>(sym->object());
bool is_ordinary;
unsigned int shndx = sym->shndx(&is_ordinary);
- if (is_ordinary && shndx == ppc_object->opd_shndx())
+ if (is_ordinary && shndx != 0 && shndx == ppc_object->opd_shndx())
{
Sized_symbol<size>* gsym = symtab->get_sized_symbol<size>(sym);
Address dst_off = gsym->value();
@@ -5882,7 +5882,7 @@ void
Target_powerpc<size, big_endian>::do_function_location(
Symbol_location* loc) const
{
- if (size == 64)
+ if (size == 64 && loc->shndx != 0)
{
if (loc->object->is_dynamic())
{
@@ -6183,7 +6183,8 @@ Target_powerpc<size, big_endian>::symval
if (shndx == 0)
return value;
Address opd_addr = symobj->get_output_section_offset(shndx);
- gold_assert(opd_addr != invalid_address);
+ if (opd_addr == invalid_address)
+ return value;
opd_addr += symobj->output_section(shndx)->address();
if (value >= opd_addr && value < opd_addr + symobj->section_size(shndx))
{
--
Alan Modra
Australia Development Lab, IBM