I don't understand meaning of this: +"a function to be evaluated during reloc processing" - flags

I don't understand meaning of this:
+"a function to be evaluated during reloc processing" - it is from flags of objdump.
How function can be evaluated during reloc processing?
Is it sequence of cpu opcodes (subrotinue) that must be called?
Or what?

https://sourceware.org/glibc/wiki/GNU_IFUNC
ifunc symbol points to resolver, which is itself in object file, and linker sees it and calls with some args which it knows somehow... and gets back address of best implementation of function.
That is what called EVALUATION.
It is all done for sake of performance. Attempt to choose best code for specific CPU.

Related

Make-array in SBCL

How does make-array work in SBCL? Are there some equivalents of new and delete operators in C++, or is it something else, perhaps assembler level?
I peeked into the source, but didn't understand anything.
When using SBCL compiled from source and an environment like Emacs/Slime, it is possible to navigate the code quite easily using M-. (meta-point). Basically, the make-array symbol is bound to multiple things: deftransform definitions, and a defun. The deftransform are used mostly for optimization, so better just follow the function, first.
The make-array function delegates to an internal make-array% one, which is quite complex: it checks the parameters, and dispatches to different specialized implementation of arrays, based on those parameters: a bit-vector is implemented differently than a string, for example.
If you follow the case for simple-array, you find a function which calls allocate-vector-with-widetag, which in turn calls allocate-vector.
Now, allocate-vector is bound to several objects, multiple defoptimizers forms, a function and a define-vop form.
The function is only:
(defun allocate-vector (type length words)
(allocate-vector type length words))
Even if it looks like a recursive call, it isn't.
The define-vop form is a way to define how to compile a call to allocate-vector. In the function, and anywhere where there is a call to allocate-vector, the compiler knows how to write the assembly that implements the built-in operation. But the function itself is defined so that there is an entry point with the same name, and a function object that wraps over that code.
define-vop relies on a Domain Specific Language in SBCL that abstracts over assembly. If you follow the definition, you can find different vops (virtual operations) for allocate-vector, like allocate-vector-on-heap and allocate-vector-on-stack.
Allocation on heap translates into a call to calc-size-in-bytes, a call to allocation and put-header, which most likely allocates memory and tag it (I followed the definition to src/compiler/x86-64/alloc.lisp).
How memory is allocated (and garbage collected) is another problem.
allocation emits assembly code using %alloc-tramp, which in turns executes the following:
(invoke-asm-routine 'call (if to-r11 'alloc-tramp-r11 'alloc-tramp) node)
There are apparently assembly routines called alloc-tramp-r11 and alloc-tramp, which are predefined assembly instructions. A comment says:
;;; Most allocation is done by inline code with sometimes help
;;; from the C alloc() function by way of the alloc-tramp
;;; assembly routine.
There is a base of C code for the runtime, see for example /src/runtime/alloc.c.
The -tramp suffix stands for trampoline.
Have also a look at src/runtime/x86-assem.S.

What does the GCC function suffix .constprop mean?

Looking at the disassembly of a C++ program, I see functions like _Z41__static_initialization_and_destruction_0ii.constprop.221. What does the constprop mean in this case? It appears to be similar in appearance to the isra suffix (and is sometimes combined, e.g. .isra.124.constprop.226), but it means something else.
From source code comments I've read - they indicate functions which have been cloned during optimization.
EDIT: This may be the answer, maybe not.
Simple constant propagation
This file implements constant propagation and merging. It looks for instructions involving only constant operands and replaces them with a constant value instead of an instruction. For example:
add i32 1, 2
becomes
i32 3
NOTE: this pass has a habit of making definitions be dead. It is a good idea to to run a DIE (Dead Instruction Elimination) pass sometime after running this pass.
SOURCE

What does the GCC function suffix "isra" mean?

While profiling a program compiled with gcc, I noticed functions like foo.isra.3. What does isra indicate? I notice that one of the functions is only called in a few places, and one of the arguments is always specified as a literal value. Maybe it means it's a variant of the function optimised for certain arguments?
According to a comment on this bug report (and similar comments I could find):
ISRA is the name of the variable that gets created by IPA SRA ...
IPA SRA is an optimization option:
-fipa-sra
Perform interprocedural scalar replacement of aggregates, removal of unused parameters and replacement of parameters passed by reference by parameters passed by value.
Enabled at levels -O2, -O3 and -Os.
So most likely, it's a version of a function with those optimizations.
In the case you mentioned, it's possible that it's replacing a pass-by-reference with a pass-by-value since it knows there's no point to passing a literal by reference.

Compiling Fortran external symbols

When compiling fortran code into object files: how does the compiler determine the symbol names?
when I use the intrinsic function "getarg" the compiler converts it into a symbol called "_getarg#12"
I looked in the external libraries and found that the symbol name inside is called "_getarg#16" what is the significance of the "#[number]" at the end of "getarg" ?
_name#length is highly Windows-specific name mangling applied to the name of routines that obey the stdcall (or __stdcall by the name of the keyword used in C) calling convention, a variant of the Pascal calling convention. This is the calling convention used by all Win32 API functions and if you look at the export tables of DLLs like KERNEL32.DLL and USER32.DLL you'd see that all symbols are named like this.
The _...#length decoration gives the number of bytes occupied by the routine arguments. This is necessary since in the stdcall calling conventions it is the callee who cleans up the arguments from the stack and not the caller as is the case with the C calling convention. When the compiler generates a call to func with two 4-byte arguments, it puts a reference to _func#8 in the object code. If the real func happens to have different number or size of arguments, its decorated name would be something different, e.g. _func#12 and hence a link error would occur. This is very useful with dynamic libraries (DLLs). Imagine that a DLL was replaced with another version where func takes one additional argument. If it wasn't for the name mangling (the technical term for prepending _ and adding #length to the symbol name), the program would still call into func with the wrong arguments and then func would increment the stack pointer with more bytes than was the size of the passed argument list, thus breaking the caller. With name mangling in place the loader would not launch the executable at all since it would not be able to resolve the reference to _func#8.
In your case it looks like the external library is not really intended to be used with this compiler or you are missing some pragma or compiler option. The getarg intrinsic takes two arguments - one integer and one assumed-sized character array (string). Some compilers pass the character array size as an additional argument. With 32-bit code this would result in 2 pointers and 1 integer being passed, totalling in 12 bytes of arguments, hence the _getarg#12. The _getarg#16 could be, for example, 64-bit routine with strings being passed by some kind of descriptor.
As IanH reminded me in his comment, another reason for this naming discrepancy could be that you are calling getarg with fewer arguments than expected. Fortran has this peculiar feature of "prototypeless" routine calls - Fortran compilers can generate calls to routines without actually knowing their signature, unlike in C/C++ where an explicit signature has to be supplied in the form of a function prototype. This is possible since in Fortran all arguments are passed by reference and pointers are always the same size, no matter the actual type they point to. In this particular case the stdcall name mangling plays the role of a very crude argument checking mechanism. If it wasn't for the mangling (e.g. on Linux with GNU Fortran where such decorations are not employed or if the default calling convention was cdecl) one could call a routine with different number of arguments than expected and the linker would happily link the object code into an executable that would then most likely crash at run time.
This is totally implementation dependent. You did not say, which compiler do you use. The (nonstandard) intrinsic can exist in more versions for different integer or character kinds. There can also be more versions of the runtime libraries for more computer architectures (e.g. 32 bit and 64 bit).

Using the "naked" attribute for functions in GCC

GCC documentation states in 6.30 Declaring Attributes of Functions:
naked
Use this attribute on the ARM, AVR, IP2K, RX and SPU ports to indicate that the specified function does not need prologue/epilogue sequences generated by the compiler. It is up to the programmer to provide these sequences. The only statements that can be safely included in naked functions are asm statements that do not have operands. All other statements, including declarations of local variables, if statements, and so forth, should be avoided. Naked functions should be used to implement the body of an assembly function, while allowing the compiler to construct the requisite function declaration for the assembler.
Can I safely call functions using C syntax from naked functions, or only by using asm?
You can safely call functions from a naked function, provided that the called functions have a full prologue and epilogue.
Note that it is a bit of a nonsense to assert that you can 'safely' use assembly language in a naked function. You are entirely responsible for anything you do using assembly language, as you are for any calls you make to 'safe' functions.
To ensure that your generic called function is not static or inlined, it should be in a seperate compilation unit.
"naked" functions do not include any prologue or epilogue -- they are naked. In particular, they do not include operations on the stack for local variables, to save or restore registers, or to return to a calling function.
That does not mean that no stack exists -- the stack is initialized in the program initialisation, not in any function initialization. Since a stack exists, called function prologues and epilogues work correctly. A function call can safely push it's return address, any registers used, and space for any local variables. On return (using the return address), the registers are restored and the stack space is released.
Static or inlined-functions may not have a full prologue and epilogue. They can and may depend on the calling function to manage the stack and to restore corrupted registers.
This leads to the next point: you need the prologue and epilogue only to encapsulate the operations of the called function. If the called function is also safe (no explicit or implicit local variables, no changes to status registers), it can be safely static and/or inlined. As with asm, it would be your responsibility to make sure this is true.
If the only thing you do in the naked function is call another function you can just use a single JMP machine code instruction.
The function you jump to will have a valid prologue and it should return directly to the caller of the naked function since JMP doesn't push a return address on the stack.
The only statements that can be safely included in naked functions are asm statements that do not have operands. All other statements, including declarations of local variables, if statements, and so forth, should be avoided.
Based on the description you already gave, I would assume that even function calls are not suitable for the "naked" keyword.

Resources