ICC inline assembler doesn`t like push/pop - inline-assembly

I try to excute assembler inline with icc in msasm:
int main (void)
{
__asm{
mov eax, 5h; //works
push eax; // after shell command /opt/intel/bin/icc -use_msasm asm.c:
// asm.c(7): (col. 5) error: Unsupported instruction form in asm
// instruction push.
//pop ebp; // the same
};
printf("success!\n");
return 1;
}
Does anybody know why icc doesn`t accept push and pop?
Thanks in advance!

You should use x64 version of registers instead.
So the correct version should like this:
__asm{
mov rax, 5h;
push rax;
};
Also, pay attention to architecture differences when dealing with pointers, 0x8*******, etc. You should never use batch Find and Replace without reading your inline first.

Related

how to load address of a label into register in powerpc

In a piece of inline assembly code, what is the best way to load the address of a label into a register?
I can do this easily in x86 or ARM. E.g.
lea my_label, %rax
...
my_label:
...
In PPC, should I use $PC and relative address to compute the address of the label? How to do that?
Thanks
OK, it's probably more complex than I thought. This might work:
void* f(void)
{
void* var_reg;
asm volatile(
"lis %[var_reg], my_label#ha\n"
"la %[var_reg], my_label#l(%[var_reg])\n"
"my_label:\n"
: [var_reg]"=&r"(var_reg)
);
return var_reg;
}

Do empty functions get optimized away in Rust?

I want to put some performance impacting function calls behind a feature gate in my code. If the feature isn't enabled, I was thinking of just having an empty implementation of that function implemented instead. That way, hopefully, the Rust complier can completely remove that from the function.
Something like this:
// Included if feature is enabled
fn foo() {
// ...
}
// Included if the feature is disabled
fn foo() {}
// Performance critical code
for i in 1..1000000000 {
// ...
foo();
}
Would the call to foo() get optimized away if it is empty?
Just try it in the amazing Compiler Explorer :)
The result assembly for your example is:
example::main:
push rbp
mov rbp, rsp
mov eax, 1
.LBB0_1:
xor ecx, ecx
cmp eax, 1000000000
setl cl
add ecx, eax
cmp eax, 1000000000
mov eax, ecx
jl .LBB0_1
pop rbp
ret
As you can see there is no call instruction and foo() isn't called at all. However, you might wonder why the loop isn't removed, as it doesn't have an effect on the outside world. I can just assume that sometimes those loops are in fact used to waste time in some sense. If you decrease the counter to 100, the loop is completely removed.
Anyway: Yes, the optimizer will remove empty functions!
According to my check with release mode on current stable Rust, the following code:
fn foo() {}
fn main() {
for _ in 1..1000000000 {
foo();
}
println!(); // a side effect so that the whole program is not optimized away
}
Compiles to the same assembly as if the loop was empty:
for _ in 1..1000000000 {}

stm32L476RG - how to execute the bootloader from firmware

