/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * List all methods in all concrete classes in a DEX file.
 */
#include "libdex/DexFile.h"
#include "libdex/DexClass.h"
#include "libdex/DexProto.h"
#include "libdex/SysUtil.h"
#include "libdex/CmdUtils.h"

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <assert.h>

static const char* gProgName = "dexlist";

/*
 * Return a newly-allocated string for the "dot version" of the class
 * name for the given type descriptor. That is, The initial "L" and
 * final ";" (if any) have been removed and all occurrences of '/'
 * have been changed to '.'.
 */
static char* descriptorToDot(const char* str)
{
    size_t at = strlen(str);
    char* newStr;

    if (str[0] == 'L') {
        assert(str[at - 1] == ';');
        at -= 2; /* Two fewer chars to copy. */
        str++; /* Skip the 'L'. */
    }

    newStr = malloc(at + 1); /* Add one for the '\0'. */
    newStr[at] = '\0';

    while (at > 0) {
        at--;
        newStr[at] = (str[at] == '/') ? '.' : str[at];
    }

    return newStr;
}

/*
 * Position table callback; we just want to catch the number of the
 * first line in the method, which *should* correspond to the first
 * entry from the table.  (Could also use "min" here.)
 */
static int positionsCallback(void* cnxt, u4 address, u4 lineNum)
{
    int* pFirstLine = (int*) cnxt;
    if (*pFirstLine == -1)
        *pFirstLine = lineNum;
    return 0;
}


/*
 * Dump a method.
 */
void dumpMethod(DexFile* pDexFile, const char* fileName,
        const DexMethod* pDexMethod, int i)
{
    const DexMethodId* pMethodId;
    const DexCode* pCode;
    const char* classDescriptor;
    const char* methodName;
    int firstLine;

    /* abstract and native methods don't get listed */
    if (pDexMethod->codeOff == 0)
        return;

    pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
    methodName = dexStringById(pDexFile, pMethodId->nameIdx);

    classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);

    pCode = dexGetCode(pDexFile, pDexMethod);
    assert(pCode != NULL);

    /*
     * If the filename is empty, then set it to something printable
     * so that it is easier to parse.
     *
     * TODO: A method may override its class's default source file by
     * specifying a different one in its debug info. This possibility
     * should be handled here.
     */
    if (fileName == NULL || fileName[0] == 0) {
        fileName = "(none)";
    }

    firstLine = -1;
    dexDecodeDebugInfo(pDexFile, pCode, classDescriptor, pMethodId->protoIdx,
        pDexMethod->accessFlags, positionsCallback, NULL, &firstLine);

    char* className = descriptorToDot(classDescriptor);
    char* desc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId);
    u4 insnsOff = pDexMethod->codeOff + offsetof(DexCode, insns);

    printf("0x%08x %d %s %s %s %s %d\n",
        insnsOff, pCode->insnsSize * 2,
        className, methodName, desc,
        fileName, firstLine);

    free(desc);
    free(className);
}

/*
 * Run through all direct and virtual methods in the class.
 */
void dumpClass(DexFile* pDexFile, int idx)
{
    const DexClassDef* pClassDef;
    DexClassData* pClassData;
    const u1* pEncodedData;
    const char* fileName;
    int i;

    pClassDef = dexGetClassDef(pDexFile, idx);
    pEncodedData = dexGetClassData(pDexFile, pClassDef);
    pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL);

    if (pClassData == NULL) {
        fprintf(stderr, "Trouble reading class data\n");
        return;
    }
    
    if (pClassDef->sourceFileIdx == 0xffffffff) {
        fileName = NULL;
    } else {
        fileName = dexStringById(pDexFile, pClassDef->sourceFileIdx);
    }
    
    /* 
     * TODO: Each class def points at a sourceFile, so maybe that
     * should be printed out. However, this needs to be coordinated
     * with the tools that parse this output.
     */
       
    for (i = 0; i < (int) pClassData->header.directMethodsSize; i++) {
        dumpMethod(pDexFile, fileName, &pClassData->directMethods[i], i);
    }

    for (i = 0; i < (int) pClassData->header.virtualMethodsSize; i++) {
        dumpMethod(pDexFile, fileName, &pClassData->virtualMethods[i], i);
    }

    free(pClassData);
}

/*
 * Process a file.
 *
 * Returns 0 on success.
 */
int process(const char* fileName)
{
    DexFile* pDexFile = NULL;
    MemMapping map;
    bool mapped = false;
    int result = -1;
    UnzipToFileResult utfr;

    utfr = dexOpenAndMap(fileName, NULL, &map, true);
    if (utfr != kUTFRSuccess) {
        if (utfr == kUTFRNoClassesDex) {
            /* no classes.dex in the APK; pretend we succeeded */
            result = 0;
            goto bail;
        }
        fprintf(stderr, "Unable to process '%s'\n", fileName);
        goto bail;
    }
    mapped = true;

    pDexFile = dexFileParse(map.addr, map.length, kDexParseDefault);
    if (pDexFile == NULL) {
        fprintf(stderr, "Warning: DEX parse failed for '%s'\n", fileName);
        goto bail;
    }

    printf("#%s\n", fileName);

    int i;
    for (i = 0; i < (int) pDexFile->pHeader->classDefsSize; i++) {
        dumpClass(pDexFile, i);
    }

    result = 0;

bail:
    if (mapped)
        sysReleaseShmem(&map);
    if (pDexFile != NULL)
        dexFileFree(pDexFile);
    return result;
}


/*
 * Show usage.
 */
void usage(void)
{
    fprintf(stderr, "Copyright (C) 2007 The Android Open Source Project\n\n");
    fprintf(stderr, "%s: dexfile [dexfile2 ...]\n", gProgName);
    fprintf(stderr, "\n");
}

/*
 * Parse args.
 */
int main(int argc, char* const argv[])
{
    int result = 0;
    int i;

    if (argc < 2) {
        fprintf(stderr, "%s: no file specified\n", gProgName);
        usage();
        return 2;
    }

    /*
     * Run through the list of files.  If one of them fails we contine on,
     * only returning a failure at the end.
     */
    for (i = 1; i < argc; i++)
        result |= process(argv[i]);

    return result;
}

