Building C++ and Assembly source in Xcode - c++

I'm trying to build a command-line application in Xcode for OS X 10.9 which contains a .cpp source file, which uses a function externally defined in a .asm assembly file. The C++ code:
#include <iostream>
using namespace std;
extern "C" void NOTHING();
int main(){
NOTHING();
return 0;
}
The following is the assembly function:
global NOTHING
section .text
NOTHING:
mov eax, 0
ret
It's a program that does nothing but temporarily move the value zero into the EAX register. I made sure to choose NASM assembly when creating the .asm source file. When I hit the 'play' button to build the executable, Xcode simply states build failed, without specifying a reason.
I could revert back to doing it all in the command line, as I would on Linux. However, if possible, I'd prefer to start using Xcode, as it combines many tools, e.g. Git, into a single application for development.
EDIT: After the answer, I have decided to abandon Xcode; the command line is just much simpler. Based on the answer, I have written the following 'makefile' for future users visiting the question:
test: main.cpp asm.o
g++ -stdlib=libstdc++ main.cpp asm.o -o test
asm.o: asm.asm
nasm -f macho64 asm.asm -o asm.o
which assumes the assembly file is 'asm.asm', the C++ 'main.cpp', and the executable created is named 'test.' As in the answer, make sure functions in the .asm file begin with an underscore.

You need to specify -f macho64 - for 64 bit x86-64 Mach-O object files. As you've already seen, Mach-O (function) symbols are prefixed with an underscore. So if you give the function definition NOTHING, you must provide the global _NOTHING in the assembly.
Also, a function with "C" linkage should be specified as: void NOTHING (void);

Related

How can I isolate the compiled logic of a C++ program from the rest of the file header data?

I want to observe the difference in op code binary output of compilation between two versions of a very basic C++ program. For example, 2 + 2 = ?, with no libraries called. I expected the compiled output to be a tiny file of binary op codes with a few small headers, being new to compiled programs, but there are large headers.
simple.cpp
int main()
{
unsigned int a = 2;
unsigned int b = 2;
unsigned int c = a + b;
}
compiler:
g++ -std=c++0x simple.cpp -o simple
Is there a format that I can export to that doesn't contain headers, just op code binary that we instruct the machine to execute? If not, what bytes or location in the resulting file can I look for to isolate the relevant logic from the program?
I need the machine code, not assembly, since my project is the analysis of differently obfuscated versions of a source file to attempt recognizing one based on the other. A complex subject with questionable feasibility, but nevertheless that's why I'm asking to isolate the machine code and not just the assembly - to test analysis against the true machine code outputs.
I tried googling the header structure but can't seem to find much info.
Seeing ld(1): GNU linker - Linux man page, you will find that you can use --oformat=output-format option to specify output format.
binary is a format that don't have headers.
Then, seeing gcc(1): GNU project C/C++ compiler - Linux man page, you will find that you can use -Wl option to pass options to the linker.
-nostdlib option is also useful to avoid extra things added.
Combining these, you can try this command:
g++ -std=c++0x simple.cpp -nostdlib -Wl,--oformat=binary -o simple

Error compiling CPP application. "error: 'posix_memalign' was not declared in this scope"

