Skip to content

Commit fbc09e7

Browse files
zeldinNelson Chu
authored and
Nelson Chu
committed
RISC-V: Implement support for big endian targets.
RISC-V instruction/code is always little endian, but data might be big-endian. Therefore, we can not use the original bfd_get/bfd_put to get/put the code for big endian targets. Add new riscv_get_insn and riscv_put_insn to always get/put code as little endian can resolve the problem. Just remember to update them once we have supported the 48-bit/128-bit instructions in the future patches. bfd/ * config.bfd: Added targets riscv64be*-*-*, riscv32be*-*-* and riscvbe*-*-*. Also added riscv_elf[32|64]_be_vec. * configure.ac: Handle riscv_elf[32|64]_be_vec. * configure: Regenerate. * elfnn-riscv.c: Include <limits.h> and define CHAR_BIT for riscv_is_insn_reloc. (riscv_get_insn): RISC-V instructions are always little endian, but bfd_get may be used for big-endian, so add new riscv_get_insn to handle the insturctions. (riscv_put_insn): Likewsie. (riscv_is_insn_reloc): Check if we are relocaing an instruction. (perform_relocation): Call riscv_is_insn_reloc to decide if we should use riscv_[get|put]_insn or bfd_[get|put]. (riscv_zero_pcrel_hi_reloc): Use riscv_[get|put]_insn, bfd_[get|put]l32 or bfd_[get|put]l16 for code. (riscv_elf_relocate_section): Likewise. (riscv_elf_finish_dynamic_symbol): Likewise. (riscv_elf_finish_dynamic_sections): Likewise. (_bfd_riscv_relax_call): Likewise. (_bfd_riscv_relax_lui): Likewise. (_bfd_riscv_relax_align): Likewise. (_bfd_riscv_relax_pc): Likewise. (riscv_elf_object_p): Handled for big endian. (TARGET_BIG_SYM, TARGET_BIG_NAME): Defined. * targets.c: Add riscv_elf[32|64]_be_vec. (_bfd_target_vector): Likewise. gas/ * config/tc-riscv.c (riscv_target_format): Add elf64-bigriscv and elf32-bigriscv. (install_insn): Always write instructions as little endian. (riscv_make_nops): Likewise. (md_convert_frag_branch): Likewise. (md_number_to_chars): Write data in target endianness. (options, md_longopts): Add -mbig-endian and -mlittle-endian options. (md_parse_option): Handle the endian options. * config/tc-riscv.h: Only define TARGET_BYTES_BIG_ENDIAN if not already defined. * configure.tgt: Added riscv64be*, riscv32be*, riscvbe*. ld/ * configure.tgt: Added riscvbe-*-*, riscv32be*-*-*, riscv64be*-*-*, riscv32be*-*-linux*, and riscv64be*-*-linux*. * Makefile.am: Added eelf32briscv.c, eelf32briscv_ilp32f.c and eelf32briscv_ilp32.c. * Makefile.in: Regenerate. * emulparams/elf32briscv.sh: Added. * emulparams/elf32briscv_ilp32.sh: Likewise. * emulparams/elf32briscv_ilp32f.sh: Likewise. * emulparams/elf64briscv.sh: Likewise. * emulparams/elf64briscv_lp64.sh: Likewise. * emulparams/elf64briscv_lp64f.sh: Likewise.
1 parent 8652882 commit fbc09e7

20 files changed

+245
-47
lines changed

bfd/ChangeLog

+29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
2021-01-06 Marcus Comstedt <[email protected]>
2+
3+
* config.bfd: Added targets riscv64be*-*-*, riscv32be*-*-* and
4+
riscvbe*-*-*. Also added riscv_elf[32|64]_be_vec.
5+
* configure.ac: Handle riscv_elf[32|64]_be_vec.
6+
* configure: Regenerate.
7+
* elfnn-riscv.c: Include <limits.h> and define CHAR_BIT for
8+
riscv_is_insn_reloc.
9+
(riscv_get_insn): RISC-V instructions are always little endian, but
10+
bfd_get may be used for big-endian, so add new riscv_get_insn to handle
11+
the insturctions.
12+
(riscv_put_insn): Likewsie.
13+
(riscv_is_insn_reloc): Check if we are relocaing an instruction.
14+
(perform_relocation): Call riscv_is_insn_reloc to decide if we should
15+
use riscv_[get|put]_insn or bfd_[get|put].
16+
(riscv_zero_pcrel_hi_reloc): Use riscv_[get|put]_insn, bfd_[get|put]l32
17+
or bfd_[get|put]l16 for code.
18+
(riscv_elf_relocate_section): Likewise.
19+
(riscv_elf_finish_dynamic_symbol): Likewise.
20+
(riscv_elf_finish_dynamic_sections): Likewise.
21+
(_bfd_riscv_relax_call): Likewise.
22+
(_bfd_riscv_relax_lui): Likewise.
23+
(_bfd_riscv_relax_align): Likewise.
24+
(_bfd_riscv_relax_pc): Likewise.
25+
(riscv_elf_object_p): Handled for big endian.
26+
(TARGET_BIG_SYM, TARGET_BIG_NAME): Defined.
27+
* targets.c: Add riscv_elf[32|64]_be_vec.
28+
(_bfd_target_vector): Likewise.
29+
130
2021-01-05 Alan Modra <[email protected]>
231

