what are dump and auxillary files? - c

Im a newcommer to Linux and the gcc commands. I was reading the
gcc documentation particularly about the -o flag where it mentions the following:
Though -o names only the primary output, it also affects the naming of
auxiliary and dump outputs. See the examples below. Unless overridden,
both auxiliary outputs and dump outputs are placed in the same
directory as the primary output. In auxiliary outputs, the suffix of
the input file is replaced with that of the ...
They mention it quite a lot following this paragraph but don't explain it. I've skimmed the document and also looked online but haven't found any satisfactory explanation. If someone could provide me some explanation or even link me to some resources where I can learn about these terms it would be greatly appreciated. Thanks!

-o file
Place the output in file. This applies regardless of the type of output produced, whether it is an executable file, an object file, an assembler file or preprocessed C code.
Since only one output file can be specified, it makes no sense to use -o when compiling more than one input file, unless you want to output an executable file.
If -o is not specified, the default behavior is to produce an executable file named a.out, an object file for source.suffix named source.o, its assembler file in source.s, and all C source code preprocessed on standard output.
source: http://www.linuxcertif.com/man/1/gcc/
hope it will be useful

Related

How is rustc able to compile source code from bash process substitution but gcc cannot?

$ rustc <(echo 'fn main(){ print!("Hello world!");}')
$ ls
63
$ gcc <(echo '#include<stdio.h> int main(){ printf("Hello world!\n"); return 0;}')
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Why can't ld link the program?
The gcc command is mostly a dispatch engine. For each input file, it determines what sort of file it is from the filename's extension, and then passes the file on to an appropriate processor. So .c files are compiled by the C compiler, .h files are assembled into precompiled headers, .go files are sent to the cgo compiler, and so on.
If the filename has no extension or the extension is not recognised, gcc assumes that it is some kind of object file which should participate in the final link step. These files are passed to the collect2 utility, which then invokes ld, possibly twice. This will be the case with process substitution, which produces filenames like /dev/fd/63, which do not include extensions.
ld does not rely on the filename to identify the object file format. It is generally built with several different object file recognisers, each of which depends on some kind of "magic number" (that is, a special pattern at or near the beginning of the file). It calls these recognisers one at a time until it finds one which is happy to interpret the file. If the file is not recognised as a binary format, ld assumes that it is a linker script (which is a plain text file) and attempts to parse it as such.
Naturally, between attempts ld needs to rewind the file, and since process substitution arranges for a pipe to be passed instead of a file, the seek will fail. (The same thing would happen if you attempted to pass the file through redirection of stdin to a pipe, which you can do: gcc will process stdin as a file if you specify - as a filename. But it insists that you tell it what kind of file it is. See below.)
Since ld can't rewind the file, it will fail after the file doesn't match its first guess. Hence the error message from ld, which is a bit misleading since you might think that the file has already been compiled and the subsequent failure was in the link step. That's not the case; because the filename had no extension, gcc skipped directly to the link phase and almost immediately failed.
In the case of process substitution, pipes, stdin, and badly-named files, you can still manually tell gcc what the file is. You do that with the -x option, which is documented in the GCC manual section on options controlling the kind of output (although in this case, the option actually controls the kind of input).
There are a number of answers to questions like this floating around the Internet, including various answers here on StackOverflow, which claim that GCC attempts to detect the language of input files. It does not do that, and it never has. (And I doubt that it ever will, since some of the languages it compiles are sufficiently similar to each other that accurate detection would be impossible.) The only component which does automatic detection is ld, and it only does that once GCC has irrevocably decided to treat the input file as an object file or linker script.
At least in your case, you can use process substition when specifying the input language manually, using -xc. However, you should put a newline after the include statement.
$ gcc -xc <(echo '#include<stdio.h>
int main(){ printf("Hello world!\n"); return 0;}')
$ ls
a.out
$ ./a.out
Hello world!
For a possible reason why this works, see Charles' answer and the comments on this answer.

How can compiling the same source code generate different object files?

After a long sequence of debugging I've narrowed my problem down to one file. And the problem is that the file compiles differently in two different directories, when everything else is the same.
I'm using CodeSourcery's arm gcc compiler (gcc version 4.3.3, Sourcery G++ Lite 2009q1-161) to compile a simple file. I was using it in one module with no issues and then I copied it to another module to use there. When it compiles, the object file is significantly different. The command line to compile the two files is identical (I used the linux history to make sure), and the 3 include files are also identical copies (checked with diff).
I did a binary compare on the two object files and they have a lot of individual byte differences scattered around. I did an objdump -D of both and compared them and there are a lot of differences. Here is dump1, dump2, and the diff. The command line is "
arm-none-eabi-gcc --std=gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o".
How is this possible? I've also compiled with -S instead of -c and looked at the assembler output and that's identical except for the directory path. So how can the object file be different?
My real problem is that when I try to link the object file for dump2 into my program, I get undefined reference errors, so something in the object is wrong, whereas the object for dump1 gets no such errors and links fine.
For large scale software, there are many implementations are doing hashing on pointers. This is one major reason that cause result randomization. Usually if the program logic is correct, the order of some internal data structures could be different which is not harmful in most cases.
And also, don't compare the 'objdump -D' output, since your are compiling the code from different directory, the string table, symbol table, DWARF or eh_frame should be different. You will certainly get lots of diff lines.
The only comparison that makes sense is to compare the output of 'objdump -d' which only takes care of the text section. If text section is same(similar) then it can be considered as identical.
Most likely your file picks up different include files. This this the most likely reason.
Check that your include paths are exactly the same, paths in the include statements. They may point to different directories. C and C++ has a feature that when you #include abcd.h it tries to load abcd.h from the directory of the calling file. Check this.

GDB: What to do when you type "list" to see the code in C, but it prints to you "No source file for address __________"

I'll try to simplify and make clear my other question here. I am basically trying to use gdb to see where myfile.c is segfaulting. However, I cannot directly examine myfile.c under gdb, but there I am given a driver program (vdriver) that will randomly test the methods I have provided for it in myfile.c
So, after compiling with "gcc -ggdb -c vdriver.c myfile.c myfile_depends_on_this.c" I run "gdb vdriver" until it segfaults. At that point, typing "list *$eip" just prints "No source file for address 0x804something"
I am also confused about how I should "gcc -ggdb -c etc,etc" for header files such as myfile.h and myfile_depends_on_this.h, because I'm not sure whether (or how) it should be included in the command or not.
But anyway, is there any way of fixing the "No source file for address" problem?
Here is how I understand your question (it's not quite clear to me):
how to debug after a segfault?
how to compile .h files?
As to
After crashes, you will no longer be in execution context and so no longer be able to use the regular debugging commands. Instead, gcc will produce a core file. You probably need to allocate space for a core file first, then debug, as described in (eg):
http://www.network-theory.co.uk/docs/gccintro/gccintro_38.html
.h files are not included in the list of files to be compiled. They are referenced from within your .c file with the usual #include (or #include "file.h") semantic
If this wasn't your question, kindly elaborate.

Creating one C file when compiling multiple sources

I have a set of C files to compile using gcc and make. The build process works fine.
I want to know if I can obtain - during compilation - one C file containing all the source code without any preprocessor macro.
One simple was would be to make a file that included all the other source files.
$cat *.c > metafile.c
This would construct such a file, depending on how you set you 'pragma once' and ifndef's this file would probably not be able to compile on its own.
On the other hand, if what you want in a file where all the preprocessor macro's have been unfolded and evaluated, then the answer is to add the following to gcc:
-save-temps
then the file .ii will contain the unfolded and evaluated macros
If you include all files to the gcc compiler at once you could use
gcc -E main.c other.c another.c
This will also include the stdlib functions maybe use -nostdinc
You can't - normally you invoke the compiler to compile just a single source file, resulting in an object file. Later you call the linker on all of the object files to create the executable - it doesn't have the original C source code available.
You can, however, create a separate shell script that calls gcc with the -E option just to preprocess the source files, and then use the cat utility to put all the sources in a single file.
You can use the -save-temps option to get the intermediate outputs. However it will be one output file per source file. Each source file gets compiled separately and represents a compilation unit which can't be mixed up.
You can also use the -E option, however that will only run the preprocessor and not continue compilation.

Including a library (lsusb) in a C program

I am still fairly new to programming with C and I am working on a program where I want to control the power to various ports on a hub I have. That is, however, not the issue I am having right now.
I found a program online that does what I want I am trying to compile it. However it uses #include<lsusb.h>. lsusb is located in a totally different folder than the file I am wanting to run (and not in a sub folder) and when I try to compile it, I, logically enough, get the error that the file lsusb.h is not found.
How can I link to this file so that it can be found?
This is more of a GCC toolchain question than a C question (although most C compilers do use the same Unixy flags).
The braces around the include file (<>) indicate you want the compiler to search its standard search path for the include file. So you can get access to that new include file either by putting it into a directory on your standard include file search path yourself, or by adding its directory to the file search path. With GCC you do the latter by giving gcc the flag -I"directoryname" where "directoryname" is the full file path to where you are keeping that new include file of yours.
Once your compiler finds it, your linker may have the exact same problem with the library file itself ("liblsusb.a"?). You fix that the same way. The flag GCC's linker will want is -L instead of -I.
See the "-I" parameter in the gcc man page. It allows you specify a directory in which to find a header file. See also -l and -L.
Or try #include "../../path_to_the_file/lsusb.h"

Resources