I'm trying to compile a CPP application (an open source project) in the latest cygwin64 environment using g++ 6.4.0 and I get the following error:
error: 'posix_memalign' was not declared in this scope
now posix_memlign can be found in stdlib.h if you compile the most simple CPP "hello world" application there wouldn't be a problem calling posix_memlign.
The make file of the project report the following setup for the compilation
g++ -DHAVE_CONFIG_H -I. -Wall -Wnon-virtual-dtor -I. -I./include -g -O3 -std=c++0x -g -O3 -std=c++0x -MT lib/rectangular_binary_matrix.lo -MD -MP -MF lib/.deps/rectangular_binary_matrix.Tpo -c lib/rectangular_binary_matrix.cc -DDLL_EXPORT -DPIC -o lib/.libs/rectangular_binary_matrix.o
so it doesn't look like it override the default include path. Any ideas?
p.s.
I was able to build the code on Linux (Redhat) without a problem.
posix_memalign is not part of the C Standard Library or the C++ Standard
library and the cygwin GCC compilers do not provide it, although other
compilers may do so, including GCC compilers from other builders.
You might consider using instead the C Standard function aligned_alloc, if you feel comfortable to edit your project source. It is provided in <cstdlib> for C++ compilation in cygwin g++ 6.4.0
Later
I do see the function in C:\cygwin64\usr\include\stdlib.h...
The fact that you can find the function declaration in the header file
does not mean that the compiler can see it after preprocessing. The same
source header may be used by many builders, exposing different
declarations to the compiler depending on the builder's settings of implementor
macros. In this case, the declaration is concealed from your compiler by
the fact that __POSIX_VISIBLE >= 200112 is false. Identifiers beginning __ are reserved for implementors.
See the explanation of this macro
and note the comment:
* The following private macros are used throughout the headers to control
* which symbols should be exposed. They are for internal use only, as
* indicated by the leading double underscore, and must never be used outside
* of these headers.
[SOLUTION FOUND]
Hello (I'm posting this on 2 threads regarding the same problem).
I'm here because I had the "POSIX_VISIBLE >= 200112" and the "posix_memalign was not declared in this scope" issue, which was halting the compilation of a program.
I'm not a programmer and tried various fixes on my own for a couple hours. Then finally Googled & came upon this site. The solutions here did not work for me, but I'll describe what did work:
The "posix_memalign" text was in a "stdlib.h" file that was being included into the code. The first problem was that in my "cygwin" directory, I have 25 instances of "stdlib.h"! Which one of those was being included?! I'm all new to this, but I finally found that
echo | gcc -E -Wp,-v -
might at least give an idea of which directory the files were being "included" from. This narrowed down the number of "stdlib.h" files to 4. Out of 4 such files, only one had the "posix_memalign" text. I tried changing the filename of that stdlib.h to see if it would cause an error--and confirm that it was the stdlib.h in question. However, this didn't effect the program. So I searched for a "stdlib.h" file in the next directory higher. THAT "stdlib.h" file also had the "POSIX" text in it. So when I changed THAT stdlib.h filename, the program DID error out. So that was the stdlib.h to deal with.
I saw that the "POSIX_VISIBLE >= 200112" instruction effected only the ONE line of code with "posix_memalign" in it. (In other words, the "POSIX_VISIBLE" instruction was not being used for the whole file.) I considered "commenting" it out, or deleting it. But then non-programmer me got the ingenious idea to simply change the ">=" to a "<". So I now had "POSIX_VISIBLE < 200112". I saved the file, ran the "configure" and "make" routine again, and boom, all was well. Program compiled properly.
Moral of the story, if you can determine the file (containing the POSIX statement and the posix_memalign) which is being accessed by your code, you may be able to solve your problem by just changing that one POSIX_VISIBLE operator as I did. (And you may want to switch that operator back after your compiling is done, in case that stdlib.h library file needs to be used by other programs in the future.)

g++ fails to link .o files into an executable

I am doing an example drill in the textbook I am using to learn from. All I need to do is compile, link and run the following 3 files:
//file my.h
extern int foo;
void print_foo();
void print(int);
my.h is a simple header file that declares the two functions and a 'global' int foo, with no initial value.
//file my.cpp
#include "my.h"
#include "std_lib_facilities.h" //not included but not source of error
void print_foo()
{
cout << foo << endl;
}
void print(int i)
{
cout << i << endl;
}
my.cpp contains the implementation of the functions included from my.h. std_lib_facilities.h is a file from the textbook, and is not the source of error (according to g++). I can edit it into the body of the question if needed.
//file use.cpp
#include "my.h"
#include <iostream>
int main() {
foo = 7;
print_foo();
print(99)
char cc; cin >> cc;
return 0;
}
use.cpp serves as the main implementation file in this program, and tries to use all three declared & defined objects.
I took the two step command approach to build using g++. First, I compiled both .cpp files:
g++ -c my.cpp use.cpp
which created two object files, my.o and use.o. I used the following command to link them:
g++ -o myprog my.o use.o
giving me this error:
Undefined symbols for architecture x86_64:
"_foo", referenced from:
print_foo() in my.o
_main in use.o
(maybe you meant: __Z9print_foov)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have tried putting
int foo;
into my.h instead of
extern int foo;
which gave me the same error.
I have tried using the
-std=c++11
flag as well which resulted in the same error.
I am using a MacBook Pro with the latest macOS (just updated in fact), if that helps with interpreting the error message.
I have tried to initialize foo, which didn't change anything.
In addition, I have tried updating the command line tools, same error.
From what I understand, the error is telling me that, even though my.h is included in both files, neither one can actually implement any function using the foo variable (which it calls _foo), despite it being explicitly declared in my.h. My guess is that the linker is using the wrong names under the hood, which make it impossible to link into an executable. This comes from the fact that the error mentioned a
__Z9print_foov
which exists nowhere in any of the files.
It almost seems like a g++ or macOS/Command Line Tools bug at this point. I don't want to add the declarations each time, because that creates duplicate symbol errors anyway. Putting my.cpp and use.cpp into one file would probably link properly, but I need to make sure that I can actually link multiple cpp files, because I will eventually (hopefully) be working with multiple cpp files that need to be linked. Any help is appreciated!
Here you declare a variable:
extern int foo;
and you use the variable:
cout << foo << endl;
but you did not define the variable anywhere. The linker error says that the linker could not find the variable's definition. To fix this, put int foo; at file scope in one of the .cpp files.
In the question you say that changing extern int foo; to int foo; gives the same error. However if you look more carefully at the error message I think you will find that it gives a different one, about multiple definitions.
I suggest to compile in two commands g++ -Wall -c my.cpp (that gives a my.o) and g++ -Wall -c use.cpp (giving use.o), then link a program with g++ my.o use.o -o myprog. Actually you should write a Makefile (see this for inspiration) and simply run make
Your translation units my.cpp and use.cpp are both declaring some extern int foo; variable which is never defined. So you need to define it in one single file (but not in others!), probably by adding (into my.cpp alone for example)
int foo;
(without the extern) or even with some explicit initial value e.g. int foo = 34;
This comes from the fact that the error mentioned a __Z9print_foov which exists nowhere
It is a mangled name, which is referenced (but not defined) in both object files (see also this).
It almost seems like a g++ or macOS/Command Line Tools bug at this point
You are very unlikely to find bugs in compiler tools (both GCC & Clang/LLVM are extremely well tested; since they are multi-million lines free software, they do have residual bugs, but you have more chances to win at the lottery than to be affected by a compiler bug). I'm coding since 1974, and it happened to me only once in my lifetime. A more realistic attitude is to be more humble, and question your own code (and knowledge) before suspecting the compiler or build chain.
BTW, always compile first with all warnings and debug info (e.g. g++ -Wall -g and perhaps also -Wextra). Use the gdb debugger. When you are convinced that your code has no bugs, you might benchmark it by asking the compiler to optimize (so use g++ -Wall -O2 perhaps also with -g to compile).
Read also the linker wikipage. Dive into your C++ textbook (see also this site and the C++11 standard, e.g. n3337 draft) to understand the difference between declaring and defining some variable or function. You generally declare a global extern variable in some common header (included in several translation units), and define it once somewhere else, but the good practice is to avoid having lots of global variables. See also C++17 new inline variables.

Can't compile any c++ file

I have this simple file, called lol.c
#include <iostream>
using namespace std;
int main() {
return(0);
}
From terminal, i type g++ lol.c
This is the output:
In file included from /usr/include/wchar.h:36:0,
from /usr/include/c++/4.9/cwchar:44,
from /usr/include/c++/4.9/bits/postypes.h:40,
from /usr/include/c++/4.9/iosfwd:40,
from /usr/include/c++/4.9/ios:38,
from /usr/include/c++/4.9/ostream:38,
from /usr/include/c++/4.9/iostream:39,
from lol.c:1:
/usr/include/stdio.h:30:22: fatal error: SDL_main.h: File o directory non esistente
#include "SDL_main.h"
^
compilation terminated.
I don't know if the problem is something with SDL, but when i try to run ../configure to install it, i have this:
configure: error: cannot run C compiled programs.
See `config.log' for more details
If is this needed, i can put config.log file too.
There are multiple problems:
you gave a .c extension to a C++ source file; that is wrong, C++ files should have a .cpp (or .cxx, .C, .c++, the last two are a bit frowned upon) extension, or the compiler may try to compile it as C code;
you are invoking gcc instead of g++; this is wrong too, calling gcc on C++ files misses several options required to compile and link correctly (including, but not limited to, linking against the C++ standard library); that was in an older revision of the question, now it says g++;
but most importantly, your build environment is completely broken (some would say "FUBAR"); it is not normal that /usr/include/stdio.h includes stuff from SDL (the fact that it cannot be found is just a minor incident compared to this); you should really purge and reinstall anything related to gcc and to the headers of the C library; look for some libc6-dev package (or similar) to reinstall (be careful not to mess with the C library proper, or your system may be rendered essentially unbootable).
You can't give .c (c extension) to a c++ file.
1 - Change it to .cpp (c++ extension, lol.cpp)
2 - You have to give options to g++ (in your case use -o to create executable file) g++ lol.cpp -o nameofyourprogram
3 - Execute through your terminal ./nameofyourprogram

Can we inspect an object file for presence of temporaries introduced by C++ compiler?

Is there a way to inspect object file generated from code below ( file1.o ) for presence of compiler introduced temporary? What tools can we use to obtain such info from object files?
//file1.cpp
void func(const int& num){}
int main(){ func(2); }
The easiest way I can think of to do this is to load up a program that uses the object file and disassemble the function in the debugger. The program code you posted would work fine for this. Just break on the call to func and then display the assembler when you single-step into the function.
In a more complex program you can usually display the assembler code for a given function by name. Check your debugger documentation for how to do this. On Windows (Visual Studio) you can open the Disassembly window and enter the name of the function to display the assembler code.
If you have the source, most compilers allow you to output assembler, sometimes mixed with the source code. For Visual C++ this is /Fa.
If you're on an ELF system and have GNU binutils you can call readelf, probably with the -s switch.
If you have the source available, it is probably easier to look at the assembler file generated by the compiler (-save-temps for gcc). Otherwise, objdump is your friend.
You can use clang -cc1 --ast-print-xml to get a XML representation of a translation unit. The presence of temporaries can be easily detected from the AST.