I'm not sure I can answer all your questions, but I'll cover the ones I know the answer to. On 22/03/2025 13:21, Massimiliano Cialdi via Gcc-help wrote: > Hi all, > > I'm working on an educational project to implement a custom loader for a > position-independent executable (PIE) running on a bare-metal Cortex-M > microcontroller, using the ARM GNU toolchain (gcc and binutils). > > Context: > - I compile my C source files with -fPIE and link with -pie. > - The resulting ELF file contains sections like .rel.dyn, .got, .got.plt, > and .dynamic. > - I extract the raw binary, which includes all sections marked with the > ALLOC flag, and I load it to an arbitrary address at runtime. > - My loader reads .rel.dyn and applies the relocations. So far, I only see > R_ARM_RELATIVE entries in this section. > > Questions: > 1. Are there practical differences between -fpie and -fPIE on Cortex-M > bare-metal targets? As of today, no. The Arm backend generates the same code for both. > - My executable is about 140KB, so it's relatively small. > - Does -fpie affect the type of relocations generated or their handling > by the loader? Not at present. > - Are there any downsides or advantages to using -fpie rather than -fPIE > in this context? -fpie generally implies trading limits on address ranges for better code size. If in future some optimizations were added improved code for -fpie, then your application might fail to build with that if it exceeded those limits. > > 2. Regarding the .rel.dyn section: > - On my builds, all entries are R_ARM_RELATIVE. > Is this always expected when using -fPIE/-pie on ARM Cortex-M? > Or could other relocation types appear, depending on compiler flags or > code patterns? > - Does using -fpie instead of -fPIE change the relocation entries or > reduce the need for relocations? The PIC/PIE model is mostly used and tested on systems that have an MMU and that can present a standardized address space view for applications. I'm aware of some people using position independent models for M-profile devices, but the approaches tend to be quite bespoke and it's generally outside my area of expertise. > > 3. On .got.plt and .dynamic sections: > - In my ELF files, I see .got.plt but no relocation entries referencing > it. On Cortex-M (without dynamic linking), is it safe to ignore > .got.plt, or should it be processed explicitly? The .got.plt is the table of addresses used by the stubs in the .plt section. This is mostly needed to support calling into shared libraries, but there might be other use cases as well. If you're not using shared libraries (which you probably aren't because they really do tend to need an MMU for the 'shared' to take effect), then you might want to check out the -fstatic-pie option to see if it simplifies things for you. > - The .dynamic section is present, but I assume it's only relevant for > dynamic linking. Can I safely ignore .dynamic in a bare-metal PIE > loader? The .dynamic section contains a lot of information that a dynamic loader/linker might require. Some of it may be redundant if you aren't using shared libraries, or have other simplifications to your binary structure. But other bits might be needed. For example, the header contains the address of the INIT_ARRAY/FINI_ARRAY data, which is needed to run C++ static constructors/destructors (or equivalent for other languages). > > Goal: > I want to implement a minimal and robust loader for PIE executables on > Cortex-M: > - The loader loads the raw binary into RAM and applies relocations. > - I'm trying to understand which sections I need to process and what > relocation handling is necessary, especially in the -fpie vs -fPIE > scenario. > > Any guidance, clarifications, or pointers to documentation would be greatly > appreciated! > There's probably a lot more that I haven't covered, but it's getting outside my real area of expertise now. Hopefully the above will get you a bit further. > Thanks in advance, > Max > > R.