332
* elflink.c (bfd_elf_link_record_dynamic_symbol): Handle no_export

bfd/config.bfd

+12-2
Original file line numberDiff line numberDiff line change
@@ -1158,14 +1158,24 @@ case "${targ}" in
11581158
;;
11591159

11601160
#ifdef BFD64
1161+
riscvbe-*-* | riscv32be*-*-*)
1162+
targ_defvec=riscv_elf32_be_vec
1163+
targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
1164+
want64=true
1165+
;;
11611166
riscv-*-* | riscv32*-*-*)
11621167
targ_defvec=riscv_elf32_vec
1163-
targ_selvecs="riscv_elf32_vec riscv_elf64_vec"
1168+
targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
1169+
want64=true
1170+
;;
1171+
riscv64be*-*-*)
1172+
targ_defvec=riscv_elf64_be_vec
1173+
targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
11641174
want64=true
11651175
;;
11661176
riscv64*-*-*)
11671177
targ_defvec=riscv_elf64_vec
1168-
targ_selvecs="riscv_elf32_vec riscv_elf64_vec"
1178+
targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec"
11691179
want64=true
11701180
;;
11711181
#endif

bfd/configure

+2
Original file line numberDiff line numberDiff line change
@@ -14919,6 +14919,8 @@ do
1491914919
pru_elf32_vec) tb="$tb elf32-pru.lo elf32.lo $elf" ;;
1492014920
riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
1492114921
riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
14922+
riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
14923+
riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
1492214924
rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
1492314925
rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
1492414926
rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;

bfd/configure.ac

+2
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ do
625625
pru_elf32_vec) tb="$tb elf32-pru.lo elf32.lo $elf" ;;
626626
riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
627627
riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
628+
riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;;
629+
riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
628630
rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
629631
rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;
630632
rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;;

bfd/elfnn-riscv.c

+74-33
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
#include "opcode/riscv.h"
3434
#include "objalloc.h"
3535

36+
#ifdef HAVE_LIMITS_H
37+
#include <limits.h>
38+
#endif
39+
#ifndef CHAR_BIT
40+
#define CHAR_BIT 8
41+
#endif
42+
3643
/* Internal relocations used exclusively by the relaxation pass. */
3744
#define R_RISCV_DELETE (R_RISCV_max + 1)
3845

@@ -125,6 +132,18 @@ struct riscv_elf_link_hash_table
125132
bfd_vma last_iplt_index;
126133
};
127134

135+
/* Instruction access functions. */
136+
137+
#define riscv_get_insn(bits, ptr) \
138+
((bits) == 16 ? bfd_getl16 (ptr) \
139+
: (bits) == 32 ? bfd_getl32 (ptr) \
140+
: (bits) == 64 ? bfd_getl64 (ptr) \
141+
: (abort (), (bfd_vma) - 1))
142+
#define riscv_put_insn(bits, val, ptr) \
143+
((bits) == 16 ? bfd_putl16 (val, ptr) \
144+
: (bits) == 32 ? bfd_putl32 (val, ptr) \
145+
: (bits) == 64 ? bfd_putl64 (val, ptr) \
146+
: (abort (), (void) 0))
128147

129148
/* Get the RISC-V ELF linker hash table from a link_info structure. */
130149
#define riscv_elf_hash_table(p) \
@@ -152,6 +171,19 @@ riscv_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
152171
bed->s->swap_reloca_out (abfd, rel, loc);
153172
}
154173

174+
/* Return true if a relocation is modifying an instruction. */
175+
176+
static bfd_boolean
177+
riscv_is_insn_reloc (const reloc_howto_type *howto)
178+
{
179+
/* Heuristic: A multibyte destination with a nontrivial mask
180+
is an instruction */
181+
return (howto->bitsize > 8
182+
&& howto->dst_mask != 0
183+
&& ~(howto->dst_mask | (howto->bitsize < sizeof(bfd_vma) * CHAR_BIT
184+
? (MINUS_ONE << howto->bitsize) : (bfd_vma)0)) != 0);
185+
}
186+
155187
/* PLT/GOT stuff. */
156188

