How to convert IL code to Mono.Cecil commands? - mono.cecil

I have the following C# code
this.Succeed = true;
yield break;
which is in IL (says dnSpy):
/* 0x0019AD95 16 */ IL_0000: ldc.i4.0
/* 0x0019AD96 7380630006 */ IL_0001: newobj instance void Class893/'<method_0>d__0'::.ctor(int32)
/* 0x0019AD9B 25 */ IL_0006: dup
/* 0x0019AD9C 02 */ IL_0007: ldarg.0
/* 0x0019AD9D 7D54560004 */ IL_0008: stfld class Class893 Class893/'<method_0>d__0'::'<>4__this'
/* 0x0019ADA2 2A */ IL_000D: ret
and i want to convert it to Mono.Cecil Instructions like these:
inst.Add(Instruction.Create(OpCodes.Ldc_I4_0));
inst.Add(Instruction.Create(OpCodes.Newobj));
inst.Add(Instruction.Create(OpCodes.Dup, 0x0019AD9B));
inst.Add(Instruction.Create(OpCodes.Ldarg_0));
inst.Add(Instruction.Create(OpCodes.Stfld, 0x0019AD9D));
inst.Add(Instruction.Create(OpCodes.Ret));
How would i do that?

You can use https://cecilifier.me (https://github.com/adrianoc/cecilifier) tool too help you learn how to translate C# to https://github.com/jbevain/cecil.
Disclaimer: I am the developer of that tool.

Related

Dubious behaviour in multithreaded client-server in C

void* thread_request_server_static(void* args); , This is where the worker threads will handle the connection (i have got 4 threads created)
request.c:
struct conn_args
{
int fd;
int filename;
int filesize;
struct conn_args *next;
}
/* other functions */
int add(int fd, char *filename, int filesize)
{
if(buffer_size >= buffer_max_size)
return 1;
struct conn_args *temp = malloc(sizeof(struct conn_args));
temp->fd = fd;
temp->filename = filename;
temp->filesize = filesize;
temp->next = NULL;
if (head == NULL)
{
head = temp;
tail = temp;
}
else
{
tail->next = temp;
tail = temp;
}
buffer_size++;
return 0;
}
struct conn_args* get_args()
{
struct conn_args *temp = NULL;
if(head!=NULL)
{
temp = head;
head = head->next;
buffer_size--;
}
return temp;
}
void *thread_request_serve_static(void *arg)
{
while (1)
{
pthread_mutex_lock(&lock);
struct conn_args *arg = get_args();
if (!arg)
pthread_cond_wait(&c, &lock);
else
{
request_serve_static(arg->fd, arg->filename, arg->filesize);
printf("Request for %s is removed from the buffer\n-----------------\n",
arg->filename);
close_or_die(arg->fd);
free(arg);
}
pthread_mutex_unlock(&lock);
}
// TODO: write code to actualy respond to HTTP requests
}
void request_handle(int fd)
{
/* variable declarations and condition checks */
pthread_mutex_lock(&lock);
int stat = add(fd, filename, sbuf.st_size);
pthread_mutex_unlock(&lock);
if (!stat)
{
printf("-----------------\nRequest for %s is added to the buffer\n",
filename);
pthread_cond_signal(&c); // wake up thread since connections arrive at the buffer.
}
else
{
printf("Server overload: Try again later!");
}
}
wserver.c:
int main(int argc, char *argv[])
{
/* variable initializations and argument reading */
pthread_t thread_pool[num_threads];
for(int i=0; i<num_threads; i++)
pthread_create(&thread_pool[i], NULL, thread_request_serve_static, NULL);
// open the socket connection
int listen_fd = open_listen_fd_or_die(port);
while (1) {
// start accepting HTTP requests from client
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);
int conn_fd = accept_or_die(listen_fd, (sockaddr_t *) &client_addr, (socklen_t *) &client_len);
// process the HTTP request
request_handle(conn_fd);
// close the connection to client
//close_or_die(conn_fd); // this has to be carefully done at the correct time in request.c
}
Starting the server,
./wserver -p 8003 (port 8003)
bash file for testing multiple connections,
multiple_clients.bash:
echo Starting requests
for ((i=15;i>0;i-=1))
do
./wclient localhost 8003 /files/test$i.html &
done
echo Requests completed
I piped the output into a test.txt and got the following, bash multiple_clients.bash > test.txt
test.txt:
/* Meta data */
This is a test HTML file -------------- 15.
/* Meta data */
/* Meta data */
This is a test HTML file ------------ 13.
/* Meta data */
/* Meta data */
This is a test HTML file ------------ 13.
/* Meta data */
/* Meta data */
This is a test HTML file ---------- 11.
/* Meta data */
/* Meta data */
This is a test HTML file --------- 10.
/* Meta data */
/* Meta data */
This is a test HTML file ---------- 11.
/* Meta data */
/* Meta data */
This is a test HTML file ----- 6.
/* Meta data */
/* Meta data */
This is a test HTML file 1.
/* Meta data */
/* Meta data */
This is a test HTML file - 2.
/* Meta data */
/* Meta data */
This is a test HTML file --- 4.
/* Meta data */
/* Meta data */
This is a test HTML file - 2.
/* Meta data */
/* Meta data */
This is a test HTML file -------- 9.
/* Meta data */
/* Meta data */
This is a test HTML file -- 3.
/* Meta data */
/* Meta data */
This is a test HTML file ---- 5.
/* Meta data */
/* Meta data */
This is a test HTML file ------- 8.
/* Meta data */
As you can see, some files are getting repeated and some are not showing up (7 and 14). Why is this? Although the total output file count is 15, this probably means it is successfully adding all the files to the buffer, but somehow skipping some files and producing duplicates of others.
The program doesn't even crash on double free error, so how is a single file getting handled twice?
Do let me know if any more info is required.
Any help would be appreciated.

