Mike Cui <cuicui@xxxxxxxxx> writes: > I want to link a small kernel to run at 0xFFFF800000000000, all text, > data, bss will fit in a 2GB region. I noticed that the 2 code models > that I can choose from, small and kernel, require the kernel to run in > the first or last 2GB of address space, not in the middle. One option > I have is large, which turns every global function call into a > indirect call. The other option, of course, is small_pic, but that > turns every global memory reference into 2 references, and I have to > setup the GOT when loading the kernel. > > If all my code and data fit in 2GB, it seems like it should be > possible for this 2GB to be located anywhere. But GCC seems to like to > generate instructions in the form of > mov $symbol, %reg > where the immediate operand $symbol is a sign extended (or zero > extended) 32-bit immediate, thus requiring symbol to be in the first > or last 2GB of address space. > > If we replaced those instructions with > lea symbol(%rip), %reg > then the only requirement is that symbol is in the same 2GB region as > the current code. > > Are there existing gcc options to do what I want? Is what I want even possible? I think you can get approximately what you want by using "#pragma GCC visibility push(protected)" at the start of some header file to give all symbols, including all external symbols, protected visibility. Then compile with -fpic. I don't know if that will cover all cases. It seems like kind of a special purpose requirement. Ian