* elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the

reloc is against read-only section.
	(elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of
	looking up section names for DT_TEXTREL.
	(elf_cris_reloc_type_class): New.
	(elf_backend_reloc_type_class): Define.

	* elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is
	against read-only section.
	(elf_backend_reloc_type_class): Define.
	(sh_elf_reloc_type_class): New.
	(sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
	looking up section names for DT_TEXTREL.

	* elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the
	reloc is against read-only section.
	(elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of
	looking up section names for DT_TEXTREL.
	(elf32_arm_reloc_type_class): New.
This commit is contained in:
Andreas Jaeger 2001-08-26 18:03:19 +00:00
parent 5b3fabc955
commit 99e4ae17b9
4 changed files with 130 additions and 113 deletions

View File

@ -1,3 +1,26 @@
2001-08-26 Andreas Jaeger <aj@suse.de>
* elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the
reloc is against read-only section.
(elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.
(elf_cris_reloc_type_class): New.
(elf_backend_reloc_type_class): Define.
* elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is
against read-only section.
(elf_backend_reloc_type_class): Define.
(sh_elf_reloc_type_class): New.
(sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.
* elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the
reloc is against read-only section.
(elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.
(elf32_arm_reloc_type_class): New.
(elf_backend_reloc_type_class): Define.
2001-08-25 Andreas Jaeger <aj@suse.de>
* oasys.c: Add missing prototypes.

View File

@ -91,6 +91,9 @@ boolean bfd_elf32_arm_get_bfd_for_interworking
PARAMS ((bfd *, struct bfd_link_info *));
boolean bfd_elf32_arm_process_before_allocation
PARAMS ((bfd *, struct bfd_link_info *, int));
static enum elf_reloc_type_class elf32_arm_reloc_type_class
PARAMS ((int));
#define INTERWORK_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK)
/* The linker script knows the section names for placement.
@ -125,7 +128,7 @@ static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] =
/* Subsequent entries in a procedure linkage table look like
this. */
static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] =
{
{
0xe59fc004, /* ldr ip, [pc, #4] */
0xe08fc00c, /* add ip, pc, ip */
0xe59cf000, /* ldr pc, [ip] */
@ -1058,7 +1061,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
/* If the start address has been set, then set the EF_ARM_HASENTRY
flag. Setting this more than once is redundant, but the cost is
not too high, and it keeps the code simple.
The test is done here, rather than somewhere else, because the
start address is only set just before the final link commences.
@ -1066,7 +1069,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
flag will not be set. */
if (bfd_get_start_address (output_bfd) != 0)
elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
globals = elf32_arm_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
@ -1110,7 +1113,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
into the output file to be resolved at run time. */
if (info->shared
&& (r_type != R_ARM_PC24
|| (h != NULL
|| (h != NULL
&& h->dynindx != -1
&& (! info->symbolic
|| (h->elf_link_hash_flags
@ -1493,7 +1496,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
corresponding bit one in the target address will be set from bit
one of the source address. */
lower_insn &= ~1;
#endif
#endif
/* Put the relocated value back in the object file: */
bfd_put_16 (input_bfd, upper_insn, hit_data);
bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
@ -1533,8 +1536,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
calculation. */
value -= sgot->output_section->vma;
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
(bfd_vma) 0);
contents, rel->r_offset, value,
(bfd_vma) 0);
case R_ARM_GOTPC:
/* Use global offset table as symbol value. */
@ -1545,8 +1548,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
value = sgot->output_section->vma;
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
(bfd_vma) 0);
contents, rel->r_offset, value,
(bfd_vma) 0);
case R_ARM_GOT32:
/* Relocation is to the entry for this symbol in the
@ -1629,8 +1632,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
}
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
(bfd_vma) 0);
contents, rel->r_offset, value,
(bfd_vma) 0);
case R_ARM_PLT32:
/* Relocation is to the entry for this symbol in the
@ -1640,8 +1643,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
without using the procedure linkage table. */
if (h == NULL)
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
(bfd_vma) 0);
contents, rel->r_offset, value,
(bfd_vma) 0);
if (h->plt.offset == (bfd_vma) -1)
/* We didn't make a PLT entry for this symbol. This
@ -1659,8 +1662,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
+ splt->output_offset
+ h->plt.offset);
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
(bfd_vma) 0);
contents, rel->r_offset, value,
(bfd_vma) 0);
case R_ARM_SBREL32:
return bfd_reloc_notsupported;
@ -1872,7 +1875,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
case R_ARM_ABS32:
if (info->shared
&& (
(!info->symbolic && h->dynindx != -1)
(!info->symbolic && h->dynindx != -1)
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
)
&& ((input_section->flags & SEC_ALLOC) != 0
@ -2310,7 +2313,7 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
if (flags & EF_ARM_MAPSYMSFIRST)
fprintf (file, _(" [mapping symbols precede others]"));
flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
| EF_ARM_MAPSYMSFIRST);
break;
@ -2506,7 +2509,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
srelgot = bfd_make_section (dynobj, ".rel.got");
if (srelgot == NULL
|| ! bfd_set_section_flags (dynobj, srelgot,
(SEC_ALLOC
(SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
@ -2534,7 +2537,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
}
else
{
/* This is a global offset table entry for a local
/* This is a global offset table entry for a local
symbol. */
if (local_got_offsets == NULL)
{
@ -2566,7 +2569,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
sgot->_raw_size += 4;
break;
case R_ARM_PLT32:
case R_ARM_PLT32:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
@ -2619,7 +2622,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
return false;
BFD_ASSERT (strncmp (name, ".rel", 4) == 0
&& strcmp (bfd_get_section_name (abfd, sec),
&& strcmp (bfd_get_section_name (abfd, sec),
name + 4) == 0);
sreloc = bfd_get_section_by_name (dynobj, name);
@ -2637,6 +2640,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
if (sec->flags & SEC_READONLY)
info->flags |= DF_TEXTREL;
}
sreloc->_raw_size += sizeof (Elf32_External_Rel);
@ -2951,14 +2956,13 @@ elf32_arm_adjust_dynamic_symbol (info, h)
static boolean
elf32_arm_size_dynamic_sections (output_bfd, info)
bfd * output_bfd;
bfd * output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info * info;
{
bfd * dynobj;
asection * s;
boolean plt;
boolean relocs;
boolean reltext;
dynobj = elf_hash_table (info)->dynobj;
BFD_ASSERT (dynobj != NULL);
@ -3000,7 +3004,6 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
memory for them. */
plt = false;
relocs = false;
reltext = false;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char * name;
@ -3046,30 +3049,10 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
}
else
{
asection * target;
/* Remember whether there are any reloc sections other
than .rel.plt. */
if (strcmp (name, ".rel.plt") != 0)
{
const char *outname;
relocs = true;
/* If this relocation section applies to a read only
section, then we probably need a DT_TEXTREL
entry. The entries in the .rel.plt section
really apply to the .got section, which we
created ourselves and so know is not readonly. */
outname = bfd_get_section_name (output_bfd,
s->output_section);
target = bfd_get_section_by_name (output_bfd, outname + 4);
if (target != NULL
&& (target->flags & SEC_READONLY) != 0
&& (target->flags & SEC_ALLOC) != 0)
reltext = true;
}
relocs = true;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
@ -3133,7 +3116,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
return false;
}
if (reltext)
if ((info->flags & DF_TEXTREL) != 0)
{
if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
return false;
@ -3457,29 +3440,48 @@ elf32_arm_post_process_headers (abfd, link_info)
i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
}
static enum elf_reloc_type_class
elf32_arm_reloc_type_class (type)
int type;
{
switch (type)
{
case R_ARM_RELATIVE:
return reloc_class_relative;
case R_ARM_JUMP_SLOT:
return reloc_class_plt;
case R_ARM_COPY:
return reloc_class_copy;
default:
return reloc_class_normal;
}
}
#define ELF_ARCH bfd_arch_arm
#define ELF_MACHINE_CODE EM_ARM
#define ELF_MAXPAGESIZE 0x8000
#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
#define elf_backend_check_relocs elf32_arm_check_relocs
#define elf_backend_relocate_section elf32_arm_relocate_section
#define elf_backend_relocate_section elf32_arm_relocate_section
#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
#define elf_backend_finish_dynamic_symbol elf32_arm_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections
#define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections
#define elf_backend_post_process_headers elf32_arm_post_process_headers
#define elf_backend_reloc_type_class elf32_arm_reloc_type_class
#define elf_backend_can_gc_sections 1
#define elf_backend_plt_readonly 1

View File

@ -85,6 +85,8 @@ static boolean elf_cris_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static void elf_cris_hide_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static enum elf_reloc_type_class elf_cris_reloc_type_class
PARAMS ((int));
static reloc_howto_type cris_elf_howto_table [] =
{
@ -2575,6 +2577,8 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
|| !bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
if (sec->flags & SEC_READONLY)
info->flags |= DF_TEXTREL;
}
sreloc->_raw_size += sizeof (Elf32_External_Rela);
@ -2642,14 +2646,13 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
static boolean
elf_cris_size_dynamic_sections (output_bfd, info)
bfd *output_bfd;
bfd *output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
bfd *dynobj;
asection *s;
boolean plt;
boolean relocs;
boolean reltext;
dynobj = elf_hash_table (info)->dynobj;
BFD_ASSERT (dynobj != NULL);
@ -2703,7 +2706,6 @@ elf_cris_size_dynamic_sections (output_bfd, info)
memory for them. */
plt = false;
relocs = false;
reltext = false;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
@ -2749,41 +2751,11 @@ elf_cris_size_dynamic_sections (output_bfd, info)
}
else
{
asection *target;
/* Remember whether there are any reloc sections other
than .rela.plt. */
if (strcmp (name, ".rela.plt") != 0)
{
const char *outname;
relocs = true;
/* If this relocation section applies to a read only
section, then we probably need a DT_TEXTREL entry.
The entries in the .rela.plt section are actually
associated with .got.plt, which we created ourselves
and so know is not readonly. */
outname = bfd_get_section_name (output_bfd,
s->output_section);
target
= bfd_get_section_by_name (output_bfd,
outname + strlen (".rela"));
/* We have to test the .text section by name, becase for
some reason it does not have SEC_READONLY set at this
time. That flag is actually set in ldmain.c:main
specifically for ".text" at a time long after this
function is called. FIXME: This might be due to a
general bug. FIXME: Have testcase for this. */
if (target != NULL
&& (target->flags & SEC_ALLOC) != 0
&& ((target->flags & SEC_READONLY) != 0
|| strcmp (outname + strlen (".rela"),
".text") == 0))
reltext = true;
}
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
s->reloc_count = 0;
@ -2842,7 +2814,7 @@ elf_cris_size_dynamic_sections (output_bfd, info)
return false;
}
if (reltext)
if ((info->flags & DF_TEXTREL) != 0)
{
if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
return false;
@ -3020,6 +2992,24 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
return true;
}
static enum elf_reloc_type_class
elf_cris_reloc_type_class (type)
int type;
{
switch (type)
{
case R_CRIS_RELATIVE:
return reloc_class_relative;
case R_CRIS_JUMP_SLOT:
return reloc_class_plt;
case R_CRIS_COPY:
return reloc_class_copy;
default:
return reloc_class_normal;
}
}
#define ELF_ARCH bfd_arch_cris
#define ELF_MACHINE_CODE EM_CRIS
@ -3063,6 +3053,7 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
#define bfd_elf32_bfd_final_link \
_bfd_elf32_gc_common_final_link
#define elf_backend_hide_symbol elf_cris_hide_symbol
#define elf_backend_reloc_type_class elf_cris_reloc_type_class
#define elf_backend_want_got_plt 1
#define elf_backend_plt_readonly 1

View File

@ -83,6 +83,8 @@ static asection * sh_elf_gc_mark_hook
static boolean sh_elf_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
static enum elf_reloc_type_class sh_elf_reloc_type_class
PARAMS ((int));
/* The name of the dynamic interpreter. This is put in the .interp
section. */
@ -1111,11 +1113,11 @@ sh_elf_relax_section (abfd, sec, link_info, again)
}
/* Get the address from which the register is being loaded. The
displacement in the mov.l instruction is quadrupled. It is a
displacement from four bytes after the movl instruction, but,
before adding in the PC address, two least significant bits
of the PC are cleared. We assume that the section is aligned
on a four byte boundary. */
displacement in the mov.l instruction is quadrupled. It is a
displacement from four bytes after the movl instruction, but,
before adding in the PC address, two least significant bits
of the PC are cleared. We assume that the section is aligned
on a four byte boundary. */
paddr = insn & 0xff;
paddr *= 4;
paddr += (laddr + 4) & ~3;
@ -2761,14 +2763,13 @@ sh_elf_adjust_dynamic_symbol (info, h)
static boolean
sh_elf_size_dynamic_sections (output_bfd, info)
bfd *output_bfd;
bfd *output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
bfd *dynobj;
asection *s;
boolean plt;
boolean relocs;
boolean reltext;
dynobj = elf_hash_table (info)->dynobj;
BFD_ASSERT (dynobj != NULL);
@ -2810,7 +2811,6 @@ sh_elf_size_dynamic_sections (output_bfd, info)
memory for them. */
plt = false;
relocs = false;
reltext = false;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
@ -2856,29 +2856,10 @@ sh_elf_size_dynamic_sections (output_bfd, info)
}
else
{
asection *target;
/* Remember whether there are any reloc sections other
than .rela.plt. */
if (strcmp (name, ".rela.plt") != 0)
{
const char *outname;
relocs = true;
/* If this relocation section applies to a read only
section, then we probably need a DT_TEXTREL
entry. The entries in the .rela.plt section
really apply to the .got section, which we
created ourselves and so know is not readonly. */
outname = bfd_get_section_name (output_bfd,
s->output_section);
target = bfd_get_section_by_name (output_bfd, outname + 5);
if (target != NULL
&& (target->flags & SEC_READONLY) != 0
&& (target->flags & SEC_ALLOC) != 0)
reltext = true;
}
relocs = true;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
@ -2934,7 +2915,7 @@ sh_elf_size_dynamic_sections (output_bfd, info)
return false;
}
if (reltext)
if ((info->flags & DF_TEXTREL) != 0)
{
if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
return false;
@ -3957,6 +3938,8 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
if (sec->flags & SEC_READONLY)
info->flags |= DF_TEXTREL;
}
sreloc->_raw_size += sizeof (Elf32_External_Rela);
@ -4441,6 +4424,23 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
return true;
}
static enum elf_reloc_type_class
sh_elf_reloc_type_class (type)
int type;
{
switch (type)
{
case R_SH_RELATIVE:
return reloc_class_relative;
case R_SH_JMP_SLOT:
return reloc_class_plt;
case R_SH_COPY:
return reloc_class_copy;
default:
return reloc_class_normal;
}
}
#ifndef ELF_ARCH
#define TARGET_BIG_SYM bfd_elf32_sh_vec
#define TARGET_BIG_NAME "elf32-sh"
@ -4484,6 +4484,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
sh_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
sh_elf_finish_dynamic_sections
#define elf_backend_reloc_type_class sh_elf_reloc_type_class
#define elf_backend_want_got_plt 1
#define elf_backend_plt_readonly 1