getting mixed C and inline assembly from gcc - c

I'm trying to diagnose why a seemingly small C function I wrote has produced a large .text section. I have used arm-elf-size and arm-elf-objdump to isolate the object file and function, but I have only been able to get these tools to produce assembly code, which I don't have the time to reverse engineer.
I tried using gcc switches "-g" which is supposed to be compatible with arm-elf-objdump -g, but it keeps producing the error "No debugging information found," which I've googled around for a bit with no clear cut answer (though other people had an identical problem).
Is there any other means of producing mixed C/assembly files so I can isolate the trouble spot in the function? Thanks!

Is there any other means of producing mixed C/assembly files so I can
isolate the trouble spot in the function?
gcc/gas can generate an assembler listing with C source; I recommend these compiler options:
-g -Wa,-adhln=filename.lst

Related

can I edit lines of code using gdb and is it also possible to save to actual source file and header file while in same debug session? linux

I have this program called parser I compiled with -g flag this is my makefile
parser: header.h parser.c
gcc -g header.h parser.c -o parser
clean:
rm -f parser a.out
code for one function in parser.c is
int _find(char *html , struct html_tag **obj)
{
char temp[strlen("<end")+1];
memcpy(temp,"<end",strlen("<end")+1);
...
...
.
return 0;
}
What I like to see when I debug the parser or something can I also have the capability to change the lines of code after hitting breakpoint and while n through the code of above function. If its not the job of gdb then is there any opensource solution to actually changing code and possible saving so when I run through the next statement in code then changed statement before doing n (possible different index of array) will execute, is there any opensource tool or can it be done in gdb do I need to do some compiling options.
I know I can assign values to variables at runtime in gdb but is this it? like is there any thing like actually also being capable of changing soure
Most C implementations are compiled. The source code is analyzed and translated to processor instructions. This translation would be difficult to do on a piecewise basis. That is, given some small change in the source code, it would be practically impossible to update the executable file to represent those changes. As part of the translation, the compiler transforms and intertwines statements, assigns processor registers to be used for computing parts of expressions, designates places in memory to hold data, and more. When source code is changed slightly, this may result in a new compilation happening to use a different register in one place or needing more or less memory in a particular function, which results in data moving back or forth. Merging these changes into the running program would require figuring out all the differences, moving things in memory, rearranging what is in what processor register, and so on. For practical purposes, these changes are impossible.
GDB does not support this.
(Appleā€™s developer tools may have some feature like this. I saw it demonstrated for the Swift programming language but have not used it.)

How do I get a full assembly code from C file?

I'm currently trying to figure out the way to produce equivalent assembly code from corresponding C source file.
I've been using the C language for several years, but have little experience with assembly language.
I was able to output the assembly code using the -S option in gcc. However, the resulting assembly code contained call instructions which in turn make a jump to another function like _exp. This is not what I wanted, I needed a fully functional assembly code in a single file, with no dependency to other code.
Is it possible to achieve what I'm looking for?
To better describe the problem, I'm showing you my code here:
#include <math.h>
float sigmoid(float i){
return 1/(1+exp(-i));
}
The platform I am working on is Windows 10 64-bit, the compiler I'm using is cl.exe from MSbuild.
My initial objective was to see, at a lowest level possible, how computers calculate mathematical functions. The level where I decided to observe the calculation process is assembly code, and the mathematical function I've chosen was sigmoid defined as above.
_exp is the standard math library function double exp(double); apparently you're on a platform that prepends a leading underscore to C symbol names.
Given a .s that calls some library functions, build it the same way you would a .c file that calls library functions:
gcc foo.S -o foo -lm
You'll get a dynamic executable by default.
But if you really want all the code in one file with no external dependencies, you can link your .c into a static executable and disassemble that.
gcc -O3 -march=native foo.c -o foo -static -lm
objdump -drwC -Mintel foo > foo.s
There's no guarantee that the _exp implementation in libm.a (static library) is identical to the one you'd get in libm.so or libm.dll or whatever, because it's a different file. This is especially true for a function like memcpy where dynamic-linker tricks are often used to select an optimal version (for your CPU) at run-time.
It is not possible in general, there are exceptions sure, I could craft one so that means other folks can too, but it isnt an interesting program.
Normally your C program, your main() entry point is only a percentage of the code. There is a bootstrap that contains the actual entry point for the operating system to launch your program, this does some things that prepare your virtual memory space so that your program can run. Zeros .bss and other such things. that is often and or should be written in assembly language (otherwise you get a chicken and egg problem) but not an assembly language file you will see unless you go find the sources for the C library, you will often get an object as part of the toolchain along with other compiler libraries, etc.
Then if you make any C calls or create code that results in a compiler library call (perform a divide on a platform that doesnt support divide, perform floating point on a platform that doesnt have floating point, etc) that is another object that came from some other C or assembly that is part of the library or compiler sources and is not something you will see during the compile/assemble/link (the chain in toolchain) process.
So except for specifically crafted trivial programs or specifically crafted tools for this purpose (for specific likely baremetal platforms), you will not see your whole program turn into one big assembly source file before it gets assembled then linked.
If not baremetal then there is of course the operating system layer which you certainly would not get to see as part of your source code, ultimately the C library calls that need the system will have a place where they do that, all compiled to object/lib before you use them, and the assembly sources for the operating system side is part of some other source and build process somewhere else.