I am working on a NUCLEO-L476RG board, trying to start the bootloader from my firmware code but its not working for me. here is the code that i am trying to execute :
#include "stm32l4xx.h"
#include "stm32l4xx_nucleo.h"
#include "core_cm4.h"
#include "stm32l4xx_hal_uart.h"
GPIO_InitTypeDef GPIO_InitStructure;
UART_HandleTypeDef UartHandle;
UART_InitTypeDef UART_InitStructre;
void BootLoaderInit(uint32_t BootLoaderStatus){
void (*SysMemBootJump)(void) = (void (*)(void)) (*((uint32_t *) 0x1FFF0004));
if(BootLoaderStatus == 1) {
HAL_DeInit(); // shut down running tasks
// Reset the SysTick Timer
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL =0;
__set_PRIMASK(1); // Disable interrupts
__set_MSP((uint32_t*) 0x20001000);
SysMemBootJump();
}
}
int main(void)
{
HAL_Init();
__GPIOC_CLK_ENABLE();
GPIO_InitStructure.Pin = GPIO_PIN_13;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
while (1) {
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
BootLoaderInit(1);
}
}
return 0;
}
What i hope to get after the execution of the firmware is that i can connect to the board with a UART and send commands/get responses from the bootloader. the commands i am trying to use come from here: USART protocol used in the STM32 bootloader.
I don't see and response from the board after connecting with the UART.
Here are some ideas taken from the answers to this question.
HAL_RCC_DeInit();
This is apparently needed to put the clocks back into the state after reset, as the bootloader expects them to be.
__HAL_REMAPMEMORY_SYSTEMFLASH();
Maps the system bootloader to address 0x00000000
__ASM volatile ("movs r3, #0\nldr r3, [r3, #0]\nMSR msp, r3\n" : : : "r3", "sp");
Set the stack pointer from bootloader ROM. Where does your 0x20001000 come from? If it's an arbitrary value, then the stack can clobber the bootloader's variables.
Then there is this alternate solution:
When I want to jump to the bootloader, I write a byte in one of the
backup register and then issue a soft-reset. Then, when the processor
will restart, at the very beginning of the program, it will read this
register.
Note that you need LSI or LSE clock for accessing the backup registers.
Try to avoid using __set_MSP(), as current implementation of this function does NOT allow you to change MSP if it is also the stack pointer which you currently use (and you most likely are). The reason is that this function marks "sp" as clobbered register, so it will be saved before and restored afterwards.
See here - STM32L073RZ (rev Z) IAP jump to bootloader (system memory)
Find your bootloader start address from the reference manual.
Then use the following code.
Make sure you have cleaned and disabled the interrupts before do so.
/* Jump to different address */
JumpAddress = *(__IO uint32_t*) (BootloaderAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
Please have a look at Official STM32 AppNote as well.

Printing Objective-C method implementation at runtime

Is it possible to print/log the implementation of a certain class method at runtime to the console screen? I am assuming the log will be in assembly which is fine by me.
You could add a breakpoint at the start of the line, step through line by line and call "disassemble" in the debugger:
One line of my code (with private information replaced) for example produced this:
-(void) method
{
__weak typeof(self) selfReference = self; // <-- This call was disassembled.
...
Project`-[Class method] + 32 at Class.m:176:
-> 0x9c5cc: ldr r1, [sp, #304]
0x9c5ce: add r0, sp, #296
0x9c5d0: blx 0x33abec ; symbol stub for: objc_initWeak
0x9c5d4: ldr r1, [sp, #304]
Edit
I can't verify it's working perfectly since I'm not too handy with assembly, but you can use the debugger (Clang I'm using) to just call
disassemble -n methodName
This claims to
Disassemble entire contents of the given function name.
NB: I did this with a breakpoint at the start of the method I was using to test
Try creating a symbolic breakpoint to stop at the method in question:

Why does DTrace give me invalid-address errors sometimes but not always?

My program:
typedef struct objc_class {
struct objc_class *isa;
struct objc_class *super_class;
char *name;
long version;
long info;
long instance_size;
void *ivars;
void *methodLists;
void *cache;
void *protocols;
} *Class;
struct objc_object {
Class isa;
};
/* Code to extract the class name from arg0 based on a snippet by Bill Bumgarner: http://friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/ */
objc$target:NSObject:-init:entry {
printf("time: %llu\n", timestamp);
printf("arg0: %p\n", arg0);
obj = (struct objc_object *)copyin(arg0, sizeof(struct objc_object));
printf("obj: %p\n", obj);
printf("obj->isa: %p\n", obj->isa);
isa = (Class)copyin((user_addr_t)obj->isa, sizeof(struct objc_class));
printf("isa: %p\n", obj->isa);
classname = copyinstr((user_addr_t)(isa->name));
printf("classname: %s\n", classname);
}
Some output:
dtrace: script 'test.d' matched 1 probe
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
CPU ID FUNCTION:NAME
0 61630 -init:entry time: 28391086668386
arg0: 1291ae10
obj: 6f0a1158
obj->isa: a023f360
isa: a023f360
classname: NSBitmapImageRep
1 61630 -init:entry time: 28391586872297
arg0: 12943560
obj: 6f4a1158
obj->isa: 2fca0
isa: 2fca0
classname: GrowlApplicationTicket
1 61630 -init:entry time: 28391586897807
arg0: 152060
obj: 6f4a1280
obj->isa: 2fe20
isa: 2fe20
classname: GrowlNotificationTicket
2 61630 -init:entry time: 28391079142905
arg0: 129482d0
obj: 700a1128
obj->isa: a0014140
isa: a0014140
classname: NSDistributedObjectsStatistics
2 61630 -init:entry time: 28391079252640
arg0: 147840
obj: 700a1250
obj->isa: a0014780
isa: a0014780
classname: NSDistantObjectTableEntry
Why the errors? It seems to be the class name (that's the only %s, and I don't get any errors if I remove it), but why does it think some classes' names are invalid pointers?
Is there any way to get the error messages to actually tell me which line of my DTrace program caused a problem?
Is there a way to call object_getClassName instead of doing this structure-inspection dance?
For what it's worth, the program I'm tracing works fineā€”it's not crashing, so I don't believe that the classes really are broken.
Colin is pretty close to correct.
See:
http://www.friday.com/bbum/2008/01/03/objective-c-using-dtrace-to-trace-messages-to-nil/
More likely than not, you need to set the DYLD_SHARED_REGION environment variable to avoid. dtrace only really works against mapped memory that is actually resident in physical memory.
You can figure out what is missing by using the vmmap command line tool.
Do a vmmap PID on your application after the above failure messages are generated. Looking at the output, see what region the addresses like 0x90206b98 fall into. Given that address, it is likely in a non-writeable shared chunk of memory that probably isn't resident and, thus, dtrace can't read from it.
This error happens when copyin / copyinstr is used on a page that's not faulted in yet. A common workaround is to let the function use the data in question, and then copyin[str] in a :::return clause. For example:
syscall::open:entry
{
self->filename = arg0; /* Hang on to the file name pointer. */
}
syscall::open:return
/self->filename/
{
#files[copyinstr(self->filename)] = count();
self->filename = 0;
}
END
{
trunc(#files, 5);
}
I haven't entirely tracked this down myself. It's possible that DTrace is trying to resolve some Objective-C symbols. Although DTrace is a dynamic tracing facility it doesn't mesh well with Objective-C dynamically loading things at runtime. When Objective-C does load new classes,etc DTrace has to resolve this and it takes a little time, especially when your app is just starting up. Even if it does get things loaded, and your objc app is still loading new classes onto the objc runtime its possible DTrace could get screwed up and print methods in the wrong order (if you care about seeing the correct order methods are being executed in), print incorrect timing results,etc.
This is my best guess based on the information provided.
DTrace was purposefully designed in such a way as to make DTrace scripts as deterministic as possible. This is why there are no if statements, loops, subroutines (other than the pseudo-subroutines provided by DTrace itself), etc. This is because the code in your DTrace script is running in kernel mode, not user-land as part of the process(es) being traced. In general, the information DTrace has access to is "read-only" (like most generalizations, this is not strictly true), being able to twiddle bits in programs, or the kernel, with something as powerful as DTrace can cause things to go very, very wrong, very very quickly.
Dollars to donuts, the problem you're having is because the page that the pointer points to is not mapped in to core by the VM system. DTrace can only examine information for memory that is in core- it can't double-fault to get the VM system to load in the page.
You can probably help alleviate the problem if you've got an idea of what the classes "should" be and forcing the pages to be mapped in to core by doing a bunch of dummy NSLog() statements that reference the needed classes at some convenient point early in your programs start up.