gcc 9.2 (and maybe other versions) is putting jump table directly in the text section. On most processors I guess this is not an issue as the text section is usually readable. But on some processors like (like the SPARC processor) this is an issue when user space text section is protected (from the OS) with an "eXecute Only" MMU protection. In such case when the code is trying to read the jump table from the text section, a data abort exception is generated and the all application is crashed. To work around the problem I have to either: * change the protection (from the OS) on the text segment to "Read and eXecute" * compile with the -fno-jump-table command line option. These 2 work arroud allow the application code (that use to work OK on gcc 8 and gcc 7) to run again when comiled with gcc 9 I believe the jump_table should go in the ro_data section. Putting them in the text section seems wrong. A jump table is data after all. Another solution is to avoid generating "jump tables" on processors/architecture that could put "eXecute Only" MMU protection on text segments. On SPARC/LEON there is also the -muser_mode command line option that could be used to avoid generating jump tables if it is not possible to move them in the ro_data section.
This is a target specific issue. That is each target decides where to put the jump table. On some targets, it is already done not in the text section but the rodata section. It seems like sparc is not one of those. the SPARC back-end does not get much attention these days as oracle has moved away from sparc really.
Nothing has changed in GCC 9.x and this is also visible with GCC 7 & 8, although the SPARC port is configured with JUMP_TABLES_IN_TEXT_SECTION set to 0.
The decision dates back to the rewrite of the SPARC port in 1998: 21652 davem /* Align to cache line in the function's code section. */ 21652 davem function_section (current_function_decl);
Created attachment 47475 [details] assembly file with jump tables in the text section
I guess JUMP_TABLES_IN_TEXT_SECTION is supposed to mean that the "jump tables" should not be put in the text section. However something is wrong then because gcc 9 (and maybe previous) is putting the jump table as a "subsection" of the text section in the generated assembly code (therefore it is part of the text section). I am attaching a generated assembly file where "jump tables" are generated and declared as subsection of the text section. In this file you can for example look at the L87 jump table which is used by the tfp_format function (this is the first jump table that triggered an exception in my test case). So assuming the intend is to put the jump table in the rodata section, something seems to be broken in the build then.
> So assuming the intend is to put the jump table in the rodata section, > something seems to be broken in the build then. No, see my earlier remark, this was intended.
DaveM, any recollection about the rationale for the decision?
I cannot think of any specific reason why the jump tables were put into the text section. I even tried to consider relocation ramifications. Maybe this makes GOT OP linker optimizations more likely when -fPIC?
> I cannot think of any specific reason why the jump tables were put into the > text section. I even tried to consider relocation ramifications. Yes, relocation considerations quickly come to mind. Thanks in any case. > Maybe this makes GOT OP linker optimizations more likely when -fPIC? I wonder whether this wouldn't stem from limitations of the Sun assembler or somesuch: in PIC mode, this would generate differences between labels from different sections, so relocations need to be generated by the assembler.
The SPARC port even has a specific implementation here: /* This is how we hook in and defer the case-vector until the end of the function. */ #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \ sparc_defer_case_vector ((LAB),(VEC), 0) #define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) \ sparc_defer_case_vector ((LAB),(VEC), 1)
Created attachment 47476 [details] Tentative fix
I think that case vector stuff was written by Richard Henderson FWIW.
> I think that case vector stuff was written by Richard Henderson FWIW. Richard, do you have any recollection of this?
The only reason I can think for jump tables to be put into the text section is the old aout format, which didn't have a separate read only data section. There should be no reason to do that these days.
Thanks for the feedback and the support. Now maybe this is not the good place to ask question but I am wondering: Most of today's processors have separate data and instruction cache. Isn't it sub optimal performance wise to load the instruction cache with jump tables (just data consuming precious cache resource) and then having to load these same jump tables again in the data cache to use them (jump tables might then be loaded twice and eat instruction cache for no reason). If there were only processors with unified cache this would not be an issue but this is not the most common case in today's processors. Am I missing something? Shouldn't most architecture put jump tables in rodata section. Thanks JC
(In reply to Jean-Christophe Dubois from comment #15) > Am I missing something? YES. Most likely it will not be loaded in the instruction cache as it is larger than the cache line size.
My though reading this is that most RICSs have problems synthesizing large literals, so putting a jump table in .text might increase the likelihood of its address being synthesizable with a PC + offset addressing mode. Putting it in .rodata would almost certainly require you to indirect through the GOT to address it. That said, if the user wants .text to be execute-only, then the jump table ought to land in .rodata.
(In reply to Mikael Pettersson from comment #17) > My though reading this is that most RICSs have problems synthesizing large > literals, so putting a jump table in .text might increase the likelihood of > its address being synthesizable with a PC + offset addressing mode. Putting > it in .rodata would almost certainly require you to indirect through the GOT > to address it. That said, if the user wants .text to be execute-only, then > the jump table ought to land in .rodata. As far as I can say with the assembly code generated today for SPARC32, the jump tables could be anywhere in memory (4GB address space) with the exact same code. I don't think it would trigger additional indirection. It might be different for other architecture.
(In reply to Andrew Pinski from comment #16) > (In reply to Jean-Christophe Dubois from comment #15) > > Am I missing something? > > YES. Most likely it will not be loaded in the instruction cache as it is > larger than the cache line size. Maybe this is not a big issue but couldn't the end of the jump table be loaded in instruction cache (depending on function alignment) with the beginning of the function it will be used with (when code is compiled with -Os functions don't seem to be aligned on cache line size) Or the beginning of the jump table with the end of the previous function. This might be only few bytes of instruction cache each time and maybe it is not an issue overall. And when you mix data and code there will also be some instruction that will enter the data cache if things are not aligned on cache line size. Maybe this is not an issue performance wise either.
GCC 8.4.0 has been released, adjusting target milestone.
Probably too late to be changed now.