I've been trying to decompile an exe file (or just one function, for all I care), and I've been running into the following error:
Decompilation failure:
FFFFFF: wrong basic type sizes in compiler settings
According to the manual, I should check these settings:
Some basic type sizes are incorrect. The decompiler requires that
sizeof(int) == 4
sizeof(bool) == 4
sizeof(enum) == 4
sizeof(long) == 4
sizeof(near pointer) == 4
Please check the type sizes in the Options, Compiler dialog box and modify them if they are incorrect.
I have checked these settings, and they are set to the specified settings. Please note that I am missing the "sizeof(near pointer)" but I have a sizeof(short) and a sizeof(longlong) that aren't specified in the manual.
I'd be grateful for a fast resolution to this problem.
Related
I'm currently testing some inline assembly in C++ on an old compiler (GCC circa 2004) and I wanted to perform the square root function on a floating point number. After trying and searching for a successful method, I came across the following code
float r3(float n){
__asm__("fsqrt" : "+t" (n));
return n;
};
which worked. The issue is, even though I understand the assembly instructions used, I'm unable to find any particular documentation as to what the "+t" flag means on the n variable. I'm under the genuine idea that it seems to be a manner by which to treat the variable n as both the input and output variable but I was unable to find any information on it. So, what exactly is the "t" flag and how does it work here?
+
Means that this operand is both read and written by the instruction.
(From here)
t
Top of 80387 floating-point stack (%st(0)).
(From here)
+ means you are reading and writing the register.
t means the value is on the top of the 80387 floating point stack.
References:
GCC manual, Extended Asm has general information about constraints - search for "constraints"
GCC manual, Machine Constraints has information about the specific constraints supported on each architecture - search for "x86 family"
I'm attempting to build Chromium 45.0.2454.85 with GCC 5.2.0. It's setup to build with -Wall and -Werror and I'd like to keep it that way (though GCC seems to be making that progressively more difficult in each new version). I've already fixed several warnings (errors) but getting to the bottom of this one is proving pretty tricky:
ui/gfx/image/image_util.cc:50:6: error: assuming signed overflow does not occur when assuming that (X - c) <= X is always true [-Werror=strict-overflow]
Here is the line it is referring to:
https://chromium.googlesource.com/chromium/src.git/+/45.0.2454.85/ui/gfx/image/image_util.cc#50
My first issue with this warning is that it points you to the function that the problem is in and makes you go hunt for the problem. I understand this warning is probably generated somewhere in the guts of the optimizer long after it's lost track of which machine code corresponds to which exact line but that's no solace when faced with tracking down the problem. With a little experimentation (removing the -1 for instance) I was able to verify my suspicion that line 81 is causing the problem (unless I'm totally off track):
for (int x = bitmap.width() - 1; x > inner_min; --x) {
My second issue is that it's saying that (X - c) <= X is always true. Based on my experimentation it seems to be talking about the comparison on line 81 but I don't see how it could be coming to this conclusion.
What is GCC doing here and what is the proper way to fix it? I don't want to go changing int's to unsigned int's to avoid the undefined signed overflow behavior in order to side step the problem.
From GCC Manual -Wstrict-overflow=1:
Warn about cases that are both questionable and easy to avoid. For
example: x + 1 > x; with -fstrict-overflow, the compiler will simplify
this to 1. This level of -Wstrict-overflow is enabled by -Wall; higher
levels are not, and must be explicitly requested.
I'd also argue that this situation doesn't meet the criteria of "easy to avoid"; please correct me if I'm wrong.
this line from gcc:
ui/gfx/image/image_util.cc:50:6: error: ...
is saying the problem is in file image_util.cc, line 50, column 6
If '50:6' is the first char of the function name, there are only a couple of possibilites.
1) the function declaration (not something deep in the body) has a problem
(suggest checking the parameters and comparing to the function prototype)
2) the prior line of the source code contains the problem.
If this is just one of a series of problems listed, then
fix the first problem listed, re-compile, repeat until no problems listed
because C compilers tend to spew lots of warnings/errors when the actual root of the problem is at or just before the line indicated
I am trying to debug calls to CreateFileA from a DLL that I do not have source code to. I can set the breakpoint in the kernel32.dll with no problem, and I know that the value pointed to by (esp + 4) is the address of the filename. What I'd like to do is to put a watch on the memory address pointed to by (esp + 4), however I cannot determine the correct watch syntax to use (providing it is even possible). For example, I've tried various patterns to the following:
(char *)&(esp + 4) -- error: operand types bad for this operation
Obviously, I can always fall back on having two memory windows open and manually enter the addresses every time the debugger breaks, but I am going for efficiency here. :)
I need to set #ifdef - checks for conditional compile. I want to automate the process but cannot specify the target OS/machine. Is there some way that the pre-compiler can resolve whether it it is running on 32-bit or 64-bit?
(Explanation) I need to define a type that is 64 bits in size. On 64bit OS it is a long, on most others it is a long long.
I found this answer - is this the correct way to go?
[edit] a handy reference for compiler macros
The only compile check you can do reliably would be sizeof(void*) == 8, true for x64 and false for x86. This is a constexpr and you can pass it to templates but you can forget using ifdef with it. There is no platform-independent way to know the address size of the target architecture (at pre-process time), you will need to ask your IDE for one. The Standard doesn't even have the concept of the address size.
No there is no standard language support for macro to determine if the machine is a 64-bit or 32-bit at preprocessor stage.
In response to your edit, there is a "macro-less for you" way to get a type that is 64 bits.
if you need a type that can hold 64 bits, then #include <cstdint> and use either int64_t or uint64_t. You can also use the Standard Integer Types provided by Boost.
Another option is to use long long. It's technically not part of the C++ standard (it will be in C++0x) but is supported on just about every compiler.
I would look at source code for a cross-platform library. It is a quite large part. Every pair of OS and compiler has own set of definitions. Few libraries You may look at:
http://www.libsdl.org/ \include\SDL_config*.h (few files)
http://qt.nokia.com/ \src\corelib\global\qglobal.h
Boost has absorbed the old Predef project. You'll want the architecture macros, more specifically BOOST_ARCH_X86_32/BOOST_ARCH_X86_64, assuming you only care about x86.
If you need a wider detection (e.g. ARM64), either add the relevant macro's to your check, or check what you actually want to check, e.g.
sizeof(void*) == 8
Well, the answer is clearly going to be OS-specific, so you need to narrow down your requirements.
For example, on Unix uname -a typically gives enough info to distinguish a 32-bit build of the OS from a 64-bit build.
The command can be invoked by your pre-compiler. Depending on its output, compiler flags can be set appropriately.
I would be tempted to hoist the detection out of the code and put that into the Makefile. Then, you can leverage system tools to detect and set the appropriate macro upon which you are switching in your code.
In your Makefile ...
<do stuff to detect and set SUPPORT_XX_BIT to the appropriate value>
gcc myFile.c -D$(SUPPORT_XX_BIT) -o myFile
In your code ...
#if defined(SUPPORT_32_BIT)
...
#elif defined(SUPPORT_64_BIT)
...
#else
#error "Select either 32 or 64 bit option\n"
#endif
Probably the easiest way might be comparing the size of int and long long. You cannot do it in the pre-processor though but you can use it in static_assert.
Edit: WoW all the negative votes. I made my point a bit more clear. Also it appears I should have mentioned 'long long' rather than 'long' because of the way MSVC works.
Often one makes assumptions about a particular platform one is coding on, for example that signed integers use two's complement storage, or that (0xFFFFFFFF == -1), or things of that nature.
Does a tool exist which can check a codebase for the most common violations of these kinds of things (for those of us who want portable code but don't have strange non-two's-complement machines)?
(My examples above are specific to signed integers, but I'm interested in other errors (such as alignment or byte order) as well)
There are various levels of compiler warnings that you may wish to have switched on, and you can treat warnings as errors.
If there are other assumptions you know you make at various points in the code you can assert them. If you can do that with static asserts you will get failure at compile time.
I know that CLang is very actively developing a static analyzer (as a library).
The goal is to catch errors at analysis time, however the exact extent of the errors caught is not that clear to me yet. The library is called "Checker" and T. Kremenek is the responsible for it, you can ask about it on clang-dev mailing list.
I don't have the impression that there is any kind of reference about the checks being performed, and I don't think it's mature enough yet for production tool (given the rate of changes going on) but it may be worth a look.
Maybe a static code analysis tool? I used one a few years ago and it reported errors like this. It was not perfect and still limited but maybe the tools are better now?
update:
Maybe one of these:
What open source C++ static analysis tools are available?
update2:
I tried FlexeLint on your example (you can try it online using the Do-It-Yourself Example on http://www.gimpel-online.com/OnlineTesting.html) and it complains about it but perhaps not in a way you are looking for:
5 int i = -1;
6 if (i == 0xffffffff)
diy64.cpp 6 Warning 650: Constant '4294967295' out of range for operator '=='
diy64.cpp 6 Info 737: Loss of sign in promotion from int to unsigned int
diy64.cpp 6 Info 774: Boolean within 'if' always evaluates to False [Reference: file diy64.cpp: lines 5, 6]
Very interesting question. I think it would be quite a challenge to write a tool to flag these usefully, because so much depends on the programmer's intent/assumptions
For example, it would be easy to recognize a construct like:
x &= -2; // round down to an even number
as being dependent on twos-complement representation, but what if the mask is a variable instead of a constant "-2"?
Yes, you could take it a step further and warn of any use of a signed int with bitwise &, any assignment of a negative constant to an unsigned int, and any assignment of a signed int to an unsigned int, etc., but I think that would lead to an awful lot of false positives.
[ sorry, not really an answer, but too long for a comment ]