58 lines
1.9 KiB
Diff
58 lines
1.9 KiB
Diff
|
From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001
|
||
|
From: Max Filippov <jcmvbkbc@gmail.com>
|
||
|
Date: Thu, 14 May 2015 05:22:55 +0300
|
||
|
Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections
|
||
|
|
||
|
elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were
|
||
|
made local, that results in link failure with the following message:
|
||
|
|
||
|
BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line
|
||
|
3372 in elf_xtensa_finish_dynamic_sections
|
||
|
|
||
|
elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by
|
||
|
relocation type. Relocation types are not changed when symbol becomes
|
||
|
local, but its PLT references are added to GOT references and
|
||
|
plt.refcount is set to 0. Such symbol cannot be unreferences in the
|
||
|
elf_xtensa_gc_sweep_hook and its extra references make calculated GOT
|
||
|
relocations section size not match number of GOT relocations.
|
||
|
|
||
|
Fix it by treating PLT reference as GOT reference when plt.refcount is
|
||
|
not positive.
|
||
|
|
||
|
2015-05-14 Max Filippov <jcmvbkbc@gmail.com>
|
||
|
bfd/
|
||
|
* elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference
|
||
|
as GOT reference when plt.refcount is not positive.
|
||
|
|
||
|
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||
|
---
|
||
|
Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388
|
||
|
Changes to ChangeLog are dropped.
|
||
|
|
||
|
bfd/elf32-xtensa.c | 6 +++++-
|
||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
|
||
|
index 53af1c6..2523670 100644
|
||
|
--- a/bfd/elf32-xtensa.c
|
||
|
+++ b/bfd/elf32-xtensa.c
|
||
|
@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd,
|
||
|
{
|
||
|
if (is_plt)
|
||
|
{
|
||
|
+ /* If the symbol has been localized its plt.refcount got moved
|
||
|
+ to got.refcount. Handle it as GOT. */
|
||
|
if (h->plt.refcount > 0)
|
||
|
h->plt.refcount--;
|
||
|
+ else
|
||
|
+ is_got = TRUE;
|
||
|
}
|
||
|
- else if (is_got)
|
||
|
+ if (is_got)
|
||
|
{
|
||
|
if (h->got.refcount > 0)
|
||
|
h->got.refcount--;
|
||
|
--
|
||
|
1.8.1.4
|
||
|
|