//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>

#if defined(__APPLE__)
#include <LLDB/LLDB.h>
#else
#include "LLDB/SBBlock.h"
#include "LLDB/SBCompileUnit.h"
#include "LLDB/SBDebugger.h"
#include "LLDB/SBFunction.h"
#include "LLDB/SBModule.h"
#include "LLDB/SBStream.h"
#include "LLDB/SBSymbol.h"
#include "LLDB/SBTarget.h"
#include "LLDB/SBThread.h"
#include "LLDB/SBProcess.h"
#endif

#include <string>

using namespace lldb;

//----------------------------------------------------------------------
// This quick sample code shows how to create a debugger instance and
// create an "i386" executable target. Then we can lookup the executable
// module and resolve a file address into a section offset address,
// and find all symbol context objects (if any) for that address: 
// compile unit, function, deepest block, line table entry and the 
// symbol.
//
// To build the program, type (while in this directory):
//
//    $ make
//
// then (for example):
//
//    $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/svn/ToT/build/Debug ./a.out executable_path file_address
//----------------------------------------------------------------------
class LLDBSentry
{
public:
    LLDBSentry() {
        // Initialize LLDB
        SBDebugger::Initialize();
    }
    ~LLDBSentry() {
        // Terminate LLDB
        SBDebugger::Terminate();
    }
};

static struct option g_long_options[] = 
{
    { "help",       no_argument,        NULL, 'h' },
    { "verbose",    no_argument,        NULL, 'v' },
	{ "arch",		required_argument,	NULL, 'a' },
	{ "platform",   required_argument,	NULL, 'p' },
	{ NULL,			0,					NULL,  0  }
};

#define PROGRAM_NAME "lldb-lookup"
void
usage ()
{
    puts (
    "NAME\n"
    "    " PROGRAM_NAME " -- symbolicate addresses using lldb.\n"
    "\n"
    "SYNOPSIS\n"
    "    " PROGRAM_NAME " [[--arch=<ARCH>] [--platform=<PLATFORM>] [--verbose] [--help] --] <PATH> <ADDRESS> [<ADDRESS>....]\n"
    "\n"
    "DESCRIPTION\n"
    "    Loads the executable pointed to by <PATH> and looks up and <ADDRESS>\n"
    "    arguments\n"
    "\n"
    "EXAMPLE\n"
    "   " PROGRAM_NAME " --arch=x86_64 -- /usr/lib/dyld 0x100000000\n"
    );
    exit(0);
}
int
main (int argc, char const *argv[])
{
    // Use a sentry object to properly initialize/terminate LLDB.
    LLDBSentry sentry;
    
    SBDebugger debugger (SBDebugger::Create());
    
    // Create a debugger instance so we can create a target
    if (!debugger.IsValid())
        fprintf (stderr, "error: failed to create a debugger object\n");
    
    bool show_usage = false;
    bool verbose = false;
    const char *arch = NULL;
    const char *platform = NULL;
    std::string short_options("h?");
    for (const struct option *opt = g_long_options; opt->name; ++opt)
    {
        if (isprint(opt->val))
        {
            short_options.append(1, (char)opt->val);
            switch (opt->has_arg)
            {
            case no_argument:
                break;
            case required_argument:
                short_options.append(1, ':'); 
                break;
            case optional_argument:
                short_options.append(2, ':'); 
                break;
            }   
        }        
    }
#ifdef __GLIBC__
    optind = 0;
#else
    optreset = 1;
    optind = 1;
#endif
    char ch;
	while ((ch = getopt_long_only(argc, (char * const *)argv, short_options.c_str(), g_long_options, 0)) != -1)
	{
		switch (ch) 
		{
        case 0:
            break;

		case 'a':
		    if (arch != NULL)
		    {
                fprintf (stderr, "error: the --arch option can only be specified once\n");
                exit(1);
		    }
            arch = optarg;
			break;

        case 'p':
            platform = optarg;
            break;            
            
        case 'v':
            verbose = true;
            break;

		case 'h':
		case '?':
		default:
			show_usage = true;
			break;
		}
	}
	argc -= optind;
	argv += optind;

    if (show_usage || argc < 2)
        usage();

    int arg_idx = 0;
    // The first argument is the file path we want to look something up in
    const char *exe_file_path = argv[arg_idx];
    const char *addr_cstr;
    const bool add_dependent_libs = false;
    SBError error;
    SBStream strm;
    strm.RedirectToFileHandle (stdout, false);

    while ((addr_cstr = argv[++arg_idx]) != NULL)
    {
        // The second argument in the address that we want to lookup
        lldb::addr_t file_addr = strtoull (addr_cstr, NULL, 0);

        // Create a target using the executable.
        SBTarget target = debugger.CreateTarget (exe_file_path,
                                                 arch,
                                                 platform,
                                                 add_dependent_libs,
                                                 error);
        if (!error.Success())
        {
            fprintf (stderr, "error: %s\n", error.GetCString());
            exit(1);
        }

        printf ("%sLooking up 0x%llx in '%s':\n", (arg_idx > 1) ? "\n" : "", file_addr, exe_file_path);

        if (target.IsValid())
        {
            // Find the executable module so we can do a lookup inside it
            SBFileSpec exe_file_spec (exe_file_path, true);
            SBModule module (target.FindModule (exe_file_spec));
        
            // Take a file virtual address and resolve it to a section offset
            // address that can be used to do a symbol lookup by address
            SBAddress addr = module.ResolveFileAddress (file_addr);
            bool success = addr.IsValid() && addr.GetSection().IsValid();
            if (success)
            {
                // We can resolve a section offset address in the module
                // and only ask for what we need. You can logical or together
                // bits from the SymbolContextItem enumeration found in 
                // lldb-enumeration.h to request only what you want. Here we
                // are asking for everything. 
                //
                // NOTE: the less you ask for, the less LLDB will parse as
                // LLDB does partial parsing on just about everything.
                SBSymbolContext sc (module.ResolveSymbolContextForAddress (addr, eSymbolContextEverything));

                strm.Printf ("    Address: %s + 0x%llx\n    Summary: ", addr.GetSection().GetName (), addr.GetOffset());
                addr.GetDescription (strm);
                strm.Printf ("\n");
                if (verbose)
                    sc.GetDescription (strm);                        
            }
            else
            {
                printf ("error: 0x%llx does not resolve to a valid file address in '%s'\n", file_addr, exe_file_path);
            }
        }
    }

    return 0;
}