157189
#define PLT_HEADER_INSNS 8
@@ -1645,10 +1677,10 @@ perform_relocation (const reloc_howto_type *howto,
16451677
/* Linker relaxation can convert an address equal to or greater than
16461678
0x800 to slightly below 0x800. C.LUI does not accept zero as a
16471679
valid immediate. We can fix this by converting it to a C.LI. */
1648-
bfd_vma insn = bfd_get (howto->bitsize, input_bfd,
1649-
contents + rel->r_offset);
1680+
bfd_vma insn = riscv_get_insn (howto->bitsize,
1681+
contents + rel->r_offset);
16501682
insn = (insn & ~MATCH_C_LUI) | MATCH_C_LI;
1651-
bfd_put (howto->bitsize, input_bfd, insn, contents + rel->r_offset);
1683+
riscv_put_insn (howto->bitsize, insn, contents + rel->r_offset);
16521684
value = ENCODE_RVC_IMM (0);
16531685
}
16541686
else if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)))
@@ -1684,9 +1716,16 @@ perform_relocation (const reloc_howto_type *howto,
16841716
return bfd_reloc_notsupported;
16851717
}
16861718

1687-
bfd_vma word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset);
1719+
bfd_vma word;
1720+
if (riscv_is_insn_reloc (howto))
1721+
word = riscv_get_insn (howto->bitsize, contents + rel->r_offset);
1722+
else
1723+
word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset);
16881724
word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
1689-
bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
1725+
if (riscv_is_insn_reloc (howto))
1726+
riscv_put_insn (howto->bitsize, word, contents + rel->r_offset);
1727+
else
1728+
bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
16901729

16911730
return bfd_reloc_ok;
16921731
}
@@ -1764,7 +1803,7 @@ riscv_zero_pcrel_hi_reloc (Elf_Internal_Rela *rel,
17641803
bfd_vma addr,
17651804
bfd_byte *contents,
17661805
const reloc_howto_type *howto,
1767-
bfd *input_bfd)
1806+
bfd *input_bfd ATTRIBUTE_UNUSED)
17681807
{
17691808
/* We may need to reference low addreses in PC-relative modes even when the
17701809
* PC is far away from these addresses. For example, undefweak references
@@ -1790,9 +1829,9 @@ riscv_zero_pcrel_hi_reloc (Elf_Internal_Rela *rel,
17901829

17911830
rel->r_info = ELFNN_R_INFO(addr, R_RISCV_HI20);
17921831

1793-
bfd_vma insn = bfd_get(howto->bitsize, input_bfd, contents + rel->r_offset);
1832+
bfd_vma insn = riscv_get_insn(howto->bitsize, contents + rel->r_offset);
17941833
insn = (insn & ~MASK_AUIPC) | MATCH_LUI;
1795-
bfd_put(howto->bitsize, input_bfd, insn, contents + rel->r_offset);
1834+
riscv_put_insn(howto->bitsize, insn, contents + rel->r_offset);
17961835
return TRUE;
17971836
}
17981837

@@ -2380,10 +2419,9 @@ riscv_elf_relocate_section (bfd *output_bfd,
23802419
&& (!bfd_link_pic (info) || h->plt.offset == MINUS_ONE))
23812420
{
23822421
/* We can use x0 as the base register. */
2383-
bfd_vma insn = bfd_get_32 (input_bfd,
2384-
contents + rel->r_offset + 4);
2422+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset + 4);
23852423
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
2386-
bfd_put_32 (input_bfd, insn, contents + rel->r_offset + 4);
2424+
bfd_putl32 (insn, contents + rel->r_offset + 4);
23872425
/* Set the relocation value so that we get 0 after the pc
23882426
relative adjustment. */
23892427
relocation = sec_addr (input_section) + rel->r_offset;
@@ -2416,10 +2454,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
24162454
if (VALID_ITYPE_IMM (relocation + rel->r_addend))
24172455
{
24182456
/* We can use tp as the base register. */
2419-
bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
2457+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
24202458
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
24212459
insn |= X_TP << OP_SH_RS1;
2422-
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
2460+
bfd_putl32 (insn, contents + rel->r_offset);
24232461
}
24242462
else
24252463
r = bfd_reloc_overflow;
@@ -2433,14 +2471,14 @@ riscv_elf_relocate_section (bfd *output_bfd,
24332471
if (x0_base || VALID_ITYPE_IMM (relocation + rel->r_addend - gp))
24342472
{
24352473
/* We can use x0 or gp as the base register. */
2436-
bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
2474+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
24372475
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
24382476
if (!x0_base)
24392477
{
24402478
rel->r_addend -= gp;
24412479
insn |= X_GP << OP_SH_RS1;
24422480
}
2443-
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
2481+
bfd_putl32 (insn, contents + rel->r_offset);
24442482
}
24452483
else
24462484
r = bfd_reloc_overflow;
@@ -2864,7 +2902,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
28642902
return FALSE;
28652903

28662904
for (i = 0; i < PLT_ENTRY_INSNS; i++)
2867-
bfd_put_32 (output_bfd, plt_entry[i], loc + 4*i);
2905+
bfd_putl32 (plt_entry[i], loc + 4*i);
28682906

28692907
/* Fill in the initial value of the .got.plt entry. */
28702908
loc = gotplt->contents + (got_address - sec_addr (gotplt));
@@ -3161,7 +3199,7 @@ riscv_elf_finish_dynamic_sections (bfd *output_bfd,
31613199
return ret;
31623200

31633201
for (i = 0; i < PLT_HEADER_INSNS; i++)
3164-
bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
3202+
bfd_putl32 (plt_header[i], splt->contents + 4*i);
31653203

31663204
elf_section_data (splt->output_section)->this_hdr.sh_entsize
31673205
= PLT_ENTRY_SIZE;
@@ -4118,8 +4156,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
41184156
/* Shorten the function call. */
41194157
BFD_ASSERT (rel->r_offset + 8 <= sec->size);
41204158

4121-
auipc = bfd_get_32 (abfd, contents + rel->r_offset);
4122-
jalr = bfd_get_32 (abfd, contents + rel->r_offset + 4);
4159+
auipc = bfd_getl32 (contents + rel->r_offset);
4160+
jalr = bfd_getl32 (contents + rel->r_offset + 4);
41234161
rd = (jalr >> OP_SH_RD) & OP_MASK_RD;
41244162
rvc = rvc && VALID_RVC_J_IMM (foff);
41254163

@@ -4149,7 +4187,7 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
41494187
/* Replace the R_RISCV_CALL reloc. */
41504188
rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), r_type);
41514189
/* Replace the AUIPC. */
4152-
bfd_put (8 * len, abfd, auipc, contents + rel->r_offset);
4190+
riscv_put_insn (8 * len, auipc, contents + rel->r_offset);
41534191

