ARM7 TDMI undefined instruction exception manual generation - exception

I am trying to test out some exception handling code running on an ARM7 TDMI processor. I am wanting to manually create an instruction opcode which will generate the "Undefined instruction" exception. So far, I've done this:
void createUndefinedException()
{
static const int instr = 0x26889912; // bad opcode
((void(*)(void))instr)();
}
I arrived at the above opcode because of a reference page I found today on the web that talks about undefined instruction opcodes at the very bottom.
The above code generates the prefetch abort exception instead of the undefined instruction exception.
Anyone have an idea of how to create this easily?
I just want to verify my handling of this exception is going to work properly.

create an asm file
.globl test_function
test_function:
.word 0x26889912
bx lr
assemble it
arm-none-linux-gnueabi-as fun.s -o fun.o
call it from your C code
extern void test_function ( void );
...
test_function();
then add it to the list of objects you are linking
arm-none-linux-gnueabi-gcc myprogram.c fun.o -o myprogram
and run it.

You need to create a function out of the address of the int:
typedef void (*Exception)(void)
static unsigned long illegalOpcode=0x26889912;
Exception e=(Exception)&illegalOpcode;
e();

Related

Can you help me make sense of this class constructor? (Adafruit_ATParser)

I am building a device for my research team. To briefly describe it, this device uses a motor and load sensor connected to an Arduino to apply a rotational force to a corn stalk and record the resistance of the stalk. We are in the process of building Bluetooth into the device. We are using this BT module.
We have a BLE GATT Service with 2 characteristics for storing DATA and 1 for holding the command which is an integer that will be read by the device and acted on. Reading the command characteristic is where we encounter our problem.
void get_input(){
uint16_t bufSize = 15;
char inputBuffer[bufSize];
bleParse = Adafruit_ATParser(); // Throws error: bleParse was not declared in this scope
bleParse.atcommandStrReply("AT+GATTCHAR=3",&inputBuffer,bufSize,1000);
Serial.print("input:");
Serial.println(inputBuffer);
}
The functions I am trying to use are found in the library for the module in Adarfruit_ATParser.cpp
/******************************************************************************/
/*!
#brief Constructor
*/
/******************************************************************************/
Adafruit_ATParser::Adafruit_ATParser(void)
{
_mode = BLUEFRUIT_MODE_COMMAND;
_verbose = false;
}
******************************************************************************/
/*!
#brief Send an AT command and get multiline string response into
user-provided buffer.
#param[in] cmd Command
#param[in] buf Provided buffer
#param[in] bufsize buffer size
#param[in] timeout timeout in milliseconds
*/
/******************************************************************************/
uint16_t Adafruit_ATParser::atcommandStrReply(const char cmd[], char* buf, uint16_t bufsize, uint16_t timeout)
{
uint16_t result_bytes;
uint8_t current_mode = _mode;
// switch mode if necessary to execute command
if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
// Execute command with parameter and get response
println(cmd);
result_bytes = this->readline(buf, bufsize, timeout, true);
// switch back if necessary
if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
return result_bytes;
}
None of the examples in the library use this. They all create their own parsers. For example, the neopixel_picker example sketch has a file called packetParser.cpp which I believe retrieves data from the BT module for that specific sketch, but it never includes or uses Adafruit_ATParser.. There are no examples of this constructor anywhere and I cannot figure out how to use it. I have tried these ways:
bleParse = Adafruit_ATParser();
Adafruit_ATParser bleParse();
Adafruit_ATParser();
ble.Adafruit_ATParser bleParse();
note: ble is an object that signifies a Serial connection between arduino and BT created with:
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);
Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
Can anyone give me a clue on how to use the Adafruit_ATParser() constructor? Also, if the constructor has no reference to the ble object, how does it pass AT commands to the BT module?
I know this is a big ask, I appreciate any input you can give me.
Like this
Adafruit_ATParser bleParse;
You were closest with this one Adafruit_ATParser bleParse();. This is a common beginner mistake because it looks right. Unfortunately it declares a function bleParse which takes no arguments and returns a Adafruit_ATParser object.
I can't answer the second question.
EDIT
I've taken the time to have a look at the code. This is what I found
class Adafruit_BluefruitLE_UART : public Adafruit_BLE
{
and
class Adafruit_BLE : public Adafruit_ATParser
{
what this means is that the Adafruit_BluefruitLE_UART class is derived from the Adafruit_BLE class which in turn is derived from the Adafruit_ATParser class. Derivation means that any public methods in Adafruit_BLE can also be used on a Adafruit_BluefruitLE_UART object. You already have an Adafruit_BluefruitLE_UART object (you called it ble) so you can just use the method you want to use on that object.
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);
Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
ble.atcommandStrReply( ... );

Why does vector.push_back(System::Byte) not compile any more in VC++ 14.29 (C++/CLI)

I have the following code that used to compile and work fine:
std::vector<unsigned char> marshal_as(cli::array<System::Byte>^ const& from)
{
std::vector<unsigned char> result;
result.reserve(from->Length);
for (int i = 0; i < from->Length; i++)
{
result.push_back(from[i]);
}
return result;
}
After updating VisualStudio to version 16.10 - which updates the C++ compiler to version 14.29 - the code produces an error:
error C2664: 'void std::vector<unsigned
char,std::allocator<_Ty>>::push_back(const _Ty &)': cannot convert
argument 1 from 'unsigned char' to 'const _Ty &'
with
[
_Ty=unsigned char
]
message : An object from the gc heap (element of a managed array) cannot be converted to a native reference
message : see
declaration of 'std::vector<unsigned
char,std::allocator<_Ty>>::push_back'
with
[
_Ty=unsigned char
]
Changing the code in the loop body to
unsigned char b = from[i];
result.push_back(b);
fixes the problem.
I would like to understand the cause of this error. Is this somehow related to a change due to the C++ 20 standard?
Is this somehow related to a change due to the C++ 20 standard?
No. While std::vector<>::push() has subtly changed in C++20, it's not a change that materially affects what's going on here, the issue is definitely clr-specific.
I would like to understand the cause of this error.
This is almost certainly (see below) an error that was always present in your code, but was not being reported by previous versions of the C++/CLI compiler.
Consider the following function:
void foo(const int& v) {
int* ptr = &v;
// store ptr somewhere, long-term.
}
It's obvious that invoking foo() with a reference to a gc-backed int would be a recipe for disaster. Yet that's exactly what result.push_back(from[i]); does.
Your code "works" because push_back() happens to do nothing with its parameter that causes an issue. However, the compiler is not supposed to know that.
N.B. I say almost certainly because I'm having a heck of a time tracking down the call signature for cli::array<T>::operator[](std::size_t) const. It's not impossible that it used to return a T and now returns const T%.

In Delphi, how do you call a private property read function from inside an asm statement

This line of Pascal code:
gh := GCanvas.Handle
(where GCanvas is a variable of type TCanvas)
converts to this in assembly language (as viewed in the CPU window):
mov eax,[GCanvas]
call TCanvas.GetHandle
mov [gh],eax
GetHandle is the private function that returns the value of FHandle defined in Graphics.pas
How can I access the TCanvas Handle property inside an asm statement?
I tried the call as above but the compiler returns "Undeclared identifier 'GetHandle'"
So how do you access properties where the value is returned by a function call?
Any help, please?
If the property accessor method is PRIVATE then the simple answer is: You can't. The compiler simply doesn't know that symbol at that point in your code. Even from Pascal, you can't, except by going via RTTI and that is probably too cumbersome to do from assembly.
The way to do it is to provide a "gateway" function that calls on to the property (which in turn calls the private function):
FUNCTION GetHandle(C : TCanvas) : HDC; Register; // Must be a Global function //
BEGIN
Result:=C.Handle
END;
and then from your assembly code:
VAR GCanvas : TCanvas;
VAR gh : THandle;
ASM
MOV EAX,GCanvas
CALL GetHandle
MOV [gh],EAX
END
If you make the GetHandle function a method of a class, you need to pass "Self" (the instance of the class) in EDX to the function as well.
I also found this this morning - if I end the asm statement to go back to Pascal and use the line
GCanvas.Handle;
this calls the GetHandle function and the result is left in eax - then enter a new asm statement and eax can be stored or pushed as needed.

Application crash calling exported delphi function from C++

I have a .DLL compiled in Delphi 7 that exports a function. I am trying to call that function from C++.
procedure SystemReload(lpMessage: PAnsiChar; dwIcon: byte; dwColor: byte);
var
dwMessage: cardinal;
procedure SystemReload_Real(lpMessage: PAnsiChar); assembler;
asm
...
end;
begin
dwMessage := $00415B30;
ShowGameMessage_Real(lpMessage);
end;
exports SystemReload name 'SystemReload';
begin
end.
And then the C++ code I am using to call the function:
int ShowGameMessage(char* Message, BYTE Icon, BYTE Color)
{
int ret;
if (exist("SysReload.dll"))
{
HMODULE hLib = LoadLibrary("SysReload.dll");
if (hLib)
{
typedef int(__stdcall *SGMessage)(char*, BYTE, BYTE);
SGMessage ShowGameMessage = (SGMessage)GetProcAddress(hLib, "SystemReload");
ret = (*ShowGameMessage)(Message, Icon, Color);
} else { FreeLibrary(hLib); }
FreeLibrary(hLib);
}
return ret;
}
The C++ code is crashing when calling the exported Delphi function.
How do I do things right without crashing the application?
You are not specifying a calling convention in your Delphi code. The default calling convention in Delphi is register (which is known as __fastcall in C++Builder, and is not supported by any other C++ compiler). Your C++ code is using __stdcall for the imported function (the default calling convention in C++ is usually __cdecl). Mixing calling conventions is undefined behavior, and can lead to all kinds of problems, including crashes. You need to specify the same calling convention in both languages. In this case, you should use stdcall in your Delphi code to match your use of __stdcall in your C++ code:
procedure SystemReload(lpMessage: PAnsiChar; dwIcon: byte; dwColor: byte); stdcall;
Also, your Delphi code is declaring the exported function as a procedure, which means it has no return value. But your C++ code is declaring the imported function as having an int return type. You should change your C++ code to use void to match your use of procedure in your Delphi code:
typedef void (__stdcall *SGMessage)(char*, BYTE, BYTE);
Also, on an unrelated note, your C++ code is calling FreeLibrary() twice if LoadLibrary() fails. You should not be calling FreeLibrary() at all if LoadLibrary() fails. Call it only once if LoadLibrary() succeeds. You should move your call to FreeLibrary() to inside your if (hLib) block:
void ShowGameMessage(char* Message, BYTE Icon, BYTE Color)
{
HMODULE hLib = LoadLibrary("SysReload.dll");
if (hLib)
{
typedef void (__stdcall *SGMessage)(char*, BYTE, BYTE);
SGMessage ShowGameMessage = (SGMessage) GetProcAddress(hLib, "SystemReload");
if (ShowGameMessage)
(*ShowGameMessage)(Message, Icon, Color);
FreeLibrary(hLib);
}
}
Your Delphi export does not look like it is __stdcall.
So either declare it as __fastcall if you are using C++Builder, or as stdcall in the DLL. Since it is a DLL export, stdcall is probably the better option.
If you don't use C++Builder, but another C++, then __fastcall is not an option, because then, your __fastcall is not compatible with Delphi's default register calling convention. Better to declare the DLL function as stdcall (or cdecl, although for DLLs, stdcall is more usual).
FWIW, using the default register calling convention for a DLL export is a no-no for the reasons layed out above.
More info: DLL dos and don'ts -- Calling convention.

How can I use SWIG to handle a JAVA to C++ call with a pointer-to-pointer argout argument?

The problem involved a JAVA call to a C-function (API) which returned a pointer-to-pointer as an argout argument. I was trying to call the C API from JAVA and I had no way to modify the API.
Using SWIG typemap to pass pointer-to-pointer:
Here is another approach using typemaps. It is targetting Perl, not Java, but the concepts are the same. And I finally managed to get it working using typemaps and no helper functions:
For this function:
typedef void * MyType;
int getblock( int a, int b, MyType *block );
I have 2 typemaps:
%typemap(perl5, in, numinputs=0) void ** data( void * scrap )
{
$1 = &scrap;
}
%typemap(perl5, argout) void ** data
{
SV* tempsv = sv_newmortal();
if ( argvi >= items ) EXTEND(sp,1);
SWIG_MakePtr( tempsv, (void *)*$1, $descriptor(void *), 0);
$result = tempsv;
argvi++;
}
And the function is defined as:
int getblock( int a, int b, void ** data );
In my swig .i file. Now, this passes back an opaque pointer in the argout typemap, becaust that's what useful for this particular situation, however, you could replace the SWIG_MakePtr line with stuff to actually do stuff with the data in the pointer if you wanted to. Also, when I want to pass the pointer into a function, I have a typemap that looks like this:
%typemap(perl5, in) void * data
{
if ( !(SvROK($input)) croak( "Not a reference...\n" );
if ( SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0 ) == -1 )
croak( "Couldn't convert $1 to $1_descriptor\n");
}
And the function is defined as:
int useblock( void * data );
In my swig .i file.
Obviously, this is all perl, but should map pretty directly to Java as far as the typemap architecture goes. Hope it helps...
[Swig] Java: Using C helper function to pass pointer-to-pointer
The problem involved a JAVA call to a C-function (API) which returned a pointer-to-pointer as an argout argument. I was trying to call the C API from JAVA and I had no way to modify the API.
The API.h header file contained:
extern int ReadMessage(HEADER **hdr);
The original C-call looked like:
HEADER *hdr;
int status;
status = ReadMessage(&hdr);
The function of the API was to store data at the memory location specified by the pointer-to-pointer.
I tried to use SWIG to create the appropriate interface file. SWIG.i created the file SWIGTYPE_p_p_header.java from API.h. The problem is the SWIGTYPE_p_p_header constructor initialized swigCPtr to 0.
The JAVA call looked like:
SWIGTYPE_p_p_header hdr = new SWIGTYPE_p_p_header();
status = SWIG.ReadMessage(hdr);
But when I called the API from JAVA the ptr was always 0.
I finally gave up passing the pointer-to-pointer as an input argument. Instead I defined another C-function in SWIG.i to return the pointer-to-pointer in a return value. I thought it was a Kludge ... but it worked!
You may want to try this:
SWIG.i looks like:
// return pointer-to-pointer
%inline %{
HEADER *ReadMessageHelper() {
HEADER *hdr;
int returnValue;
returnValue = ReadMessage(&hdr);
if (returnValue!= 1) hdr = NULL;
return hdr;
}%}
The inline function above could leak memory as Java won't take ownership of the memory created by ReadMessageHelper, since the HEADER instance iscreated on the heap.
The fix for the memory leak is to define ReadMessageHelper as a newobject in order for Java to take control of the memory.
%newobject ReadMessageHelper();
JAVA call now would look like:
HEADER hdr;
hdr = SWIG.ReadMessageHelper();
If you are lucky, as I was, you may have another API available to release the message buffer. In which case, you wouldn’t have to do the previous step.
William Fulton, the SWIG guru, had this to say about the approach above:
“I wouldn't see the helper function as a kludge, more the simplest solution to a tricky problem. Consider what the equivalent pure 100% Java code would be for ReadMessage(). I don't think there is an equivalent as Java classes are passed by reference and there is no such thing as a reference to a reference, or pointer to a pointer in Java. In the C function you have, a HEADER instances is created by ReadMessage and passed back to the caller. I don't see how one can do the equivalent in Java without providing some wrapper class around HEADER and passing the wrapper to the ReadMessage function. At the end of the day, ReadMessage returns a newly created HEADER and the Java way of returning newly created objects is to return it in the return value, not via a parameter.”