* readelf.c (get_machine_dlags): Add support for RX's PID mode.

* ld-scripts/phdrs.exp: Expect to fail for the RX.

	* elf32-rx.c: Add support for PID mode.
	(rx_elf_relocate_section): Add checks for unsafe PID relocations.
	Include addend in R_RX_SYM relocations.

	* config/rx-defs.h (rx_pid_register): New.
	(rx_gp_register): New.
	* config/rx-parse.y (rx_lex): Add support for %gpreg and %pidreg.
	(displacement): Add PID support.
	* config/tc-rx.c (rx_pid_mode): New.
	(rx_num_int_regs): New.
	(rx_pid_register): New.
	(rx_gp_register): New.
	(options): Add -mpid and -mint-register= options.
	(md_longopts): Likewise.
	(md_parse_option): Likewise.
	(md_show_usage): Likewise.
	(rx_pid_symbol): New.
	(rx_pidreg_symbol): New.
	(rx_gpreg_symbol): New.
	(md_begin): Support PID.
	(rx_validate_fix_sub): Support PID.
	(tc_gen_reloc): Support PID.
	* doc/c-rx.texi: Document PID support.

	* rx.h (E_FLAG_RX_PID): New.
This commit is contained in:
Nick Clifton 2011-10-05 14:13:31 +00:00
parent b1c8db38fc
commit d4cb0ea0ca
14 changed files with 293 additions and 44 deletions

View File

@ -1,3 +1,10 @@
2011-10-05 DJ Delorie <dj@redhat.com>
Nick Clifton <nickc@redhat.com>
* elf32-rx.c: Add support for PID mode.
(rx_elf_relocate_section): Add checks for unsafe PID relocations.
Include addend in R_RX_SYM relocations.
2011-09-30 Tristan Gingold <gingold@adacore.com>
* dwarf2.c (struct dwarf2_debug): Add field debug_sections.

View File

