boost::context for arm64? - c++

I am trying to compile boost::context for iOS(armv7, armv7s, arm64):
errors
jump_arm_aapcs_macho_gas.S:52:18: error: ',' expected
stmia a1, {v1-v8,sp-lr} # save V1-V8,SP-LR
^
jump_arm_aapcs_macho_gas.S:53:14: error: register expected
str lr, [a1,#40] # save LR as PC
^
jump_arm_aapcs_macho_gas.S:69:18: error: invalid variant 'use'
mov a1, a3 # use third arg as return value after jump
^
jump_arm_aapcs_macho_gas.S:70:39: error: unexpected token at start of statement
# and as first arg in context function
^
jump_arm_aapcs_macho_gas.S:71:18: error: ',' expected
ldmia a2, {v1-v8,sp-pc} # restore v1-V8,SP-PC
^
jump_arm_aapcs_macho_gas.S
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
stmia a1, {v1-v8,sp-lr} # save V1-V8,SP-LR
str lr, [a1,#40] # save LR as PC
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
cmp a4, #0 # test if fpu env should be preserved
beq 1f
mov a4, a1
add a4, #52
vstmia a4, {d8-d15} # save S16-S31
mov a4, a2
add a4, #52
vldmia a4, {d8-d15} # restore S16-S31
1:
#endif
mov a1, a3 # use third arg as return value after jump
# and as first arg in context function
ldmia a2, {v1-v8,sp-pc} # restore v1-V8,SP-PC
If I remove arm64, and set the architecture to armv7 only, it compiles, so the code should be fine.
Is there any way to get this to compile for arm64?

ARM64 (AArch64) is pretty different from ARM32 (A32), both in instructions and the register set. The calling conventions (ABI) differs too. You'd need to rewrite the assembler snippets. I would recommend contacting the developer(s) since you don't seem to be familiar with the low-level details to do it yourself.

Related

How to get LLVM IR AST

There's lots of information how to use Clang / LLVM to get the C or C++ AST. I'd like the IR AST. That is:
Given xor i1 %1, true, how do I get something like
xor : i1 # operator, binary
%1 # operand 1
true # operand 2

Find all possible paths from lists with adjacent elements in Prolog?

I apologize in advance for the awkward title as it's a bit hard to put clearly in just a few words.
The goal is to find all possible paths and the total energy used from one "room" to another based on the input rooms. So the list [r1,r2,3] would mean you can travel from room 1 to room 2, and from room 2 to room 1, and it would take 3 energy either way. You are not allowed to travel to a room previously traveled to.
Here is the list of lists that represent which rooms can be traveled too.
adjacent([[r1,r2,8],[r1,r3,2],[r1,r4,4],[r2,r3,7],[r3,r4,1],[r2,r5,2],[r4,r6,5],[r6,r3,9],[r3,r5,3]]).
And here is my code which does correctly find a path, however all future possible paths are just repeating previous rooms because I'm unsure on how to implement that functionality. I figured I could simply use not member(PosPath, Paths) since Paths hold the list of all previously traveled to elements but it seems like it adds PosPath to Paths sometime beforehand so it always fails.
trip(Start,End,[Start,End],Energy):- adjacent(List), member([Start,End,Energy],List).
trip(Start,End,[Start|Paths],TotalE) :-
adjacent(List),
member([Start,PosPath,E], List),
% not member(PosPath, Paths),
trip(PosPath,End,Paths,PathE).
% TotalE is E+PathE.
Output:
?- trip(r1, r6, Path, TotalE).
Path = [r1, r2, r3, r4, r6]
Total = Total
Yes (0.00s cpu, solution 1, maybe more)
Path = [r1, r2, r3, r4, r6, r3, r4, r6]
Total = Total
Yes (0.00s cpu, solution 2, maybe more)
Path = [r1, r2, r3, r4, r6, r3, r4, r6, r3, r4, r6]
TotalE = TotalE
Yes (0.00s cpu, solution 3, maybe more)
Since the rooms in [r1,r2,3] represent a bidirectional path I would suggest a predicate that describes this symmetry, let's call it from_to_cost/3:
from_to_cost(X,Y,C) :-
adjacent(L),
member([X,Y,C],L).
from_to_cost(X,Y,C) :-
adjacent(L),
member([Y,X,C],L).
For the calling predicate I would suggest a somewhat more descriptive name, say start_end_path_cost/4, that correspond to your predicate trip/4. For the predicate that describes the actual relation two additional arguments are needed: An accumulator to sum up the cost of the path, that starts at 0 and a list of visited rooms that starts with the first room as the single element [S]:
start_end_path_cost(S,E,P,C) :-
s_e_p_c_(S,E,P,C,0,[S]).
The actual relation has to describe two cases:
1) If the start-room and the end-room are equal the path is found. Then the cost and the accumulator are equal as well and the path is empty.
2) Otherwise there is an intermediary room that has not been visited yet and can be reached from S:
s_e_p_c_(E,E,[],C,C,_Visited).
s_e_p_c_(S,E,[X|Path],C,C0,Visited) :-
maplist(dif(X),Visited),
from_to_cost(S,X,SXC),
C1 is C0+SXC,
s_e_p_c_(X,E,Path,C,C1,[X|Visited]).
Now your example query finds all solutions and terminates:
?- start_end_path_cost(r1, r6, Path, TotalE).
Path = [r2, r3, r4, r6],
TotalE = 21 ;
Path = [r2, r3, r6],
TotalE = 24 ;
Path = [r2, r5, r3, r4, r6],
TotalE = 19 ;
Path = [r2, r5, r3, r6],
TotalE = 22 ;
Path = [r3, r4, r6],
TotalE = 8 ;
Path = [r3, r6],
TotalE = 11 ;
Path = [r4, r6],
TotalE = 9 ;
Path = [r4, r3, r6],
TotalE = 14 ;
false.
And the most general query finds all 137 solutions for your given connections and terminates as well:
?- start_end_path_cost(S, E, Path, TotalE).
S = E,
Path = [],
TotalE = 0 ;
S = r1,
E = r2,
Path = [r2],
TotalE = 8 ;
S = r1,
E = r3,
Path = [r2, r3],
TotalE = 15 ;
.
.
.
S = r5,
E = r1,
Path = [r3, r6, r4, r1],
TotalE = 21 ;
S = r5,
E = r2,
Path = [r3, r6, r4, r1, r2],
TotalE = 29 ;
false.
Edit:
Concerning your question in the comments: yes it is possible. You can define a predicate that describes the first argument to not be an element of the list that's the second argument, let's call it nonmember/2:
nonmember(_A,[]).
nonmember(A,[H|T]):-
dif(A,H),
nonmember(A,T).
Then you can replace the maplist goal in s_e_p_c_/6 by nonmember/2 like so:
s_e_p_c_(E,E,[],C,C,_Visited).
s_e_p_c_(S,E,[X|Path],C,C0,Visited) :-
nonmember(X,Visited), % <- here
from_to_cost(S,X,SXC),
C1 is C0+SXC,
s_e_p_c_(X,E,Path,C,C1,[X|Visited]).
With this change the queries yield the same results.

