forked from OSchip/llvm-project
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:
parent
5caed4e8a8
commit
c3a160062d
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue