I'm using memcpy on my ARM platform and I want to view the sourecode of memcpy. Viewing an objectdump from my sourcecode, I know this memcpy is used:
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m/libc.a(lib_a-memcpy.o)
How can I look at the .c source code of memcpy?
On some compilers (with some optimization flags), memcpy would use some __builtin_memcpy which is magically handled by the compiler (and could even not emit any function call, but always be inlined and specialized).
See this related question and the documentation of GCC builtins. Ultimately, dive into the source code of your GCC compiler.
Look also into the source code of your libc. It probably mentions __builtin_mempcy in some internal header.
Of course, use gcc -S -fverbose-asm -O and see the generated assembler file *.s
Related
Many questions about forcing the order of functions in a binary to match the order of the source file
For example, this post, that post and others
I can't understand why would gcc want to change their order in the first place?
What could be gained from that?
Moreover, why is toplevel-reorder default value is true?
GCC can change the order of functions, because the C standard (e.g. n1570 or newer) allows to do that.
There is no obligation for GCC to compile a C function into a single function in the sense of the ELF format. See elf(5) on Linux
In practice (with optimizations enabled: try compiling foo.c with gcc -Wall -fverbose-asm -O3 foo.c then look into the emitted foo.s assembler file), the GCC compiler is building intermediate representations like GIMPLE. A big lot of optimizations are transforming GIMPLE to better GIMPLE.
Once the GIMPLE representation is "good enough", the compiler is transforming it to RTL
On Linux systems, you could use dladdr(3) to find the nearest ELF function to a given address. You can also use backtrace(3) to inspect your call stack at runtime.
GCC can even remove functions entirely, in particular static functions whose calls would be inline expanded (even without any inline keyword).
I tend to believe that if you compile and link your entire program with gcc -O3 -flto -fwhole-program some non static but unused functions can be removed too....
And you can always write your own GCC plugin to change the order of functions.
If you want to guess how GCC works: download and study its source code (since it is free software) and compile it on your machine, invoke it with GCC developer options, ask questions on GCC mailing lists...
See also the bismon static source code analyzer (some work in progress which could interest you), and the DECODER project. You can contact me by email about both. You could also contribute to RefPerSys and use it to generate GCC plugins (in C++ form).
What could be gained from that?
Optimization. If the compiler thinks some code is like to be used a lot it may put that code in a different region than code which is not expected to execute often (or is an error path, where performance is not as important). And code which is likely to execute after or temporally near some other code should be placed nearby, so it is more likely to be in cache when needed.
__attribute__((hot)) and __attribute__((cold)) exist for some of the same reasons.
why is toplevel-reorder default value is true?
Because 99% of developers are not bothered by this default, and it makes programs faster. The 1% of developers who need to care about ordering use the attributes, profile-guided optimization or other features which are likely to conflict with no-toplevel-reorder anyway.
I'm debugging the glibc library. I've built it with -g3 -O flags. I can print most macros, but not this one. I'm debugging malloc(), and there are a lot of macros that use __alignof__. But I can't find its definition anywhere in glibc source code. Here is an example:
(gdb) p MALLOC_ALIGN_MASK
No symbol "__alignof__" in current context.
And also I got the same problem with __builtin_offsetof. But this one is an built in macro. So the 2 cases are a bit different. Solving this problem will speed up my debugging a bit.
You won't get any debugging information. Since __alignof__ is, like sizeof, only known at compile-time. See alignof from <stdalign.h>
Even by recompiling GCC itself, you won't get it (there is no debugging information available). __alignof__ is processed at compile time (so __alignof__ (double) is replaced by 8 during compilation, for x86-64 ABI).
You could guess by yourself the expanded value of MALLOC_ALIGN_MASK.
You could define a const int my_malloc_align_mask = MALLOC_ALIGN_MASK; and use p my_malloc_align_mask in the debugger.
I'm debugging the glibc library.
This is weird. You should trust the glibc library to behave as documented (yes, beware of undefined behavior).
GDB only has a very approximate implementation of C and C++. It does not use the same C and C++ parser as GCC, so some things are missing, including this GCC extension. GDB recognizes _Alignof, but it is not exactly the same as __alignof__. But it will work in this case, so you could change the glibc sources to use it.
LLDB uses the Clang parsers and therefore does not suffer from this particular problem, but will not help you here because apparently, the debugger does not recognize the DWARF data generated by the -g3 option, so the macro information is missing from the executable.
Is there anywhere I can find side-by-side examples of dead simple C and x86 programs? The examples I've found so far on the Internet seem to jump straight from "here's Hello World in x86" to "write your own operating system!" I'm having trouble internalizing what has to happen when you do things like call a function.
I would recommend a look at GCC's intermediate assembly output, for example call
gcc -S a.c
then look at a.s
Most of the time, smaller and easier to understand assembly is generated by optimizing, so you would rather use
gcc -O -S a.c
If you mean x86 assembly language, use objdump --disassemble myprog (on any GNU system) to show the assembly language generated by your C program. If your system doesn't have objdump, you can use ndisasm.
Assuming you mean x86 assembler then with gcc you can use gcc -S yourhelloworldprogram.c to get assembler output. For Visual Studio you can get assembler output by following this: How do I get the assembler output from a C file in VS2005
I reccommend ddd. You can have the both C sources (if you built with debug symbols) and the machine code showing. You can also step over the code interactively probing register and memory values. A great learning tool.
On gcc you can use the -save-temps -fverbose-asm options which is better than the -S option because it still generates the object file and you get also the preprocessor file. The verbose-asm is also important because it adds comments to the assembly output that make the link between the function and variable names of your program and the generated assembly code. Especially when generating with optimization it often is difficult to make the link between the source C and the assembly.
Lets say I have written a program in C and compiled it with both gcc (as C) and g++ (as C++), which compiled executable will run faster: the one created by gcc or by g++? I think using the g++ compiler will make the executable slow, but I'm not sure about it.
Let me clarify my question again because of confusion about gcc:
Let's say I compile program a.c like this in the terminal:
gcc a.c
g++ a.c
Which a.out executable will run faster?
Firstly: the question (and some of the other answers) seem to be based on the faulty premise that C is a strict subset of C++, which is not in fact the case. Compiling C as C++ is not the same as compiling it as C: it can change the meaning of your program!
C will mostly compile as C++, and will mostly give the same results, but there are some things that are explicitly defined to give different behaviour.
Here's a simple example - if this is your a.c:
#include <stdio.h>
int main(void)
{
printf("%d\n", sizeof('x'));
return 0;
}
then compiling as C will give one result:
$ gcc a.c
$ ./a.out
4
and compiling as C++ will give a different result (unless you're using an unusual platform where int and char are the same size):
$ g++ a.c
$ ./a.out
1
because the C specification defines a character literal to have type int, and the C++ specification defines it to have type char.
Secondly: gcc and g++ are not "the same compiler". The same back end code is used, but the C and C++ front ends are different pieces of code (gcc/c-*.c and gcc/cp/*.c in the gcc source).
Even if you stick to the parts of the language that are defined to do the same thing, there is no guarantee that the C++ front end will parse the code in exactly the same way as the C front end (i.e. giving exactly the same input to the back end), and hence no guarantee that the generated code will be identical. So it is certainly possible that one might happen to generate faster code than the other in some cases - although I would imagine that you'd need complex code to have any chance of finding a difference, as most of the optimisation and code generation magic happens in the common back end of the compiler; and the difference could be either way round.
I think they they will both produce the same machine code, and therefore the same speed on your computer.
If you want to find out, you could compile the assembly for both and compare the two, but I'm betting that they create the same assembly, and therefore the same machine code.
Profile it and try it out. I'm certain it will depend on the actual code, even if it would require potentially a really weird case to get any different bytecode. Though if you don't have extern C {} around your C code, and or works fine in C, I'm not sure how "compiling it as though it were C++" could provide any speed, unless the particular compiler optimizations in g++ just happen to be a bit better for your particular situation...
The machine code generated should be identical. The g++ version of a.out will probably link in a couple of extra support libraries. This will make the startup time of a.out be slower by a few system calls.
There is not really any practical difference though. The Linux linker will not become noticeably slower until you reach 20-40 linked libraries and thousands of symbols to resolve.
The gcc and g++ executables are just frontends, they are not the actual compilers. They both run the actual C or C++ compilers (and ld, ar, whatever is needed to produce the output you asked for) based on the file extensions. So you'll get the exact same result. G++ is commonly used for C++ because it links with the standard C++ library (iostreams etc.).
If you want to compile C code as C++, either change the file extension, or do something like this:
gcc test.c -otest -x c++
http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/G_002b_002b-and-GCC.html
GCC is a compiler collection. It is mainly used for compilation of C,C++,Ada,Java and many more programming languages.
G++ is a part of gnu compiler collection(gcc).
I mean gcc includes g++ as well. When we use gcc for compilation of C++ it uses g++. The output files will be different because the G++ compiler uses its own run time library.
Edit: Okay, to clarify things, because we have a bit of confusion in naming here. GCC is the GNU Compiler Collection. It can compile Ada, C++, C, and a billion and a half other languages. It is a "backend" to the various languages "front end" compilers like GNAT. Go read the link i made at the top of the page from GCC.GNU.Org.
GCC can also refer to the GNU C Compiler. This will compile C++ code if given the -lstdc++ command, but normally will choke and die because it's not pulling in the C++ libraries.
G++, the GNU C++ Compiler, like the GNU C Compiler is a front end to the GNU Compiler Collection. It's difference between the C Compiler is that it automatically includes those libraries and makes a few other small tweaks, because it's assuming it's going to be fed C++ code to compile.
This is where the confusion comes from. Does this clarify things a bit?
I want to compile my C-code without the (g)libc. How can I deactivate it and which functions depend on it?
I tried -nostdlib but it doesn't help: The code is compilable and runs, but I can still find the name of the libc in the hexdump of my executable.
If you compile your code with -nostdlib, you won't be able to call any C library functions (of course), but you also don't get the regular C bootstrap code. In particular, the real entry point of a program on Linux is not main(), but rather a function called _start(). The standard libraries normally provide a version of this that runs some initialization code, then calls main().
Try compiling this with gcc -nostdlib -m32:
// Tell the compiler incoming stack alignment is not RSP%16==8 or ESP%16==12
__attribute__((force_align_arg_pointer))
void _start() {
/* main body of program: call main(), etc */
/* exit system call */
asm("movl $1,%eax;"
"xorl %ebx,%ebx;"
"int $0x80"
);
__builtin_unreachable(); // tell the compiler to make sure side effects are done before the asm statement
}
The _start() function should always end with a call to exit (or other non-returning system call such as exec). The above example invokes the system call directly with inline assembly since the usual exit() is not available.
The simplest way to is compile the C code to object files (gcc -c to get some *.o files) and then link them directly with the linker (ld). You will have to link your object files with a few extra object files such as /usr/lib/crt1.o in order to get a working executable (between the entry point, as seen by the kernel, and the main() function, there is a bit of work to do). To know what to link with, try linking with the glibc, using gcc -v: this should show you what normally comes into the executable.
You will find that gcc generates code which may have some dependencies to a few hidden functions. Most of them are in libgcc.a. There may also be hidden calls to memcpy(), memmove(), memset() and memcmp(), which are in the libc, so you may have to provide your own versions (which is not hard, at least as long as you are not too picky about performance).
Things might get clearer at times if you look at the produced assembly (use the -S flag).