llvm / llvm/llvm-project

LLD emits incorrect section-based relocations using "--emit-relocs" after an AArch64 Errata fix

Open
#223,356 3 comments 0 reactions 0 assignees View on GitHub
lld:ELF
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

### Descriptions:

A recent errata fix (PR #170495), which introduced synthetic local symbols for .text sections to prevent Chromium crashes, causes a regression when combined with the --emit-relocs flag.
In our case it means it could be more then one .text section symbol having same sec id in the final binary. During the copy relocation phase, LLD initialize a symbol look-up table which uses a map for this process [here](https://github.com/llvm/llvm-project/blame/main/lld/ELF/SyntheticSections.cpp#L2087). Since there are multiple '.text' section symbol so the last symbol will override the previous one. Consequently LLD will emits incorrect section-based relocation entries, they have wrong "base" address.

For example, as a results Bolt will process the binary incorrectly (#184332).

Please see this minimal example which triggers the described issue above.

### Steps to reproduce:

#### minimal_example.s

```asm
.section .note.gnu.property,"a"
.p2align 3
.long 4
.long 0x10 // descriptor length
.long 0x5 // GNU property type
.asciz "GNU"
.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
.long 4
.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
.long 0

.section .text.01, "ax", %progbits
.balign 4096
.globl _start
.type _start, %function
_start:
bl far_away_no_bti

.section .text.far, "ax", %progbits
.globl far_away_no_bti
.type far_away, function
far_away_no_bti:
.space 4096 - 28, 0
adrp x0, table
ldr x1, [x1, #0]
ldr x0, [x0, :got_lo12:table]
.space 0x8000000, 0
ret

.section .text
dat: .quad 0

.section .data
table:
.quad dat
```
#### LDS
```
SECTIONS {
.text 0x10000 : {
*(.text.01);
. += 0x8000000;
*(.text.far);
}
}
```

#### Compile:

```
llvm-mc -mattr=+bti -filetype=obj -triple=aarch64 -o a.o minimal_reproducer.s
```

#### Link:

```
ld.lld --script lds.s -fix-cortex-a53-843419 --emit-relocs -verbose a.o -o exe-bad --threads=1
```

In this example we have 3 '.text' sections symbols in symTab.

```
Symbol table '.symtab' contains 35 entries:
Num: Value Size Type Bind Vis Ndx Name
...
10: 0000000000010000 0 SECTION LOCAL DEFAULT 2 .text
11: 0000000010012050 0 SECTION LOCAL DEFAULT 4 .data
12: 0000000000010000 0 SECTION LOCAL DEFAULT 2 .text
13: 0000000008010038 0 SECTION LOCAL DEFAULT 2 .text
...
```

The reloc symbol value should be '0010000' , but it uses the last '.text' symbol value.

```
Relocation section '.rela.data' at offset 0x100220a0 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000010012050 0000000d00000101 R_AARCH64_ABS64 0000000008010038 .text + 10002040
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with minimal_example.s and lds.s using the llvm-mc and ld.lld commands in the report. Read lld/ELF/SyntheticSections.cpp around the copy-relocation symbol lookup at the linked line, then inspect the emitted .rela.data entry. Done means section-based relocations use the correct .text symbol base when --emit-relocs and the AArch64 errata fix are combined.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.