I am using gcc to compile a set of c codes. And my question is: can I tell gcc not to generate some specific instructions?
e.g. I don't want gcc to generate MUL instruction, how should I do?
I'm working on self implemented MIPS cpu and related codes, and for some reasons, I don't want gcc to generate some weird instructions that I've not implemented. It seems that I need to hack the gcc a little bit.
Based on Krister Walfridsson's blog, the way to do it could be:
Add an command line option to the machine.opt file, so to create a global variable.
Find the instruction node in machine.md or other files, that emits the instruction you want to disable. Change the condition to be on the new variable you'v added. When the condition is not met, gcc would emit a call to a function that you'll supply in your .c file or lib file.
As a simpler example, take a look at the ft32 architecture directory. It creates an global variable NODIV based on a -mnodiv command line option. The instruction node in the ft32.md file contains:
(define_insn "divsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(div:SI
(match_operand:SI 1 "register_operand" "r,r")
(match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
"!TARGET_NODIV"
"div.l %0,%1,%2")
In this ft32 case, when the variable is not set, gcc emits div.l assembly code. When it is set, it would make a call to a function named __divsi3.
Though I have not tried this out. Will update with exact information when I get a chance to try it out.
Related
I'm handed a variable CC which contains the executable that refers to the compiler on the system. I need to take this executable and eventually call it with some compiler-specific link arguments.
My current approach seems very fragile:
def guess_compiler(cc):
out = subprocess.check_output((cc, '--version'))
for possible in (b'clang', b'gcc'):
if possible in out:
return possible.decode()
else:
# Fall back to gcc
return 'gcc'
From this I'm using a mapping of the specific linker arguments I care about:
return {
'clang': '-Wl,-undefined,dynamic_lookup',
'gcc': '-Wl,--unresolved-symbols=ignore-all',
}[cc]
In short, I'm hoping there's a better (less fragile) way to do what I've accomplished.
For those looking for why I want something like this, it's mostly for portability in a project I'm implementing.
I'd rather call a compiler with some dummy code and these flags passed in. This is also what tools like Autotools and CMake do.
The problem with your current approach is that text string you see in --version output can actually be arbitrary. For instance, when clang wasn't that popular, FreeBSD's cc --version have been giving
GCC 4.2.1 -compatible Clang bla bla
So, just call the compiler with each flag you are interested in and then look at exit code.
An example of how to do this:
for flag in FLAGS:
try:
subprocess.check_call((cc, 'test.c', flag), cwd=tmpdir)
return flag
except subprocess.CalledProcessError:
pass
else:
# wellp, none of them worked, fall back to gcc and they'll get a
# hopefully reasonable error message
return FLAG_GCC
I just figured this out but instead of splitting my new question ("why?") into another question I think its best if the solution to this problem and an explanation were to be kept on the same page.
I'm writing a basic assembly program to just start and immediately quit using the kernel interrupt at int 0x80. My current code is simply as follows:
/* Simple exit via kern-interrupt */
.globl start
start:
pushl $0x0
movl $0x1, %eax
subl $4, %esp
int $0x80
assembled with
as -arch i386 <file>.s
upon executing I get a one-line error:
Illegal instruction
It's bizzare, even commenting everything out still results in Illegal instruction despite there being no instructions at all. Am I missing a linking step, despite there being no other files to link to? Yes I am
EDIT: Allow me to rephrase my question, why do you need to link when there is no library or anything to link to?
You do need to link it to create an executable. By default, as just gives you an object file, which is something you can link into an executable (either with other object files or on its own) but is not itself a valid executable. Try:
as -arch i386 -o file.o file.s
ld -o file file.o
In answer to your question:
Why do you need to link when there is no library or anything to link to?
Because the assembler doesn't know that you're not going to link with something else.
Unlike the gcc compiler where it assumes you want a program unless told otherwise (with the -c option), as gives you an object file by default. From the manpage:
"as" is primarily intended to assemble the output of the GNU C compiler "gcc" for use by the linker "ld"
If you want a one-step command, you can create a script such as asld:
as -arch i386 -o $1.o $1.s
ld -o $1 $1.o
and then just use asld file.
Or, you could set up makefiles to do all the heavy lifting for you.
You could make the same argument about a C program, I am not using any libraries why do I have to link.
Because that is how the toolchain was designed. One set of tools takes you from source code (any/many languages) to object files which are most of the time incomplete. The link stage, even if as paxdiablo shows, only takes your object file and makes it an executable, is required. If nothing else your .text address is (usually) needed and that comes from the linker stage.
It makes a lot of sense to do it this way, the link stage is complicated enough as it is, make that one tool that does that job and is good at that job. Do your system engineering and define an interface to that tool. The language tools have a complicated job to do have them just do that job, the output being an object file, which is as far as they can resolve without having to become a linker.
If you wish to not use this toolchain and perhaps use nasm or something like that where you can go directly from assembly to binary in one command line step.
Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}
In this episode of "let's be stupid", we have the following problem: a C++ library has been wrapped with a layer of code that exports its functionality in a way that allows it to be called from C. This results in a separate library that must be linked (along with the original C++ library and some object files specific to the program) into a C program to produce the desired result.
The tricky part is that this is being done in the context of a rigid build system that was built in-house and consists of literally dozens of include makefiles. This system has a separate step for the linking of libraries and object files into the final executable but it insists on using gcc for this step instead of g++ because the program source files all have a .c extension, so the result is a profusion of undefined symbols. If the command line is manually pasted at a prompt and g++ is substituted for gcc, then everything works fine.
There is a well-known (to this build system) make variable that allows flags to be passed to the linking step, and it would be nice if there were some incantation that could be added to this variable that would force gcc to act like g++ (since both are just driver programs).
I have spent quality time with the gcc documentation searching for something that would do this but haven't found anything that looks right, does anybody have suggestions?
Considering such a terrible build system write a wrapper around gcc that exec's gcc or g++ dependent upon the arguments. Replace /usr/bin/gcc with this script, or modify your PATH to use this script in preference to the real binary.
#!/bin/sh
if [ "$1" == "wibble wobble" ]
then
exec /usr/bin/gcc-4.5 $*
else
exec /usr/bin/g++-4.5 $*
fi
The problem is that C linkage produces object files with C name mangling, and that C++ linkage produces object files with C++ name mangling.
Your best bet is to use
extern "C"
before declarations in your C++ builds, and no prefix on your C builds.
You can detect C++ using
#if __cplusplus
Many thanks to bmargulies for his comment on the original question. By comparing the output of running the link line with both gcc and g++ using the -v option and doing a bit of experimenting, I was able to determine that "-lstdc++" was the magic ingredient to add to my linking flags (in the appropriate order relative to other libraries) in order to avoid the problem of undefined symbols.
For those of you who wish to play "let's be stupid" at home, I should note that I have avoided any use of static initialization in the C++ code (as is generally wise), so I wasn't forced to compile the translation unit containing the main() function with g++ as indicated in item 32.1 of FAQ-Lite (http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html).
I'm using Qt Creator with gdb to debug my C++ code on a Linux Platform. Whenever I use a boost::shared_ptr or the like, the debugger steps into the header files containing the boost implementation (i.e. /usr/include/boost/shared_ptr.hpp). I would like to ignore these files in terms of debugging and simply step over them. I know that I can step out as soon as it reaches one of these files, but it would be much easier to debug without doing so several times per debugging session.
I'm using the gcc compiler (g++), running on OpenSuSE Linux 11.2 with QtCreator 2.2 (which uses gdb as the debugger.)
Edit to add: The question is geared toward Boost files, but could also apply toward STL files as well.
GDB without stepping into STL and all other libraries in /usr:
Put the following in your .gdbinit file. It searches through the sources that gdb has loaded or will potentially load (gdb command info sources), and skips them when their absolute path starts with "/usr". It's hooked to the run command, because symbols might get reloaded when executing it.
# skip all STL source files
define skipstl
python
# get all sources loadable by gdb
def GetSources():
sources = []
for line in gdb.execute('info sources',to_string=True).splitlines():
if line.startswith("/"):
sources += [source.strip() for source in line.split(",")]
return sources
# skip files of which the (absolute) path begins with 'dir'
def SkipDir(dir):
sources = GetSources()
for source in sources:
if source.startswith(dir):
gdb.execute('skip file %s' % source, to_string=True)
# apply only for c++
if 'c++' in gdb.execute('show language', to_string=True):
SkipDir("/usr")
end
end
define hookpost-run
skipstl
end
To check the list of files to be skipped, set a breakpoint somewhere (e.g., break main) and run gdb (e.g., run), then check with info sources upon reaching the breakpoint:
(gdb) info skip
Num Type Enb What
1 file y /usr/include/c++/5/bits/unordered_map.h
2 file y /usr/include/c++/5/bits/stl_set.h
3 file y /usr/include/c++/5/bits/stl_map.h
4 file y /usr/include/c++/5/bits/stl_vector.h
...
Its easy to extend this to skip other directories as well by adding a call to SkipDir(<some/absolute/path>).
gdb is scriptable. it has while, if, variables, shell subcommands, user-defined functions (define) etc etc. it has python interface for scriptability.
With a bit of work, you can to make gdb script along these lines:
define step-bypass-boost
step
while 1
use "info source", put current source file into variable
if source file does not match */boost/* then
break-loop
end
step
end
end
or find whether somebody already made such script
Instead of doing s (step), you can
b on first line of your function where you want to stop (b Class::method, or b file.cpp:line),
then c.
gdb will bypass the boost code and break at the point given in b, where you want it
this works but can seem tedious. it's matter of habit. becomes easier with repetition.
msvc behaves similar to gdb
From https://stackoverflow.com/a/31629136/5155476:
I had this same need. I extended the 'skip' command in gdb to support a new type 'dir'. I can now do this in gdb:
skip dir /usr
and then I'm never stopped in any of my 3rd party headers.
Here's a webpage w/ this info + the patch if it helps anyone: info & patch to skip directories in GDB