[AArch64] Fix pointer inequality in pointers to the same ifunc symbol#945
Open
parth-07 wants to merge 1 commit intoqualcomm:mainfrom
Open
[AArch64] Fix pointer inequality in pointers to the same ifunc symbol#945parth-07 wants to merge 1 commit intoqualcomm:mainfrom
parth-07 wants to merge 1 commit intoqualcomm:mainfrom
Conversation
f0375c4 to
db53f97
Compare
This commit fixes pointer inequality in pointers to the same ifunc
symbol. Let's understand the issue in more detail using the below
example:
```cpp
char *foo_impl() { return "foo"; }
static char *(*foo_resolver())(void) { return foo_impl; }
char *foo() __attribute__((ifunc("foo_resolver")));
char *(*foogp)() = foo;
int main() {
char *(*foop)() = foo;
}
```
`foogp` and `foop` pointers both point to the same function `foo`.
However, their values were different. The root cause was improper
handling of the underlying relocations when the symbol is of type ifunc.
```
char *(*foogp)() = foo; // R_AARCH64_ABS64
// ...
char *(*foop)() = foo; // R_AARCH64_ADR_GOT_PAGE + R_AARCH64_LD64_GOT_LO12_NC
```
Previously, the linker resolved the R_AARCH64_ABS64 relocation here to
the plt slot of foo, let's refer to it as plt[foo], and the
GOT-relocations were resolved to the .got.plt slot of foo, let's refer
to it as .got.plt[foo]. As a result, foogp stores the address of
plt[foo] and foop stores the contents of .got.plt[foo], that is, the
address of the resolved function foo. Clearly, the two values are
different.
We resolve this issue by creating a got slot for foo when the foo has
both an absolute reference and a GOT-reference. The got slot of foo
is filled by the linker and stores the address of plt[foo].
With this, both the absolute-reference and got-reference to an ifunc symbol
results in the same address. Please note that:
- we do not create .got slot of foo when we only have an absolute reference
to foo because .got slot is unnecessary in this case, and
- we do not create .got slot of foo when we only have a GOT-reference
because in this case we can directly use .got.plt slot and access the
function directly without any indirection penalty or the
pointer-inequality bug.
Resolves qualcomm#913
Signed-off-by: Parth Arora <partaror@qti.qualcomm.com>
db53f97 to
9ac9369
Compare
quic-seaswara
requested changes
Mar 18, 2026
|
|
||
| recordGOT(symInfo, G); | ||
| symInfo->setReserved(symInfo->reserved() | Relocator::ReserveGOT); | ||
| } |
Contributor
There was a problem hiding this comment.
The GNU linker creates a igot and igot.plt probably it would be useful to follow the pattern for IFUNC symbols.
Contributor
There was a problem hiding this comment.
This can simplify the ifunc implementation too, probably we can reserve the GOT and PLT slots and later remove the GOT slots not needed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit fixes pointer inequality in pointers to the same ifunc symbol. Let's understand the issue in more detail using the below example:
foogpandfooppointers both point to the same functionfoo. However, their values were different. The root cause was improper handling of the underlying relocations when the symbol is of type ifunc.Previously, the linker resolved the R_AARCH64_ABS64 relocation here to the plt slot of foo, let's refer to it as plt[foo], and the GOT-relocations were resolved to the .got.plt slot of foo, let's refer to it as .got.plt[foo]. As a result, foogp stores the address of plt[foo] and foop stores the contents of .got.plt[foo], that is, the address of the resolved function foo. Clearly, the two values are different.
We resolve this issue by creating a got slot for foo when the foo has both an absolute reference and a GOT-reference. The got slot of foo is filled by the linker and stores the address of plt[foo]. With this, both the absolute-reference and got-reference to an ifunc symbol results in the same address. Please note that:
Resolves #913