* 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:
parent
b1c8db38fc
commit
d4cb0ea0ca
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user