Problem when use BSP library to audio record on stm32f769i-Discovery

I am working with stm32f769 to record using mems sensor and board support package library for stm32f769. But I have problem when using BSP_AUDIO_IN_Record function. I realized that the HAL_DFSDM_FilterRegConvCpltCallback and HAL_DFSDM_FilterRegConvHalfCpltCallback function was not called when execution finished and no sound value was saved, but the application still works fine with the template from ST.
How can I fix this?
My code:
int main(void)
{
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
BSP_AUDIO_IN_Init(BSP_AUDIO_FREQUENCY_16K, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR);
BSP_AUDIO_IN_AllocScratch (Scratch_, SCRATCH_BUFF_SIZE);
BSP_AUDIO_IN_Record((uint16_t*)&BufferCtl.pcm_buff[0], AUDIO_IN_PCM_BUFFER_SIZE);
BufferCtl.fptr = 1;
BufferCtl.pcm_ptr = 0;
BufferCtl.offset = 0;
BufferCtl.wr_state = BUFFER_EMPTY;
while (1)
{
}
}
and library:
stm32f769i_discovery.c
stm32f769i_discovery.h
stm32f769i_discovery_audio.c
stm32f769i_discovery_audio.h
wm8994.c
wm8994.h
Perhaps you forgot to implement the IRQ functions? They are mandatory in certain use cases (like your own for example), and they have to implement proper HAL_xxx_IRQHandler() of a relevant peripheral driver. These IRQ handler functions are processing and calling the right Callback functions.
Look at the file stm32f7xx_it.c in STM32 HAL examples. Below you can see code fragment from such file from the Audio_playback_and_record STM32 HAL example.
/* SAI handler declared in "stm32f769i_eval_audio.c" file */
extern SAI_HandleTypeDef haudio_out_sai;
extern DFSDM_Filter_HandleTypeDef haudio_in_dfsdm_leftfilter;
extern DFSDM_Filter_HandleTypeDef haudio_in_dfsdm_rightfilter;
// ...
// ...
/**
* #brief This function handles DMA2 Stream 4 interrupt request.
* #param None
* #retval None
*/
void AUDIO_SAIx_DMAx_IRQHandler(void)
{
HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
}
/**
* #brief This function handles DMA2 Stream 0 interrupt request.
* #param None
* #retval None
*/
void AUDIO_DFSDM_DMAx_LEFT_IRQHandler(void)
{
HAL_DMA_IRQHandler(haudio_in_dfsdm_leftfilter.hdmaReg);
}
/**
* #brief This function handles DMA2 Stream 0 interrupt request.
* #param None
* #retval None
*/
void AUDIO_DFSDM_DMAx_RIGHT_IRQHandler(void)
{
HAL_DMA_IRQHandler(haudio_in_dfsdm_rightfilter.hdmaReg);
}
Another issue could be your method of checking whether audio recording really happened. In the code you provided I cannot find anything like that, so I can't help you without you providing more details.

DOS: how to get current country code or code page in Turbo C

