Can I avoid g++ surround _stdcall with __attribute__ string - attributes

I use MinGW's g++ to preprocess my file which has the following function:
[call_as(ReadAt)]
HRESULT _stdcall RemoteReadAt(
[in] ULARGE_INTEGER ulOffset,
[out, size_is(cb), length_is(*pcbRead)]
byte *pv,
[in] ULONG cb,
[out] ULONG *pcbRead);
The preprocess output is:
[call_as(ReadAt)]
HRESULT __attribute__((__stdcall__)) RemoteReadAt(
[in] ULARGE_INTEGER ulOffset,
[out, size_is(cb), length_is(*pcbRead)]
byte *pv,
[in] ULONG cb,
[out] ULONG *pcbRead);
Is there a g++ option that avoids changing the 2nd line in the output? Please assume that I won't have access to the file so I am looking for a g++ option.

I was able to use the g++ option: -D_stdcall=_stdcall

Related

Is it possible to dump inode information from the inotify subsystem?

I am trying to figure out what files my editor is watching on.
I have learnt that count the number of inotify fds from /proc/${PID}/fd is possible, and my question is: Is it possible to dump the list of watched inodes by one process?
UPDATE:
I have updated one working solution, and thanks for a helpful reference here.
UPDATE 2: well, recently I found kallsyms_lookup_name (and more symbols) not export since Linux Kernel v5.7, so I decide to update my own solution if anyone else cares.
Solved.
With the help of kprobe mechanism used in khook , I just simply hook the __x64_sys_inotify_add_watch and use user_path_at to steal the dentry.
The code snippet is listed below, and my working solution is provided here.
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
//regs->(di, si, dx, r10), reference: arch/x86/include/asm/syscall_wrapper.h#L125
//SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, u32, mask)
KHOOK_EXT(long, __x64_sys_inotify_add_watch, const struct pt_regs *);
static long khook___x64_sysinotify_add_watch(const struct pt_regs *regs)
{
int wd;
struct path path;
unsigned int flags = 0;
char buf[PATH_MAX];
char *pname;
// decode the registers
int fd = (int) regs->di;
const char __user *pathname = (char __user *) regs->si;
u32 mask = (u32) regs->dx;
// do the original syscall
wd = KHOOK_ORIGIN(__x64_sys_inotify_add_watch, regs);
// get the pathname
if (!(mask & IN_DONT_FOLLOW))
flags |= LOOKUP_FOLLOW;
if (mask & IN_ONLYDIR)
flags |= LOOKUP_DIRECTORY;
if ( wd>=0 && (user_path_at(AT_FDCWD, pathname, flags, &path)==0) )
{
pname = dentry_path_raw(path.dentry, buf, PATH_MAX); //"pname" points to "buf[PATH_MAX]"
path_put(&path);
printk("%s, PID %d add (%d,%d): %s\n", current->comm, task_pid_nr(current), fd, wd, pname);
}
return wd;
}

Windows c++ struct with Bit field, packing

