+2006-05-22 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.
+
2006-05-19 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-ia64.c (ELF_MAXPAGESIZE): Fix a typo in comment.
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);
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
#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"
}
}
+ /* 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
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;
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;
{
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))
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);
+ 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)
Dynamic section at offset 0xb4 contains 18 entries:
Tag Type Name/Value
- 0x00000004 \(HASH\) 0x16c
- 0x00000005 \(STRTAB\) 0x30c
- 0x00000006 \(SYMTAB\) 0x1fc
- 0x0000000a \(STRSZ\) 84 \(bytes\)
+ 0x00000004 \(HASH\) 0x[0-9a-f]*
+ 0x00000005 \(STRTAB\) 0x[0-9a-f]*
+ 0x00000006 \(SYMTAB\) 0x[0-9a-f]*
+ 0x0000000a \(STRSZ\) [0-9]* \(bytes\)
0x0000000b \(SYMENT\) 16 \(bytes\)
0x00000015 \(DEBUG\) 0x0
- 0x00000003 \(PLTGOT\) 0x1003e0
- 0x00000011 \(REL\) 0x360
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]*
+ 0x00000011 \(REL\) 0x[0-9a-f]*
0x00000012 \(RELSZ\) 8 \(bytes\)
0x00000013 \(RELENT\) 8 \(bytes\)
0x70000001 \(MIPS_RLD_VERSION\) 1
0x70000005 \(MIPS_FLAGS\) NOTPOT
0x70000006 \(MIPS_BASE_ADDRESS\) 0
- 0x7000000a \(MIPS_LOCAL_GOTNO\) 7
- 0x70000011 \(MIPS_SYMTABNO\) 17
- 0x70000012 \(MIPS_UNREFEXTNO\) 12
- 0x70000013 \(MIPS_GOTSYM\) 0x11
+ 0x7000000a \(MIPS_LOCAL_GOTNO\) [0-9]*
+ 0x70000011 \(MIPS_SYMTABNO\) [0-9]*
+ 0x70000012 \(MIPS_UNREFEXTNO\) [0-9]*
+ 0x70000013 \(MIPS_GOTSYM\) 0x[0-9a-f]*
0x00000000 \(NULL\) 0x0