41544192
/* Delete unnecessary JALR. */
41554193
*again = TRUE;
@@ -4223,9 +4261,9 @@ _bfd_riscv_relax_lui (bfd *abfd,
42234261
if (undefined_weak)
42244262
{
42254263
/* Change the RS1 to zero. */
4226-
bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
4264+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
42274265
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
4228-
bfd_put_32 (abfd, insn, contents + rel->r_offset);
4266+
bfd_putl32 (insn, contents + rel->r_offset);
42294267
}
42304268
else
42314269
rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_I);
@@ -4235,9 +4273,9 @@ _bfd_riscv_relax_lui (bfd *abfd,
42354273
if (undefined_weak)
42364274
{
42374275
/* Change the RS1 to zero. */
4238-
bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
4276+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
42394277
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
4240-
bfd_put_32 (abfd, insn, contents + rel->r_offset);
4278+
bfd_putl32 (insn, contents + rel->r_offset);
42414279
}
42424280
else
42434281
rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_S);
@@ -4268,13 +4306,13 @@ _bfd_riscv_relax_lui (bfd *abfd,
42684306
: ELF_MAXPAGESIZE)))
42694307
{
42704308
/* Replace LUI with C.LUI if legal (i.e., rd != x0 and rd != x2/sp). */
4271-
bfd_vma lui = bfd_get_32 (abfd, contents + rel->r_offset);
4309+
bfd_vma lui = bfd_getl32 (contents + rel->r_offset);
42724310
unsigned rd = ((unsigned)lui >> OP_SH_RD) & OP_MASK_RD;
42734311
if (rd == 0 || rd == X_SP)
42744312
return TRUE;
42754313

42764314
lui = (lui & (OP_MASK_RD << OP_SH_RD)) | MATCH_C_LUI;
4277-
bfd_put_32 (abfd, lui, contents + rel->r_offset);
4315+
bfd_putl32 (lui, contents + rel->r_offset);
42784316

42794317
/* Replace the R_RISCV_HI20 reloc. */
42804318
rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_RVC_LUI);
@@ -4376,11 +4414,11 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
43764414

