compiling assembly with Visual C++ Express 2010 64 Bit - visual-c++

How do I compile assembly code in a separate file?
If my function is of the type "void __fastcall foo(unsigned long long, unsigned long long, unsigned long long, unsigned long long&, unsigned long long&)", how do I implement this in my .asm file?

.code
foo PROC
; do stuff here
foo ENDP
end

Related

`gs` missing from user_regs_struct?

I've got the following piece of code which failed to compile on i386 with "gs" missing.
I've looked at the struct definition, and it's clearly there.
Any idea what I got wrong?
Thanks!
struct user_regs_struct regs_struct;
struct iovec pt_iov = {
.iov_base = &regs,
.iov_len = sizeof(regs),
};
if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
#if defined(__x86_64__)
return regs_struct.fs;
#elif defined(__i386__)
return regs_struct.gs; <<< Got an error about "gs" not being a field of user_regs_struct
}
P.S: I know I should produce a small test case but I could not. It didn't hit this error on a standalone app. (never mind that I don't have the hardware to test it locally). All I knew was this error popped up when the code is part of a larger system, being built remotely.
That's why I was hoping maybe somebody recognized this as a "known-issue" or have some intuition as to what might be the issue.
Looks like the i386 version of user_regs_struct calls it xgs for some reason.
In sys/user.h, there's an #ifdef __x86_64__. The #else
/* These are the 32-bit x86 structures. */ side of the file has this content:
struct user_regs_struct
{
long int ebx;
long int ecx;
long int edx;
long int esi;
long int edi;
long int ebp;
long int eax;
long int xds;
long int xes;
long int xfs;
long int xgs;
long int orig_eax;
long int eip;
long int xcs;
long int eflags;
long int esp;
long int xss;
};
Perhaps that changed in some glibc version? This is on x86-64 Arch GNU/Linux, so those are plain vanilla glibc headers (taken from the Linux kernel).
ack user_regs_struct /usr/include found the right file right away. (like grep -r).
Note the top of the file says:
/* The whole purpose of this file is for GDB and GDB only. Don't read
too much into it. Don't use it for anything other than GDB unless
you know what you are doing. */
I don't know exactly why there's such a stern warning, or if they really mean for ptrace in general. If it's more than that, I'd be cautious about using it blindly if reading the header and checking the struct member names wasn't obvious to you. Maybe it's fine, maybe it's not, just saying that I wouldn't rely on code you write using it for anything critical without more research.

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++.

ioctl command wrong in 64 bit system from 32 bit user code

I'm upgrading a device driver from a 32bit RHEL 2.6.32 to 64bit RHEL 2.6.33.9.
I have a program that talks to that driver using ioctl. It works perfectly when both the driver and the program are either 64bit or 32bit. But when the driver is 64bit, and my program is 32 bit, the ioctl command received by the driver (in compat_ioctl) does not match the values defined by the _IOR and _IOW macros.
In my driver's switch statement, the default case prints out the values of all the valid commands, which are 1-12. The 32bit ioctl command is nowhere near those values.
Can someone tell me what would cause the command from a 32bit user program to be messed up when received in a 64bit driver?
Here's some of the code: I had to type it in; the code is on a secured system without internet access, so please forgive any typos. It actually does comile and run!
// IOCTL commands from the include file - most omitted
// ...
#define PORTIO_GET_IRQ_CNT_CMD 10
#define PORTIO_CLR_IRQ_CNT_CMD 11
#define PORTIO_GET_IRQ_TIME_CMD 12
#define PORTIO_IOCTL 'k' // magic number for ioctl
// IOCTL Macros
#define PORTIO_GET_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)
Here's the 32 bit compatible IOCTL routine, from portio.c. I've confirmed that this is being called only when my program is compiled as 32bit, and the driver is 64bit.
static long portio_compat_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned char cmd_number;
int cmd_size=0;
//...
cmd_number = _IOC_NR( cmd );
cmd_size = _IOC_SIZE( cmd );
printk( KERN_ALERT "Portio Compat IOCTL number,size = %d,%d, cmd_number, cmd_size );
//... Switch statement and cases, based on cmd_number
}
The output looks like this:
Portio Compat IOTCL number,size = 224,3157
Of course, the code expects IOCTL numbers from 1-12, and sizes around 4 or 8. That's exactly what comes back when the code and driver are both either 64bit or 32bit.
It seems to me that your function compat_ioctl takes too many parameters. Look at other definitions in the Linux kernel:
long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
http://lxr.linux.no/#linux+v3.5.3/block/compat_ioctl.c#L654
#define PORTIO_GET_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)
change unsigned long to unit64_t (fixed data type)
remove all pointer from ioctl macro arguments,
have :
.compat_ioctl
.unlocked_ioctl in kernel pointing to same function.