union AP
{
UCHAR bin[28];
struct{
ULONGLONG TA :42;
UINT St :6;
UINT Reserved1 :3;
UINT fo :4;
UINT P :9;
UINT cy :17;
UINT Reserved2 :3;
UINT A :12;
UINT Fg :8;
UINT P2 :24;
UINT Fp :10;
UINT SChNum :22;
UINT ItAdrs:32;
UINT IEAdrs:32;
}stt;
I want to use stt when stt's size is 28 byte.
but This code's size of stt is 32byte.
I think this code's needs "packing" because of 'ULONGLONG TA:42'.
#pragma pack(push,1)
#pragma pack(1)
both code didn't work.
how to packing struct that has bit field symbol.
I create my code on visual studio 2012 with c++, windows7
The C/C++ standards allow the compiler to insert padding between bitfields when the base types of the bitfields are different. So the padding is likely coming between your ULONGLONG and the subsequent UINT. Try splitting your ULONGLONG into two UINT members; that should eliminate the padding.

Building in VC6, need unsigned long long

I need to build a purchased library (with source) that was built in VC 2010. We have to build with VC6. I ran across signed and unsigned "long long". I am using "_int64" for the signed type but was unable to find anything for the unsigned type. Has anyone run across a solution? Apologies if this is documented, I have had no luck in finding anything.
__int64 is a vendor-specific base type. It can be combined with the unsigned modifier, just like:
unsigned char unsigned __int8
unsigned short unsigned __int16
unsigned int unsigned __int32
unsigned long unsigned __int32
(unsigned long long) unsigned __int64
(unsigned __int128)
Where the parenthesized names are not available in VC6, but are supported in the current version of Visual C++.

How do I open a file named 𤭢.txt with CreateFile() API function?

Code points of some Unicode characters (like 𤭢) consume more than 2-bytes. How do I use Win32 API functions like CreateFile() with these characters?
WinBase.h
WINBASEAPI
__out
HANDLE
WINAPI
CreateFileA(
__in LPCSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);
WINBASEAPI
__out
HANDLE
WINAPI
CreateFileW(
__in LPCWSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
LPCSTR and LPCWSTR are define in WinNT.h as:
typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;
CHAR and WCHAR is defined in WinNT.h as:
typedef char CHAR;
#ifndef _MAC
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
#endif
CreateFileA() accepts LPCSTR file names, which are stored in 8-bit char array internally.
CreateFileW() accepts LPCWSTR file names, which are stored in 16-bit wchar_t array internally.
I have created a file in the position C:\𤭢.txt. It looks like it is not possible to open this file using CreateFile(), because it contains the character 𤭢 whose Unicode code point is 0x24B62 which doesn't fit even in a WCHAR array cell.
But that file exists in my harddisk and Windows manages it normally. How do I open this file by a Win32 API function, like Windows does internally?
Such characters are represented by UTF-16 surrogate pairs. It takes two wide character elements to represent that code point. So, you just need to call CreateFile passing the necessary surrogate pair. And naturally you need to use the wide variant of CreateFile.
Presumably you won't be hard-coding such a filename in your code. In which case you'll be getting it from a file dialog, FindFirstFile, etc. And those APIs will give you the appropriate UTF-16 encoded buffer for the file.

ICU library in Android NDK

I am trying to create a JNI wrapper for a C library that depends on the ICU libraries (libicuuc.so and libicui18n.so).
I tried building ICU4C in my NDK (both standard and CrystaX versions, on a Mac OS X machine) and kept running into linking issues like this:
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/udata.o: In function `openCommonData':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/udata.c:836: undefined reference to `icudt42_dat'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strFromWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:365: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:415: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:314: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strToWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:164: undefined reference to `mbstowcs'
collect2: ld returned 1 exit status
I also tried the suggestion given at unicode support in android ndk but no luck. I got stuck at:
arm-eabi-g++ -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -D_REENTRANT -I../common -I../../icu/source/common -I../../icu/source/i18n "-DDEFAULT_ICU_PLUGINS=\"/usr/local/lib/icu\" " -DU_COMMON_IMPLEMENTATION -DHAVE_CONFIG_H -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -std=c++0x -fvisibility=hidden -c -o errorcode.ao ../../icu/source/common/errorcode.cpp
In file included from ../../icu/source/common/unicode/ptypes.h:23,
from ../../icu/source/common/unicode/umachine.h:52,
from ../../icu/source/common/unicode/utypes.h:36,
from ../../icu/source/common/errorcode.cpp:17:
/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/sys/types.h:122: error: 'uint64_t' does not name a type
make[1]: *** [errorcode.ao] Error 1
make: *** [all-recursive] Error 2
Any help would be appreciated.
It seems that two files are involved in this issue. icu/source/common/unicode/ptypes.h which calls sys/types.h includes
#if ! U_HAVE_UINT64_T
typedef unsigned long long uint64_t;
/* else we may not have a 64-bit type */
#endif
By including sys/types.h from Android, we involve (near line 122/124)
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
typedef uint64_t u_int64_t;
#endif
It seems that uint64_t has not been declared when it is assigned to u_int64_t. Indeed, sys/types.h includes stdint.h which has the following:
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
typedef __int16_t int16_t;
typedef __uint16_t uint16_t;
typedef __int32_t int32_t;
typedef __uint32_t uint32_t;
#if defined(__STDC_INT64__)
typedef __int64_t int64_t;
typedef __uint64_t uint64_t;
#endif
Likely STRICT_ANSI is not defined. Seems like this is a bug in the Android code in sys/types.h. If STDC_INT64 is not defined, it will not define uint64_t so it can't define u_int64_t. Perhaps the real solution is to have sys/types.h modified so that it has
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
$if defined(__STDC_INT64__)
typedef uint64_t u_int64_t;
#endif
#endif
If you fix this, the next error will be in cstring.h:109
icu/source/common/cstring.h:109: error: 'int64_t' has not been declared
If you instead #define STDC_INT64 in common/unicode/ptypes.h it will go substantially farther, but will end at
icu/source/common/ustrenum.cpp:118: error: must #include <typeinfo> before using typeid
with more info here: http://groups.google.com/group/android-ndk/browse_thread/thread/2ec9dc289d815ba3?pli=1 but no real solutions
I also had this issue:
undefined reference to `mbstowcs'
You should build and link with higher version of android api.
Note:
I tried to link it with libraries from android-ndk/platforms/android-4... I had thought that 4 is version of Android, but 4 is version of Android API. And Android API 4 corresponds to Android 1.6 witch is very very old there is really no mbstowcs function in libc
Here is how i solved the problem. It is dirty but it works. The lib got compiled:
1. file: /icu4c/common/cwchar.h
comment out the #if U_HAVE_WCHAR_H and the respective #endif so the <wchar.h> is always included.
replace the previous uprv_wcstombs definition with:
#define uprv_wcstombs(mbstr, wcstr, count) U_STANDARD_CPP_NAMESPACE wcs2mbs(mbstr, wcstr, count)
replace the previous uprv_mbstowcs definition with:
#define uprv_mbstowcs(wcstr, mbstr, count) U_STANDARD_CPP_NAMESPACE mbs2wcs(wcstr, mbstr, count)
2. file: /icu4c/common/ustr_wcs.cpp
somewhere at the top, under the already existing includes add the line:
#include "../wcsmbs.h"
3. create new file "icu4c/wcsmbs.h"
size_t mbs2wcs(wchar_t * __ restrict pwcs, const char * __ restrict s, size_t n)
{
mbstate_t mbs;
const char *sp;
memset(&mbs, 0, sizeof(mbs));
sp=s;
return (mbsrtowcs(pwcs,&sp,n,&mbs));
}
size_t wcs2mbs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
{
mbstate_t mbs;
const wchar_t *pwcsp;
memset(&mbs,0,sizeof(mbs));
pwcsp = pwcs;
return (wcsrtombs(s,&pwcsp,n,&mbs));
}
Hope it helps.
There has been an effort to provide NDK wrappers for the ICU libraries that are part of the system: https://android-review.googlesource.com/c/153001/.

Resources