How to get some locale-specific information where the country can be detected? E.g. current country code, keyboard layout or code page in Turbo C in DOS environment?
If that is not possible with Turbo C library functions, some BIOS calls could do that (INT 21)?.
KEYB program is able to show e.g. keyboard layout. That would be more than enough for my purposes:
https://www.dosbox.com/wiki/KEYB
Use INT 21h, AX=6501h. Here's code for Turbo C:
#include <dos.h>
#include <stdio.h>
struct country_info_buffer
{
unsigned char info_id;
unsigned short buffer_size;
unsigned short country_id;
unsigned short code_page;
struct COUNTRY country_info;
};
int main()
{
/* Registers for INT21 call */
union REGS regs;
struct SREGS sregs;
/* Output buffer */
struct country_info_buffer info;
/* Get current value of segment registers */
segread(&sregs);
/* Get extended country information / general internationalization info */
regs.x.ax = 0x6501;
/* Global code page */
regs.x.bx = 0xFFFF;
/* Current country */
regs.x.dx = 0xFFFF;
/* Size of output buffer */
regs.x.cx = sizeof(info);
/* Pointer to output buffer goes to ES:DI */
sregs.es = FP_SEG(&info);
regs.x.di = FP_OFF(&info);
/* Call int21 */
intdosx(&regs, &regs, &sregs);
if (regs.x.cflag)
{
printf("Call failed, ax=%d\n", regs.x.ax);
return 1;
}
printf("Country code: %d, Code page: %d\n", info.country_id, info.code_page);
return 0;
}
Btw. Ralf Brown's Interrupt List is great resource for DOS system calls. Too bad it stopped being maintained even before DOS ran out of favors, so some "newest" stuff isn't described there.

What's wrong with my C-code?

