On Thu, 2021-04-22 at 17:25 -0500, Peng Yu wrote: > On 4/22/21, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > > On Thu, 22 Apr 2021 at 19:45, Peng Yu wrote: > > > The man is not well written in this and is confusing. It also > > > doesn't > > > explain the underlying details. > > > > The manual seems quite clear regarding those options. > > Here is why the manpage of these 4 options is poorly written. > > > -fpic > > Generate position-independent code (PIC) suitable for use in > > a shared library, > > The above sentence means it can be used for shared libraries or can > just be used for shared library? > > It is ambiguous as written in this way. I don't know what you are talking about, is there any difference with "shared library" and "shared libraries"? > > if supported for the target machine. > > If not supported on the target machine, so what? How do I know what > target machines support it? gcc will exit with a non-zero status. If you don't use a target machine, you won't need to know it. If you use a target machine, you can check its psABI and remember the result easily. > > Such code accesses all constant addresses through a global > offset table (GOT). > > "Such code" is to give a definition of any position-independent code. > Or more narrowly, just mean the code generated by this option. It just means the code generated by this option *here*. But it does not mean other code won't use GOT. (Why should we discuss English grammar on gcc-help?!) > > The dynamic loader resolves the GOT entries when the program starts > > (the dynamic loader is not part of GCC; it is part of the operating > > system). If the > GOT size for the linked executable exceeds a > machine-specific maximum size, you get an error message from the > linker indicating that -fpic does not work; in that case, > recompile with -fPIC instead. > > This is a forward reference to -fPIC. It hasn't explained what -fPIC > is at this point in the manpage. Who made the rule saying "a manual can not have forward references?" > > (These maximums are 8k on the SPARC, 28k on AArch64 and 32k on the > > m68k and RS/6000. The x86 has no such limit.) > > This seems to be an incompletely mentioned list of architectures. What > about other architectures? As mentioned in this thread, the upper and > lower case options are no different on x86. But this can not be seen > here. If you really care those architectures, read the psABI of them. > > Position-independent code requires special support, and > > therefore works only on certain machines. For the x86, GCC supports > > PIC for System V but not for the Sun 386i. > > Code > > generated for the IBM RS/6000 is always position- > > independent. > > So -fpic should not be specified on IBM RS/6000? Is it still a > relevant architecture nowadays? It seems to be an old architecture > which is not relevant nowadays. This seems to be some history text > lingering on the manpage. Why not delete them from the manpage? The architecture of RS/6000 is PowerPC. PowerPC is absolutely relevant today, and the code generated for other PowerPC CPUs are also always postion-independent. > https://en.wikipedia.org/wiki/IBM_RISC_System/6000 > > > When this flag is set, the macros "__pic__" and "__PIC__" > > are defined to 1. > > What these values are for? If I were to write it, I would add a clause > to explain what it is for. Like "... are defined to 1, which is for > blah blah." Then you can use C preprocessor directives to determine if the code is being built as PIC. Should it be explained again to a rational C/C++ programmer? > > -fPIC > If supported for the target machine, emit > position-independent code, suitable for dynamic linking and avoiding > any limit on the size of the global offset table. > > The above description doesn't apply to -fpic. Or they equally apply to > -fpic. I don't see the difference between -fpic and -fPIC up reading > here. In -fpic it's said the code is limited by GOT size, and in -fPIC it's said explicitly that the code won't be limited by GOT size anymore. So what? > > This option makes a difference on AArch64, m68k, PowerPC and SPARC. > > Difference of what? It could mean on these systems, specifying this > option can be different from not specifying them. Or it could mean > this option has different effects on these systems. Again it is an > ambiguous sentence. It's just you don't understand the idiom "make a difference". Again why should we discuss English grammar on gcc-help?! > > Position-independent code requires special support, and > > therefore works only on certain machines. > > What special support? What certain machines? At least the machine should have some way to get the program counter. > > When this flag is set, the macros "__pic__" and "__PIC__" > > are defined to 2. > > Same question. What are these for? And how they are used? > > > -fpie > > -fPIE > These options are similar to -fpic and -fPIC, but the > generated position-independent code can be only linked into > executables. > > This is also ambiguous. What does "linked into executables" mean? > "shared library" can also be linked into executables? The wording > choice should be reconsidered. As I understand from previous > discussion. This seems to mean, to make shared library, -fpic/-fPIC > should be used. To make executable -fpie/-fPIE should be used. But as > it is written, it is confusing. > > > Usually these options are used to compile code that will be linked > > using the -pie GCC option. > > What "usual" cases are referred? As I said, you can generate some position independant code for a non position independant executable. It's "unusual", and does not make any sense IMO. But you can't say there are no such cases. > > -fpie and -fPIE both define the macros "__pie__" and > > "__PIE__". The macros have the value 1 for -fpie and 2 for -fPIE. > > What are these used for? > > > If you want more > > details, you can always go looking in the code. Also see page 15 in > > https://www.akkadia.org/drepper/dsohowto.pdf > > The problem is not just "more details". It is the man page is poorly > written. The problem is *you* have too little knowledge and want to get too many, and using a wrong way (keep doing experiments and asking questions). > This dsohowto.pdf document does not help to answer my question of > -fpic/-fPIC/-fpie/-fPIE at this moment. As it is written, "The most > important recommendation is to always use -fpic or -fPIC when > generating code which ends up in DSOs. " It doesn't explain what -fpic > and -fPIC are, and their difference. So it does not help. > > > More generally, https://lwn.net/Articles/276782/ has links to a series > > of great blog posts about symbol relocations and linking. > > https://www.airs.com/blog/archives/549 is from the same author. > > Article 549 says "It turns out to be quite simple to create a PIE: a > PIE is simply an executable shared library." So this also causes > confusion here. The "shared library" in "Generate > position-independent code (PIC) suitable for use in a shared library," > actually means "shared library" that is not executable? > > By "executable", it means whether it can be run or not? Many .so files > (see below) do have the x permission. So the word "executable" is also > ambiguous? > > $ ls -lgG /lib/x86_64-linux-gnu/libc-2.31.so > -rwxr-xr-x 1 1839792 2021/01/05-00:47:42 /lib/x86_64-linux-gnu/libc- > 2.31.so > > "To make a shared library executable you just need to give it a > PT_INTERP segment and appropriate startup code." > > Although there is this explanation of executable afterward, it is > again confusing. The following .so file also has .interp. I don't know > what "startup code" specifically refers to. But it does have some > startup code. However, I don't think the author means this file is an > "executable". My understanding of "executable" is just something that > can run. > > $ readelf -x .interp /lib/x86_64-linux-gnu/libc-2.31.so > > Hex dump of section '.interp': > 0x00193f20 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux- > 0x00193f30 7838362d 36342e73 6f2e3200 x86-64.so.2. > > $ objdump -d /lib/x86_64-linux-gnu/libc-2.31.so |grep start > 26b97: 48 8b 05 a2 73 19 00 mov > 0x1973a2(%rip),%rax # > 1bdf40 <_dl_starting_up> > 0000000000026c20 <__libc_start_main@@GLIBC_2.2.5>: > 26c3a: 48 8b 15 ff 72 19 00 mov > 0x1972ff(%rip),%rdx # > 1bdf40 <_dl_starting_up> > ... > > Do you see what is wrong with writeup like these? libc.so is just a special case. If you run it directly it will print its version info. I don't know any other shared object with such a "feature" (and this libc feature is never used by 99.99% of people, I think). > Any verbal explanation on a complex topic like is very likely to end > up confusions and ambiguities. I don't know the best solution. But it > seems concrete runnable examples > (https://linux.xidian.edu.cn/git/xry111/pie_vs_pic > is good in this regard) and explaining the disassembled results (it > lacks this aspect though to understand what exactly is going on, I am > not blaming it (as it is not made for this purpose), just to mention > the fact) is one way to go to fully resolve these problems. Showing disassemble everywhere is stupid for a compiler manual. The compiler is being improved every time moment and a better optimization will change the outputed assemble code. Then what? Update the disassemble everywhere in the doc? > Nevertheless, the manpage is poorly written even from a pure English > language point of view. If you believe your English is better, you can always make a change and send it to gcc-patches. That's how things work in FOSS community. Let me re-assert: The problem is *you* have too little knowledge and want to get too many, and using a wrong way (keep doing experiments and asking questions). >From the previous posts, I can deduce: you don't know ELF, you don't know in a system which parts are belong to GCC, you don't know C more than a newbie who can only write "hello world" (as you don't know UB). Then you want to understand all of these just by playing with GCC, and sending other people a long list of questions? You won't improve yourself efficiently in this way, even if we don't consider that sending a long list of questions is quite disrespectful in maybe all cultures. We've wasted two days trying to teach you. It's really more efficient for you to buy a CS:APP and a bottle of coffee, then close yourself in a room and read CS:APP carefully for 12 hours. And, when you come up with a question, spend at least 30 minutes trying to understand it yourself, then at least other 30 minutes trying to get the answer with Google. If you speak Chinese you should also buy this book and read it carefully, along with CS:APP: https://item.jd.com/10067200.html Ah, before that you may need to read something like C Primer, as you don't know C well. Anyway you still have many things to learn from the textbooks. -- Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University