Windbg conditional break point not working as expected, is my syntax correct?

I was trying to learn how to set conditional break point inside windbg, I've program named ConsoleApplication7 like below:
int main()
{
int r1 = 0;
r1 += 1;
r1 = 3;
return 0;
}
I compile this program with VC. Then in windbg, I setup the "Symbol path" and "Source path", open ConsoleApplication7.exe inside windbg, windbg runs and opens the .cpp file.
Inside windbg I set a conditional break point, I wish the program should when in line "r1=3".
bp consoleapplication7!main "j (poi(r1)>2) ''; 'gc'"
But when I press "g", windbg doesn't say it "Hit breakpoint", but just print out registers information. After running "g" for 3 times, the program terminate, like below:
0:000> bp consoleapplication7!main "j (poi(r1)>2) ''; 'gc'"
*** WARNING: Unable to verify checksum for ConsoleApplication7.exe
0:000> bl
0 e 01251380 0001 (0001) 0:**** ConsoleApplication7!main "j (poi(r1)>2) ''; 'gc'"
0:000> g
eax=00718918 ebx=7efde000 ecx=0071b880 edx=00000001 esi=00000000 edi=00000000
eip=01251380 esp=002afeb4 ebp=002aff00 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
ConsoleApplication7!main:
01251380 55 push ebp
0:000> g
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=77c02100 edi=77c020c0
eip=77b1fcd2 esp=002afe18 ebp=002afe34 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!NtTerminateProcess+0x12:
77b1fcd2 83c404 add esp,4
0:000> g
^ No runnable debuggees error in 'g'
Other commands like ba, bp works well in the program, just conditional break point doesn't.
Is my conditional statement correct? Why it doesn't work?
I tried the suggestion from Dono's answer, but it shows another problem
0:000> bp ConsoleApplication7!main+0x3e "j (poi(r1) > 2) ''; 'gc'"
0:000> bl
0 e 008e143e 0001 (0001) 0:**** ConsoleApplication7!main+0x3e "j (poi(r1) > 2) ''; 'gc'"
0:000> g
(4458.4840): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=7efde000 ecx=d3392f75 edx=00000001 esi=00000000 edi=00000000
eip=cccccccc esp=0046f82c ebp=cccccccc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
cccccccc ?? ???
Seems this conditional break point leads to an exception?
Thanks!
I also tried Blabb's suggestion, unluckily, it didn't work:
0:000> t "$$>a< c:\\autostep.txt"
Couldn't resolve error at 'r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" } '
eax=00000001 ebx=7efde000 ecx=00000000 edx=00000001 esi=00000000 edi=001dfcb0
eip=013b13c0 esp=001dfbac ebp=001dfcb0 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
ConsoleApplication7!f:
013b13c0 55 push ebp
Seems C++ style command didn't work, so I changed it to MASM style
j (poi(r1)==3)''; 't "$$>a< c:\\autostep.txt"'
Save as c:\autostep.txt
Then I restart windbg to reload it.
0:000> t "$$>a< c:\\autostep.txt"
eax=00000000 ebx=00000000 ecx=bc260000 edx=0015dc38 esi=fffffffe edi=00000000
eip=77ba0e15 esp=0042f804 ebp=0042f830 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000244
ntdll!LdrpDoDebuggerBreak+0x2d:
77ba0e15 8975fc mov dword ptr [ebp-4],esi ss:002b:0042f82c=00000000
0:000> g
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=77c02100 edi=77c020c0
eip=77b1fcd2 esp=0042fb94 ebp=0042fbb0 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!NtTerminateProcess+0x12:
77b1fcd2 83c404 add esp,4
This time, it has no syntax issue, when it doesn't break/stop as I expected. Did I miss anything?
Thanks.
First of all you should be aware that your program will be optimized away to just xor eax,eax ; ret
Unless you compile in debug mode and explicitly disable optimizations with /Od switch
( I assume you are using visual monster project in debug mode which takes care of this )
Second you should be aware is that debugger does not know your r1 r2 or whatever unless symbol information is present and event then you should be aware that there are two expression evaluator MASM and C++ and by default windbg uses MASM
? poi(r1) == MASM evaluation
?? r1 == c++ evaluation
other wise debugger understands only the variables that cpu understands like BYTE , WORD , DWORD , QWORD .... etc and addresses
when you set conditional breakpoint like bp xxxxxmodule!yyyyysymbol "condition" conditions are evaluated only on the address specified not further below
so your condition was evaluated only on main
you should step further down and evaluate your condition on each step until you encounter a match
your code compiled and main() disassembled will look like this
0:000> .dml_flow steptest!main .
<No previous node>
STEPTEST!main (013e6aa0):
e:\test\steptest\steptest.cpp
2 013e6aa0 push ebp
2 013e6aa1 mov ebp,esp
2 013e6aa3 push ecx
3 013e6aa4 mov dword ptr [ebp-4],0
4 013e6aab mov eax,dword ptr [ebp-4]
4 013e6aae add eax,1
4 013e6ab1 mov dword ptr [ebp-4],eax
5 013e6ab4 mov dword ptr [ebp-4],3
6 013e6abb xor eax,eax
7 013e6abd mov esp,ebp
7 013e6abf pop ebp
7 013e6ac0 ret
<No next node>
0:000> lsa .
1: int main()
2: {
3: int r1 = 0;
> 4: r1 += 1;
5: r1 = 3;
6: return 0;
7: }
so your condition can be true only on line 6 or in assembly at address 013e6abb xor eax, eax
you set a conditional bp on 013e6aa0 and the condition was evaluated at that address only
you need to find a way to step till 013e6abb
that is you should
step <evaluate> if match stop else repeat step and evaluate until match occurs
to do that put the following line in a file named autostep.txt and save it to c:\
explanation of the script
if the c++ expression r1 equals 3 show the locals else step and reevaluate by running this script again ( so this script will be executed on each instruction sequence until a match is found )
.if ( ##c++(r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" }
now open the exe in windbg and do
bp xxxxmod!main
g
t "$$>a< c:\\autostep.txt"
windbg will break when r1 is 3
E:\test\STEPTEST>cdb -c "g steptest!main" STEPTEST.exe
0:000> cdb: Reading initial command 'g steptest!main'
STEPTEST!main:
013e6aa0 55 push ebp
0:000> t "$$>a< c:\\autostep.txt"
r1 = 0n3
013e6abb 33c0 xor eax,eax
0:000> ?? r1
int 0n3
0:000> ? poi(r1)
Evaluate expression: 3 = 00000003
0:000> ? &main ; ? &#eip
Evaluate expression: 20867744 = 013e6aa0
Evaluate expression: 20867771 = 013e6abb
0:000>
you can invoke the script in cmd.exe
cat c:\autostep.txt
.if ( ##c++(r1) == 3 ) { dv } .else { t "$$>a< c:\\autostep.txt" }
cdb -c "g steptest!main;$$>a< c:\autostep.txt" STEPTEST.exe
0:000> cdb: Reading initial command 'g steptest!main;$$>a< c:\autostep.txt'
r1 = 0n3
eax=00000001 ebx=7ffd6000 ecx=a4894de4 edx=00000001 esi=00a2dd04 edi=00a2dd08
eip=009d6abb esp=0019f8d0 ebp=0019f8d4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
STEPTEST!main+0x1b:
009d6abb 33c0 xor eax,eax
0:000>
Your command means: Unconditionally break at the start of the main function. Then, if r1 > 2, do nothing; otherwise, continue.
Note that bp takes an address and breaks on it. Because you have symbols (PDB), you are able to convert the symbol "consoleapplication7!main" into an address. This points to the start of the function, where r1 has not yet even been initialized, so there is no way for it to be > 2, except for random garbage values.
So first you need to break at a more reasonable spot. There are multiple ways to do this. You can "unscramble" the assembly code uf consoleapplication7!main and determine the offset address to break. Something like bp ConsoleApplication7!main+0x35 "j (poi(r1) > 2) ''; 'gc'". This may be a little difficult. An easier method is to specify the line number such as bp `driver.cpp:6` "j (poi(r1) > 2) ''; 'gc'", assuming your main function is in a file called driver.cpp.
Also, you need to careful whether your application was compiled for debug or release mode. In release mode, most of your main function can be optimized away as the value of r1 can be pre-computed at compile time. This will naturally affect the offsets.
And finally, unless you have a habit of using j to mean "if", I would suggest the more modern .if (condition) { commands } .else { commands } syntax. While they do the same thing, the later is much more readable.
See here for further details.

How to print a Defs register using Tablegen

I have the following comparison instruction:
def CMPrr : Txx32<(outs), (DataRegs:$lhs, DataRegs:$rhs),
"cmp $lhs, $rhs",
[]> {
bits<4> lhs;
bits<4> rhs;
let Defs = [D9];
}
The Instruction printer emits the following output:
cmp d0, d5
I also want to print the Defs register along with this emission. So the output should be like:
cmp d9, d0, d5
Is there a way of printing the Defs register inside the asm string? One way might be to simply write d9 inside the asm string. Is there any other way to perform this operation.

gdb/lldb call a function and break in it

I have a global function in a long run program :
int test()
{
int a = 12;
int c = 10;
printf("a=%d",a);
a += c ;
printf("a=%d", a);
return a;
}
I debug the program and break, then issue the following command:
(lldb) call test()
a=12a=22(int) $0 = 22
(lldb)
I want it to break in test() method every line after I hit call test(), not just return the result immediately. Anyone knows how to do it ?
------------------------------------ Answer Below ------------------------------------
#Jason Molenda 's answer is the right answer,use expr -i0 -- test() instead of call test():
(lldb) b test
Breakpoint 1: 4 locations.
(lldb) expr -i0 -- test()
error: Execution was interrupted, reason: breakpoint 1.1.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
(lldb)
Now it break in test(), but raise an error!!! How to avoid the error ?
The expression command in lldb (call is an alias for expression) takes a dozen or so options, one of them being whether lldb should stop on a breakpoint while executing the expression, --ignore-breakpoints false, or -i false, or -i 0.
(lldb) br s -n printf
Breakpoint 2: where = libsystem_c.dylib`printf, address = 0x00007fff89ee7930
(lldb) expr -- (void)printf("hi\n")
hi
(lldb) expr -i0 -- (void)printf("hi\n")
error: Execution was interrupted, reason: breakpoint 2.1.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
Process 15259 stopped
* thread #1: tid = 0xf0daf, 0x00007fff89ee7930 libsystem_c.dylib`printf, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
#0: 0x00007fff89ee7930 libsystem_c.dylib`printf
libsystem_c.dylib`printf:
-> 0x7fff89ee7930: pushq %rbp
0x7fff89ee7931: movq %rsp, %rbp
0x7fff89ee7934: pushq %r15
0x7fff89ee7936: pushq %r14
(lldb)
There was some thought put in to the default behavior (whether to stop on a breakpoint or not), and this seemed the behavior most people would expect.
As I said, the call command is just an alias for expression. If you want to change the behavior of it, you can overwrite the alias with one of your own. e.g. command alias call expr -i false -- will do the trick. You can put this in your ~/.lldbinit file and you'll be set.
It's not a joke? Just checked standard breakpoint to be sure:
(gdb) b test
Breakpoint 2 at 0x400671: file t.c, line 6.
(gdb) call test()
Breakpoint 2, test () at t.c:6
6 printf("a\n");