llvm / llvm/llvm-project

Clang generates .rodata non-local relocations with `-fno-direct-access-external-data -fno-PIE`

Open
#197,254 0 comments 0 reactions 0 assignees View on GitHub
clang
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

When compiling the following source code, Clang generates a `.rodata._ZTV5Local` section containing the `Local`'s vtable. The problem is that the base class is declared in a library, so the entry point of the virtual function `S::f()` is not known at link time. When using `-fno-direct-external-access-data` , the compiler was supposed to know that the entry is extern and thus not force the address to be the executable's PLT. GCC compiles this correctly.

It makes no difference if the executable is linked `-pie` or `-no-pie`. But the problem does go away if the source is compiled `-fPIE`.

Godbolt tree link: https://godbolt.org/z/j5en7on1x

Sources inline:

lib.h:
```c++
#ifdef BUILD
# define LIB_API __attribute__((visibility("protected")))
#else
# define LIB_API __attribute__((visibility("default")))
#endif

struct LIB_API S
{
virtual ~S();
virtual void *f();
};
```
lib.cpp:
```c++
#define BUILD
#include "lib.h"

S::~S() { }
void *S::f() { return nullptr; }
```
main.cpp:
```c++
#include "lib.h"

struct Local : S { };
int main()
{
Local l;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.