mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
Add MN10300 linker relaxation support for symbol differences
This commit is contained in:
parent
97030eea00
commit
bfff164249
@ -1,3 +1,22 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config.bfd: Recognise am34-linux-gnu target.
|
||||
* reloc.c: Add BFD_RELOC_MN10300_SYM_DIFF relocation.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* libbfd.h: Regenerate.
|
||||
* elf-m10300.c (elf_mn10300_howto): Add R_MN10300_SYM_DIFF.
|
||||
(mn10300_reloc_map): Likewise.
|
||||
(mn10300_elf_check_relocs): Do not create dynamic relocs for
|
||||
symbol differences or relocations against absolute symbols.
|
||||
(mn10300_elf_final_link_relocate): Likewise.
|
||||
Handle R_MN10300_SYM_DIFF relocs.
|
||||
(mn10300_elf_relocate_section): Fix for creating local copys of
|
||||
dynamic relocs.
|
||||
(mn10300_elf_relax_delete_bytes): Adjust symbols at the end of the
|
||||
region. Adjust the size of function symbols.
|
||||
(mn10300_elf_relax_section): Ignore symbols that are in discarded
|
||||
sections.
|
||||
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* elf-m10300.c: Convert to ISO C.
|
||||
|
@ -2774,6 +2774,11 @@ in the instruction. */
|
||||
/* Adjust by program base. */
|
||||
BFD_RELOC_MN10300_RELATIVE,
|
||||
|
||||
/* Together with another reloc targeted at the same location,
|
||||
allows for a value that is the difference of two symbols
|
||||
in the same section. */
|
||||
BFD_RELOC_MN10300_SYM_DIFF,
|
||||
|
||||
|
||||
/* i386/elf relocations */
|
||||
BFD_RELOC_386_GOT32,
|
||||
|
@ -71,6 +71,7 @@ esac
|
||||
targ_cpu=`echo $targ | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
case "${targ_cpu}" in
|
||||
alpha*) targ_archs=bfd_alpha_arch ;;
|
||||
am34*|am33_2.0*) targ_archs=bfd_mn10300_arch ;;
|
||||
arm*) targ_archs=bfd_arm_arch ;;
|
||||
bfin*) targ_archs=bfd_bfin_arch ;;
|
||||
c30*) targ_archs=bfd_tic30_arch ;;
|
||||
@ -107,7 +108,6 @@ xscale*) targ_archs=bfd_arm_arch ;;
|
||||
xtensa*) targ_archs=bfd_xtensa_arch ;;
|
||||
z80|r800) targ_archs=bfd_z80_arch ;;
|
||||
z8k*) targ_archs=bfd_z8k_arch ;;
|
||||
am33_2.0) targ_archs=bfd_mn10300_arch ;;
|
||||
*) targ_archs=bfd_${targ_cpu}_arch ;;
|
||||
esac
|
||||
|
||||
@ -197,9 +197,10 @@ case "${targ}" in
|
||||
;;
|
||||
#endif /* BFD64 */
|
||||
|
||||
am33_2.0-*-linux*)
|
||||
am34-*-linux* | am33_2.0-*-linux*)
|
||||
targ_defvec=bfd_elf32_am33lin_vec
|
||||
;;
|
||||
|
||||
arc-*-elf*)
|
||||
targ_defvec=bfd_elf32_littlearc_vec
|
||||
targ_selvecs=bfd_elf32_bigarc_vec
|
||||
|
238
bfd/elf-m10300.c
238
bfd/elf-m10300.c
@ -446,6 +446,30 @@ static reloc_howto_type elf_mn10300_howto_table[] =
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
EMPTY_HOWTO (24),
|
||||
EMPTY_HOWTO (25),
|
||||
EMPTY_HOWTO (26),
|
||||
EMPTY_HOWTO (27),
|
||||
EMPTY_HOWTO (28),
|
||||
EMPTY_HOWTO (29),
|
||||
EMPTY_HOWTO (30),
|
||||
EMPTY_HOWTO (31),
|
||||
EMPTY_HOWTO (32),
|
||||
|
||||
HOWTO (R_MN10300_SYM_DIFF, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont,/* complain_on_overflow */
|
||||
NULL, /* special handler. */
|
||||
"R_MN10300_SYM_DIFF", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE) /* pcrel_offset */
|
||||
};
|
||||
|
||||
struct mn10300_reloc_map
|
||||
@ -480,6 +504,7 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] =
|
||||
{ BFD_RELOC_MN10300_GLOB_DAT, R_MN10300_GLOB_DAT },
|
||||
{ BFD_RELOC_MN10300_JMP_SLOT, R_MN10300_JMP_SLOT },
|
||||
{ BFD_RELOC_MN10300_RELATIVE, R_MN10300_RELATIVE },
|
||||
{ BFD_RELOC_MN10300_SYM_DIFF, R_MN10300_SYM_DIFF }
|
||||
};
|
||||
|
||||
/* Create the GOT section. */
|
||||
@ -619,6 +644,7 @@ mn10300_elf_check_relocs (bfd *abfd,
|
||||
asection *sec,
|
||||
const Elf_Internal_Rela *relocs)
|
||||
{
|
||||
bfd_boolean sym_diff_reloc_seen;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
const Elf_Internal_Rela *rel;
|
||||
@ -642,6 +668,7 @@ mn10300_elf_check_relocs (bfd *abfd,
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
local_got_offsets = elf_local_got_offsets (abfd);
|
||||
rel_end = relocs + sec->reloc_count;
|
||||
sym_diff_reloc_seen = FALSE;
|
||||
|
||||
for (rel = relocs; rel < rel_end; rel++)
|
||||
{
|
||||
@ -814,53 +841,98 @@ mn10300_elf_check_relocs (bfd *abfd,
|
||||
h->non_got_ref = 1;
|
||||
break;
|
||||
|
||||
case R_MN10300_SYM_DIFF:
|
||||
sym_diff_reloc_seen = TRUE;
|
||||
break;
|
||||
|
||||
case R_MN10300_32:
|
||||
if (h != NULL)
|
||||
h->non_got_ref = 1;
|
||||
|
||||
/* If we are creating a shared library, then we need to copy
|
||||
the reloc into the shared library. */
|
||||
/* If we are creating a shared library, then we
|
||||
need to copy the reloc into the shared library. */
|
||||
if (info->shared
|
||||
&& (sec->flags & SEC_ALLOC) != 0)
|
||||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
/* Do not generate a dynamic reloc for a
|
||||
reloc associated with a SYM_DIFF operation. */
|
||||
&& ! sym_diff_reloc_seen)
|
||||
{
|
||||
/* When creating a shared object, we must copy these
|
||||
reloc types into the output file. We create a reloc
|
||||
section in dynobj and make room for this reloc. */
|
||||
if (sreloc == NULL)
|
||||
asection * sym_section = NULL;
|
||||
|
||||
/* Find the section containing the
|
||||
symbol involved in the relocation. */
|
||||
if (h == NULL)
|
||||
{
|
||||
const char * name;
|
||||
Elf_Internal_Sym * isymbuf;
|
||||
Elf_Internal_Sym * isym;
|
||||
|
||||
name = (bfd_elf_string_from_elf_section
|
||||
(abfd,
|
||||
elf_elfheader (abfd)->e_shstrndx,
|
||||
elf_section_data (sec)->rel_hdr.sh_name));
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
|
||||
BFD_ASSERT (CONST_STRNEQ (name, ".rela")
|
||||
&& streq (bfd_get_section_name (abfd, sec), name + 5));
|
||||
|
||||
sreloc = bfd_get_section_by_name (dynobj, name);
|
||||
if (sreloc == NULL)
|
||||
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||
if (isymbuf == NULL)
|
||||
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
|
||||
symtab_hdr->sh_info, 0,
|
||||
NULL, NULL, NULL);
|
||||
if (isymbuf)
|
||||
{
|
||||
flagword flags;
|
||||
|
||||
flags = (SEC_HAS_CONTENTS | SEC_READONLY
|
||||
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
|
||||
if ((sec->flags & SEC_ALLOC) != 0)
|
||||
flags |= SEC_ALLOC | SEC_LOAD;
|
||||
sreloc = bfd_make_section_with_flags (dynobj, name, flags);
|
||||
if (sreloc == NULL
|
||||
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
|
||||
return FALSE;
|
||||
isym = isymbuf + r_symndx;
|
||||
/* All we care about is whether this local symbol is absolute. */
|
||||
if (isym->st_shndx == SHN_ABS)
|
||||
sym_section = bfd_abs_section_ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
sym_section = h->root.u.def.section;
|
||||
}
|
||||
|
||||
sreloc->size += sizeof (Elf32_External_Rela);
|
||||
/* If the symbol is absolute then the relocation can
|
||||
be resolved during linking and there is no need for
|
||||
a dynamic reloc. */
|
||||
if (sym_section != bfd_abs_section_ptr)
|
||||
{
|
||||
/* When creating a shared object, we must copy these
|
||||
reloc types into the output file. We create a reloc
|
||||
section in dynobj and make room for this reloc. */
|
||||
if (sreloc == NULL)
|
||||
{
|
||||
const char * name;
|
||||
|
||||
name = (bfd_elf_string_from_elf_section
|
||||
(abfd,
|
||||
elf_elfheader (abfd)->e_shstrndx,
|
||||
elf_section_data (sec)->rel_hdr.sh_name));
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
|
||||
BFD_ASSERT (CONST_STRNEQ (name, ".rela")
|
||||
&& streq (bfd_get_section_name (abfd, sec), name + 5));
|
||||
|
||||
sreloc = bfd_get_section_by_name (dynobj, name);
|
||||
if (sreloc == NULL)
|
||||
{
|
||||
flagword flags;
|
||||
|
||||
flags = (SEC_HAS_CONTENTS | SEC_READONLY
|
||||
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
|
||||
if ((sec->flags & SEC_ALLOC) != 0)
|
||||
flags |= SEC_ALLOC | SEC_LOAD;
|
||||
sreloc = bfd_make_section_with_flags (dynobj, name, flags);
|
||||
if (sreloc == NULL
|
||||
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
sreloc->size += sizeof (Elf32_External_Rela);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELF32_R_TYPE (rel->r_info) != R_MN10300_SYM_DIFF)
|
||||
sym_diff_reloc_seen = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -904,6 +976,9 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
|
||||
asection *sym_sec ATTRIBUTE_UNUSED,
|
||||
int is_local ATTRIBUTE_UNUSED)
|
||||
{
|
||||
static asection * sym_diff_section;
|
||||
static bfd_vma sym_diff_value;
|
||||
bfd_boolean is_sym_diff_reloc;
|
||||
unsigned long r_type = howto->type;
|
||||
bfd_byte * hit_data = contents + offset;
|
||||
bfd * dynobj;
|
||||
@ -937,13 +1012,54 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
|
||||
return bfd_reloc_dangerous;
|
||||
}
|
||||
|
||||
is_sym_diff_reloc = FALSE;
|
||||
if (sym_diff_section != NULL)
|
||||
{
|
||||
BFD_ASSERT (sym_diff_section == input_section);
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_MN10300_32:
|
||||
case R_MN10300_24:
|
||||
case R_MN10300_16:
|
||||
case R_MN10300_8:
|
||||
value -= sym_diff_value;
|
||||
sym_diff_section = NULL;
|
||||
is_sym_diff_reloc = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
sym_diff_section = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_MN10300_SYM_DIFF:
|
||||
BFD_ASSERT (addend == 0);
|
||||
/* Cache the input section and value.
|
||||
The offset is unreliable, since relaxation may
|
||||
have reduced the following reloc's offset. */
|
||||
sym_diff_section = input_section;
|
||||
sym_diff_value = value;
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_MN10300_NONE:
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_MN10300_32:
|
||||
if (info->shared
|
||||
/* Do not generate relocs when an R_MN10300_32 has been used
|
||||
with an R_MN10300_SYM_DIFF to compute a difference of two
|
||||
symbols. */
|
||||
&& is_sym_diff_reloc == FALSE
|
||||
/* Also, do not generate a reloc when the symbol associated
|
||||
with the R_MN10300_32 reloc is absolute - there is no
|
||||
need for a run time computation in this case. */
|
||||
&& sym_sec != bfd_abs_section_ptr
|
||||
/* If the section is not going to be allocated at load time
|
||||
then there is no need to generate relocs for it. */
|
||||
&& (input_section->flags & SEC_ALLOC) != 0)
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
@ -1370,6 +1486,10 @@ mn10300_elf_relocate_section (bfd *output_bfd,
|
||||
&& elf_hash_table (info)->dynamic_sections_created
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, hh))
|
||||
|| (r_type == R_MN10300_32
|
||||
/* _32 relocs in executables force _COPY relocs,
|
||||
such that the address of the symbol ends up
|
||||
being local. */
|
||||
&& !info->executable
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, hh)
|
||||
&& ((input_section->flags & SEC_ALLOC) != 0
|
||||
/* DWARF will emit R_MN10300_32 relocations
|
||||
@ -1551,7 +1671,7 @@ static bfd_boolean
|
||||
elf32_mn10300_count_hash_table_entries (struct bfd_hash_entry *gen_entry ATTRIBUTE_UNUSED,
|
||||
void * in_args)
|
||||
{
|
||||
int *count = (int *)in_args;
|
||||
int *count = (int *) in_args;
|
||||
|
||||
(*count) ++;
|
||||
return TRUE;
|
||||
@ -1576,9 +1696,9 @@ static int
|
||||
sort_by_value (const void *va, const void *vb)
|
||||
{
|
||||
struct elf32_mn10300_link_hash_entry *a
|
||||
= *(struct elf32_mn10300_link_hash_entry **)va;
|
||||
= *(struct elf32_mn10300_link_hash_entry **) va;
|
||||
struct elf32_mn10300_link_hash_entry *b
|
||||
= *(struct elf32_mn10300_link_hash_entry **)vb;
|
||||
= *(struct elf32_mn10300_link_hash_entry **) vb;
|
||||
|
||||
return a->value - b->value;
|
||||
}
|
||||
@ -1735,8 +1855,14 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
|
||||
{
|
||||
if (isym->st_shndx == sec_shndx
|
||||
&& isym->st_value > addr
|
||||
&& isym->st_value < toaddr)
|
||||
&& isym->st_value <= toaddr)
|
||||
isym->st_value -= count;
|
||||
/* Adjust the function symbol's size as well. */
|
||||
else if (isym->st_shndx == sec_shndx
|
||||
&& ELF_ST_TYPE (isym->st_info) == STT_FUNC
|
||||
&& isym->st_value + isym->st_size > addr
|
||||
&& isym->st_value + isym->st_size <= toaddr)
|
||||
isym->st_size -= count;
|
||||
}
|
||||
|
||||
/* Now adjust the global symbols defined in this section. */
|
||||
@ -1752,8 +1878,15 @@ mn10300_elf_relax_delete_bytes (bfd *abfd,
|
||||
|| sym_hash->root.type == bfd_link_hash_defweak)
|
||||
&& sym_hash->root.u.def.section == sec
|
||||
&& sym_hash->root.u.def.value > addr
|
||||
&& sym_hash->root.u.def.value < toaddr)
|
||||
&& sym_hash->root.u.def.value <= toaddr)
|
||||
sym_hash->root.u.def.value -= count;
|
||||
/* Adjust the function symbol's size as well. */
|
||||
else if (sym_hash->root.type == bfd_link_hash_defined
|
||||
&& sym_hash->root.u.def.section == sec
|
||||
&& sym_hash->type == STT_FUNC
|
||||
&& sym_hash->root.u.def.value + sym_hash->size > addr
|
||||
&& sym_hash->root.u.def.value + sym_hash->size <= toaddr)
|
||||
sym_hash->size -= count;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1981,7 +2114,7 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
local symbol in the global hash table. */
|
||||
amt = strlen (sym_name) + 10;
|
||||
new_name = bfd_malloc (amt);
|
||||
if (new_name == 0)
|
||||
if (new_name == NULL)
|
||||
goto error_return;
|
||||
|
||||
sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
|
||||
@ -2090,7 +2223,7 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
local symbol in the global hash table. */
|
||||
amt = strlen (sym_name) + 10;
|
||||
new_name = bfd_malloc (amt);
|
||||
if (new_name == 0)
|
||||
if (new_name == NULL)
|
||||
goto error_return;
|
||||
|
||||
sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
|
||||
@ -2302,7 +2435,7 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
local symbol in the global hash table. */
|
||||
amt = strlen (sym_name) + 10;
|
||||
new_name = bfd_malloc (amt);
|
||||
if (new_name == 0)
|
||||
if (new_name == NULL)
|
||||
goto error_return;
|
||||
sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
|
||||
sym_name = new_name;
|
||||
@ -2514,7 +2647,6 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
asection *sym_sec = NULL;
|
||||
const char *sym_name;
|
||||
char *new_name;
|
||||
bfd_vma saved_addend;
|
||||
|
||||
/* A local symbol. */
|
||||
isym = isymbuf + ELF32_R_SYM (irel->r_info);
|
||||
@ -2535,22 +2667,22 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
&& ELF_ST_TYPE (isym->st_info) == STT_SECTION
|
||||
&& sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
|
||||
{
|
||||
bfd_vma saved_addend;
|
||||
|
||||
saved_addend = irel->r_addend;
|
||||
symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
|
||||
symval = _bfd_elf_rela_local_sym (abfd, isym, & sym_sec, irel);
|
||||
symval += irel->r_addend;
|
||||
irel->r_addend = saved_addend;
|
||||
}
|
||||
else
|
||||
{
|
||||
symval = (isym->st_value
|
||||
+ sym_sec->output_section->vma
|
||||
+ sym_sec->output_offset);
|
||||
}
|
||||
symval = (isym->st_value
|
||||
+ sym_sec->output_section->vma
|
||||
+ sym_sec->output_offset);
|
||||
|
||||
/* Tack on an ID so we can uniquely identify this
|
||||
local symbol in the global hash table. */
|
||||
new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
|
||||
if (new_name == 0)
|
||||
if (new_name == NULL)
|
||||
goto error_return;
|
||||
sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
|
||||
sym_name = new_name;
|
||||
@ -2576,6 +2708,10 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
regular reloc processing. */
|
||||
continue;
|
||||
|
||||
/* Check for a reference to a discarded symbol and ignore it. */
|
||||
if (h->root.root.u.def.section->output_section == NULL)
|
||||
continue;
|
||||
|
||||
symval = (h->root.root.u.def.value
|
||||
+ h->root.root.u.def.section->output_section->vma
|
||||
+ h->root.root.u.def.section->output_offset);
|
||||
@ -3284,7 +3420,7 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
case 0x93:
|
||||
/* sp-based offsets are zero-extended. */
|
||||
if (code >= 0x90 && code <= 0x93
|
||||
&& (long)value < 0)
|
||||
&& (long) value < 0)
|
||||
continue;
|
||||
|
||||
/* Note that we've changed the relocation contents, etc. */
|
||||
@ -3341,7 +3477,7 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
|
||||
/* mov imm16, an zero-extends the immediate. */
|
||||
if (code == 0xdc
|
||||
&& (long)value < 0)
|
||||
&& (long) value < 0)
|
||||
continue;
|
||||
|
||||
/* Note that we've changed the relocation contents, etc. */
|
||||
@ -3422,12 +3558,12 @@ mn10300_elf_relax_section (bfd *abfd,
|
||||
case 0xe3:
|
||||
/* cmp imm16, an zero-extends the immediate. */
|
||||
if (code == 0xdc
|
||||
&& (long)value < 0)
|
||||
&& (long) value < 0)
|
||||
continue;
|
||||
|
||||
/* So do sp-based offsets. */
|
||||
if (code >= 0xb0 && code <= 0xb3
|
||||
&& (long)value < 0)
|
||||
&& (long) value < 0)
|
||||
continue;
|
||||
|
||||
/* Note that we've changed the relocation contents, etc. */
|
||||
|
@ -1046,6 +1046,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_MN10300_GLOB_DAT",
|
||||
"BFD_RELOC_MN10300_JMP_SLOT",
|
||||
"BFD_RELOC_MN10300_RELATIVE",
|
||||
"BFD_RELOC_MN10300_SYM_DIFF",
|
||||
|
||||
"BFD_RELOC_386_GOT32",
|
||||
"BFD_RELOC_386_PLT32",
|
||||
|
@ -2361,6 +2361,12 @@ ENUM
|
||||
BFD_RELOC_MN10300_RELATIVE
|
||||
ENUMDOC
|
||||
Adjust by program base.
|
||||
ENUM
|
||||
BFD_RELOC_MN10300_SYM_DIFF
|
||||
ENUMDOC
|
||||
Together with another reloc targeted at the same location,
|
||||
allows for a value that is the difference of two symbols
|
||||
in the same section.
|
||||
COMMENT
|
||||
|
||||
ENUM
|
||||
|
@ -1,3 +1,24 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* expr.c (expr): Test md_allow_local_subtract (if defined) before
|
||||
allowing the evaluation of an expression involving two symbols
|
||||
defined in the same section.
|
||||
* doc/internals.texi (md_allow_local_subtract): Document the new
|
||||
macro.
|
||||
* config/tc-mn10300.h (md_allow_local_subtract): Define.
|
||||
(RELAX_EXPANSION_POSSIBLE): Define.
|
||||
(MAX_RELOC_EXPANSION): Define.
|
||||
(TC_FRAG_TYPE): Define.
|
||||
* config/tc-mn10300.c (md_assemble): Mark fragments as containing code.
|
||||
(tc_gen_reloc): Return an array of relocs. If necessary generate
|
||||
two relocs to handle an expressions involving the difference of
|
||||
two symbols.
|
||||
(mn10300_fix_adjustable): Do not test TC_FORCE_RELOCATION_LOCAL
|
||||
when then fixup is not pc-relative.
|
||||
(mn10300_allow_local_subtract): New function. Determine when it
|
||||
is safe to compute the difference between two symbols at assemble
|
||||
time.
|
||||
|
||||
2007-10-19 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/tc-ppc.c (ppc_parse_name): Skip leading '%'.
|
||||
|
@ -2141,15 +2141,21 @@ keep_going:
|
||||
|
||||
dwarf2_emit_insn (size);
|
||||
}
|
||||
|
||||
/* Label this frag as one that contains instructions. */
|
||||
frag_now->tc_frag_data = TRUE;
|
||||
}
|
||||
|
||||
/* If while processing a fixup, a reloc really needs to be created
|
||||
then it is done here. */
|
||||
|
||||
arelent *
|
||||
arelent **
|
||||
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
{
|
||||
static arelent * no_relocs = NULL;
|
||||
static arelent * relocs[MAX_RELOC_EXPANSION + 1];
|
||||
arelent *reloc;
|
||||
|
||||
reloc = xmalloc (sizeof (arelent));
|
||||
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
|
||||
@ -2158,9 +2164,13 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||
_("reloc %d not supported by object file format"),
|
||||
(int) fixp->fx_r_type);
|
||||
return NULL;
|
||||
free (reloc);
|
||||
return & no_relocs;
|
||||
}
|
||||
|
||||
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
|
||||
relocs[0] = reloc;
|
||||
relocs[1] = NULL;
|
||||
|
||||
if (fixp->fx_subsy
|
||||
&& S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
|
||||
@ -2173,44 +2183,33 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
{
|
||||
reloc->sym_ptr_ptr = NULL;
|
||||
|
||||
/* If we got a difference between two symbols, and the
|
||||
subtracted symbol is in the current section, use a
|
||||
PC-relative relocation. If both symbols are in the same
|
||||
section, the difference would have already been simplified
|
||||
to a constant. */
|
||||
/* If we have a difference between two (non-absolute) symbols we must
|
||||
generate two relocs (one for each symbol) and allow the linker to
|
||||
resolve them - relaxation may change the distances between symbols,
|
||||
even local symbols defined in the same segment. */
|
||||
if (S_GET_SEGMENT (fixp->fx_subsy) == seg)
|
||||
{
|
||||
arelent * reloc2 = xmalloc (sizeof * reloc);
|
||||
|
||||
relocs[0] = reloc2;
|
||||
relocs[1] = reloc;
|
||||
|
||||
reloc2->address = reloc->address;
|
||||
reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_MN10300_SYM_DIFF);
|
||||
reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
|
||||
reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
||||
*reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
|
||||
|
||||
reloc->addend = fixp->fx_offset;
|
||||
if (S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
|
||||
reloc->addend += S_GET_VALUE (fixp->fx_addsy);
|
||||
|
||||
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
||||
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
|
||||
reloc->addend = (reloc->address - S_GET_VALUE (fixp->fx_subsy)
|
||||
+ fixp->fx_offset);
|
||||
|
||||
switch (fixp->fx_r_type)
|
||||
{
|
||||
case BFD_RELOC_8:
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput,
|
||||
BFD_RELOC_8_PCREL);
|
||||
return reloc;
|
||||
|
||||
case BFD_RELOC_16:
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput,
|
||||
BFD_RELOC_16_PCREL);
|
||||
return reloc;
|
||||
|
||||
case BFD_RELOC_24:
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput,
|
||||
BFD_RELOC_24_PCREL);
|
||||
return reloc;
|
||||
|
||||
case BFD_RELOC_32:
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput,
|
||||
BFD_RELOC_32_PCREL);
|
||||
return reloc;
|
||||
|
||||
default:
|
||||
/* Try to compute the absolute value below. */
|
||||
break;
|
||||
}
|
||||
fixp->fx_pcrel = 0;
|
||||
fixp->fx_done = 1;
|
||||
return relocs;
|
||||
}
|
||||
|
||||
if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
|
||||
@ -2247,14 +2246,14 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
default:
|
||||
reloc->sym_ptr_ptr
|
||||
= (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
|
||||
return reloc;
|
||||
return relocs;
|
||||
}
|
||||
}
|
||||
|
||||
if (reloc->sym_ptr_ptr)
|
||||
free (reloc->sym_ptr_ptr);
|
||||
free (reloc);
|
||||
return NULL;
|
||||
return & no_relocs;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2262,7 +2261,7 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
|
||||
reloc->addend = fixp->fx_offset;
|
||||
}
|
||||
return reloc;
|
||||
return relocs;
|
||||
}
|
||||
|
||||
int
|
||||
@ -2377,11 +2376,14 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
|
||||
bfd_boolean
|
||||
mn10300_fix_adjustable (struct fix *fixp)
|
||||
{
|
||||
if (TC_FORCE_RELOCATION_LOCAL (fixp))
|
||||
return FALSE;
|
||||
|
||||
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
||||
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
||||
if (fixp->fx_pcrel)
|
||||
{
|
||||
if (TC_FORCE_RELOCATION_LOCAL (fixp))
|
||||
return FALSE;
|
||||
}
|
||||
/* Non-relative relocs can (and must) be adjusted if they do
|
||||
not meet the criteria below, or the generic criteria. */
|
||||
else if (TC_FORCE_RELOCATION (fixp))
|
||||
return FALSE;
|
||||
|
||||
/* Do not adjust relocations involving symbols in code sections,
|
||||
@ -2395,8 +2397,9 @@ mn10300_fix_adjustable (struct fix *fixp)
|
||||
symbols, because they too break relaxation. We do want to adjust
|
||||
other mergable symbols, like .rodata, because code relaxations
|
||||
need section-relative symbols to properly relax them. */
|
||||
if (! (S_GET_SEGMENT(fixp->fx_addsy)->flags & SEC_MERGE))
|
||||
if (! (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
|
||||
return FALSE;
|
||||
|
||||
if (strncmp (S_GET_SEGMENT (fixp->fx_addsy)->name, ".debug", 6) == 0)
|
||||
return FALSE;
|
||||
|
||||
@ -2502,3 +2505,60 @@ const pseudo_typeS md_pseudo_table[] =
|
||||
{ "mn10300", set_arch_mach, MN103 },
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
/* Returns FALSE if there is some mn10300 specific reason why the
|
||||
subtraction of two same-section symbols cannot be computed by
|
||||
the assembler. */
|
||||
|
||||
bfd_boolean
|
||||
mn10300_allow_local_subtract (expressionS * left, expressionS * right, segT section)
|
||||
{
|
||||
bfd_boolean result;
|
||||
fragS * left_frag;
|
||||
fragS * right_frag;
|
||||
fragS * frag;
|
||||
|
||||
/* If we are not performing linker relaxation then we have nothing
|
||||
to worry about. */
|
||||
if (linkrelax == 0)
|
||||
return TRUE;
|
||||
|
||||
/* If the symbols are not in a code section then they are OK. */
|
||||
if ((section->flags & SEC_CODE) == 0)
|
||||
return TRUE;
|
||||
|
||||
/* Otherwise we have to scan the fragments between the two symbols.
|
||||
If any instructions are found then we have to assume that linker
|
||||
relaxation may change their size and so we must delay resolving
|
||||
the subtraction until the final link. */
|
||||
left_frag = symbol_get_frag (left->X_add_symbol);
|
||||
right_frag = symbol_get_frag (right->X_add_symbol);
|
||||
|
||||
if (left_frag == right_frag)
|
||||
return ! left_frag->tc_frag_data;
|
||||
|
||||
result = TRUE;
|
||||
for (frag = left_frag; frag != NULL; frag = frag->fr_next)
|
||||
{
|
||||
if (frag->tc_frag_data)
|
||||
result = FALSE;
|
||||
if (frag == right_frag)
|
||||
break;
|
||||
}
|
||||
|
||||
if (frag == NULL)
|
||||
for (frag = right_frag; frag != NULL; frag = frag->fr_next)
|
||||
{
|
||||
if (frag->tc_frag_data)
|
||||
result = FALSE;
|
||||
if (frag == left_frag)
|
||||
break;
|
||||
}
|
||||
|
||||
if (frag == NULL)
|
||||
/* The two symbols are on disjoint fragment chains
|
||||
- we cannot possibly compute their difference. */
|
||||
return FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -98,13 +98,21 @@ void mn10300_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
|
||||
|
||||
#define md_number_to_chars number_to_chars_littleendian
|
||||
|
||||
/* Don't bother to adjust relocs. */
|
||||
/* #define tc_fix_adjustable(FIX) 0 */
|
||||
#define tc_fix_adjustable(FIX) mn10300_fix_adjustable (FIX)
|
||||
extern bfd_boolean mn10300_fix_adjustable PARAMS ((struct fix *));
|
||||
extern bfd_boolean mn10300_fix_adjustable (struct fix *);
|
||||
|
||||
/* We do relaxing in the assembler as well as the linker. */
|
||||
extern const struct relax_type md_relax_table[];
|
||||
#define TC_GENERIC_RELAX_TABLE md_relax_table
|
||||
|
||||
#define DWARF2_LINE_MIN_INSN_LENGTH 1
|
||||
|
||||
/* The difference between same-section symbols may be affected by linker
|
||||
relaxation, so do not resolve such expressions in the assembler. */
|
||||
#define md_allow_local_subtract(l,r,s) mn10300_allow_local_subtract (l, r, s)
|
||||
extern bfd_boolean mn10300_allow_local_subtract (expressionS *, expressionS *, segT);
|
||||
|
||||
#define RELOC_EXPANSION_POSSIBLE
|
||||
#define MAX_RELOC_EXPANSION 2
|
||||
|
||||
#define TC_FRAG_TYPE bfd_boolean
|
||||
|
@ -1535,6 +1535,18 @@ The function should return the debug format that is preferred by the CPU
|
||||
backend. This format will be used when generating assembler specific debug
|
||||
information.
|
||||
|
||||
@item md_allow_local_subtract (@var{left}, @var{right}, @var{section})
|
||||
If defined, GAS will call this macro when evaluating an expression which is the
|
||||
difference of two symbols defined in the same section. It takes three
|
||||
arguments: @code{expressioS * @var{left}} which is the symbolic expression on
|
||||
the left hand side of the subtraction operation, @code{expressionS *
|
||||
@var{right}} which is the symbolic expression on the right hand side of the
|
||||
subtraction, and @code{segT @var{section}} which is the section containing the two
|
||||
symbols. The macro should return a non-zero value if the expression should be
|
||||
evaluated. Targets which implement link time relaxation which may change the
|
||||
position of the two symbols relative to each other should ensure that this
|
||||
macro returns zero in situations where this can occur.
|
||||
|
||||
@end table
|
||||
|
||||
@node Object format backend
|
||||
|
@ -1738,6 +1738,9 @@ expr (int rankarg, /* Larger # is higher rank. */
|
||||
&& right.X_op == O_symbol
|
||||
&& resultP->X_op == O_symbol
|
||||
&& retval == rightseg
|
||||
#ifdef md_allow_local_subtract
|
||||
&& md_allow_local_subtract (resultP, & right, rightseg)
|
||||
#endif
|
||||
&& (SEG_NORMAL (rightseg)
|
||||
|| right.X_add_symbol == resultP->X_add_symbol)
|
||||
&& frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol),
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* gas/mn10300/basic.exp: Run pr997 test.
|
||||
* gas/mn10300/pr997.s: New test.
|
||||
* gas/mn10300/pr887.l: Expected output.
|
||||
|
||||
2007-10-17 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* gas/m68k/mcf-movsr.s: New.
|
||||
|
@ -1801,6 +1801,7 @@ if [istarget mn10300*-*-*] then {
|
||||
do_am33_8
|
||||
|
||||
run_list_test "movpc" ""
|
||||
run_list_test "pr997" "-a"
|
||||
|
||||
run_dump_test "am33-2"
|
||||
run_dump_test "relax"
|
||||
|
20
gas/testsuite/gas/mn10300/pr997.l
Normal file
20
gas/testsuite/gas/mn10300/pr997.l
Normal file
@ -0,0 +1,20 @@
|
||||
GAS LISTING .*/pr997.s.*page 1
|
||||
|
||||
|
||||
1.*.data
|
||||
2.*
|
||||
3 0000 68656C6C.*msg:.*.asciz "hello world.\\n"
|
||||
3 6F20776F
|
||||
3 726C642E
|
||||
3 0A00
|
||||
4.*msglen = .-msg-1
|
||||
5.*msglen=msglen & 0xff
|
||||
|
||||
.*GAS LISTING.*/pr997.s.*page 2
|
||||
|
||||
|
||||
DEFINED SYMBOLS
|
||||
.*/pr997.s:3.*.data:0+00 msg
|
||||
.*/pr997.s:4.*\*ABS\*:0+0d msglen
|
||||
|
||||
NO UNDEFINED SYMBOLS
|
5
gas/testsuite/gas/mn10300/pr997.s
Normal file
5
gas/testsuite/gas/mn10300/pr997.s
Normal file
@ -0,0 +1,5 @@
|
||||
.data
|
||||
|
||||
msg: .asciz "hello world.\n"
|
||||
msglen = .-msg-1
|
||||
msglen=msglen & 0xff
|
@ -1,3 +1,7 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* mn10300.h: Add R_MN10300_SYM_DIFF reloc.
|
||||
|
||||
2007-10-18 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* common.h (NT_PPC_VMX): New macro.
|
||||
|
@ -50,6 +50,7 @@ START_RELOC_NUMBERS (elf_mn10300_reloc_type)
|
||||
RELOC_NUMBER (R_MN10300_GLOB_DAT, 21)
|
||||
RELOC_NUMBER (R_MN10300_JMP_SLOT, 22)
|
||||
RELOC_NUMBER (R_MN10300_RELATIVE, 23)
|
||||
RELOC_NUMBER (R_MN10300_SYM_DIFF, 33)
|
||||
END_RELOC_NUMBERS (R_MN10300_MAX)
|
||||
|
||||
/* Machine variant if we know it. This field was invented at Cygnus,
|
||||
|
@ -1,3 +1,7 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* configure.tgt: Add support for am34-linux-gnu target.
|
||||
|
||||
2007-10-17 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* ldlang.c (lang_check_section_addresses): Also report size of
|
||||
|
@ -400,6 +400,7 @@ mips*-*-sysv4*) targ_emul=elf32btsmip
|
||||
mmix-*-*) targ_emul=mmo
|
||||
targ_extra_emuls=elf64mmix
|
||||
;;
|
||||
am34-*-linux*) targ_emul=elf32am33lin ;;
|
||||
am33_2.0-*-linux*) targ_emul=elf32am33lin ;;
|
||||
mn10200-*-*) targ_emul=mn10200 ;;
|
||||
mn10300-*-*) targ_emul=mn10300
|
||||
|
@ -1,3 +1,19 @@
|
||||
2007-10-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* ld-mn10300: New test directory.
|
||||
* ld-mn10300/mn10300.exp: Run the new tests.
|
||||
* ld-mn10300/i112045-1.s: Linker relaxation test.
|
||||
* ld-mn10300/i112045-1.d: Expected disassembly.
|
||||
* ld-mn10300/i112045-2.s: Linker relaxation test.
|
||||
* ld-mn10300/i112045-2.d: Expected disassembly.
|
||||
* ld-mn10300/i126256-1.c: Test source.
|
||||
* ld-mn10300/i126256-2.c: Test source.
|
||||
* ld-mn10300/i135409.s: Linker relaxation test.
|
||||
* ld-mn10300/i135409.d: Expected symbol table contents.
|
||||
* ld-mn10300/i136434.s: Linker string section merge test.
|
||||
* ld-mn10300/i136434.d: Expected disassembly.
|
||||
* ld-mn10300/i136434-2.s: Test source file.
|
||||
|
||||
2007-10-17 Zack Weinberg <zack@codesourcery.com>
|
||||
Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Mark Shinwell <shinwell@codesourcery.com>
|
||||
|
22
ld/testsuite/ld-mn10300/i112045-1.d
Normal file
22
ld/testsuite/ld-mn10300/i112045-1.d
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
tmpdir/i112045-1.x: file format elf32-.*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+0 <_start>:
|
||||
0: fc d0 f8 0f[ ]+add 4088,a0
|
||||
4: 00 00
|
||||
6: cb[ ]+nop[ ]+
|
||||
7: cb[ ]+nop[ ]+
|
||||
|
||||
0+08 <L01>:
|
||||
8: fc d0 2b 01[ ]+add 299,a0
|
||||
c: 00 00
|
||||
e: cb[ ]+nop[ ]+
|
||||
f: cb[ ]+nop[ ]+
|
||||
|
||||
0+010 <L02>:
|
||||
10: fc d0 08 00[ ]+add 8,a0
|
||||
14: 00 00
|
||||
16: cb[ ]+nop[ ]+
|
||||
17: cb[ ]+nop[ ]+
|
14
ld/testsuite/ld-mn10300/i112045-1.s
Normal file
14
ld/testsuite/ld-mn10300/i112045-1.s
Normal file
@ -0,0 +1,14 @@
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
add 0x1000 - L01, A0
|
||||
nop
|
||||
nop
|
||||
L01:
|
||||
add L01 + 0x123, A0
|
||||
nop
|
||||
nop
|
||||
L02:
|
||||
add L02 - L01, A0
|
||||
nop
|
||||
nop
|
6
ld/testsuite/ld-mn10300/i112045-2.d
Normal file
6
ld/testsuite/ld-mn10300/i112045-2.d
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
tmpdir/i112045-2.x: file format elf32-.*
|
||||
|
||||
DYNAMIC RELOCATION RECORDS
|
||||
OFFSET TYPE VALUE
|
||||
[0-9a-f]+ R_MN10300_RELATIVE \*ABS\*\+0x[0-9a-f]+
|
12
ld/testsuite/ld-mn10300/i112045-2.s
Normal file
12
ld/testsuite/ld-mn10300/i112045-2.s
Normal file
@ -0,0 +1,12 @@
|
||||
.section .data
|
||||
L01:
|
||||
.long L04 - L01
|
||||
L02:
|
||||
.long L04 - L02
|
||||
L03:
|
||||
.long L04 - L03
|
||||
L04:
|
||||
.long L04
|
||||
.long L00
|
||||
.equ L00, 0xff
|
||||
|
7
ld/testsuite/ld-mn10300/i126256-1.c
Normal file
7
ld/testsuite/ld-mn10300/i126256-1.c
Normal file
@ -0,0 +1,7 @@
|
||||
void
|
||||
sub0 (int i)
|
||||
{
|
||||
extern int sub (int);
|
||||
|
||||
sub (i);
|
||||
}
|
5
ld/testsuite/ld-mn10300/i126256-2.c
Normal file
5
ld/testsuite/ld-mn10300/i126256-2.c
Normal file
@ -0,0 +1,5 @@
|
||||
int
|
||||
sub (int i)
|
||||
{
|
||||
return i + 10;
|
||||
}
|
11
ld/testsuite/ld-mn10300/i135409.d
Normal file
11
ld/testsuite/ld-mn10300/i135409.d
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
Symbol table '.symtab' contains .. entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
#...
|
||||
..: 0[0-9a-f]+[ ]+7 FUNC LOCAL DEFAULT . _func
|
||||
#...
|
||||
..: 0[0-9a-f]+[ ]+0 NOTYPE LOCAL DEFAULT . A
|
||||
..: 0[0-9a-f]+[ ]+7 FUNC GLOBAL DEFAULT . _func2
|
||||
#...
|
||||
..: 0[0-9a-f]+[ ]+0 NOTYPE GLOBAL DEFAULT . BOTTOM
|
||||
#...
|
29
ld/testsuite/ld-mn10300/i135409.s
Normal file
29
ld/testsuite/ld-mn10300/i135409.s
Normal file
@ -0,0 +1,29 @@
|
||||
.text
|
||||
|
||||
nop
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
.type _func, @function
|
||||
_func:
|
||||
mov L001,A1
|
||||
nop
|
||||
A:
|
||||
mov L001,A1
|
||||
.size _func, . - _func
|
||||
|
||||
|
||||
.global _func2
|
||||
_func2:
|
||||
.type _func2, @function
|
||||
mov L001,A1
|
||||
nop
|
||||
mov L001,A1
|
||||
.size _func2, . - _func2
|
||||
|
||||
.global BOTTOM
|
||||
BOTTOM:
|
||||
|
||||
.data
|
||||
L001:
|
||||
|
16
ld/testsuite/ld-mn10300/i36434-2.s
Normal file
16
ld/testsuite/ld-mn10300/i36434-2.s
Normal file
@ -0,0 +1,16 @@
|
||||
.section .text
|
||||
.global _bar
|
||||
.type _bar,@function
|
||||
_bar:
|
||||
mov .LC1,d0
|
||||
mov .LC2,d1
|
||||
nop
|
||||
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.LC1:
|
||||
.rept 32768
|
||||
.byte 'a'
|
||||
.endr
|
||||
.byte 0
|
||||
.LC2:
|
||||
.string "abc\n"
|
16
ld/testsuite/ld-mn10300/i36434.d
Normal file
16
ld/testsuite/ld-mn10300/i36434.d
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
tmpdir/i36434.x: file format elf32-.*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
08000000 <_start>:
|
||||
8000000: fc cd 18 80 mov 134250520,d1
|
||||
8000004: 00 08
|
||||
8000006: cb nop
|
||||
|
||||
08000007 <_bar>:
|
||||
8000007: fc cc 14 00 mov 134217748,d0
|
||||
800000b: 00 08
|
||||
800000d: fc cd 15 80 mov 134250517,d1
|
||||
8000011: 00 08
|
||||
8000013: cb nop
|
10
ld/testsuite/ld-mn10300/i36434.s
Normal file
10
ld/testsuite/ld-mn10300/i36434.s
Normal file
@ -0,0 +1,10 @@
|
||||
.section .text
|
||||
.global _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
mov .LC2,d1
|
||||
nop
|
||||
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.LC2:
|
||||
.string "\n"
|
94
ld/testsuite/ld-mn10300/mn10300.exp
Normal file
94
ld/testsuite/ld-mn10300/mn10300.exp
Normal file
@ -0,0 +1,94 @@
|
||||
# Expect script for ld-mn10300 tests
|
||||
# Copyright (C) 2007 Free Software Foundation
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
if {!([istarget "am3*-*-*"]) && !([istarget "mn10300*-*-*"]) } {
|
||||
return
|
||||
}
|
||||
|
||||
# Set up a list as described in ld-lib.exp
|
||||
|
||||
set am33_tests {
|
||||
{
|
||||
"am33 string merging"
|
||||
"--relax -Ttext 0x8000000"
|
||||
""
|
||||
{ "i36434.s" "i36434-2.s" }
|
||||
{ {objdump -dz i36434.d} }
|
||||
"i36434.x"
|
||||
}
|
||||
{
|
||||
"difference of two symbols"
|
||||
"-Ttext 0"
|
||||
""
|
||||
{ "i112045-1.s" }
|
||||
{ {objdump -d i112045-1.d} }
|
||||
"i112045-1.x"
|
||||
}
|
||||
{
|
||||
"(shared) difference of two symbols"
|
||||
"-shared"
|
||||
""
|
||||
{ "i112045-2.s" }
|
||||
{ {objdump -R i112045-2.d} }
|
||||
"i112045-2.x"
|
||||
}
|
||||
{
|
||||
"adjustment of symbols due to relaxation"
|
||||
"-Tdata 1f -relax"
|
||||
""
|
||||
{ "i135409.s" }
|
||||
{ {readelf --syms i135409.d } }
|
||||
"i135409.x"
|
||||
}
|
||||
}
|
||||
|
||||
run_ld_link_tests $am33_tests
|
||||
|
||||
proc i126256-test { } {
|
||||
global CC
|
||||
global ld
|
||||
global srcdir
|
||||
global subdir
|
||||
|
||||
set tmpdir tmpdir
|
||||
set testname "Issue 126256 - seg fault whilst linking one shared library into another when relaxation is enabled."
|
||||
|
||||
if { ![ld_compile "$CC -mrelax -fPIC" $srcdir/$subdir/i126256-1.c $tmpdir/i126256-1.o] } {
|
||||
unresolved $testname
|
||||
return
|
||||
}
|
||||
|
||||
if { ![ld_compile "$CC -mrelax -fPIC" $srcdir/$subdir/i126256-2.c $tmpdir/i126256-2.o] } {
|
||||
unresolved $testname
|
||||
return
|
||||
}
|
||||
|
||||
if { ![ld_simple_link $ld $tmpdir/i126256-1.so "-shared $tmpdir/i126256-1.o -e 0"]} {
|
||||
unresolved $testname
|
||||
return
|
||||
}
|
||||
|
||||
if { ![ld_simple_link $ld $tmpdir/i126256-2.so "--relax -shared $tmpdir/i126256-2.o $tmpdir/i126256-1.so -e 0"]} {
|
||||
fail $testname
|
||||
return
|
||||
}
|
||||
|
||||
pass $testname
|
||||
}
|
||||
|
||||
i126256-test
|
Loading…
Reference in New Issue
Block a user