Value optimized out in GDB: Can gdb handle decoding it automatically?

1) First I want to know, how to decode such variables ?
I know the solutions to this problem, remove optimization flag, make it volatile, I dont want to do all that. Is there any solution which can be done without compiling the source again ? The problem is whenever i make any changes, it takes ages to compile, so I dont want to compile it with different optimization flags, also I had tried once changing the optimization flag, but it crashed just because of change in compilation flags, for reasons I cant fathom.
Also I am not able to find documentation about understanding various registers when I do "info reg". i was expecting some variable ( whose value I knew, what would it be ) but info reg is showing me all different values. I am missing something here. The architecture I am working on is x86_64
2) I want to know what are the restrictions faced by gdb to decode such register variables ? Or is this problem already tackled by someone. I have read at many places that going through the assembly code, you can find out which variable is in that register. If thats true, why it cant be build into gdb. Please point me to relevant pages if there are solutions to this problem
If you don't have the source and compile with debug/no optimizations (i.e. 3rd party code.) the best you can do would be to disassemble the code and try to determine how the variables are stored.
In gdb the disassemble instruction will dump the assembly for the given function:
disassemble <function name>
Or if symbols have been stripped
disassemble <address>
where <address> is the entry point to the function.
You may also have to inspect where the function is called to determine the calling conventions used.
Once you've figured out the structure of the functions and variable layout (stack variables or registers), when debugging you can step through each instruction with nexti and stepi and watch how the values in the variables change by dumping the contents of the registers or memory locations.
I don't know any good primers or tutorials myself but this question and its answers may be of use to you. Personally I find myself referencing the Intel manuals the most. They can be downloaded in pdf from Intel's website. I don't have a link handy at the moment. If someone else does perhaps they can update my answer.
Have you looked at compiling your code un-optimized?
Try one of these in your gcc options:
-Og
Optimize debugging experience. -Og enables optimizations that do not interfere with debugging. It should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience.
-O0
Reduce compilation time and make debugging produce the expected results. This is the default.

ARM assembler: bad immediate value for offset

I am using GCC crosscompiler to compile to an ARM platform. I have a problem where, using opitmization -O3 gives me a "bad immediate value for offset (4104)" on a temp file ccm4baaa.s. Can't find this file either.
How do I debug this, or find the source of the error? I know that it's located somewhere in hyper.c, but it's impossible to find it because there is no errors showing in hyper.c. Only the cryptic error message above.
Best Regards
Mr Gigu
There have been similar known bugs in previous releases of GCC. It might just be a matter of updating your version of the GCC toolchain. Which one are you using currently?
In order to debug the problem and find the offending source, in these cases it helps to add the gcc option -save-temps to the compilation. The effect is that the compiler keeps the intermediate assembly files (and the pre-processor output) for you to examine.

how to see the optimized code in c

I can examine the optimization using profiler, size of the executable file and time to take for the execution.
I can get the result of the optimization.
But I have these questions,
How to get the optimized C code.
Which algorithm or method used by C to optimize a code.
Thanks in advance.
you can get an idea of optimization using the option -fdump-tree-optimized with gcc .
and you'll get an optimised file. you cannot run the code but using that you can get an idea of optimization . dont forget to include -O2 or -O3 or some other level.
Usually the code isn't optimized as C. Usually optimization passes are done long after the C has been converted into some form of intermediate representation that is easier for a compiler to work with in memory. Therefore, a direct answer to your question is that the optimized C code never exists.
A C compiler does not usually produce optimized C at any stage. Rather, the compiler turns C into a simplified internal representation, and most compiler optimizations will be done on one or more of those intermediate representations. Then the compiler generates assembly or a binary from that.
The closest you can get is probably to compile a file to assembly with no optimization and again with highest optimization, and then compare the assembly output. You will have to have a good grasp of assembly language to do that. If you are using gcc, read about the -S and -O switches for how to do (or not do) this.
If your goal is to write faster code, then, your best bet is to write better C by using better algorithms and data structures at the C level by carefully using the profiler.
If your goal is just to understand optimization, try Program Optimization and Compiler Optimization on Wikipedia for some general information.
If you're using GCC, use an argument to optimize the code and use --save-temps as an argument. Everyone saying C code isn't optimized as C when compiling with GCC is wrong to an extent. Write a recursive Fibonacci sequence generator in C, and read through the preprocessed code. The aforementioned argument also saves the generated assembly in the directory GCC is called from. If you're more comfortable with Intel-syntax assembly, use -masm=intel as an argument as well.
if you understand assembler, you can inspect the assembler generated code by compiler.

Resources