Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong sign extension for 32bit relocations #564

Closed
BrunoASMauricio opened this issue Jun 9, 2023 · 2 comments
Closed

Wrong sign extension for 32bit relocations #564

BrunoASMauricio opened this issue Jun 9, 2023 · 2 comments

Comments

@BrunoASMauricio
Copy link

The following minimal example showcases how the 32 bit relocation symbol R_ARC_32_ME is malfunctioning.

asm.S

.text
.global main
.align 4
main:

1001:
  st 1, [0xF0000008]
  j @1001b

tarc.ld

ENTRY(main)
SECTIONS
{
 . = 0x80000100;
 .text : { *(.text) }
}

Compiling it with:
arc64-elf-gcc asm.S -mcpu=hs6x --specs=nsim.specs -T tarc.ld -nostartfiles -nostdlib

Yields

/tmp/ccpBYbhK.o: in function `main':
(.text+0xc): relocation truncated to fit: R_ARC_32_ME against `no symbol'
collect2: error: ld returned 1 exit status

This happens because the 0x8000_0000 gets sign extended when it shouldn't. Replacing that value with 0x7000_0000 "fixes this".
It is expected for these values to be unsigned.

@BrunoASMauricio
Copy link
Author

After cross-referencing the 32 bit relocations that are set as "signed" in include/elf/arc-reloc.def with the ABI, we can take two conclusions:

  1. ARC_32_ME_S is NOT IN THE ABI, nor does it seem to be used anywhere (created issue Relocation symbol ARC_32_ME_S is defined but not used #565 for this)
  2. There are quite a few 32 bit relocations that the ABI does not specify are signed/unsigned but are set as signed. A table of the respective entries in the ABI follows:
Enum Hex ELF Reloc Type Description Details
18 0x12 R_ARC_SDA32 SDA relocation word32 = ME ((S+A)-SDA_BASE)
27 0x1b R_ARC_32_ME Runtime relocation word32 = ME (S + A)
30 0x1e R_ARC_SDA32_ME SDA relocation word32 = ME ((S+A)-SDA_BASE)
49 0x31 R_ARC_32_PCREL PC-relative (data) word32 = (S+A-PDATA)
50 0x32 R_ARC_PC32 PC-relative word32 = ME (S+A-P)
51 0x33 R_ARC_GOTPC32 PC-relative GOT reference word32 = ME (GOT + G + A - P)
52 0x34 R_ARC_PLT32 PC-relative (PLT) word32 = ME (L+A-P)
54 0x36 R_ARC_GLOB_DAT GOT relocation word32= S
55 0x37 R_ARC_JMP_SLOT Runtime relocation word32 = ME(S)
56 0x38 R_ARC_RELATIVE Runtime relocation word32 = ME(B+A)
57 0x39 R_ARC_GOTOFF GOT relocation word32 = ME(S+A-GOT)
58 0x3a R_ARC_GOTPC PC-relative (GOT) word32 = ME(GOT_BEGIN - P)
98 0x62 R_ARC_PCLO32_ME_2 PC-relative address word32 = ME ((S + A - P ) >> 2)
99 0x63 R_ARC_PLT34 PC-relative (PLT) word32 = ME ((L + A - P ) >> 2)

@claziss besides R_ARC_32_ME, which of these should be set to bitfield?

@claziss
Copy link
Contributor

claziss commented Jun 15, 2023

@BrunoASMauricio corrected relocs types:

Enum Hex ELF Reloc Type Type Details
18 0x12 R_ARC_SDA32 signed word32 = ((S+A)-SDA_BASE)
27 0x1b R_ARC_32_ME bitfiled word32 = ME (S + A)
30 0x1e R_ARC_SDA32_ME signed word32 = ME ((S+A)-SDA_BASE)
49 0x31 R_ARC_32_PCREL signed word32 = (S+A-PDATA)
50 0x32 R_ARC_PC32 signed word32 = ME (S+A-P)
51 0x33 R_ARC_GOTPC32 signed word32 = ME (GOT + G + A - P)
52 0x34 R_ARC_PLT32 signed word32 = ME (L+A-P)
54 0x36 R_ARC_GLOB_DAT bitfiled word32= S
55 0x37 R_ARC_JMP_SLOT bitfiled word32 = ME(S)
56 0x38 R_ARC_RELATIVE bitfiled word32 = ME(B+A)
57 0x39 R_ARC_GOTOFF signed word32 = ME(S+A-GOT)
58 0x3a R_ARC_GOTPC signed word32 = ME(GOT_BEGIN - P)
98 0x62 R_ARC_PCLO32_ME_2 signed word32 = ME ((S + A - P ) >> 2)
99 0x63 R_ARC_PLT34 signed word32 = ME ((L + A - P ) >> 2)

@claziss claziss changed the title Wrong sign extension for R_ARC_32_ME relocation Wrong sign extension for 32bit relocations Jun 15, 2023
@claziss claziss closed this as completed Jun 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants