x86: Disallow ".long foo@PLT - .L4" for PLT32 relocation
Binutils' x86 assembler now disallows `.long foo@PLT - .L4` to prevent incorrect PLT32 relocations.
This change disallows the assembly syntax .long foo@PLT - .L4 for PLT32 relocations on x86. The discussion clarifies that the correct relocation type for PLT32 is R_X86_64_PLT32, which involves L + A - P. While .long can be used, it lacks a proper relocation type for PLT expressions, leading to potential issues. The decision is to reject this specific syntax to avoid ambiguity and ensure correct relocation handling, rather than issuing a warning, as it can originate from both hand-written and compiled code.
- proposer
Clarifies that the x86 assembler now disallows `.long foo@PLT - .L4` for PLT32 relocations, explaining the underlying relocation calculation and overflow conditions.
“L + A - P with the usual meaning of L - address of PLT entry for the referenced symbol A - addend P - address of the storage unit being relocated Since the result has to be a valid (64-bit) address, sign-extension is necessary, and hence the overflow condition has to match that (starting from the 32-bit input field).”
- reviewer
Seeks clarification on the R_X86_64_PLT32 calculation and the expected linker behavior for overflow conditions.
“Would you please provide me with the calculation R_X86_64_PLT32 stands for and what the calculation required would be for `.long' should we have an actual relocation representing this operation? Also what is the linker expected by the psABI to do on an overflow condition?”
- contributor
Explains that for `.long`, there is no correct relocation type for PLT expressions, and R_X86_64_PLT32 is the appropriate type for PLT expressions, while R_X86_64_PC32 is for simple PC-relative expressions.
“For .long there simply is no correct relocation type to use for PLT (and, fwiw, simple PC-relative) expressions. The correct type to use is R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).”
- reviewer
Acknowledges the explanation regarding `.long` and `.slong` and questions whether an assembly warning would be appropriate, inquiring about the origin of this assembly pattern.
“Ack, understood, although would perhaps an assembly warning be in order? Does this case typically come from handwritten assembly or one of compiled origin?”
- proposer
States that a warning is not feasible because the problematic assembly syntax can originate from both handwritten and compiled code.
“Both, hence imo a warning is out of question.”
Technical Tradeoffs
- Disallowing the syntax outright, rather than issuing a warning, might break existing code that relies on this behavior, even if it's technically incorrect.
- The decision to reject `.long` for PLT expressions implies that users must explicitly use the correct syntax, potentially increasing assembly code complexity.
In Details
This patch addresses an ambiguity in x86 assembly syntax related to PC-relative relocations involving the PLT. Specifically, it disallows the construct .long symbol@PLT - offset when generating PLT32 relocations. The core issue is that .long doesn't have a directly corresponding relocation type for such expressions, unlike R_X86_64_PLT32 which correctly handles L+A-P. The decision to reject this syntax outright, rather than warn, stems from its potential to appear in both hand-written assembly and compiler output.
- x86
- A family of instruction set architectures (ISAs) for microprocessors, commonly used in desktop and server computers.
- PLT
- Procedure Linkage Table. A table used in ELF executables to resolve dynamic library calls at runtime. It acts as an intermediary between the program and the actual library functions.
- PLT32 relocation
- A type of relocation specific to the x86-64 architecture that encodes a 32-bit offset for accessing the Procedure Linkage Table. It is often used for indirect calls to functions in shared libraries.
- R_X86_64_PLT32
- An ELF relocation type for the x86-64 architecture. It calculates a 32-bit PC-relative offset to an entry in the Procedure Linkage Table (PLT).
- R_X86_64_PC32
- An ELF relocation type for the x86-64 architecture. It calculates a 32-bit PC-relative offset to a symbol.
- ELF
- Executable and Linkable Format. A standard file format for object files, executables, and shared libraries on Unix-like systems.
- psABI
- Processor-specific Application Binary Interface. Defines the low-level conventions for how software components interact at the machine code level, including function calling conventions, data type representations, and system call interfaces.
- addend
- A constant value included in a relocation entry that is added to the base address of a symbol to calculate the final address.