I am trying to find the sched_clock defination for arm64 but could not find it, where and how it is implemented .
For example for x86, following is where it is defined
#ifdef CONFIG_PARAVIRT
unsigned long long sched_clock(void)
{
return paravirt_sched_clock();
}
#else
unsigned long long
sched_clock(void) __attribute__((alias("native_sched_clock")));
#endif
Same way it is defined for other archtectitures.
Could any one point me out for arm64 how it is implemented?
Related
According to this MSDN page, a data type LONGLONG is defined as below.
#if !defined(_M_IX86)
typedef __int64 LONGLONG;
#else
typedef double LONGLONG;
#endif
And it says LONGLONG is a 64-bit signed integer. But double is a floating-point type, not an integer type. So, do I find a typo? Or am I missing a point?
This is a documentation bug. It looks to be a lossy conversion from source to documentation1. The actual definition in winnt.h is a fair bit more complex:
//
// __int64 is only supported by 2.0 and later midl.
// __midl is set by the 2.0 midl and not by 1.0 midl.
//
#define _ULONGLONG_
#if (!defined (_MAC) && (!defined(MIDL_PASS) || defined(__midl)) && (!defined(_M_IX86) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)))
typedef __int64 LONGLONG;
typedef unsigned __int64 ULONGLONG;
#define MAXLONGLONG (0x7fffffffffffffff)
#else
#if defined(_MAC) && defined(_MAC_INT_64)
typedef __int64 LONGLONG;
typedef unsigned __int64 ULONGLONG;
#define MAXLONGLONG (0x7fffffffffffffff)
#else
typedef double LONGLONG;
typedef double ULONGLONG;
#endif //_MAC and int64
#endif
To understand what's going on, let's strip this down by removing everything not immediately relevant.
Assume that defined(_MAC) evaluates to 0.
Assume that defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 evaluates to 1. That appears to be true even going back as far as Visual C++ 6.0.
Strip symbols not relevant here (_ULONGLONG_, ULONGLONG, MAXLONGLONG).
Apply indentation without changing any other semantics.
The definition is now a lot easier to parse:
//
// __int64 is only supported by 2.0 and later midl.
// __midl is set by the 2.0 midl and not by 1.0 midl.
//
#if !defined(MIDL_PASS) || defined(__midl)
typedef __int64 LONGLONG;
#else
typedef double LONGLONG;
#endif
With that it should be clear that the conditional is a guarding the MIDL compiler (not the C++ compiler). The comment above has rationale, too: Version 1 of the MIDL compiler2 didn't support __int64 as a keyword, but version 2 (and later) do.
Translated into English: If this code isn't parsed by the MIDL compiler, or the MIDL compiler's version is 2 or above, alias LONGLONG with __int64. Otherwise (that is, using the MIDL compiler version 1), pick a double as a best effort.
This is of little practical use today. You can assume that LONGLONG is an alias for __int64, regardless of whether the definition is pulled in by the MIDL or C++ compiler. I wasn't able to find a version history for MIDL.exe, but I assume that version 1 is "ancient".
1 I'm reluctant to accept that having .NET developers write the tooling to generate C documentation from source was a Good Idea™.
2 This refers to the compiler version, not the MIDL language version.
With your code snippet, I think it is approach to guarantee that LONGLONG is 64bit under your environment Because double is the only 64bit type which is supported by _M_IX86 in the standard, maybe POSIX. The standard has no __int64 type.
I'm trying to create library with two versions of the same function using
__asm__(".symver ......
approach
library.h
#ifndef CTEST_H
#define CTEST_H
int first(int x);
int second(int x);
#endif
library.cpp
#include "simple.h"
#include <stdio.h>
__asm__(".symver first_1_0,first#LIBSIMPLE_1.0");
int first_1_0(int x)
{
printf("lib: %s\n", __FUNCTION__);
return x + 1;
}
__asm__(".symver first_2_0,first##LIBSIMPLE_2.0");
int first_2_0(int x)
{
int y;
printf("lib: %d\n", y);
printf("lib: %s\n", __FUNCTION__);
return (x + 1) * 1000;
}
int second(int x)
{
printf("lib: %s\n", __FUNCTION__);
return x + 2;
}
And here is the version scripf file
LIBSIMPLE_1.0{
global:
first; second;
local:
*;
};
LIBSIMPLE_2.0{
global:
first;
local:
*;
};
When build library using gcc, everything works well, and i am able to link to a library binary. Using nm tool i see that both first() and second() function symbols are exported.
Now, when i try to use g++, non of the symbols are exported.
So i tried to use extern "C" directive to wrap both declarations
extern "C" {
int first(int x);
int second(int x);
}
nm shows that second() function symbol is exported, but first() still remain unexported, and mangled.
What is here i am missing to make this to work? Or it is impossible with the c++ compiler to achieve this?
I don't know why, with 'extern "C"', 'first' was not exported - suspect there is something else interfering.
Otherwise C++ name mangling is certainly a pain here. The 'asm' directives (AFAIK) require the mangled names for C++ functions, not the simple 'C' name. So 'int first(int)' would need to be referenced as (e.g.) '_Z5firsti' instead of just 'first'. This is, of course, a real pain as far as portability goes...
The linker map file is more forgiving as its supported 'extern "C++" {...}' blocks to list C++ symbols in their as-written form - 'int first(int)'.
This whole process is a maintainance nightmare. What I'd really like would be a function attribute which could be used to specify the alias and version...
Just to add a reminder that C++11 now supports inline namespaces which can be used to provide symbol versioning in C++.
I am attempting to build CryptoPP with Cygwin x86_64, but I'm having some trouble with osrng.cpp.
I'm using gcc's C++ compiler, and I'm getting the following error at line 50 of osrng.cpp
$ make
g++ -DNDEBUG -g -O2 -march=native -pipe -c osrng.cpp
osrng.cpp: In constructor ‘CryptoPP::MicrosoftCryptoProvider::MicrosoftCryptoProvider()’:
osrng.cpp:50:80: error: invalid conversion from ‘CryptoPP::MicrosoftCryptoProvider::ProviderHandle* {aka long unsigned int*}’ to ‘HCRYPTPROV* {aka long long unsigned int*}’ [-fpermissive]
if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
^
In file included from /usr/include/w32api/windows.h:95:0,
from osrng.cpp:19:
/usr/include/w32api/wincrypt.h:646:26: error: initializing argument 1 of ‘WINBOOL CryptAcquireContextA(HCRYPTPROV*, LPCSTR, LPCSTR, DWORD, DWORD)’ [-fpermissive]
WINIMPM WINBOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv,LPCSTR szContainer,LPCSTR szProvider,DWORD dwProvType,DWORD dwFlags);
^
GNUmakefile:208: recipe for target 'osrng.o' failed
make: *** [osrng.o] Error 1
I have successfully compiled the whole thing under the 32bit version of Cygwin before.
How can I fix this for the 64bit edition?
EDIT As suggested by #Yakov's answer, I replaced if defined(_WIN64)if defined(__x86_64__) by if in line 30 of osrng.h.
Sadly though, I immediately run into the next problem, indicated by the following error:
$ make
g++ -DNDEBUG -g -O2 -march=native -pipe -c fipstest.cpp
In file included from dll.h:30:0,
from fipstest.cpp:8:
osrng.h:34:19: error: expected ‘;’ at end of member declaration
typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h>
^
osrng.h:34:27: error: ‘ProviderHandle’ does not name a type
typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h>
^
osrng.h:38:2: error: ‘ProviderHandle’ does not name a type
ProviderHandle GetProviderHandle() const {return m_hProvider;}
^
osrng.h:40:2: error: ‘ProviderHandle’ does not name a type
ProviderHandle m_hProvider;
^
GNUmakefile:208: recipe for target 'fipstest.o' failed
make: *** [fipstest.o] Error 1
Thankfully, GCC error messages have improved significantly in recent releases. The {aka}s tell you that there is a mismatch between long and long long. Keep in mind that Win64 is LLP64: long is still only 32-bits, and you need a long long to match the size of a pointer. Most (all?) other 64-bit platforms are LP64, meaning that long matches the size of a pointer.
In this particular case, see the if defined(_WIN64) in osrng.h; you will need to change that condition to if defined(__x86_64__) instead.
You might run into problems with the __int64 type as well. Replace those with long long. (Occurs here, here and here.)
You might also find word64 useful. From Crypto++'s config.h:
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 word64;
#define W64LIT(x) x##ui64
#else
typedef unsigned long long word64;
#define W64LIT(x) x##ULL
#endif
There's a couple of Cygwin defines in there too. But they don't look interesting. For example:
#ifndef TYPE_OF_SOCKLEN_T
# if defined(_WIN32) || defined(__CYGWIN__)
# define TYPE_OF_SOCKLEN_T int
# else
# define TYPE_OF_SOCKLEN_T ::socklen_t
# endif
#endif
#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS)
# define __USE_W32_SOCKETS
#endif
(Sorry about the comment here. Its too bing to fit in the little comment block).
I thought one feature of dynamic libraries (and by extension Apple's Mach-O Frameworks) was to leave some symbols (methods) undefined until the using application gets linked, but it appears all symbols have to be resolved for clang++ to successfully build a Framework.
For example, in building a framework for flight simulations, one might leave a C routine named aero undefined (but with an 'extern aero()' specification.) But XCode 4.2 refuses to build the framework, calling _aero an "undefined symbol."
Here's the header file included by both Objective-C and ANSI-C routines:
// FlightVehicleCAdapter_data.h
#ifndef FlightVehicleCAdapter_data_h
#define FlightVehicleCAdapter_data_h
#ifdef __cplusplus
external "C" {
#endif
extern void aero( void );
#ifdef __cplusplus
}
#endif
And here is where it gets called:
// FlightVehicleCAdapter.m
-(void) calcAero {
aero();
[self setBodyAeroForce_lb: [lsVector3 vectorFromScalarX:fv_data->f_aero_v.x
Y:fv_data->f_aero_v.y
Z:fv_data->f_aero_v.z]];
[self setBodyAeroMoment_ftlb:[lsVector3 vectorFromScalarX:fv_data->m_aero_v.x
Y:fv_data->m_aero_v.y
Z:fv_data->m_aero_v.z]];
}
I had hoped to be able to define the real aero() routine in the application that would link this framework, but when trying to build the framework itself the linker refuses to build it without a concrete aero() implementation:
Undefined symbols for architecture [i386|x86_64]:
"_aero", referenced from:
-[FlightVehicleCAdapter calcAero] in FlightVehicleCAdapter.o
So I then defined a dummy aero() routine:
// dummy_aero.c
// not showing fv_data structure definition for clarity
void aero(void){
fv_data->f_aero_v.x = 0.0;
fv_data->f_aero_v.y = 0.0;
fv_data->f_aero_v.z = 0.0;
fv_data->m_aero_v.x = 0.0;
fv_data->m_aero_v.y = 0.0;
fv_data->m_aero_v.z = 0.0;
}
This definition of aero() satisfies clang++ such that the Mach-O framework (dynamic library) is successfully built. But when I link the resulting framework with the application target which includes a non-trivial aero() routine, the framework's dummy aero() is being called instead of the application's aero().
You need to pass the -bundle_loader <executable> option to the linker, although I'm not sure that works for frameworks. Alternatively, you can use -undefined dynamic_lookup.
You need to do this for aero():
#ifdef __cplusplus
extern "C" {
#endif
extern void aero( void );
#ifdef __cplusplus
}
#endif
This makes sure the function is declared in C++ to have a C-resolvable name. C++ builds names differently than C does.
Note that then aero() can be linked at runtime.
I'd like to compile a c programm developed for linux using cc under os x.
It includes the header sys/io.h.
When compiling I get the error that this file could not be found?
Isn't there any sys/io.h header file under os x?
Any help would be really appreciated!
Thanks!
Include <sys/uio.h> instead.
or why not both?
#ifdef __APPLE__
#include <sys/uio.h>
#else
#include <sys/io.h>
#endif
In case of Apple OS (OSX/iOS) the code will know compile with <sys/uio.h>
You can manually add it to your project, and it should compile.
https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/+/master/sysroot/usr/include/sys/io.h
Edit: You need features.h as well
https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/+/master/sysroot/usr/include/features.h
Finally got cursor support in my kernel, although the functions in io.h weren't working for me. They compiled fine, and may help someone else. This is the code I'm going forward with...
static inline void outb(unsigned short port, unsigned char value)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (value));
}
static inline unsigned char inb(unsigned short port)
{
unsigned char value;
__asm__ __volatile__ ("inb %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
void update_cursor(int row, int col)
{
unsigned short position=(row*80) + col;
// cursor LOW port to vga INDEX register
outb(0x3D4, 0x0F);
outb(0x3D5, (unsigned char)(position&0xFF));
// cursor HIGH port to vga INDEX register
outb(0x3D4, 0x0E);
outb(0x3D5, (unsigned char )((position>>8)&0xFF));
}
What bibor has written is perfect. Though my file looks something like this and works well.
#ifdef __linux
#include <io.h>
#elseif __apple
#include<uio.h>
$ ls /usr/include/sys/io.h
ls: /usr/include/sys/io.h: No such file or directory
It doesn't look like it. You may have to do some porting.
Linux has this header file. It looks like it has to do with low level port input and output.
In general, things in /usr/include/sys are going to be operating-system specific, so you'll have to port to a new architecture if it's not already ported.