mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 18:08:24 +08:00
PR26569, R_RISCV_RVC_JUMP results in buffer overflow
This patch corrects "size" and "bitsize" in R_RISCV_RVC_* reloc howtos so that elfnn-riscv.c:perform_relocation doesn't access past the end of a section. I've also corrected "size" in the R_RISCV_CALL* reloc howtos since these relocs apply to two consecutive instructions. That caused fallout in the assembler with complaints about "fixup not contained within frag" due to tc-riscv.c:append_insn finishing off a frag after the auipc insn making up a "call" macro. Which is a little rude since the CALL reloc also relocates the following jalr. Fixed by changing the frag handling a little. I've also changed R_RISCV_ALIGN and R_RISCV_TPREL_ADD marker reloc howtos to look like R_RISCV_NONE, and corrected dst_mask for numerous relocs, not that it matters very much. bfd/ PR 26569 * elfxx-riscv.c (howto_table): Correct size and bitsize of R_RISCV_RVC_BRANCH, R_RISCV_RVC_JUMP, and R_RISCV_RVC_LUI. Correct size for R_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPREL32, R_RISCV_CALL, and R_RISCV_CALL_PLT. Make R_RISCV_TPREL_ADD and R_RISCV_ALIGN like R_RISCV_NONE. Correct dst_mask many relocs. gas/ * config/tc-riscv.c (append_insn): Don't tie off frags at CALL relocs. (riscv_call): Tie them off after the jalr. (md_apply_fix): Zero fx_size of RELAX fixup.
This commit is contained in:
@ -1,3 +1,12 @@
|
||||
2020-09-21 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26569
|
||||
* elfxx-riscv.c (howto_table): Correct size and bitsize of
|
||||
R_RISCV_RVC_BRANCH, R_RISCV_RVC_JUMP, and R_RISCV_RVC_LUI.
|
||||
Correct size for R_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPREL32,
|
||||
R_RISCV_CALL, and R_RISCV_CALL_PLT. Make R_RISCV_TPREL_ADD and
|
||||
R_RISCV_ALIGN like R_RISCV_NONE. Correct dst_mask many relocs.
|
||||
|
||||
2020-09-17 Mikael Pettersson <mikpelinux@gmail.com>
|
||||
|
||||
PR ld/18808
|
||||
|
@ -69,7 +69,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 64 bit relocation. */
|
||||
@ -99,7 +99,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_RELATIVE", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_RISCV_COPY, /* type */
|
||||
@ -133,7 +133,7 @@ static reloc_howto_type howto_table[] =
|
||||
/* Dynamic TLS relocations. */
|
||||
HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
@ -142,7 +142,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_TLS_DTPMOD32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
|
||||
@ -161,7 +161,7 @@ static reloc_howto_type howto_table[] =
|
||||
|
||||
HOWTO (R_RISCV_TLS_DTPREL32, /* type */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
@ -170,7 +170,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_TLS_DTPREL32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_RISCV_TLS_DTPREL64, /* type */
|
||||
@ -198,7 +198,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_TLS_TPREL32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_RISCV_TLS_TPREL64, /* type */
|
||||
@ -254,7 +254,7 @@ static reloc_howto_type howto_table[] =
|
||||
/* 32-bit PC-relative function call (AUIPC/JALR). */
|
||||
HOWTO (R_RISCV_CALL, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
@ -270,7 +270,7 @@ static reloc_howto_type howto_table[] =
|
||||
/* Like R_RISCV_CALL, but not locally binding. */
|
||||
HOWTO (R_RISCV_CALL_PLT, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
@ -466,14 +466,14 @@ static reloc_howto_type howto_table[] =
|
||||
/* TLS LE thread pointer usage. May be relaxed. */
|
||||
HOWTO (R_RISCV_TPREL_ADD, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
3, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_RISCV_TPREL_ADD", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
@ -490,7 +490,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_ADD8", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 16-bit in-place addition, for local label subtraction. */
|
||||
@ -505,7 +505,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_ADD16", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 32-bit in-place addition, for local label subtraction. */
|
||||
@ -520,7 +520,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_ADD32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 64-bit in-place addition, for local label subtraction. */
|
||||
@ -550,7 +550,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SUB8", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 16-bit in-place addition, for local label subtraction. */
|
||||
@ -565,7 +565,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SUB16", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 32-bit in-place addition, for local label subtraction. */
|
||||
@ -580,7 +580,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SUB32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 64-bit in-place addition, for local label subtraction. */
|
||||
@ -633,7 +633,7 @@ static reloc_howto_type howto_table[] =
|
||||
addend rounded up to the next power of two. */
|
||||
HOWTO (R_RISCV_ALIGN, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
3, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
@ -643,13 +643,13 @@ static reloc_howto_type howto_table[] =
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 8-bit PC-relative branch offset. */
|
||||
HOWTO (R_RISCV_RVC_BRANCH, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
1, /* size */
|
||||
16, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed, /* complain_on_overflow */
|
||||
@ -663,8 +663,8 @@ static reloc_howto_type howto_table[] =
|
||||
/* 11-bit PC-relative jump offset. */
|
||||
HOWTO (R_RISCV_RVC_JUMP, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
1, /* size */
|
||||
16, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
@ -678,8 +678,8 @@ static reloc_howto_type howto_table[] =
|
||||
/* High 6 bits of 18-bit absolute address. */
|
||||
HOWTO (R_RISCV_RVC_LUI, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
1, /* size */
|
||||
16, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
@ -807,7 +807,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SET8", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 16-bit in-place setting, for local label subtraction. */
|
||||
@ -822,7 +822,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SET16", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 32-bit in-place setting, for local label subtraction. */
|
||||
@ -837,7 +837,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_SET32", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* 32-bit PC relative. */
|
||||
@ -852,7 +852,7 @@ static reloc_howto_type howto_table[] =
|
||||
"R_RISCV_32_PCREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
MINUS_ONE, /* dst_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
};
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
2020-09-21 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26569
|
||||
* config/tc-riscv.c (append_insn): Don't tie off frags at CALL
|
||||
relocs.
|
||||
(riscv_call): Tie them off after the jalr.
|
||||
(md_apply_fix): Zero fx_size of RELAX fixup.
|
||||
|
||||
2020-09-018 David Faust <david.faust@oracle.com>
|
||||
|
||||
* testsuite/gas/bpf/alu-xbpf.d: New file.
|
||||
|
@ -1133,9 +1133,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
|
||||
optimized away or compressed by the linker during relaxation, to prevent
|
||||
the assembler from computing static offsets across such an instruction.
|
||||
This is necessary to get correct EH info. */
|
||||
if (reloc_type == BFD_RELOC_RISCV_CALL
|
||||
|| reloc_type == BFD_RELOC_RISCV_CALL_PLT
|
||||
|| reloc_type == BFD_RELOC_RISCV_HI20
|
||||
if (reloc_type == BFD_RELOC_RISCV_HI20
|
||||
|| reloc_type == BFD_RELOC_RISCV_PCREL_HI20
|
||||
|| reloc_type == BFD_RELOC_RISCV_TPREL_HI20
|
||||
|| reloc_type == BFD_RELOC_RISCV_TPREL_ADD)
|
||||
@ -1311,8 +1309,13 @@ static void
|
||||
riscv_call (int destreg, int tempreg, expressionS *ep,
|
||||
bfd_reloc_code_real_type reloc)
|
||||
{
|
||||
/* Ensure the jalr is emitted to the same frag as the auipc. */
|
||||
frag_grow (8);
|
||||
macro_build (ep, "auipc", "d,u", tempreg, reloc);
|
||||
macro_build (NULL, "jalr", "d,s", destreg, tempreg);
|
||||
/* See comment at end of append_insn. */
|
||||
frag_wane (frag_now);
|
||||
frag_new (0);
|
||||
}
|
||||
|
||||
/* Load an integer constant into a register. */
|
||||
@ -3031,6 +3034,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
|
||||
fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
|
||||
fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
|
||||
fixP->fx_next->fx_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user