[llvm-commits] [llvm] r157505 - /llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Bill Wendling isanbard at gmail.com
Mon May 28 22:16:26 PDT 2012


If I library allows information to be available outside of it, but doesn't give that code write permissions, then that would cause a failure.

This is what a linkedit segment is:

-seglinkedit
              Create  the  link edit segment, named ``__LINKEDIT'' (this is the default).  This segment con-
              tains all the link edit information (relocation information, symbol table, string table, etc.)
              in  the object file.  If the segment protection for this segment is not specified, the initial
              protection is not writable.  This can only be specified when  the  output  file  type  is  not
              MH_OBJECT  and MH_PRELOAD output file types.  To get at the contents of this section, the Mach
              header and load commands must be parsed from the link editor defined symbols  like  `__mh_exe-
              cute_header' (see Mach-O(5)).

More details here:

	http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

-bw


On May 28, 2012, at 8:56 PM, Nick Lewycky wrote:

> Bill Wendling wrote:
>> Author: void
>> Date: Fri May 25 18:55:00 2012
>> New Revision: 157505
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=157505&view=rev
>> Log:
>> The llvm_gcda_increment_indirect_counter function writes to the arguments that
>> are passed in. However, those arguments may be in a write-protected area, as far
>> as the runtime library is concerned.
> 
> I don't understand how this can happen. The arguments are chosen by the instrumentation pass and they point to writable globals.
> 
> For instance, the data could be placed into
>> a 'linkedit' section, which isn't writable.
> 
> I'm not familiar with 'linkedit'. Is the problem here an issue of the linkage type? Or is the global getting marked isConstant=true somehow?
> 
> Emit the code from
>> llvm_gcda_increment_indirect_counter directly into the function instead.
> 
> That can't be right, you're just inlining the function. The arguments would still be in a read-only area. What's going on?
> 
> Nick
> 
>> 
>> Note: The code for this is ugly, and can lead to bloat. We should look into
>> simplifying this code instead of having all of these branches.
>> 
>> <rdar://problem/11181370>
>> 
>> Modified:
>>     llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
>> 
>> Modified: llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp?rev=157505&r1=157504&r2=157505&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp Fri May 25 18:55:00 2012
>> @@ -70,7 +70,9 @@
>> 
>>      // Get pointers to the functions in the runtime library.
>>      Constant *getStartFileFunc();
>> -    Constant *getIncrementIndirectCounterFunc();
>> +    void incrementIndirectCounter(IRBuilder<>  &Builder, BasicBlock *Exit,
>> +                                  GlobalVariable *EdgeState,
>> +                                  Value *CounterPtrArray);
>>      Constant *getEmitFunctionFunc();
>>      Constant *getEmitArcsFunc();
>>      Constant *getEndFileFunc();
>> @@ -501,16 +503,17 @@
>>          }
>>          for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
>>            // call runtime to perform increment
>> -          BasicBlock::iterator InsertPt =
>> -            ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
>> +          BasicBlock *BB = ComplexEdgeSuccs[i+1];
>> +          BasicBlock::iterator InsertPt = BB->getFirstInsertionPt();
>> +          BasicBlock *Split = BB->splitBasicBlock(InsertPt);
>> +          InsertPt = BB->getFirstInsertionPt();
>>            IRBuilder<>  Builder(InsertPt);
>>            Value *CounterPtrArray =
>>              Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
>>                                                 i * ComplexEdgePreds.size());
>> -          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
>> -                              EdgeState, CounterPtrArray);
>> -          // clear the predecessor number
>> -          Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
>> +
>> +          // Build code to increment the counter.
>> +          incrementIndirectCounter(Builder, Split, EdgeState, CounterPtrArray);
>>          }
>>        }
>>      }
>> @@ -573,14 +576,52 @@
>>    return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
>>  }
>> 
>> -Constant *GCOVProfiler::getIncrementIndirectCounterFunc() {
>> -  Type *Args[] = {
>> -    Type::getInt32PtrTy(*Ctx),                  // uint32_t *predecessor
>> -    Type::getInt64PtrTy(*Ctx)->getPointerTo(),  // uint64_t **state_table_row
>> -  };
>> -  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
>> -                                              Args, false);
>> -  return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy);
>> +/// incrementIndirectCounter - Emit code that increments the indirect
>> +/// counter. The code is meant to copy the llvm_gcda_increment_indirect_counter
>> +/// function, but because it's inlined into the function, we don't have to worry
>> +/// about the runtime library possibly writing into a protected area.
>> +void GCOVProfiler::incrementIndirectCounter(IRBuilder<>  &Builder,
>> +                                            BasicBlock *Exit,
>> +                                            GlobalVariable *EdgeState,
>> +                                            Value *CounterPtrArray) {
>> +  Type *Int64Ty = Type::getInt64Ty(*Ctx);
>> +  ConstantInt *NegOne = ConstantInt::get(Type::getInt32Ty(*Ctx), 0xffffffff);
>> +
>> +  // Create exiting blocks.
>> +  BasicBlock *InsBB = Builder.GetInsertBlock();
>> +  Function *Fn = InsBB->getParent();
>> +  BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn, Exit);
>> +  BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn, Exit);
>> +
>> +  // uint32_t pred = *EdgeState;
>> +  // if (pred == 0xffffffff) return;
>> +  Value *Pred = Builder.CreateLoad(EdgeState, "predecessor");
>> +  Value *Cond = Builder.CreateICmpEQ(Pred, NegOne);
>> +  InsBB->getTerminator()->eraseFromParent();
>> +  BranchInst::Create(Exit, PredNotNegOne, Cond, InsBB);
>> +
>> +  Builder.SetInsertPoint(PredNotNegOne);
>> +
>> +  // uint64_t *counter = CounterPtrArray[pred];
>> +  // if (!counter) return;
>> +  Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty);
>> +  Value *GEP = Builder.CreateGEP(CounterPtrArray, ZExtPred);
>> +  Value *Counter = Builder.CreateLoad(GEP, "counter");
>> +  Cond = Builder.CreateICmpEQ(Counter,
>> +                              Constant::getNullValue(Type::getInt64PtrTy(*Ctx, 0)));
>> +  Builder.CreateCondBr(Cond, Exit, CounterEnd);
>> +
>> +  Builder.SetInsertPoint(CounterEnd);
>> +
>> +  // ++*counter;
>> +  Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
>> +                                 ConstantInt::get(Int64Ty, 1));
>> +  Builder.CreateStore(Add, Counter);
>> +  Builder.CreateBr(Exit);
>> +
>> +  // Clear the predecessor number
>> +  Builder.SetInsertPoint(Exit->getFirstInsertionPt());
>> +  Builder.CreateStore(NegOne, EdgeState);
>>  }
>> 
>>  Constant *GCOVProfiler::getEmitFunctionFunc() {
>> @@ -588,8 +629,7 @@
>>      Type::getInt32Ty(*Ctx),    // uint32_t ident
>>      Type::getInt8PtrTy(*Ctx),  // const char *function_name
>>    };
>> -  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
>> -                                              Args, false);
>> +  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
>>    return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
>>  }
>> 
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>> 
> 





More information about the llvm-commits mailing list