I am building a makefile for an SDL/OpenGL program. In looking at the Makefile for the SDL2.0 examples, I see compiler flags such as DHAVE_OPENGL, and D_REENTRANT. Nowhere in the man pages for gcc can I find information on either of these flags. Where on the internet/my system can I find documentation about all the flags supported by gcc?
the -D option is used not to define specific compiler flags but to pass macro definitions to the preprocessor.
Indeed -DHAVE_OPENGL is like having #define HAVE_OPENGL 1 in your source code. So they are not related to the compiler per se but just on the code you are compiling.
Here you can find a comprehensive documentation of GCC options in any case.
Those are not compiler flags per-se. -D is a compiler flag, but what follows is a pre-processor definition. You will not find any information on what those mean in the compiler docs because it affects the behavior (e.g. which portions of the code are actually included during compilation) of the actual code that you are building.
So unfortunately, the only way you will know what defining those pre-processor tokens will do is if you investigate the source code you are compiling or if the library you are using documents them.
Generally speaking however, HAVE_OPENGL lets SDL know to compile GL-related code.
Re-entrancy is used for thread safety, and although _REENTRANT is not a standard pre-processor definition (though commonly used with some C stdlib implementations), it is safe to assume that it will cause your software to select re-entrant versions of functions whenever possible.
Related
The documentation very specifically states this limitation but I can't seem to find any explanation as to why it would be the case.
I had hoped that CMake's WINDOWS_EXPORT_ALL_SYMBOLS would eliminate the need to alter source code written for GCC to be linked correctly in MSVC.
So with that assumption, I misinterpreted the documentation cited above where it says:
For global data symbols, __declspec(dllimport) must still be used when compiling against the code in the .dll
and took it as a limitation of the CMake feature, rather than a requirement of MSVC (which was quite my mistake.)
One modern Linux security hardening tactic is to compile & link code with the option -Wl,-z-noexecstack, this marks the DLL or binary as not needing an executable stack. This condition can be checked using readelf or other means.
I have been working with uClibc and noticed that it produces objects (.so files) that do not have this flag set. Yet uClibc has a configuration option UCLIBC_BUILD_NOEXECSTACK which according to the help means:
Mark all assembler files as noexecstack, which will mark uClibc
as not requiring an executable stack. (This doesn't prevent other
files you link against from claiming to need an executable stack, it
just won't cause uClibc to request it unnecessarily.)
This is a security thing to make buffer overflows harder to exploit.
...etc...
On some digging into the Makefiles this is correct - the flag is only applied to the assembler.
Because the flag is only passed to the assembler does this mean that the uClibc devs have missed an important hardening flag? There are other options, for example UCLIBC_BUILD_RELRO which do result in the equivalent flag being added to the linker (as -Wl,-z,relro)
However a casual observer could easily misread this and assume, as I originally did, that UCLIBC_BUILD_NOEXECSTACK is actually marking the .so file when it is in fact not. OpenWRT for example ensures that that flag is set when it builds uClibc.
Why would uClibc not do things the 'usual' way? What am I missing here? Are the libraries (e.g. librt.so, libpthread.so, etc) actually not NX?
EDIT
I was able to play with the Makefiles and get the noexecstack bit by using the -Wl,-z,noexecstack argument. So why would they not use that as well?
OK, it turns out after list conversation and further research that:
the GNU linker sets the DLL / executable stack state based on the 'lowest common denominator' i.e. if any linked or referenced part has an exec stack then the whole object is set this way
the 'correct' way to resolve this problem is actually to find and fix assembly / object files that use an exec stack when they dont need to.
Using the linker to 'fix' things is a workaround if you can't otherwise fix the root cause.
So for uClibc solution is to submit a bug so that the underlying objects get fixed. Otherwise anything linked with static libraries wont get a non-exec stack.
For my own question, if building a custom firmware not using any static libraries it is possibly sufficient to use the linker flag.
References:
Ubuntu Security Team - Executable Stacks
Given a static library StaticLib, how to know in advance which compiler and linker options and libraries to use in linux? There are some programs that shows dependencies but I think no one gives specific options for a specific compiler. Something like StaticLib depens on Lib1, Lib2 and Lib3, so use the options -x -y -x for gcc.
There are in Stackoverflow and in the Internet, thousand of specific questions that would be answered automatically just by answering this general question.
Static libraries don't have explicit dependencies on libraries - unlike dynamic libraries, which do (and whose dependencies you can see with ldd on a Unix-like platform). You can use nm to look at which symbols are defined, undefined, etc. within the library, and that will give you some information. There is no single answer to the question "which library contains the definition for the symbol that my library references but is undefined?" since any library with a definition for that symbol is as valid as any other to the linker. (This is also true with dynamic libraries - the dependencies advertised by them are just guides to the linker.)
As for compiler flags, there is no universal way to determine which flags to use to link with a given library, since various compilers will either strip out this information from the resulting library/executable in certain cases, or just never record it in the first place. Developers will usually advertise this information out of band alongside their libraries, e.g. "to link against this library, use flag XXX".
I am currently following a course at my University in which, at this stage, we learn about the assembler code behind certain C/C++ constructs.
The workflow usually goes like this: the lab assistant briefly speaks about a topic, we figure out the quirks and then solve some totally random problem using inline assembly.
(For example: He briefly talks about how struct (members) are stored in memory, we figure out the pattern and then we write the solution using inline assembly to a simple problem in which we use a struct.)
The lab assistant (as well as the rest of the group) is using the Visual C++ compiler and debugger (for disassembly) for his demonstrations however I cannot use it due to ethical reasons and thus I opted for g++ and gdb.
What I find awkward about g++'s inline assembly compared to Visual C++ is the fact that:
If I want to write a 'block' of inline assembly I have two options: Have a single asm("..") construct in which each instruction is preceded by a \n\t (leads to a lot of clutter). Or have each instruction in its own asm("..") block (leads to a lot of typing).
If I want to reference a local variable in the inline assembly I have to either use the extended syntax or reference it by using offsets to esp/ebp.
In respect to the two issues above I prefer the Visual C++'s inline assembly style in which in order to write an asm block all I have to do is __asm { .. } and write each instruction on a new line and in order to reference a variable I just have to write its name.
Throughout my searches I have discovered that Apple's g++ supports the same syntax as Visual C++ with a switch (-fasm-blocks) however this does not seem to be the case for GNU g++.
In the hopes that I might have missed something I am asking here if it is possible to compile Visual C++ like inline assembly blocks under GNU g++.
The syntax you are referring to is not Microsoft specific. As you have found, Apple had it too (although Apple gave up on GCC and switched to Clang). AFAIK, Metrowerks supports the same syntax. GCC does not support it (probably because GCC guys believe that GCC is so good that nobody needs to write assembly anymore :-)). However, there is no need to type \n\t all the time, you can replace it with ;. For example:
void foo()
{
asm("xor %eax,%eax;"
"rep; nop;"
"nop;"
"sfence;"
"nop;");
}
Hope it helps. Good Luck!
I have a FORTRAN 95 program that needs to make some calls to the LAPACK library. I recently found out that Cygwin because it can install LAPACK as an extra option.
Well, LAPACK exists in the /lib/lapack/ directory as "cyglapack.dll". Having only a very informal training in Fortran programming, I have no idea how to reference a .dll library as opposed to a .mod module.
Any suggestions or directions to articles answering my question are GREATLY appreciated!
(P.S. I did search first.. I don't think I know the proper terms to get a useful article.)
Conceptually calling Lapack should be as easy as calling any other DLL. You just have to figure out what link flags and statements to include in your build statement(s).
From Fortran you would, probably, declare as EXTERNAL the functions from Lapack that you wan't to use. This tells the compiler not to bother looking for a definition of the function in your sources, or in a mod file, but that the definition will be provided at link time. This is where the fun begins, as you try to ensure that the signatures of your calls match the signatures expected by the DLL.
I might be able to provide more help if you provide more information. What is your Windows development environment ? What Fortran compiler are you using ? What compile and link tools are you using ? What does your current link statement look like ?
Search terms: dynamic linking fortran
Take a look at this page:
http://sources.redhat.com/ml/binutils/2001-12/msg00471.html
It mentions using dlltool to generate a .a file from a .dll file. Presumably you should be able to link to that in the normal way (usually a lib switch on the compile command).
Otherwise, consider running a linux Live CD for the sake of avoiding the problem in the first place! If you're a student or an academic, see if you can find a server with fortran installed (the IT staff are usually pretty helpful) where you can compile and run your program.