How can I get the distance between two instructions in LLVM? - llvm

I'm developing a tool which will inject multi faults into the source code using LLVM. I need to inject a fault into the begin instruction and then the instruction after certain instructions. How can I get the distance between two instructions(using instruction count)? Is there any convenient function to achieve that or the only way is to iterate all instructions within this block and the successors of the block?

If you only need distance between instructions in a basic block, you need to iterate on each instruction in a Basic Block. for example. see how each instruction is iterated in: https://github.com/llvm-mirror/llvm/blob/2c4ca6832fa6b306ee6a7010bfb80a3f2596f824/lib/Analysis/CodeMetrics.cpp#L121
for (const Instruction &I : *BB) {
// Skip ephemeral values.
if (EphValues.count(&I))
continue;
// Special handling for calls.
if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
ImmutableCallSite CS(&I);
...
If you want to have a measure of distance between instructions across basic blocks, it is slightly complicated. It would require the use of DFS visit number of each basic block. Using DFS number along with the position of an instruction relative to it's basic block can be used to have some notion of distance.

Related

Fastest way to insert a character at the beginning of the string in C++?

So while solving problems on Leetcode I came across this problem. To generate a string normally, I could just use str.push_back('a'). But if I want to generate the string backwards I would use this same method and reverse the string at the end. Using str.insert() resulted in Time Limit Exceeded and str='a'+str; would as expected result in Memory Limit Exceeded. Wanted to know if there was an easy way to insert a character at the beginning of the string in C++
You already answered your own question by saying reversing. Just use += operator to append and then reverse.
As another way, first push elements into a stack then pop them to fill string.
If it is still slow, then divide the output into small segments and pipeline the reversing + appending parts to hide latency using multiple threads. While one thread is reversing a segment, another thread can create another segment. Then you join all threads and join their output segments to make single array of chars to be converted to string. If each segment is size of L1 cache, then the reversing should be fast.
If you can't use threads, then you can still do the reversing inside sse/avx registers, they have shuffle commands that can help you use the instruction level parallelism to hide the latency, unless they are slower than L1 access.

How to find all basic blocks appearing between two specific basic blocks in LLVM IR level?

I am doing some analysis in LLVM and for some reasons I want to find all basic blocks that can be executed between two specific basic blocks.
For example, assume that we have two basic blocks named A and B. Now I want to know which basic blocks can appear after executing basic block A and before basic block B.
One possible solution is using the reachability analysis of control glow graph. For example, if basic block C is reachable from A and also basic block B is reachable from C, then we can say C can be executed after A and before B.
The only thing that I could find in the LLVM was this function in llvm/analysis/CFG.h:
/// Determine whether instruction 'To' is reachable from 'From', without passing
/// through any blocks in ExclusionSet, returning true if uncertain.
///
/// Determine whether there is a path from From to To within a single function.
/// Returns false only if we can prove that once 'From' has been executed then
/// 'To' can not be executed. Conservatively returns true.
///
/// This function is linear with respect to the number of blocks in the CFG,
/// walking down successors from From to reach To, with a fixed threshold.
/// Using DT or LI allows us to answer more quickly. LI reduces the cost of
/// an entire loop of any number of blocks to be the same as the cost of a
/// single block. DT reduces the cost by allowing the search to terminate when
/// we find a block that dominates the block containing 'To'. DT is most useful
/// on branchy code but not loops, and LI is most useful on code with loops but
/// does not help on branchy code outside loops.
bool isPotentiallyReachable(
const Instruction *From, const Instruction *To,
const SmallPtrSetImpl<BasicBlock *> *ExclusionSet = nullptr,
const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr);
But the problem is that this function is so conservative and the answers are not certain. I want to know the certain answers.
The concept you're looking for is called domination. You want the blocks that are dominated by A and postdominated by B. For this, you make or obtain a DominatorTree and a PostDominatorTree, and look at the parts of the trees that are below A and B. You can obtain one from the pass managers, if you're writing a pass.
However, note that LLVM's code is conservative because this sort of thing tends to become complicated in a hurry. What about blocks that are executed after A (ie. dominated by A) but that return or throw an exception instead of branching to B? Do you want those? What if there's an infinite loop? Those can be intentional. What if an exception might be thrown and the handler isn't postdominated by B? This sort of thing is full of cases you have to think about.

LLVM - given a register, get where it was last used in the IR representation

I am trying to keep track of data flow in my source code. For that, I'm looking at instructions of type load and obtaining which register they're loading the value from with the use of
*(LI->getPointerOperand())
LI being the instruction of type LoadInst. Now I need to know where this register was last accessed so that I can point that check the data flow from that instruction to this one. Any suggestions will be highly appreciated.
Initially, simplify the problem by excluding loops and functions with multiple exits, so that you have a function CFG as a single entry and single exit graph.
One (probably simplistic) way would be to first find all its users by doing something like:
llvm::Instruction i = [the register for that LoadInst];
auto users = i->users();
Then using the PostDominatorTree and the getLevel method of the DomTreeNodeBase (I think this was introduced with LLVM 5.0.0, if not available in your version you could use getChildren and perform a BFS traversal), you could filter through those with the highest level number.
I'm not sure what you want to do with loops, but if nothing special, the above should suffice. For dealing with multiple exits from functions you could make use of the mergereturn pass prior to any processing.

How could I insert/remove an edge in LLVM?

Could I insert a new edge by changing its destination, and remove another edge by its source and destination. In other words, could I replace the basic block destination of an edge by another one, to make some modification in the CFG?
I tried getEdge() function in ProfileInfo, but it didn't work:
// to replace the basic block
Bb->getTerminator()->replaceUsesOfWith((*SI), (*rit));
// trying to set the new basic block as a new destination
xx = ProfileInfo::getEdge(Bb,(*rit));
A basic block has a single terminator instruction. However, this terminator can be one of several instructions which are quite different. Some can have multiple edges. So it's not quite as simple as it seems you assume.
What you can do is look at the terminator of a block and modify the instruction to branch to a different destination. This depends on the instruction, and (of course) on your specific needs.

How gdb reconstructs stacktrace for C++?

I have divided the whole question into smaller ones:
What kind of different algorithms GDB is capable to use to reconstruct stacktraces?
How each of the stacktrace reconstruction algorithm works at high level? Advantages and disadvantages?
What kind of meta-information compiler needs to provide in program for each stacktrace reconstruction algorithm to work?
And also corresponding g++ compiler switches that enable/disable particular algorithm?
Speaking Pseudocode, you could call the stack "an array of packed stack frames", where every stack frame is a data structure of variable size you could express like:
template struct stackframe<N> {
uintptr_t contents[N];
#ifndef OMIT_FRAME_POINTER
struct stackframe<> *nextfp;
#endif
void *retaddr;
};
Problem is that every function has a different <N> - frame sizes vary.
The compiler knows frame sizes, and if creating debugging information will usually emit these as part of that. All the debugger then needs to do is to locate the last program counter, look up the function in the symbol table, then use that name to look up the framesize in the debugging information. Add that to the stackpointer and you get to the beginning of the next frame.
If using this method you don't require frame linkage, and backtracing will work just fine even if you use -fomit-frame-pointer. On the other hand, if you have frame linkage, then iterating the stack is just following a linked list - because every framepointer in a new stackframe is initialized by the function prologue code to point to the previous one.
If you have neither frame size information nor framepointers, but still a symbol table, then you can also perform backtracing by a bit of reverse engineering to calculate the framesizes from the actual binary. Start with the program counter, look up the function it belongs to in the symbol table, and then disassemble the function from the start. Isolate all operations between the beginning of the function and the program counter that actually modify the stackpointer (write anything to the stack and/or allocate stackspace). That calculates the frame size for the current function, so subtract that from the stackpointer, and you should (on most architectures) find the last word written to the stack before the function was entered - which is usually the return address into the caller. Re-iterate as necessary.
Finally, you can perform a heuristic analysis of the contents of the stack - isolate all words in the stack that are within executably-mapped segments of the process address space (and thereby could be function offsets aka return addresses), and play a what-if game looking up the memory, disassembling the instruction there and see if it actually is a call instruction of sort, if so whether that really called the 'next' and if you can construct an uninterrupted call sequence from that. This works to a degree even if the binary is completely stripped (although all you could get in that case is a list of return addresses). I don't think GDB employs this technique, but some embedded lowlevel debuggers do. On x86, due to the varying instruction lengths, this is terribly difficult to do because you can't easily "step back" through an instruction stream, but on RISC, where instruction lengths are fixed, e.g. on ARM, this is much simpler.
There are some holes that make simple or even complex/exhaustive implementations of these algorithms fall over sometimes, like tail-recursive functions, inlined code, and so on. The gdb sourcecode might give you some more ideas:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/frame.c
GDB employs a variety of such techniques.