43774415
/* Write as many RISC-V NOPs as we need. */
43784416
for (pos = 0; pos < (nop_bytes & -4); pos += 4)
4379-
bfd_put_32 (abfd, RISCV_NOP, contents + rel->r_offset + pos);
4417+
bfd_putl32 (RISCV_NOP, contents + rel->r_offset + pos);
43804418

43814419
/* Write a final RVC NOP if need be. */
43824420
if (nop_bytes % 4 != 0)
4383-
bfd_put_16 (abfd, RVC_NOP, contents + rel->r_offset + pos);
4421+
bfd_putl16 (RVC_NOP, contents + rel->r_offset + pos);
43844422

43854423
/* Delete the excess bytes. */
43864424
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
@@ -4487,9 +4525,9 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
44874525
{
44884526
/* Change the RS1 to zero, and then modify the relocation
44894527
type to R_RISCV_LO12_I. */
4490-
bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
4528+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
44914529
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
4492-
bfd_put_32 (abfd, insn, contents + rel->r_offset);
4530+
bfd_putl32 (insn, contents + rel->r_offset);
44934531
rel->r_info = ELFNN_R_INFO (sym, R_RISCV_LO12_I);
44944532
rel->r_addend = hi_reloc.hi_addend;
44954533
}
@@ -4505,9 +4543,9 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
45054543
{
45064544
/* Change the RS1 to zero, and then modify the relocation
45074545
type to R_RISCV_LO12_S. */
4508-
bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
4546+
bfd_vma insn = bfd_getl32 (contents + rel->r_offset);
45094547
insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
4510-
bfd_put_32 (abfd, insn, contents + rel->r_offset);
4548+
bfd_putl32 (insn, contents + rel->r_offset);
45114549
rel->r_info = ELFNN_R_INFO (sym, R_RISCV_LO12_S);
45124550
rel->r_addend = hi_reloc.hi_addend;
45134551
}
@@ -4919,7 +4957,8 @@ static bfd_boolean
49194957
riscv_elf_object_p (bfd *abfd)
49204958
{
49214959
/* There are only two mach types in RISCV currently. */
4922-
if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0)
4960+
if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0
4961+
|| strcmp (abfd->xvec->name, "elf32-bigriscv") == 0)
49234962
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32);
49244963
else
49254964
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64);
@@ -4938,6 +4977,8 @@ riscv_elf_obj_attrs_arg_type (int tag)
49384977

49394978
#define TARGET_LITTLE_SYM riscv_elfNN_vec
49404979
#define TARGET_LITTLE_NAME "elfNN-littleriscv"
4980+
#define TARGET_BIG_SYM riscv_elfNN_be_vec
4981+
#define TARGET_BIG_NAME "elfNN-bigriscv"
49414982

49424983
#define elf_backend_reloc_type_class riscv_reloc_type_class
49434984

bfd/targets.c

+4
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,8 @@ extern const bfd_target powerpc_xcoff_vec;
843843
extern const bfd_target pru_elf32_vec;
844844
extern const bfd_target riscv_elf32_vec;
845845
extern const bfd_target riscv_elf64_vec;
846+
extern const bfd_target riscv_elf32_be_vec;
847+
extern const bfd_target riscv_elf64_be_vec;
846848
extern const bfd_target rl78_elf32_vec;
847849
extern const bfd_target rs6000_xcoff64_vec;
848850
extern const bfd_target rs6000_xcoff64_aix_vec;
@@ -1237,6 +1239,8 @@ static const bfd_target * const _bfd_target_vector[] =
12371239
#ifdef BFD64
12381240
&riscv_elf32_vec,
12391241
&riscv_elf64_vec,
1242+
&riscv_elf32_be_vec,
1243+
&riscv_elf64_be_vec,
12401244
#endif
12411245
&rl78_elf32_vec,
12421246

gas/ChangeLog

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2021-01-06 Marcus Comstedt <[email protected]>
2+
3+
* config/tc-riscv.c (riscv_target_format): Add elf64-bigriscv and
4+
elf32-bigriscv.
5+
(install_insn): Always write instructions as little endian.
6+
(riscv_make_nops): Likewise.
7+
(md_convert_frag_branch): Likewise.
8+
(md_number_to_chars): Write data in target endianness.
9+
(options, md_longopts): Add -mbig-endian and -mlittle-endian options.
10+
(md_parse_option): Handle the endian options.
11+
* config/tc-riscv.h: Only define TARGET_BYTES_BIG_ENDIAN if not
12+
already defined.
13+
* configure.tgt: Added riscv64be*, riscv32be*, riscvbe*.
14+
115
2021-01-04 H.J. Lu <[email protected]>
216

317
PR ld/26256

0 commit comments

Comments
 (0)