Mac Office 2011 VBA and Dylib

I'm working on a Word 2011 plugin in Mac OS. Currently, I need to write a code in VBA Macro to retrieve a String from another application (through Socket communication). So, basically in Windows, I can simply make a DLL which help me to do Socket communication with the other application and return the String value to VBA Macro.
However, in Mac, I'm able to build a .dylib (in C) and using VBA to communicate with the dylib. However, I'm having a trouble with the return String. My simple C code is something like:
char * tcpconnect(char* arguments)
{}
First, it always contains Chr(0) characters. Secondly, I suspected that this C function will not be able to handle Unicode String.
Do you guys have any experiences or have any similar example of this?
Thanks,
David
My original post was an attempt to imitate SysAllocStringByteLen() using malloc(), but this will fail when Excel tries to free the returned memory. Using Excel to allocate the memory fixes that issue, and is less code as well, e.g.:
in test.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LPCSTR const char *
#define LPSTR char *
#define __declspec(dllexport)
#define WINAPI
char *saved_string = NULL;
int32_t saved_len = -1;
#define _CLEANUP if(saved_string) free(saved_string)
__attribute__((destructor))
static void finalizer(void) {
_CLEANUP;
}
int32_t __declspec(dllexport) WINAPI get_saved_string(LPSTR pszString, int cSize) {
int32_t old_saved_len = saved_len;
if(saved_len > 0 && cSize >= saved_len)
strncpy(pszString, saved_string, saved_len);
if(saved_string) {
free(saved_string);
saved_string = NULL;
saved_len = -1;
}
return old_saved_len;
}
int32_t __declspec(dllexport) WINAPI myfunc(LPCSTR *pszString) {
int len = (pszString && *pszString ? strlen(*pszString) : 0);
saved_string = malloc(len + 5);
saved_len = len + 5;
sprintf(saved_string, "%s%.*s", "abc:", len, *pszString);
return saved_len;
}
Compile the above with
gcc -g -arch i386 -shared -o test.dylib test.c
Then, in a new VBA module, use the below and run "test", which will prepend "abc:" to the string "hi there" and output the result the debug window:
Public Declare Function myfunc Lib "<colon-separated-path>:test.dylib" (s As String) As Long
Public Declare Function get_saved_string Lib "<colon-separated-path>:test.dylib" (ByVal s As String, ByVal csize As Long) As Long
Option Explicit
Public Function getDLLString(string_size As Long) As String
Dim s As String
If string_size > 0 Then
s = Space$(string_size + 1)
get_saved_string s, string_size + 1
End If
getDLLString = s
End Function
Public Sub test()
Debug.Print getDLLString(myfunc("hi there"))
End Sub

Inline assembly in Haskell

Can I somehow use inline assembly in Haskell (similar to what GCC does for C)?
I want to compare my Haskell code to the reference implementation (ASM) and this seems the most straightforward way. I guess I could just call Haskell from C and use GCC inline assembly, but I'm still interested if I can do it the other way around.
(I'm on Linux/x86)
There are two ways:
Call C via the FFI, and use inline assembly on the C side.
Write a CMM fragment that calls C (without the FFI), and uses inlined assembly.
Both solutions use inline assembly on the C side. The former is the most idiomatic. Here's an example, from the rdtsc package:
cycles.h:
static __inline__ ticks getticks(void)
{
unsigned int tbl, tbu0, tbu1;
do {
__asm__ __volatile__ ("mftbu %0" : "=r"(tbu0));
__asm__ __volatile__ ("mftb %0" : "=r"(tbl));
__asm__ __volatile__ ("mftbu %0" : "=r"(tbu1));
} while (tbu0 != tbu1);
return (((unsigned long long)tbu0) << 32) | tbl;
}
rdtsc.c:
unsigned long long rdtsc(void)
{
return getticks();
}
rdtsc.h:
unsigned long long rdtsc(void);
rdtsc.hs:
foreign import ccall unsafe "rdtsc.h" rdtsc :: IO Word64
Finally:
A slightly non-obvious solution is to use the LLVM or Harpy packages to call some generated assembly.

Resources