Why strcpy is defined in Lint_strcpy.c in minix? - freebsd

For example in FreeBSD strcpy is defined in lib/libc/string/strcpy.c. Why in minix it is defined in lib/libc/string/Lint_strcpy.c, not in strcpy.c just like in FreeBSD? What does Lint prefix mean?
It's worth mentioning that in minix some functions (like strpcpy) are defined in this way. I mean, strpcpy is defined in lib/libc/string/strpcpy.c but strcpy is defined in lib/libc/string/Lint_strcpy.c. What's the point in this?

If you actually look at the source inside lib/libc/string/Lint_strcpy.c you'll find it is an empty definition.
As in the original NetBSD source, the actual definition of strcpy() used in building the C library for Minix is in common/lib/libc/string/strcpy.c.
This is done so that the same definition can be shared directly from the same source file for both the kernel and userland.
The Lint_ prefix indicates a file which is there just for the purpose of creating a "lint library", and is effectively a shortcut to somewhat simplify the build process for lint libraries (they could/should in theory use the common source file too).

Related

What does tinfo6 stands for?

Working with Haskell and particularly GHC I can see tinfo6 word quite often. Mostly it appears in arch-vendor-os triple x86_64-linux-tinfo6 like if it was some sort of OS. But what really does tinfo6 mean?
it appears in arch-vendor-os triple x86_64-linux-tinfo6
I think you are confusing GNU target triplets with GHC target triplets. A GHC target triplet is <architecture>-<operating system>-<ABI>.
So, tinfo6 is the ABI. I don't know much about GHC, but I do remember that it has a calling convention that is not the C calling convention.
Fun fact: this calling convention can actually not be expressed in C, therefore the C backend of GHC actually calls GCC to generate assembly, then a Perl(!!!) script that is part of the GHC compiler searches for calls in the assembly code and re-writes them to the GHC calling convention; after that, the compiler will call GCC (or rather GAS) again, to assemble the object file. (This rather clever but somewhat crazy hack is one of the reasons for the push to native and LLVM backends.)
So, unfortunately, I don't know what tinfo6 means but I am pretty sure it is the name of the GHC calling convention or ABI.

Why are some foreign functions statically linked while others are dynamically linked?

I'm working on a program that needs to manipulate git repositories. I've decided to use libgit2. Unfortunately, the haskell bindings for it are several years out of date and lack several functions that I require. Because of this I've decided to write the portions that use libgit2 in C and call them through the FFI. For demonstration purposes one of them is called git_update_repo.
git_update_repo works perfectly when used in a pure C program, however when it's called from haskell an assertion fails indicating that the libgit2 global init function, git_libgit2_init, hasn't been called. But, git_libgit2_init is called by git_update_repo. And if I use gdb I can see that git_libgit2_init is indeed called and reports that the initialization has been successful.
I've used nm to examine the executables and found something interesting. In a pure C executable, all the libgit2 functions are dynamically linked (as expected). However, in my haskell executable, git_libgit2_init is dynamically linked, while the rest of the libgit2 functions are statically linked. I'm certain that this mismatch is the cause of my issue.
So why do certain functions get linked dynamically and others statically? How can I change this?
The relevant settings in my .cabal file are
cc-options: -g
c-sources:
src/git-bindings.c
extra-libraries:
git2

Which code in LLVM IR runs before "main()"?

Does anyone know the general rule for exactly which LLVM IR code will be executed before main?
When using Clang++ 3.6, it seems that global class variables have their constructors called via a function in the ".text.startup" section of the object file. For example:
define internal void #__cxx_global_var_init() section ".text.startup" {
call void #_ZN7MyClassC2Ev(%class.MyClass* #M)
ret void
}
From this example, I'd guess that I should be looking for exactly those IR function definitions that specify section ".text.startup".
I have two reasons to suspect my theory is correct:
I don't see anything else in my LLVM IR file (.ll) suggesting that the global object constructors should be run first, if we assume that LLVM isn't sniffing for C++ -specific function names like "__cxx_global_var_init". So section ".text.startup" is the only obvious means of saying that code should run before main(). But even if that's correct, we've identified a sufficient condition for causing a function to run before main(), but haven't shown that it's the only way in LLVM IR to cause a function to run before main().
The Gnu linker, in some cases, will use the first instruction in the .text section to be the program entry point. This article on Raspberry Pi programming describes causing the .text.startup content to be the first body of code appearing in the program's .text section, as a means of causing the .text.startup code to run first.
Unfortunately I'm not finding much else to support my theory:
When I grep the LLVM 3.6 source code for the string ".startup", I only find it in the CLang-specific parts of the LLVM code. For my theory to be correct, I would expect to have found that string in other parts of the LLVM code as well; in particular, parts outside of the C++ front-end.
This article on data initialization in C++ seems to hint at ".text.startup" having a special role, but it doesn't come right out and say that the Linux program loader actually looks for a section of that name. Even if it did, I'd be surprised to find a potentially Linux-specific section name carrying special meaning in platform-neutral LLVM IR.
The Linux 3.13.0 source code doesn't seem to contain the string ".startup", suggesting to me that the program loader isn't sniffing for a section with the name ".text.startup".
The answer is pretty easy - LLVM is not executing anything behind the scenes. It's a job of the C runtime (CRT) to perform all necessary preparations before running main(). This includes (but not limited to) to static ctors and similar things. The runtime is usually informed about these objects via addresses of constructores being emitted in the special sections (e.g. .init_array or .ctors). See e.g. http://wiki.osdev.org/Calling_Global_Constructors for more information.