Working in z/os mainframe, I have the following situation. I can't record a transaction.
here is my code,
it is written for transaction using jcl. Bur something goes wrong.
/* Include standard C header files */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Include WebSphere MQ API header file */
#include <cmqc.h>
/* Boolean constants */
#define TRUE 1
#define FALSE 0
/* Function prototypes */
void displayUsage (char *programName);
void displayMQError (char *message, MQLONG compCode, MQLONG reason);
double parseAmount (char *amountString);
/* Main Program */
int main (int argc, char *argv[])
{
/* Variable definitions */
double paymentAmount; /* Payment amount */
MQBYTE msgBuffer[1024]; /* Buffer for messages */
MQCHAR* qmgrName; /* Queue manager name */
MQCHAR* requestQueueName; /* Request queue name */
MQCHAR* replyQueueName; /* Reply queue name */
MQCHAR* userID; /* Contestant user ID */
MQCHAR* paymentDescription; /* Payment description */
MQGMO getMsgOptions = {MQGMO_DEFAULT}; /* Get options */
MQHCONN hConn = MQHC_UNUSABLE_HCONN; /* Connection handle */
MQHOBJ requestHObj = MQHO_UNUSABLE_HOBJ; /* Request queue handle */
MQHOBJ replyHObj = MQHO_UNUSABLE_HOBJ; /* Reply queue handle */
MQLONG compCode; /* API completion code */
MQLONG openOptions; /* Open queue options */
MQLONG reason; /* API reason code */
MQLONG replyMsgLength = 0; /* Reply msg length */
MQMD requestMsgDesc = {MQMD_DEFAULT}; /* Message descriptor */
MQMD replyMsgDesc = {MQMD_DEFAULT}; /* Message descriptor */
MQOD requestQueueDesc = {MQOD_DEFAULT}; /* Object descriptor */
MQOD replyQueueDesc = {MQOD_DEFAULT}; /* Object descriptor */
MQPMO putMsgOptions = {MQPMO_DEFAULT}; /* Put options */
/*****************************************/
/* Initialisation and parameter checking */
/*****************************************/
printf ("********************************************************\n");
printf ("Credit card payment unit test tool\n");
printf ("********************************************************\n");
printf (" \n");
switch (argc)
{
case 7 : qmgrName = argv[1];
requestQueueName = argv[2];
replyQueueName = argv[3];
userID = argv[4];
paymentAmount = parseAmount (argv[5]);
if ( ( paymentAmount < 0.01 )
|| ( paymentAmount > 9999.99 ) )
{
printf ("The payment amount must be a valid numeric " \
"within the range 0.01 to 9999.99\n");
displayUsage (argv[0]);
return (1);
}
paymentDescription = argv[6];
if ( ( strlen (paymentDescription) < 1 )
|| ( strlen (paymentDescription) > 35 ) )
{
printf ("The payment description must be 1-35 " \
"characters\n");
displayUsage (argv[0]);
return (1);
}
break;
default : printf ("Incorrect usage!\n");
displayUsage (argv[0]);
return (1);
}
printf ("You have requested a payment of %.2f with description " \
"'%s' for contestant %s\n", paymentAmount,
paymentDescription, userID);
printf (" \n");
Can you help me?
I don't know how to write my Parm parameters...
When you have a problem, try to track all the outputs back to the inputs via the program.
From one of your other questions:
********************************************************
Credit card payment unit test tool
********************************************************
Incorrect usage!
Program Usage
-------------
PAYMENT <queue manager> <cics request queue> <reply queue> <userid> <payment value> <payment description>
The payment description has a maximum length of 35 characters.
The monetary value must be within the range 0.01 - 9999.99
The first two lines are easy to explain. The last two lines, not so. They are there to blinker us, as that exact text appears in the program. However, it seems that the exact same text is used in the displayUsage function.
It is bad to display identical text in different error circumstances. That's why we use message numbers - the message may then be the same, but the number will identify exactly where it has come from.
A clue is that you can't even get a very simple PARM to be accepted.
A further clue is that Incorrect usage!.
When does that message get printed? When there are other than seven parameters. Err... but you only supply six.
So, if there are supposed to be six parameters, the program is wrong. If you should be supplying seven parameters, your PARM is wrong.
You can demonstrate this with
// PARM='A,B,C,D,1,F,G'
That will work.
As an aside, why was switch used instead of a simple if anyway? Using if would have made the problem more obvious.

Visual C++ 6.0 Name mangling, even within extern "C" and dllexport, RPC Stubs not generating

Hey guys im working on creating a new function in legacy visual C++ 6.0 dll project, so that a C# dll can call into, however i unable to do so due to name mangling and it seems no matter what I do I can't stop it, (i used dumpbin to view the names) here is the relevant code
this is a really trimmed down verstion of the header file
#ifdef _V7SSCOMM_CPP_
#define _DECL_V7COMM_DLL __declspec(dllexport)
#else
#define _DECL_V7COMM_DLL __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
_DECL_V7COMM_DLL DWORD V7ssGetFileDirInfoUnicode(LPCSTR szSign, V7_FILE_LIST_TYPE eListType, LPCSTR szServer, LPCSTR szLibrary, LPCSTR szExt, DWORD *pdwFileCnt, wchar_t *pbyFileBuf, DWORD *pdwFileBufSize);
#ifdef __cplusplus
}
#endif
#endif
and for the cpp file
_DECL_V7COMM_DLL DWORD V7ssGetFileDirInfoUnicode(LPCSTR szSign,
V7_FILE_LIST_TYPE eListType,
LPCSTR szServer, LPCSTR szLibrary, LPCSTR szExt,
DWORD *pdwFileCnt, wchar_t *pbyFileBuf, DWORD *pdwFileBufSize)
{
if (!szSign || !szServer || !szLibrary || !szExt || !pdwFileCnt || !pbyFileBuf || !pdwFileBufSize)
return (RPC_S_INVALID_ARG);
error_status_t Error = rpcGetFileDirInfoUnicode(
/* [in] */ g_hRpcBinding,
/* [in, string] */ (unsigned char *)szSign,
/* [in] */ (unsigned long)eListType,
/* [in, string] */ (unsigned char *)szServer,
/* [in, string] */ (unsigned char *)szLibrary,
/* [in, string] */ (unsigned char *)szExt,
/* [out] */ (unsigned long *)pdwFileCnt,
/* [out, size_is(*pdwFileBufSize)] */ (wchar_t *)pbyFileBuf,
/* [in, out] */ (unsigned long *)pdwFileBufSize);
return (Error);
} // end V7ssGetFileDirInfoUnicode()
dumpbin returns the following
1 0 00001401 ?V7ssGetFileDirInfoUnicode##YAKPBDW4tag_V7_FILE_LIST_TYPE##000PAKPAG2#Z
not what i wanted ideally it would only be V7ssGetFileDirInfoUnicode
As far as i can tell and from what i have been reading the way i trying to do this means i don't need to define this in the .def file. What is odd, is im following the same extact setup as pre-existing functions that show up correctly.
I would be grateful for any help.Thanks!
Update
the .def file option works as far as not name mangling, that being said the MIDL compiler is not creating the RPC stub, I think these two issues are related.
also here is the MIDL version, taken from the C file iteself
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 5.01.0164 */
/* at Wed Sep 21 08:57:22 2011
*/
/* Compiler settings for V7Rpc.idl:
Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext
error checks: allocation ref bounds_check enum stub_data
*/
//##MIDL_FILE_HEADING( )
If you are certain that you included the header file from the .cpp file, then you might try adding a .def file to your project. There might be other ways, but that has always seemed to be a critical part in reducing the name mangling in the exports. The contents would look something like this.
EXPORTS
V7ssGetFileDirInfoUnicode

Resources