summaryrefslogtreecommitdiff
path: root/bfd/elf32-m32r.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-m32r.c')
-rw-r--r--bfd/elf32-m32r.c205
1 files changed, 133 insertions, 72 deletions
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 21d37b176ce..b7609e02ada 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -669,7 +669,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_M32R_RELATIVE", /* name */
+ "R_M32R_RELATIVE", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
@@ -678,15 +678,15 @@ static reloc_howto_type m32r_elf_howto_table[] =
HOWTO (R_M32R_GOTOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 24, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_M32R_GOTOFF", /* name */
+ "R_M32R_GOTOFF", /* name */
FALSE, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 24-bit relocation used when setting PIC offset
@@ -803,6 +803,48 @@ static reloc_howto_type m32r_elf_howto_table[] =
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
TRUE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_ULO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_ULO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_SLO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_SLO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_LO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* Handle the R_M32R_10_PCREL reloc. */
@@ -863,7 +905,7 @@ m32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset,
bfd_reloc_status_type status;
/* Sanity check the address (offset in section). */
- if (offset > input_section->_cooked_size)
+ if (offset > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
relocation = symbol_value + addend;
@@ -942,7 +984,7 @@ m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
}
/* Sanity check the address (offset in section). */
- if (reloc_entry->address > input_section->_cooked_size)
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
@@ -1115,7 +1157,7 @@ m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
a section relative addend which is wrong. */
/* Sanity check the address (offset in section). */
- if (reloc_entry->address > input_section->_cooked_size)
+ if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
@@ -1263,6 +1305,9 @@ static const struct m32r_reloc_map m32r_reloc_map[] =
{ BFD_RELOC_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_ULO },
{ BFD_RELOC_M32R_GOTPC_HI_SLO, R_M32R_GOTPC_HI_SLO },
{ BFD_RELOC_M32R_GOTPC_LO, R_M32R_GOTPC_LO },
+ { BFD_RELOC_M32R_GOTOFF_HI_ULO, R_M32R_GOTOFF_HI_ULO },
+ { BFD_RELOC_M32R_GOTOFF_HI_SLO, R_M32R_GOTOFF_HI_SLO },
+ { BFD_RELOC_M32R_GOTOFF_LO, R_M32R_GOTOFF_LO },
};
static reloc_howto_type *
@@ -2020,7 +2065,7 @@ printf("m32r_elf_adjust_dynamic_symbol()\n");
srel = htab->srelbss;
BFD_ASSERT (srel != NULL);
- srel->_raw_size += sizeof (Elf32_External_Rela);
+ srel->size += sizeof (Elf32_External_Rela);
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
}
@@ -2031,8 +2076,7 @@ printf("m32r_elf_adjust_dynamic_symbol()\n");
power_of_two = 3;
/* Apply the required alignment. */
- s->_raw_size = BFD_ALIGN (s->_raw_size,
- (bfd_size_type) (1 << power_of_two));
+ s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (dynobj, s))
{
if (! bfd_set_section_alignment (dynobj, s, power_of_two))
@@ -2041,10 +2085,10 @@ printf("m32r_elf_adjust_dynamic_symbol()\n");
/* Define the symbol as being at this point in the section. */
h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
+ h->root.u.def.value = s->size;
/* Increment the section size to make room for the symbol. */
- s->_raw_size += h->size;
+ s->size += h->size;
return TRUE;
}
@@ -2104,10 +2148,10 @@ allocate_dynrelocs (h, inf)
/* If this is the first .plt entry, make room for the special
first entry. */
- if (s->_raw_size == 0)
- s->_raw_size += PLT_ENTRY_SIZE;
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
- h->plt.offset = s->_raw_size;
+ h->plt.offset = s->size;
/* If this symbol is not defined in a regular file, and we are
not generating a shared library, then set the symbol to this
@@ -2122,14 +2166,14 @@ allocate_dynrelocs (h, inf)
}
/* Make room for this entry. */
- s->_raw_size += PLT_ENTRY_SIZE;
+ s->size += PLT_ENTRY_SIZE;
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- htab->sgotplt->_raw_size += 4;
+ htab->sgotplt->size += 4;
/* We also need to make an entry in the .rel.plt section. */
- htab->srelplt->_raw_size += sizeof (Elf32_External_Rela);
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
}
else
{
@@ -2159,11 +2203,11 @@ allocate_dynrelocs (h, inf)
s = htab->sgot;
- h->got.offset = s->_raw_size;
- s->_raw_size += 4;
+ h->got.offset = s->size;
+ s->size += 4;
dyn = htab->root.dynamic_sections_created;
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
- htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
}
else
h->got.offset = (bfd_vma) -1;
@@ -2232,7 +2276,7 @@ allocate_dynrelocs (h, inf)
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
asection *sreloc = elf_section_data (p->sec)->sreloc;
- sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela);
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
}
return TRUE;
@@ -2296,7 +2340,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
}
@@ -2334,7 +2378,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
- srel->_raw_size += p->count * sizeof (Elf32_External_Rela);
+ srel->size += p->count * sizeof (Elf32_External_Rela);
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
info->flags |= DF_TEXTREL;
}
@@ -2354,10 +2398,10 @@ printf("m32r_elf_size_dynamic_sections()\n");
{
if (*local_got > 0)
{
- *local_got = s->_raw_size;
- s->_raw_size += 4;
+ *local_got = s->size;
+ s->size += 4;
if (info->shared)
- srel->_raw_size += sizeof (Elf32_External_Rela);
+ srel->size += sizeof (Elf32_External_Rela);
}
else
*local_got = (bfd_vma) -1;
@@ -2385,7 +2429,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
}
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
{
- if (s->_raw_size != 0 && s != htab->srelplt)
+ if (s->size != 0 && s != htab->srelplt)
relocs = TRUE;
/* We use the reloc_count field as a counter if we need
@@ -2398,7 +2442,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
continue;
}
- if (s->_raw_size == 0)
+ if (s->size == 0)
{
/* If we don't need this section, strip it from the
output file. This is mostly to handle .rela.bss and
@@ -2418,7 +2462,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
section's contents are written out. This should not happen,
but this way if it does, we get a R_M32R_NONE reloc instead
of garbage. */
- s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
if (s->contents == NULL)
return FALSE;
}
@@ -2439,7 +2483,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
return FALSE;
}
- if (htab->splt->_raw_size != 0)
+ if (htab->splt->size != 0)
{
if (! add_dynamic_entry (DT_PLTGOT, 0)
|| ! add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -2528,6 +2572,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd *dynobj;
bfd_vma *local_got_offsets;
asection *sgot, *splt, *sreloc;
+ bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
dynobj = htab->root.dynobj;
local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -2561,8 +2606,8 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type < 0 || r_type >= (int) R_M32R_max)
{
- (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
- bfd_archive_filename (input_bfd),
+ (*_bfd_error_handler) (_("%B: unknown relocation type %d"),
+ input_bfd,
(int) r_type);
bfd_set_error (bfd_error_bad_value);
ret = FALSE;
@@ -2582,7 +2627,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
howto = m32r_elf_howto_table + r_type;
r_symndx = ELF32_R_SYM (rel->r_info);
- if (info->relocatable && (use_rel == TRUE))
+ if (info->relocatable && use_rel)
{
/* This is a relocatable link. We don't have to change
anything, unless the reloc is against a section symbol,
@@ -2658,7 +2703,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
sec = local_sections[r_symndx];
sym_name = "<local symbol>";
- if (use_rel == FALSE)
+ if (!use_rel)
{
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
addend = rel->r_addend;
@@ -2685,7 +2730,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
else
{
/* External symbol. */
- if (info->relocatable && (use_rel == FALSE))
+ if (info->relocatable && !use_rel)
continue;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
@@ -2779,7 +2824,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
/* Sanity check the address. */
- if (offset > input_section->_raw_size)
+ if (offset > high_address)
{
r = bfd_reloc_outofrange;
goto check_reloc;
@@ -2787,6 +2832,31 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
switch ((int) r_type)
{
+ case R_M32R_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table (for ld24 rx, #uimm24). eg access at label+addend
+
+ ld24 rx. #label@GOTOFF + addend
+ sub rx, r12. */
+
+ BFD_ASSERT (sgot != NULL);
+
+ relocation = -(relocation - sgot->output_section->vma);
+ rel->r_addend = -rel->r_addend;
+ break;
+
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
+ BFD_ASSERT (sgot != NULL);
+
+ relocation -= sgot->output_section->vma;
+
+ if ((r_type == R_M32R_GOTOFF_HI_SLO)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+ break;
+
case R_M32R_GOTPC24:
/* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
ld24 rx,#_GLOBAL_OFFSET_TABLE_
@@ -2961,7 +3031,6 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
case R_M32R_26_PCREL_RELA:
case R_M32R_HI16_ULO_RELA:
case R_M32R_LO16_RELA:
- case R_M32R_SDA16_RELA:
if (info->shared
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
@@ -3094,6 +3163,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
goto check_reloc;
+ case (int) R_M32R_SDA16_RELA:
case (int) R_M32R_SDA16 :
{
const char *name;
@@ -3125,11 +3195,11 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
else
{
(*_bfd_error_handler)
- (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
- bfd_archive_filename (input_bfd),
+ (_("%B: The target (%s) of an %s relocation is in the wrong section (%A)"),
+ input_bfd,
+ sec,
sym_name,
- m32r_elf_howto_table[(int) r_type].name,
- bfd_get_section_name (abfd, sec));
+ m32r_elf_howto_table[(int) r_type].name);
/*bfd_set_error (bfd_error_bad_value); ??? why? */
ret = FALSE;
continue;
@@ -3450,7 +3520,7 @@ printf("m32r_elf_finish_dynamic_sections()\n");
BFD_ASSERT (sgot != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
- dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
for (; dyncon < dynconend; dyncon++)
{
@@ -3481,10 +3551,7 @@ printf("m32r_elf_finish_dynamic_sections()\n");
case DT_PLTRELSZ:
s = htab->srelplt->output_section;
BFD_ASSERT (s != NULL);
- if (s->_cooked_size != 0)
- dyn.d_un.d_val = s->_cooked_size;
- else
- dyn.d_un.d_val = s->_raw_size;
+ dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
@@ -3501,10 +3568,7 @@ printf("m32r_elf_finish_dynamic_sections()\n");
if (htab->srelplt != NULL)
{
s = htab->srelplt->output_section;
- if (s->_cooked_size != 0)
- dyn.d_un.d_val -= s->_cooked_size;
- else
- dyn.d_un.d_val -= s->_raw_size;
+ dyn.d_un.d_val -= s->size;
}
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
@@ -3513,7 +3577,7 @@ printf("m32r_elf_finish_dynamic_sections()\n");
/* Fill in the first entry in the procedure linkage table. */
splt = htab->splt;
- if (splt && splt->_raw_size > 0)
+ if (splt && splt->size > 0)
{
if (info->shared)
{
@@ -3545,7 +3609,7 @@ printf("m32r_elf_finish_dynamic_sections()\n");
}
/* Fill in the first three entries in the global offset table. */
- if (sgot && sgot->_raw_size > 0)
+ if (sgot && sgot->size > 0)
{
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
@@ -3615,11 +3679,6 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
|| 0 /* FIXME: check SHF_M32R_CAN_RELAX */)
return TRUE;
- /* If this is the first time we have been called for this section,
- initialize the cooked size. */
- if (sec->_cooked_size == 0)
- sec->_cooked_size = sec->_raw_size;
-
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Get a copy of the native relocations. */
@@ -3649,12 +3708,7 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
else
{
/* Go get them off disk. */
- contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (contents == NULL)
- goto error_return;
-
- if (! bfd_get_section_contents (abfd, sec, contents,
- (file_ptr) 0, sec->_raw_size))
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
goto error_return;
}
}
@@ -3734,7 +3788,7 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
/* Do nothing if no room in the section for this to be what we're
looking for. */
- if (irel->r_offset > sec->_cooked_size - 8)
+ if (irel->r_offset > sec->size - 8)
continue;
/* Make sure the next relocation applies to the next
@@ -3776,7 +3830,7 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
if (pcrel_value >= -(1 << 25) && pcrel_value < (1 << 25) + 4
/* Do nothing if no room in the section for this to be what we're
looking for. */
- && (irel->r_offset <= sec->_cooked_size - 12)
+ && (irel->r_offset <= sec->size - 12)
/* Ensure the next insn is "jl rN". */
&& ((code = bfd_get_16 (abfd, contents + irel->r_offset + 8)),
code != (0x1ec0 | reg)))
@@ -3943,14 +3997,14 @@ m32r_elf_relax_delete_bytes (abfd, sec, addr, count)
power larger than the number of bytes we are deleting. */
irelalign = NULL;
- toaddr = sec->_cooked_size;
+ toaddr = sec->size;
irel = elf_section_data (sec)->relocs;
irelend = irel + sec->reloc_count;
/* Actually delete the bytes. */
memmove (contents + addr, contents + addr + count, toaddr - addr - count);
- sec->_cooked_size -= count;
+ sec->size -= count;
/* Adjust all the relocs. */
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
@@ -4027,7 +4081,7 @@ m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
- input_section->_raw_size);
+ input_section->size);
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
@@ -4208,8 +4262,7 @@ m32r_elf_merge_private_bfd_data (ibfd, obfd)
|| ((in_flags & EF_M32R_ARCH) == E_M32R2_ARCH))
{
(*_bfd_error_handler)
- (_("%s: Instruction set mismatch with previous modules"),
- bfd_archive_filename (ibfd));
+ (_("%B: Instruction set mismatch with previous modules"), ibfd);
bfd_set_error (bfd_error_bad_value);
return FALSE;
@@ -4313,6 +4366,10 @@ m32r_elf_gc_sweep_hook (abfd, info, sec, relocs)
case R_M32R_GOT16_HI_ULO:
case R_M32R_GOT16_HI_SLO:
case R_M32R_GOT16_LO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
case R_M32R_GOT24:
case R_M32R_GOTPC_HI_ULO:
case R_M32R_GOTPC_HI_SLO:
@@ -4442,6 +4499,10 @@ m32r_elf_check_relocs (abfd, info, sec, relocs)
{
case R_M32R_GOT16_HI_ULO:
case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
case R_M32R_GOT16_LO:
case R_M32R_GOTPC24:
case R_M32R_GOTPC_HI_ULO: