Added support for the fragile ivars provided by

Apple's Objective-C 2.0 runtime.  They are enabled
if the Objective-C runtime has the proper version.

llvm-svn: 123694
This commit is contained in:
Sean Callanan 2011-01-17 23:42:46 +00:00
parent 5caed4e8a8
commit c3a160062d
9 changed files with 135 additions and 14 deletions

View File

@ -289,6 +289,23 @@ public:
GetFunctionAddress (const ConstString &name,
uint64_t &ptr);
//------------------------------------------------------------------
/// [Used by IRForTarget] Get the address of a symbol given nothing
/// but its name.
///
/// @param[in] name
/// The name of the symbol.
///
/// @param[out] ptr
/// The absolute address of the function in the target.
///
/// @return
/// True if the address could be retrieved; false otherwise.
//------------------------------------------------------------------
bool
GetSymbolAddress (const ConstString &name,
uint64_t &ptr);
//------------------------------------------------------------------
/// [Used by CommandObjectExpression] Materialize the entire struct
/// at a given address, which should be aligned as specified by

View File

@ -25,6 +25,7 @@ namespace llvm
namespace lldb_private
{
class Process;
class RecordingMemoryManager;
//----------------------------------------------------------------------
@ -49,10 +50,15 @@ public:
/// The LLVM-friendly target triple for use in initializing the
/// compiler.
///
/// @param[in process
/// If non-NULL, the process to customize the expression for
/// (e.g., by tuning Objective-C runtime support). May be NULL.
///
/// @param[in] expr
/// The expression to be parsed.
//------------------------------------------------------------------
ClangExpressionParser (const char *target_triple,
Process *process,
ClangExpression &expr);
//------------------------------------------------------------------

View File

@ -322,12 +322,9 @@ private:
/// @param[in] llvm_module
/// The module currently being processed.
///
/// @param[in] V
/// @param[in] value
/// The variable.
///
/// @param[in] Store
/// True if the access is a store.
///
/// @return
/// True on success; false otherwise
//------------------------------------------------------------------
@ -335,6 +332,22 @@ private:
MaybeHandleVariable (llvm::Module &llvm_module,
llvm::Value *value);
//------------------------------------------------------------------
/// Handle a single externally-defined symbol
///
/// @param[in] llvm_module
/// The module currently being processed.
///
/// @param[in] symbol
/// The symbol.
///
/// @return
/// True on success; false otherwise
//------------------------------------------------------------------
bool
HandleSymbol (llvm::Module &llvm_module,
llvm::Value *symbol);
//------------------------------------------------------------------
/// Handle all the arguments to a function call
///

View File

@ -452,6 +452,36 @@ ClangExpressionDeclMap::GetFunctionAddress
return true;
}
bool
ClangExpressionDeclMap::GetSymbolAddress
(
const ConstString &name,
uint64_t &ptr
)
{
assert (m_parser_vars.get());
// Back out in all cases where we're not fully initialized
if (m_parser_vars->m_exe_ctx->target == NULL)
return false;
SymbolContextList sc_list;
m_parser_vars->m_exe_ctx->target->GetImages().FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, sc_list);
if (!sc_list.GetSize())
return false;
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(0, sym_ctx);
const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
ptr = sym_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
return true;
}
// Interface for CommandObjectExpression
bool

View File

@ -21,6 +21,7 @@
#include "lldb/Expression/IRToDWARF.h"
#include "lldb/Expression/RecordingMemoryManager.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@ -177,6 +178,7 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
//===----------------------------------------------------------------------===//
ClangExpressionParser::ClangExpressionParser(const char *target_triple,
Process *process,
ClangExpression &expr) :
m_expr(expr),
m_target_triple (),
@ -211,10 +213,18 @@ ClangExpressionParser::ClangExpressionParser(const char *target_triple,
// Setup objective C
m_compiler->getLangOpts().ObjC1 = true;
m_compiler->getLangOpts().ObjC2 = true;
// We need to enable the fragile ABI for things target triples that
// support it.
// m_compiler->getLangOpts().ObjCNonFragileABI = true; // NOT i386
// m_compiler->getLangOpts().ObjCNonFragileABI2 = true; // NOT i386
if (process)
{
if (process->GetObjCLanguageRuntime())
{
if (process->GetObjCLanguageRuntime()->GetRuntimeVersion() == lldb::eAppleObjC_V2)
{
m_compiler->getLangOpts().ObjCNonFragileABI = true; // NOT i386
m_compiler->getLangOpts().ObjCNonFragileABI2 = true; // NOT i386
}
}
}
m_compiler->getLangOpts().ThreadsafeStatics = false;
m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access

View File

@ -214,7 +214,7 @@ ClangFunction::CompileFunction (Stream &errors)
// Okay, now compile this expression
m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), NULL, *this));
num_errors = m_parser->Parse (errors);

View File

@ -253,7 +253,7 @@ ClangUserExpression::Parse (Stream &error_stream,
m_expr_decl_map->WillParse(exe_ctx);
ClangExpressionParser parser(target_triple.GetCString(), *this);
ClangExpressionParser parser(target_triple.GetCString(), exe_ctx.process, *this);
unsigned num_errors = parser.Parse (error_stream);

View File

@ -105,7 +105,7 @@ ClangUtilityFunction::Install (Stream &error_stream,
m_expr_decl_map->WillParse(exe_ctx);
ClangExpressionParser parser(target_triple.GetCString(), *this);
ClangExpressionParser parser(target_triple.GetCString(), exe_ctx.process, *this);
unsigned num_errors = parser.Parse (error_stream);

View File

@ -1069,6 +1069,44 @@ IRForTarget::MaybeHandleVariable (Module &llvm_module, Value *llvm_value_ptr)
return true;
}
bool
IRForTarget::HandleSymbol (Module &llvm_module,
Value *symbol)
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
lldb_private::ConstString name(symbol->getName().str().c_str());
uint64_t symbol_addr;
if (!m_decl_map->GetSymbolAddress (name, symbol_addr))
{
if (log)
log->Printf ("Symbol \"%s\" had no address", name.GetCString());
return false;
}
if (log)
log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), symbol_addr);
const Type *symbol_type = symbol->getType();
const IntegerType *intptr_ty = Type::getIntNTy(llvm_module.getContext(),
(llvm_module.getPointerSize() == Module::Pointer64) ? 64 : 32);
Constant *symbol_addr_int = ConstantInt::get(intptr_ty, symbol_addr, false);
Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
if (log)
log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
symbol->replaceAllUsesWith(symbol_addr_ptr);
return true;
}
bool
IRForTarget::MaybeHandleCallArguments (Module &llvm_module, CallInst *Old)
{
@ -1250,9 +1288,16 @@ IRForTarget::ResolveExternals (Module &llvm_module, Function &llvm_function)
(*global).getName().str().c_str(),
DeclForGlobalValue(llvm_module, global));
if (DeclForGlobalValue(llvm_module, global) &&
!MaybeHandleVariable (llvm_module, global))
return false;
if ((*global).getName().str().find("OBJC_IVAR") == 0)
{
if (!HandleSymbol(llvm_module, global))
return false;
}
else if (DeclForGlobalValue(llvm_module, global))
{
if (!MaybeHandleVariable (llvm_module, global))
return false;
}
}
return true;