How to retrieve the type of architecture (linux versus Windows) within my fortran code

How can I retrieve the type of architecture (linux versus Windows) in my fortran code? Is there some sort of intrinsic function or subroutine that gives this information? Then I would like to use a switch like this every time I have a system call:
if (trim(adjustl(Arch))=='Linux') then
resul = system('ls > output.txt')
elseif (trim(adjustl(Arch))=='Windows')
resul = system('dir > output.txt')
else
write(*,*) 'architecture not supported'
stop
endif
thanks
A.
The Fortran 2003 standard introduced the GET_ENVIRONMENT_VARIABLE intrinsic subroutine. A simple form of call would be
call GET_ENVIRONMENT_VARIABLE (NAME, VALUE)
which will return the value of the variable called NAME in VALUE. The routine has other optional arguments, your favourite reference documentation will explain all. This rather assumes that you can find an environment variable to tell you what the executing platform is.
If your compiler doesn't yet implement this standard approach it is extremely likely to have a non-standard approach; a routine called getenv used to be available on more than one of the Fortran compilers I've used in the recent past.
The 2008 standard introduced a standard function COMPILER_OPTIONS which will return a string containing the compilation options used for the program, if, that is, the compiler supports this sort of thing. This seems to be less widely implemented yet than GET_ENVIRONMENT_VARIABLE, as ever consult your compiler documentation set for details and availability. If it is available it may also be useful to you.
You may also be interested in the 2008-introduced subroutine EXECUTE_COMMAND_LINE which is the standard replacement for the widely-implemented but non-standard system routine that you use in your snippet. This is already available in a number of current Fortran compilers.
There is no intrinsic function in Fortran for this. A common workaround is to use conditional compilation (through makefile or compiler supported macros) such as here. If you really insist on this kind of solution, you might consider making an external function, e.g., in C. However, since your code is built for a fixed platform (Windows/Linux, not both), the first solution is preferable.

Tools that list the prototypes in .so library

Is there a tool(like command) in Linux that list the prototypes in a .so library.
I found nm close to my need, but what I got are just symbols.
If the library is a C library, it does not contain by itself the signature of the functions. These are in the header files (that the library should give), unless the .so library has been compiled with debugging information enabled by -g (which is not usual for production libraries).
Even in C++, the .so library (without -g) don't contain the declaration of involved classes. The mangled names only refer to class or type names...
In short, you need the header files of libraries. Most Linux distributions package them separately from the library itself. For instance, on Debian you have both the libjansson4 package (containing the .soshared library, needed to run applications liked with the Jansson library) and the libjansson-dev package (containing the shared objects and header files useful to build an application calling functions in Jansson library). Debian also provides libjansson-dbg (for the debugging information or variant of the library) and libjansson-doc (for the documentation) packages.
Simple answer: no you cannot do that (for C).
Longer answer:
You can get "prototypes" as you named them ONLY for C++, because functions' declarations are mangled. Mangling really means encoding the whole function signature (or prototype if you like) into one string of characters without spaces, e.g:
CCertificate::GetInfo(Utils::TCertInfo&) const
which is in mangled form:
_ZZNK12CCertificate7GetInfoERN5Utils9TCertInfoEE8
Mangling was intoduced because of function overloading in C++ (functions with the same name but taking different number of parameters and/or different types). In C you do not have oveloading, so the functions are identified (in shared libraries) by name (which is NOT mangled).
To summarise: all functions in shared libraries are identified by name, but for C++ these names are mangled names, for C they are not mangled.
Mangling gives you that additional "side effect" that you can see the function signature (e.g. invoking nm -C).
Hope that helps.

Resources