@ -462,6 +462,13 @@ rx_elf_relocate_section
struct elf_link_hash_entry ** sym_hashes;
Elf_Internal_Rela * rel;
Elf_Internal_Rela * relend;
bfd_boolean pid_mode;
bfd_boolean saw_subtract = FALSE;
if (elf_elfheader (output_bfd)->e_flags & E_FLAG_RX_PID)
pid_mode = TRUE;
else
pid_mode = FALSE;
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
@ -488,6 +495,9 @@ rx_elf_relocate_section
sec = NULL;
relocation = 0;
if (rx_stack_top == 0)
saw_subtract = FALSE;
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
@ -553,6 +563,28 @@ rx_elf_relocate_section
_bfd_error_handler (_("%B:%A: Warning: deprecated Red Hat reloc " type " detected against: %s."), \
input_bfd, input_section, name)
/* Check for unsafe relocs in PID mode. These are any relocs where
an absolute address is being computed. There are special cases
for relocs against symbols that are known to be referenced in
crt0.o before the PID base address register has been initialised. */
#define UNSAFE_FOR_PID \
do \
{ \
if (pid_mode \
&& sec != NULL \
&& sec->flags & SEC_READONLY \
&& !(input_section->flags & SEC_DEBUGGING) \
&& strcmp (name, "__pid_base") != 0 \
&& strcmp (name, "__gp") != 0 \
&& strcmp (name, "__romdatastart") != 0 \
&& !saw_subtract) \
_bfd_error_handler (_("%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"), \
input_bfd, input_section, howto->name, \
input_section->output_section->vma + input_section->output_offset + rel->r_offset, \
name, sec->name); \
} \
while (0)
/* Opcode relocs are always big endian. Data relocs are bi-endian. */
switch (r_type)
{
@ -573,16 +605,19 @@ rx_elf_relocate_section
WARN_REDHAT ("RX_RH_8_NEG");
relocation = - relocation;
case R_RX_DIR8S_PCREL:
UNSAFE_FOR_PID;
RANGE (-128, 127);
OP (0) = relocation;
break;
case R_RX_DIR8S:
UNSAFE_FOR_PID;
RANGE (-128, 255);
OP (0) = relocation;
break;
case R_RX_DIR8U:
UNSAFE_FOR_PID;
RANGE (0, 255);
OP (0) = relocation;
break;
@ -591,6 +626,7 @@ rx_elf_relocate_section
WARN_REDHAT ("RX_RH_16_NEG");
relocation = - relocation;
case R_RX_DIR16S_PCREL:
UNSAFE_FOR_PID;
RANGE (-32768, 32767);
#if RX_OPCODE_BIG_ENDIAN
#else
@ -601,6 +637,7 @@ rx_elf_relocate_section
case R_RX_RH_16_OP:
WARN_REDHAT ("RX_RH_16_OP");
UNSAFE_FOR_PID;
RANGE (-32768, 32767);
#if RX_OPCODE_BIG_ENDIAN
OP (1) = relocation;
@ -612,6 +649,7 @@ rx_elf_relocate_section
break;
case R_RX_DIR16S:
UNSAFE_FOR_PID;
RANGE (-32768, 65535);
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
{
@ -626,6 +664,7 @@ rx_elf_relocate_section
break;
case R_RX_DIR16U:
UNSAFE_FOR_PID;
RANGE (0, 65536);
#if RX_OPCODE_BIG_ENDIAN
OP (1) = relocation;
@ -637,6 +676,7 @@ rx_elf_relocate_section
break;
case R_RX_DIR16:
UNSAFE_FOR_PID;
RANGE (-32768, 65536);
#if RX_OPCODE_BIG_ENDIAN
OP (1) = relocation;
@ -648,6 +688,7 @@ rx_elf_relocate_section
break;
case R_RX_DIR16_REV:
UNSAFE_FOR_PID;
RANGE (-32768, 65536);
#if RX_OPCODE_BIG_ENDIAN
OP (0) = relocation;
@ -665,6 +706,7 @@ rx_elf_relocate_section
break;
case R_RX_RH_24_NEG:
UNSAFE_FOR_PID;
WARN_REDHAT ("RX_RH_24_NEG");
relocation = - relocation;
case R_RX_DIR24S_PCREL:
@ -681,6 +723,7 @@ rx_elf_relocate_section
break;
case R_RX_RH_24_OP:
UNSAFE_FOR_PID;
WARN_REDHAT ("RX_RH_24_OP");
RANGE (-0x800000, 0x7fffff);
#if RX_OPCODE_BIG_ENDIAN
@ -695,6 +738,7 @@ rx_elf_relocate_section
break;
case R_RX_DIR24S:
UNSAFE_FOR_PID;
RANGE (-0x800000, 0x7fffff);
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
{
@ -711,6 +755,7 @@ rx_elf_relocate_section
break;
case R_RX_RH_24_UNS:
UNSAFE_FOR_PID;
WARN_REDHAT ("RX_RH_24_UNS");
RANGE (0, 0xffffff);
#if RX_OPCODE_BIG_ENDIAN
@ -725,6 +770,7 @@ rx_elf_relocate_section
break;
case R_RX_RH_32_NEG:
UNSAFE_FOR_PID;
WARN_REDHAT ("RX_RH_32_NEG");
relocation = - relocation;
#if RX_OPCODE_BIG_ENDIAN
@ -741,6 +787,7 @@ rx_elf_relocate_section
break;
case R_RX_RH_32_OP:
UNSAFE_FOR_PID;
WARN_REDHAT ("RX_RH_32_OP");
#if RX_OPCODE_BIG_ENDIAN
OP (3) = relocation;
@ -920,6 +967,7 @@ rx_elf_relocate_section
/* Complex reloc handling: */
case R_RX_ABS32:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
#if RX_OPCODE_BIG_ENDIAN
OP (3) = relocation;
@ -935,6 +983,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS32_REV:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
#if RX_OPCODE_BIG_ENDIAN
OP (0) = relocation;
@ -951,6 +1000,7 @@ rx_elf_relocate_section
case R_RX_ABS24S_PCREL:
case R_RX_ABS24S:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (-0x800000, 0x7fffff);
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
@ -968,6 +1018,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS16:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (-32768, 65535);
#if RX_OPCODE_BIG_ENDIAN
@ -980,6 +1031,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS16_REV:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (-32768, 65535);
#if RX_OPCODE_BIG_ENDIAN
@ -1008,6 +1060,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS16U:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (0, 65536);
#if RX_OPCODE_BIG_ENDIAN
@ -1020,6 +1073,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS16UL:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
relocation >>= 2;
RANGE (0, 65536);
@ -1033,6 +1087,7 @@ rx_elf_relocate_section
break;
case R_RX_ABS16UW:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
relocation >>= 1;
RANGE (0, 65536);
@ -1046,18 +1101,21 @@ rx_elf_relocate_section
break;
case R_RX_ABS8:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (-128, 255);
OP (0) = relocation;
break;
case R_RX_ABS8U:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
RANGE (0, 255);
OP (0) = relocation;
break;
case R_RX_ABS8UL:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
relocation >>= 2;
RANGE (0, 255);
@ -1065,14 +1123,16 @@ rx_elf_relocate_section
break;
case R_RX_ABS8UW:
UNSAFE_FOR_PID;
RX_STACK_POP (relocation);
relocation >>= 1;
RANGE (0, 255);
OP (0) = relocation;
break;
case R_RX_ABS8S_PCREL:
case R_RX_ABS8S:
UNSAFE_FOR_PID;
case R_RX_ABS8S_PCREL:
RX_STACK_POP (relocation);
RANGE (-128, 127);
OP (0) = relocation;
@ -1082,7 +1142,8 @@ rx_elf_relocate_section
if (r_symndx < symtab_hdr->sh_info)
RX_STACK_PUSH (sec->output_section->vma
+ sec->output_offset
+ sym->st_value);
+ sym->st_value
+ rel->r_addend);
else
{
if (h != NULL
@ -1090,7 +1151,8 @@ rx_elf_relocate_section
|| h->root.type == bfd_link_hash_defweak))
RX_STACK_PUSH (h->root.u.def.value
+ sec->output_section->vma
+ sec->output_offset);
+ sec->output_offset
+ rel->r_addend);
else
_bfd_error_handler (_("Warning: RX_SYM reloc with an unknown symbol"));
}
@ -1121,6 +1183,7 @@ rx_elf_relocate_section
{
int32_t tmp1, tmp2;
saw_subtract = TRUE;
RX_STACK_POP (tmp1);
RX_STACK_POP (tmp2);
tmp2 -= tmp1;
@ -1143,6 +1206,7 @@ rx_elf_relocate_section
{
int32_t tmp1, tmp2;
saw_subtract = TRUE;
RX_STACK_POP (tmp1);
RX_STACK_POP (tmp2);
tmp1 /= tmp2;
@ -2893,7 +2957,7 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
}
else if (old_flags != new_flags)
{
flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP;
flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP | E_FLAG_RX_PID;
if ((old_flags ^ new_flags) & known_flags)
{

View File

@ -1,4 +1,9 @@
2011-10-04 Paul Woegerer <paul_woegerer@mentor.com>
2011-10-05 DJ Delorie <dj@redhat.com>
Nick Clifton <nickc@redhat.com>
* readelf.c (get_machine_dlags): Add support for RX's PID mode.
2011-10-04 Paul Woegerer <paul_woegerer@mentor.com>
Carlos O'Donell <carlos@codesourcery.com>
* dwarf.c (display_debug_lines_decoded): Index directory_table with

View File

@ -2595,14 +2595,19 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
strcat (buf, ", 64-bit doubles");
if (e_flags & E_FLAG_RX_DSP)
strcat (buf, ", dsp");
if (e_flags & E_FLAG_RX_PID)
strcat (buf, ", pid");
break;
case EM_S390:
if (e_flags & EF_S390_HIGH_GPRS)
strcat (buf, ", highgprs");
break;
case EM_TI_C6000:
if ((e_flags & EF_C6000_REL))
strcat (buf, ", relocatable module");
break;
}
}

View File

@ -204,28 +204,32 @@ if { ![is_elf_format] } then {
# Test objdump -WL on a file that contains line information for multiple files and search directories.
if { ![binutils_assemble $srcdir/$subdir/dw2-decodedline.S tmpdir/dw2-decodedline.o] } then {
fail "objdump decoded line"
}
if [is_remote host] {
set decodedline_testfile [remote_download host tmpdir/dw2-decodedline.o]
if { ![is_elf_format] } then {
unsupported "objump decode line"
} else {
set decodedline_testfile tmpdir/dw2-decodedline.o
}
if { ![binutils_assemble $srcdir/$subdir/dw2-decodedline.S tmpdir/dw2-decodedline.o] } then {
fail "objdump decoded line"
}
set got [remote_exec host "$OBJDUMP $OBJDUMPFLAGS -WL $decodedline_testfile" "" "/dev/null" "objdump.out"]
if [is_remote host] {
set decodedline_testfile [remote_download host tmpdir/dw2-decodedline.o]
} else {
set decodedline_testfile tmpdir/dw2-decodedline.o
}
if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
fail "objdump -WL (reason: unexpected output)"
send_log $got
send_log "\n"
}
set got [remote_exec host "$OBJDUMP $OBJDUMPFLAGS -WL $decodedline_testfile" "" "/dev/null" "objdump.out"]
if { [regexp_diff objdump.out $srcdir/$subdir/objdump.WL] } then {
fail "objdump -WL"
} else {
pass "objdump -WL"
if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
fail "objdump -WL (reason: unexpected output)"
send_log $got
send_log "\n"
}
if { [regexp_diff objdump.out $srcdir/$subdir/objdump.WL] } then {
fail "objdump -WL"
} else {
pass "objdump -WL"
}
}
# Options which are not tested: -a -d -D -R -T -x -l --stabs

View File

@ -1,3 +1,26 @@
2011-10-05 DJ Delorie <dj@redhat.com>
Nick Clifton <nickc@redhat.com>
* config/rx-defs.h (rx_pid_register): New.
(rx_gp_register): New.
* config/rx-parse.y (rx_lex): Add support for %gpreg and %pidreg.
(displacement): Add PID support.
* config/tc-rx.c (rx_pid_mode): New.
(rx_num_int_regs): New.
(rx_pid_register): New.
(rx_gp_register): New.
(options): Add -mpid and -mint-register= options.
(md_longopts): Likewise.
(md_parse_option): Likewise.
(md_show_usage): Likewise.
(rx_pid_symbol): New.
(rx_pidreg_symbol): New.
(rx_gpreg_symbol): New.
(md_begin): Support PID.
(rx_validate_fix_sub): Support PID.
(tc_gen_reloc): Support PID.
* doc/c-rx.texi: Document PID support.
2011-09-27 Kai Tietz <ktietz@redhat.com>
* config/obj-coff.c (obj_coff_section): Add 'e' as specifier

View File

@ -34,6 +34,9 @@
#define RX_RELAX_IMM 2
#define RX_RELAX_DISP 3
extern int rx_pid_register;
extern int rx_gp_register;
extern int rx_error (char *);
extern void rx_lex_init (char *, char *);
extern void rx_base1 (int);

View File

@ -1170,6 +1170,8 @@ rx_lex (void)
return 0;
if (ISALPHA (*rx_lex_start)
|| (rx_pid_register != -1 && memcmp (rx_lex_start, "%pidreg", 7) == 0)
|| (rx_gp_register != -1 && memcmp (rx_lex_start, "%gpreg", 6) == 0)
|| (*rx_lex_start == '.' && ISALPHA (rx_lex_start[1])))
{
unsigned int i;
@ -1183,6 +1185,28 @@ rx_lex (void)
save = *e;
*e = 0;
if (strcmp (rx_lex_start, "%pidreg") == 0)
{
{
rx_lval.regno = rx_pid_register;
*e = save;
rx_lex_start = e;
rx_last_token = REG;
return REG;
}
}
if (strcmp (rx_lex_start, "%gpreg") == 0)
{
{
rx_lval.regno = rx_gp_register;
*e = save;
rx_lex_start = e;
rx_last_token = REG;
return REG;
}
}
if (rx_last_token == 0)
for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++)
if (check_condition (condition_opcode_table[ci].string))
@ -1482,6 +1506,13 @@ displacement (expressionS exp, int msize)
}
}
if (exp.X_op == O_subtract)
{
exp.X_md = BFD_RELOC_RX_DIFF;
O2 (exp);
return 2;
}
if (exp.X_op != O_constant)
{
rx_error (_("displacements must be constants"));

View File

@ -1,5 +1,5 @@
/* tc-rx.c -- Assembler for the Renesas RX
Copyright 2008, 2009, 2010
Copyright 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -51,6 +51,11 @@ static int elf_flags = 0;
bfd_boolean rx_use_conventional_section_names = FALSE;
static bfd_boolean rx_use_small_data_limit = FALSE;
static bfd_boolean rx_pid_mode = FALSE;
static int rx_num_int_regs = 0;
int rx_pid_register;
int rx_gp_register;
enum options
{
OPTION_BIG = OPTION_MD_BASE,
@ -60,7 +65,9 @@ enum options
OPTION_CONVENTIONAL_SECTION_NAMES,
OPTION_RENESAS_SECTION_NAMES,
OPTION_SMALL_DATA_LIMIT,
OPTION_RELAX
OPTION_RELAX,
OPTION_PID,
OPTION_INT_REGS,
};
#define RX_SHORTOPTS ""
@ -83,6 +90,8 @@ struct option md_longopts[] =
{"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
{"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
{"relax", no_argument, NULL, OPTION_RELAX},
{"mpid", no_argument, NULL, OPTION_PID},
{"mint-register", required_argument, NULL, OPTION_INT_REGS},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
@ -123,6 +132,15 @@ md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
case OPTION_RELAX:
linkrelax = 1;
return 1;
case OPTION_PID:
rx_pid_mode = TRUE;
elf_flags |= E_FLAG_RX_PID;
return 1;
case OPTION_INT_REGS:
rx_num_int_regs = atoi (optarg);
return 1;
}
return 0;
}
@ -138,6 +156,9 @@ md_show_usage (FILE * stream)
fprintf (stream, _(" --muse-conventional-section-names\n"));
fprintf (stream, _(" --muse-renesas-section-names [default]\n"));
fprintf (stream, _(" --msmall-data-limit\n"));
fprintf (stream, _(" --mrelax\n"));
fprintf (stream, _(" --mpid\n"));
fprintf (stream, _(" --mint-register=<value>\n"));
}
static void
@ -584,16 +605,44 @@ const pseudo_typeS md_pseudo_table[] =
};
static asymbol * gp_symbol;
static asymbol * rx_pid_symbol;
static symbolS * rx_pidreg_symbol;
static symbolS * rx_gpreg_symbol;
void
md_begin (void)
{
/* Make the __gp and __pid_base symbols now rather
than after the symbol table is frozen. We only do this
when supporting small data limits because otherwise we
pollute the symbol table. */
/* The meta-registers %pidreg and %gpreg depend on what other
options are specified. The __rx_*_defined symbols exist so we
can .ifdef asm code based on what options were passed to gas,
without needing a preprocessor */
if (rx_pid_mode)
{
rx_pid_register = 13 - rx_num_int_regs;
rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base"));
rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined");
S_SET_VALUE (rx_pidreg_symbol, rx_pid_register);
S_SET_SEGMENT (rx_pidreg_symbol, absolute_section);
}
if (rx_use_small_data_limit)
/* Make the __gp symbol now rather
than after the symbol table is frozen. We only do this
when supporting small data limits because otherwise we
pollute the symbol table. */
gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
{
if (rx_pid_mode)
rx_gp_register = rx_pid_register - 1;
else
rx_gp_register = 13 - rx_num_int_regs;
gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined");
S_SET_VALUE (rx_gpreg_symbol, rx_gp_register);
S_SET_SEGMENT (rx_gpreg_symbol, absolute_section);
}
}
char * rx_lex_start;
@ -1150,7 +1199,7 @@ rx_handle_align (fragS * frag)
&& subseg_text_p (now_seg))
{
int count = (frag->fr_next->fr_address
- frag->fr_address
- frag->fr_address
- frag->fr_fix);
unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
@ -2222,10 +2271,10 @@ md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
}
arelent **
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
{
static arelent * reloc[5];
int is_opcode = 0;
bfd_boolean is_opcode = FALSE;
if (fixp->fx_r_type == BFD_RELOC_NONE)
{
@ -2250,9 +2299,11 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
&& fixp->fx_subsy)
{
fixp->fx_r_type = BFD_RELOC_RX_DIFF;
is_opcode = 1;
is_opcode = TRUE;
}
else if (sec)
is_opcode = sec->flags & SEC_CODE;
/* Certain BFD relocations cannot be translated directly into
a single (non-Red Hat) RX relocation, but instead need
multiple RX relocations - handle them here. */
@ -2283,6 +2334,8 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
case 2:
if (!is_opcode && target_big_endian)
reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
else if (is_opcode)
reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
else
reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
break;

View File

@ -74,11 +74,25 @@ This is the default.
@item -msmall-data-limit
This option tells the assembler that the small data limit feature of
the RX port of GCC is being used. This results in the assembler
generating an undefined reference to a symbol called __gp for use by
the relocations that are needed to support the small data limit
generating an undefined reference to a symbol called @code{__gp} for
use by the relocations that are needed to support the small data limit
feature. This option is not enabled by default as it would otherwise
pollute the symbol table.
@cindex @samp{-mpid}
@item -mpid
This option tells the assembler that the position independent data of the
RX port of GCC is being used. This results in the assembler
generating an undefined reference to a symbol called @code{__pid_base},
and also setting the RX_PID flag bit in the e_flags field of the ELF
header of the object file.
@cindex @samp{-mint-register}
@item -mint-register=@var{num}
This option tells the assembler how many registers have been reserved
for use by interrupt handlers. This is needed in order to compute the
correct values for the @code{%gpreg} and @code{%pidreg} meta registers.
@end table
@node RX-Modifiers
@ -86,22 +100,45 @@ pollute the symbol table.
@cindex RX modifiers
@cindex syntax, RX
@cindex %gp
The assembler supports several modifiers when using symbol addresses
The assembler supports one modifier when using symbol addresses
in RX instruction operands. The general syntax is the following:
@smallexample
%modifier(symbol)
%gp(symbol)
@end smallexample
@table @code
@cindex symbol modifiers
The modifier returns the offset from the @var{__gp} symbol to the
specified symbol as a 16-bit value. The intent is that this offset
should be used in a register+offset move instruction when generating
references to small data. Ie, like this:
@item %gp
@c FIXME: Add documentation here.
@smallexample
mov.W %gp(_foo)[%gpreg], r1
@end smallexample
The assembler also supports two meta register names which can be used
to refer to registers whose values may not be known to the
programmer. These meta register names are:
@table @code
@cindex @samp{%gpreg}
@item %gpreg
The small data address register.
@cindex @samp{%pidreg}
@item %pidreg
The PID base address register.
@end table
Both registers normally have the value r13, but this can change if
some registers have been reserved for use by interrupt handlers or if
both the small data limit and position independent data features are
being used at the same time.
@node RX-Directives
@section Assembler Directives

View File

@ -1,3 +1,7 @@
2011-10-05 DJ Delorie <dj@redhat.com>
* rx.h (E_FLAG_RX_PID): New.
2011-09-21 David S. Miller <davem@davemloft.net>
* sparc.h (Tag_GNU_Sparc_HWCAPS): New object attribute.

View File

@ -116,7 +116,8 @@ END_RELOC_NUMBERS (R_RX_max)
/* Values for the e_flags field in the ELF header. */
#define E_FLAG_RX_64BIT_DOUBLES (1 << 0)
#define E_FLAG_RX_DSP (1 << 1) /* Defined in the RX CPU Object file specification, but not explained. */
#define E_FLAG_RX_DSP (1 << 1) /* Defined in the RX CPU Object file specification, but not explained. */
#define E_FLAG_RX_PID (1 << 2) /* Unofficial - DJ */
/* These define the addend field of R_RX_RH_RELAX relocations. */
#define RX_RELAXA_IMM6 0x00000010 /* Imm8/16/24/32 at bit offset 6. */

View File

@ -1,3 +1,7 @@
2011-10-05 Nick Clifton <nickc@redhat.com>
* ld-scripts/phdrs.exp: Expect to fail for the RX.
2011-09-30 Alan Modra <amodra@gmail.com>
* ld-powerpc/tocopt.d: Update.

View File

@ -60,6 +60,14 @@ if ![ld_simple_link $ld tmpdir/phdrs $ldopt] {
set exec_output [prune_warnings $exec_output]
verbose -log $exec_output
# The RX port sets the p_paddr of loadable segments to 0 in order
# to be compatible with Renesas tools. When an RX executable is
# loaded into a BFD based tool the code tries to reconstruct the
# correct vaddr and paddr values. This is not always possible
# however and this test is one example of where the reconstruction
# fails.
setup_xfail rx-*-*
if [regexp $phdrs_regexp $exec_output] {
pass $testname
} else {