From: Daniel Jacobowitz <drow@false.org>
To: binutils@sourceware.org
Subject: MIPS textrel fix
Date: Fri, 19 May 2006 00:37:00 -0000 [thread overview]
Message-ID: <20060518213149.GA14720@nevyn.them.org> (raw)
While stuck offline earlier today, I revisited the textrel-1 MIPS
failure. Eric originally tried setting DF_TEXTREL during section
relocation, but it's too late: we add the entry in size_dynamic_sections.
But I couldn't see any other way to get it right, since there's no
hook to predict whether elf-eh-frame.c will eliminate a relocation.
The easiest approach I found was to annul the DT_TEXTREL and DT_FLAGS
changes in finish_dynamic_sections if no text relocations were
actually generated. This is not immensely pretty, but does work.
OK?
For background, the problem arises from the use of absolute addresses
in .eh_frame. In this case, they're being produced by gas CFI
directives. Is there a reason we can't mix and match encodings?
i.e. why not have gas use a PC-relative format? I'm sure there's
a reason, but I can't think of it...
--
Daniel Jacobowitz
CodeSourcery
2006-05-18 Daniel Jacobowitz <dan@codesourcery.com>
* elflink.c (_bfd_elf_add_dynamic_entry): Remove DT_TEXTREL
check.
(bfd_elf_final_link): Add a late DT_TEXTREL check.
* elfxx-mips.c (MIPS_ELF_READONLY_SECTION): Define.
(mips_elf_create_dynamic_relocation): Set DF_TEXTREL.
(_bfd_mips_elf_check_relocs): Delete MIPS_READONLY_SECTION.
Use MIPS_ELF_READONLY_SECTION.
(_bfd_mips_elf_size_dynamic_sections): Clear DF_TEXTREL after
creating DT_TEXTREL.
(_bfd_mips_elf_finish_dynamic_sections): Clear textrel markers
if no text relocations were generated.
Index: elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.210.2.3
diff -u -p -r1.210.2.3 elflink.c
--- elflink.c 17 May 2006 05:14:21 -0000 1.210.2.3
+++ elflink.c 18 May 2006 21:24:41 -0000
@@ -2810,10 +2810,6 @@ _bfd_elf_add_dynamic_entry (struct bfd_l
if (! is_elf_hash_table (hash_table))
return FALSE;
- if (info->warn_shared_textrel && info->shared && tag == DT_TEXTREL)
- _bfd_error_handler
- (_("warning: creating a DT_TEXTREL in a shared object."));
-
bed = get_elf_backend_data (hash_table->dynobj);
s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
BFD_ASSERT (s != NULL);
@@ -8655,6 +8651,32 @@ bfd_elf_final_link (bfd *abfd, struct bf
if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
goto error_return;
+ /* Check for DT_TEXTREL (late, in case the backend removes it). */
+ if (info->warn_shared_textrel && info->shared)
+ {
+ bfd_byte *dyncon, *dynconend;
+
+ /* Fix up .dynamic entries. */
+ o = bfd_get_section_by_name (dynobj, ".dynamic");
+ BFD_ASSERT (o != NULL);
+
+ dyncon = o->contents;
+ dynconend = o->contents + o->size;
+ for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
+
+ if (dyn.d_tag == DT_TEXTREL)
+ {
+ _bfd_error_handler
+ (_("warning: creating a DT_TEXTREL in a shared object."));
+ break;
+ }
+ }
+ }
+
for (o = dynobj->sections; o != NULL; o = o->next)
{
if ((o->flags & SEC_HAS_CONTENTS) == 0
Index: elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.165
diff -u -p -r1.165 elfxx-mips.c
--- elfxx-mips.c 27 Mar 2006 11:30:53 -0000 1.165
+++ elfxx-mips.c 18 May 2006 21:24:42 -0000
@@ -535,6 +535,11 @@ static bfd *reldyn_sorting_bfd;
#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \
(strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
+/* Whether the section is readonly. */
+#define MIPS_ELF_READONLY_SECTION(sec) \
+ ((sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) \
+ == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+
/* The name of the stub section. */
#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
@@ -4909,6 +4914,12 @@ mips_elf_create_dynamic_relocation (bfd
}
}
+ /* If we've written this relocation for a readonly section,
+ we need to set DF_TEXTREL again, so that we do not delete the
+ DT_TEXTREL tag. */
+ if (MIPS_ELF_READONLY_SECTION (input_section))
+ info->flags |= DF_TEXTREL;
+
return TRUE;
}
\f
@@ -6513,15 +6524,13 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
if (sreloc == NULL)
return FALSE;
}
-#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
if (info->shared)
{
/* When creating a shared object, we must copy these
reloc types into the output file as R_MIPS_REL32
relocs. Make room for this reloc in .rel(a).dyn. */
mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
- if ((sec->flags & MIPS_READONLY_SECTION)
- == MIPS_READONLY_SECTION)
+ if (MIPS_ELF_READONLY_SECTION (sec))
/* We tell the dynamic linker that there are
relocations against the text segment. */
info->flags |= DF_TEXTREL;
@@ -6534,8 +6543,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
defined in a dynamic object. */
hmips = (struct mips_elf_link_hash_entry *) h;
++hmips->possibly_dynamic_relocs;
- if ((sec->flags & MIPS_READONLY_SECTION)
- == MIPS_READONLY_SECTION)
+ if (MIPS_ELF_READONLY_SECTION (sec))
/* We need it to tell the dynamic linker if there
are relocations against the text segment. */
hmips->readonly_reloc = TRUE;
@@ -7452,6 +7460,12 @@ _bfd_mips_elf_size_dynamic_sections (bfd
{
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
return FALSE;
+
+ /* Clear the DF_TEXTREL flag. It will be set again if we
+ write out an actual text relocation; we may not, because
+ at this point we do not know whether e.g. any .eh_frame
+ absolute relocations have been converted to PC-relative. */
+ info->flags &= ~DF_TEXTREL;
}
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
@@ -8478,6 +8492,7 @@ _bfd_mips_elf_finish_dynamic_sections (b
if (elf_hash_table (info)->dynamic_sections_created)
{
bfd_byte *b;
+ int dyn_to_skip = 0, dyn_skipped = 0;
BFD_ASSERT (sdyn != NULL);
BFD_ASSERT (g != NULL);
@@ -8632,15 +8647,44 @@ _bfd_mips_elf_finish_dynamic_sections (b
+ htab->srelplt->output_offset);
break;
+ case DT_TEXTREL:
+ /* If we didn't need any text relocations after all, delete
+ the dynamic tag. */
+ if (!(info->flags & DF_TEXTREL))
+ {
+ dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
+ swap_out_p = FALSE;
+ }
+ break;
+
+ case DT_FLAGS:
+ /* If we didn't need any text relocations after all, clear
+ DF_TEXTREL from DT_FLAGS. */
+ if (!(info->flags & DF_TEXTREL))
+ dyn.d_un.d_val &= ~DF_TEXTREL;
+ else
+ swap_out_p = FALSE;
+ break;
+
default:
swap_out_p = FALSE;
break;
}
- if (swap_out_p)
+ if (swap_out_p || dyn_skipped)
(*get_elf_backend_data (dynobj)->s->swap_dyn_out)
- (dynobj, &dyn, b);
+ (dynobj, &dyn, b - dyn_skipped);
+
+ if (dyn_to_skip)
+ {
+ dyn_skipped += dyn_to_skip;
+ dyn_to_skip = 0;
+ }
}
+
+ /* Wipe out any trailing entries if we shifted down a dynamic tag. */
+ if (dyn_skipped > 0)
+ memset (b - dyn_skipped, 0, dyn_skipped);
}
if (sgot != NULL && sgot->size > 0)
next reply other threads:[~2006-05-18 21:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-19 0:37 Daniel Jacobowitz [this message]
2006-05-19 0:50 ` Daniel Jacobowitz
2006-05-19 6:09 ` Eric Christopher
2006-05-19 9:03 ` David Daney
2006-05-19 9:12 ` Thiemo Seufer
2006-05-19 9:26 ` David Daney
2006-05-19 10:18 ` Eric Christopher
2006-05-22 20:28 ` Daniel Jacobowitz
2006-05-22 20:28 ` Thiemo Seufer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060518213149.GA14720@nevyn.them.org \
--to=drow@false.org \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).