https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81490
Bug ID: 81490 Summary: x86: Handling of symbol ranges for __seg_fs/__seg_gs Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: hpa at zytor dot com Target Milestone: --- Note: this was tested with gcc 6.3.1, but I believe there is no changes in later versions. On x86, gcc assumes that the valid range of symbols compiled with __seg_fs and __seg_gs are the same as for symbols in the normal namespace. This is not appropriate, as in general these symbols will be unrelated to the symbol addresses, especially in position-independent code. __thread does the right thing, and generates 32-bit absolute references rather than (%rip)-relative. From an optimization point of view, there seems to be two independent parameters: 1. If the range is restricted to [0, 2G), [-2G, 2G) or unrestricted. This affects what kind of address expressions are available. 2. If the range is guaranteed to be within [-2G, 2G) of the loaded image. In this case (%rip)-relative addressing can be used. This one is IMO not really significant. We would like to migrate the way we do percpu variable handling in the Linux kernel to something compiler-aware. __seg_gs is a much closer fit for us than __thread, for several reasons: a. The Linux kernel has a concept of percpu pointers, i.e. addresses that are unresolved with respect to which CPU they reference. b. The percpu base pointer, unlike the __thread base pointer, is volatile as it can change if a thread is preempted. c. gcc still does not appear to provide for a mechanism to specify which segment register is the thread base pointer.