HTTP/1.1 301 Moved Permanently
Location: https://codeberg.org/gabi-250
gabi-250 / llvm-guard-handler Goto Github PK
View Code? Open in Web Editor NEWExperimenting with LLVM
License: MIT License
Experimenting with LLVM
License: MIT License
HTTP/1.1 301 Moved Permanently
Location: https://codeberg.org/gabi-250
The return address is supposed to be 0x40313f
, but the stackmap
call generated for __unopt_get_number
is at 0x403141
.
11│ 0x0000000000403137 <+23>: mfence
12│ 0x000000000040313a <+26>: callq 0x403120 <__unopt_get_number>
13│ 0x000000000040313f <+31>: mov %eax,%ebx
14│ 0x0000000000403141 <+33>: mfence
15│ 0x0000000000403144 <+36>: mov %ebx,-0xc(%rbp)
Direct stack map locations represent an alloca
's relative location on the stack.
How many bytes to copy when mapping the direct locations of trace
to the direct locations of __unopt_trace
?
Locations which cannot fit in a uint64_t
are not restored correctly. This can be fixed by returning a uint64_t *
in stmap_get_location_value
.
Indirect stack map locations (register spills) are not currently handled.
Which locations should be passed as arguments to llvm.experimental.stackmap
and llvm.experimental.patchpoint
?
In trace.c
, changing:
...
uint64_t opt_location_value =
stmap_get_location_value(sm, opt_rec.locations[i], r, bp);
if (type == REGISTER) {
uint16_t reg_num = unopt_rec.locations[i].dwarf_reg_num;
uint64_t loc_size =
stmap_get_location_value(sm, opt_rec.locations[i + 1], r, bp);
memcpy(r + reg_num, &opt_location_value, loc_size);
...
to
...
uint64_t opt_location_value =
stmap_get_location_value(sm, opt_rec.locations[i], r, bp);
uint16_t reg_num = 0;
if (type == REGISTER) {
reg_num = unopt_rec.locations[i].dwarf_reg_num;
uint64_t loc_size =
stmap_get_location_value(sm, opt_rec.locations[i + 1], r, bp);
memcpy(r + reg_num, &opt_location_value, loc_size);
...
causes the wrong address to be stored in the stack map.
Global values are not currently recorded in the stack map. This means an llvm.experimental.patchpoint
call inserted before an instruction such as printf
might not record the correct state. This is because printf
uses a format string, which is a global value.
For example, consider the following scenario: in the optimized version, the global value is loaded into a register after the call to the patchpoint
intrinsic happens (so its value is never recorded), while in the unoptimized version, the global variable is loaded before the stackmap
call.
Stackmaps should be inserted everywhere they may be necessary, not just in the trace
and __unopt_trace
functions.
The current implementation crashes if a guard fails in a function that takes more than 6 arguments, or inside a function called by a function with more than 6 arguments. The return address cannot be found, due to the fact that an incorrect number of values are popped off the stack after the call.
The unoptimized function:
...
4035cc: 31 ff xor %edi,%edi
4035ce: be 01 00 00 00 mov $0x1,%esi
4035d3: ba 02 00 00 00 mov $0x2,%edx
4035d8: b9 03 00 00 00 mov $0x3,%ecx
4035dd: 41 b8 fb ff ff ff mov $0xfffffffb,%r8d
4035e3: 45 31 c9 xor %r9d,%r9d
4035e6: c7 04 24 0a 00 00 00 movl $0xa,(%rsp)
4035ed: c7 44 24 08 6e 00 00 movl $0x6e,0x8(%rsp)
4035f4: 00
4035f5: c7 44 24 10 e6 00 00 movl $0xe6,0x10(%rsp)
4035fc: 00
4035fd: e8 ae fe ff ff callq 4034b0 <__unopt_more_indirection2>
<the stack is not resized here, even though this instruction is reached from the optimized function, which pushes additional values to the stack>
...
The optimized function:
...
4032a1: 31 ff xor %edi,%edi
4032a3: be 01 00 00 00 mov $0x1,%esi
4032a8: ba 02 00 00 00 mov $0x2,%edx
4032ad: b9 03 00 00 00 mov $0x3,%ecx
4032b2: 41 b8 fb ff ff ff mov $0xfffffffb,%r8d
4032b8: 45 31 c9 xor %r9d,%r9d
4032bb: 68 e6 00 00 00 pushq $0xe6
4032c0: 6a 6e pushq $0x6e
4032c2: 6a 0a pushq $0xa
4032c4: e8 d7 fe ff ff callq 4031a0 <more_indirection2>
4032c9: 48 83 c4 20 add $0x20,%rsp
...
Each frame_t
has its own set of registers.
The frames which correspond to inlined functions are supposed to have the same register state as the function inside which they were inlined. If each frame_t
stores its own register array, then the register state may become inconsistent.
Live locations stored in floating-point registers cannot be restored, because unw_get_fpreg
is not implemented for x86-64
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.