bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/25213] New: [RISCV] SUB6 applied without 6-bit mask


From: luismarques at lowrisc dot org
Subject: [Bug binutils/25213] New: [RISCV] SUB6 applied without 6-bit mask
Date: Thu, 21 Nov 2019 21:18:18 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=25213

            Bug ID: 25213
           Summary: [RISCV] SUB6 applied without 6-bit mask
           Product: binutils
           Version: 2.34 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: luismarques at lowrisc dot org
  Target Milestone: ---

Created attachment 12087
  --> https://sourceware.org/bugzilla/attachment.cgi?id=12087&action=edit
object file with DWARF data with field with R_RISCV_SUB6 relocation applied

Steps to reproduce:

- Create an object file where you have some DWARF field with the value 0x42 and
for that offset you apply an `R_RISCV_SUB6` relocation with a value of 4 (see
attachment for an example).

- Do a dwarf dump and check the relocated value. Example:

  $ riscv64-unknown-elf-objdump --dwarf bug.o | grep "DW_AT_high_pc     :"

    <1f>   DW_AT_high_pc     : 0x42
    <4b>   DW_AT_high_pc     : 0xffffffff
    <77>   DW_AT_high_pc     : 0xffffffffffffffff
    <a3>   DW_AT_high_pc     : 0x41
    <cf>   DW_AT_high_pc     : 0x3e <-- here
    <fb>   DW_AT_high_pc     : 0x45
    <127>   DW_AT_high_pc     : 0x3f
    <153>   DW_AT_high_pc     : 0x4345
    <17f>   DW_AT_high_pc     : 0x413f
    <1ab>   DW_AT_high_pc     : 0x46444345
    <1d7>   DW_AT_high_pc     : 0x3e40413f
    <203>   DW_AT_high_pc     : 0x142424242424242
    <22f>   DW_AT_high_pc     : 0xff42424242424242

- Expected value: keep the upper 2 bits and write the computed relocation value
to the lower 6 bits: 0x7E
  - (0x42 & 0xC0) | (((0x42 & 0x3F) - 4) & 0x3F)
    = 0x40 | ((2 - 4) & 0x3F)
    = 0x40 | (-1 & 0x3F)
    = 0x40 | 0x3F
    = 3F

- Obtained value: 3F (overrides upper 2 bits)

This seems to be an issue in `elfxx-riscv.c`. Despite the `dst_mask` being
correctly specified in the `HOWTO` entry as 0x3f, `riscv_elf_add_sub_reloc`
doesn't seem to apply the mask. Instead, it applies the same operations as for
`SUB8`. Since `SUB6` also has a `howto->bitsize` of 8 it produces the same
result as `SUB8`.

The `R_RISCV_SUB6` relocation is correctly applied by `ld`. Steps to reproduce:

- Get the same object file
- Get a linker script that links things starting a the 0 address (e.g. `touch
test.lds`)
- Link with `riscv64-unknown-elf-ld -Ttest.lds -static bug.o"
- Check the result.
  - $ riscv64-unknown-elf-objdump -D a.out | grep "ce:"
      ce:   7e00 (...)
- This seems to be because, by contrast, the relocation is applied with the
proper mask in `elfnn-riscv.c`:

  bfd_vma word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset);
  word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
  bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]