/*
 * File elf.c - processing of ELF files
 *
 * Copyright (C) 1996, Eric Youngdale.
 *		 1999-2004 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif

#include "debugger.h"

#if defined(__svr4__) || defined(__sun)
#define __ELF__
#endif

#ifdef HAVE_ELF_H
# include <elf.h>
#endif
#ifdef HAVE_SYS_ELF32_H
# include <sys/elf32.h>
#endif
#ifdef HAVE_SYS_EXEC_ELF_H
# include <sys/exec_elf.h>
#endif
#if !defined(DT_NUM)
# if defined(DT_COUNT)
#  define DT_NUM DT_COUNT
# else
/* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */
#  define DT_NUM 24
# endif
#endif
#ifdef HAVE_LINK_H
# include <link.h>
#endif
#ifdef HAVE_SYS_LINK_H
# include <sys/link.h>
#endif

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

typedef struct tagELF_DBG_INFO
{
    void *elf_addr;
} ELF_DBG_INFO;

#ifdef __ELF__

/*
 * Walk through the entire symbol table and add any symbols we find there.
 * This can be used in cases where we have stripped ELF shared libraries,
 * or it can be used in cases where we have data symbols for which the address
 * isn't encoded in the stabs.
 *
 * This is all really quite easy, since we don't have to worry about line
 * numbers or local data variables.
 */
static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, const char* addr,
				  void *load_addr, const Elf32_Shdr* symtab,
				  const Elf32_Shdr* strtab)
{
    const char*         curfile = NULL;
    struct name_hash*   curr_sym = NULL;
    int		        flags;
    int		        i;
    DBG_VALUE           new_value;
    int		        nsym;
    const char*         strp;
    const char*         symname;
    const Elf32_Sym*    symp;

    symp = (Elf32_Sym *)(addr + symtab->sh_offset);
    nsym = symtab->sh_size / sizeof(*symp);
    strp = (char *)(addr + strtab->sh_offset);

    for (i = 0; i < nsym; i++, symp++)
    {
        /*
         * Ignore certain types of entries which really aren't of that much
         * interest.
         */
        if (ELF32_ST_TYPE(symp->st_info) == STT_SECTION || 
            symp->st_shndx == SHN_UNDEF)
        {
            continue;
        }

        symname = strp + symp->st_name;

        /*
         * Save the name of the current file, so we have a way of tracking
         * static functions/data.
         */
        if (ELF32_ST_TYPE(symp->st_info) == STT_FILE)
        {
            curfile = symname;
            continue;
        }

        new_value.type = NULL;
        new_value.addr.seg = 0;
        new_value.addr.off = (unsigned long)load_addr + symp->st_value;
        new_value.cookie = DV_TARGET;
        flags = SYM_WINE | ((ELF32_ST_TYPE(symp->st_info) == STT_FUNC)
                            ? SYM_FUNC : SYM_DATA);
        if (ELF32_ST_BIND(symp->st_info) == STB_GLOBAL)
            curr_sym = DEBUG_AddSymbol(symname, &new_value, NULL, flags);
        else
            curr_sym = DEBUG_AddSymbol(symname, &new_value, curfile, flags);

        /*
         * Record the size of the symbol.  This can come in handy in
         * some cases.  Not really used yet, however.
         */
        if (symp->st_size != 0)
            DEBUG_SetSymbolSize(curr_sym, symp->st_size);
    }

    return TRUE;
}

/*
 * Loads the symbolic information from ELF module stored in 'filename'
 * the module has been loaded at 'load_offset' address, so symbols' address
 * relocation is performed
 * returns
 *	-1 if the file cannot be found/opened
 *	0 if the file doesn't contain symbolic info (or this info cannot be
 *	read or parsed)
 *	1 on success
 */
enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
{
    enum DbgInfoLoad    dil = DIL_ERROR;
    char*	        addr = (char*)0xffffffff;
    int		        fd = -1;
    struct stat	        statbuf;
    const Elf32_Ehdr*   ehptr;
    const Elf32_Shdr*   spnt;
    const char*	        shstrtab;
    int	       	        i;
    int		        stabsect, stabstrsect, debugsect;
    
    if (module->type != DMT_ELF || !module->elf_dbg_info)
    {
	WINE_ERR("Bad elf module '%s'\n", module->module_name);
	return DIL_ERROR;
    }

    /* check that the file exists, and that the module hasn't been loaded yet */
    if (stat(module->module_name, &statbuf) == -1) goto leave;
    if (S_ISDIR(statbuf.st_mode)) goto leave;

    /*
     * Now open the file, so that we can mmap() it.
     */
    if ((fd = open(module->module_name, O_RDONLY)) == -1) goto leave;

    dil = DIL_NOINFO;
    /*
     * Now mmap() the file.
     */
    addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (addr == (char*)0xffffffff) goto leave;

    /*
     * Next, we need to find a few of the internal ELF headers within
     * this thing.  We need the main executable header, and the section
     * table.
     */
    ehptr = (Elf32_Ehdr*)addr;
    spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);

    stabsect = stabstrsect = debugsect = -1;

    for (i = 0; i < ehptr->e_shnum; i++)
    {
	if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
	    stabsect = i;
	if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
	    stabstrsect = i;
	if (strcmp(shstrtab + spnt[i].sh_name, ".debug_info") == 0)
	    debugsect = i;
    }

    if (stabsect != -1 && stabstrsect != -1)
    {
        /*
         * OK, now just parse all of the stabs.
         */
        if (DEBUG_ParseStabs(addr,
                             module->elf_dbg_info->elf_addr,
                             spnt[stabsect].sh_offset,
                             spnt[stabsect].sh_size,
                             spnt[stabstrsect].sh_offset,
                             spnt[stabstrsect].sh_size))
        {
            dil = DIL_LOADED;
        }
        else
        {
            dil = DIL_ERROR;
            WINE_WARN("Couldn't read correctly read stabs\n");
            goto leave;
        }
    }
    else if (debugsect != -1)
    {
        /* Dwarf 2 debug information */
        dil = DIL_NOT_SUPPORTED;
    }
    /* now load dynamic symbol info */
    for (i = 0; i < ehptr->e_shnum; i++)
    {
	if ((strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0) &&
	    (spnt[i].sh_type == SHT_SYMTAB))
	    DEBUG_ProcessElfSymtab(module, addr, module->elf_dbg_info->elf_addr,
				   spnt + i, spnt + spnt[i].sh_link);

	if ((strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0) &&
	    (spnt[i].sh_type == SHT_DYNSYM))
	    DEBUG_ProcessElfSymtab(module, addr, module->elf_dbg_info->elf_addr,
				   spnt + i, spnt + spnt[i].sh_link);
    }

leave:
    if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
    if (fd != -1) close(fd);

    return dil;
}

static unsigned is_dt_flag_valid(unsigned d_tag)
{
#ifndef DT_PROCNUM
#define DT_PROCNUM 0
#endif
#ifndef DT_EXTRANUM
#define DT_EXTRANUM 0
#endif
    return (d_tag >= 0 && d_tag < DT_NUM + DT_PROCNUM + DT_EXTRANUM)
#if defined(DT_LOOS) && defined(DT_HIOS)
        || (d_tag >= DT_LOOS && d_tag < DT_HIOS)
#endif
#if defined(DT_LOPROC) && defined(DT_HIPROC)
        || (d_tag >= DT_LOPROC && d_tag < DT_HIPROC)
#endif
        ;
}

/*
 * Loads the information for ELF module stored in 'filename'
 * the module has been loaded at 'load_offset' address
 * returns
 *	-1 if the file cannot be found/opened
 *	0 if the file doesn't contain symbolic info (or this info cannot be
 *	read or parsed)
 *	1 on success
 */
static enum DbgInfoLoad DEBUG_ProcessElfFile(HANDLE hProcess,
                                             const char* filename,
					     void *load_offset,
					     struct elf_info* elf_info)
{
    static const unsigned char elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
    enum DbgInfoLoad    dil = DIL_ERROR;
    const char*	        addr = (char*)0xffffffff;
    int		        fd = -1;
    struct stat	        statbuf;
    const Elf32_Ehdr*   ehptr;
    const Elf32_Shdr*   spnt;
    const Elf32_Phdr*	ppnt;
    const char*         shstrtab;
    int	       	        i;
    DWORD	        delta;

    WINE_TRACE("Processing elf file '%s' at %p\n", filename, load_offset);

    /* check that the file exists, and that the module hasn't been loaded yet */
    if (stat(filename, &statbuf) == -1) goto leave;

    /*
     * Now open the file, so that we can mmap() it.
     */
    if ((fd = open(filename, O_RDONLY)) == -1) goto leave;

    /*
     * Now mmap() the file.
     */
    addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (addr == (char*)-1) goto leave;

    dil = DIL_NOINFO;

    /*
     * Next, we need to find a few of the internal ELF headers within
     * this thing.  We need the main executable header, and the section
     * table.
     */
    ehptr = (Elf32_Ehdr*)addr;
    if (memcmp(ehptr->e_ident, elf_signature, sizeof(elf_signature))) goto leave;

    spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);

    /* if non relocatable ELF, then remove fixed address from computation
     * otherwise, all addresses are zero based
     */
    delta = (load_offset == 0) ? ehptr->e_entry : 0;

    /* grab size of module once loaded in memory */
    ppnt = (Elf32_Phdr*)(addr + ehptr->e_phoff);
    elf_info->size = 0;
    for (i = 0; i < ehptr->e_phnum; i++)
    {
	if (ppnt[i].p_type != PT_LOAD) continue;
        elf_info->size += (ppnt[i].p_align <= 1) ? ppnt[i].p_memsz :
            (ppnt[i].p_memsz + ppnt[i].p_align - 1) & ~(ppnt[i].p_align - 1);
    }

    for (i = 0; i < ehptr->e_shnum; i++)
    {
	if (strcmp(shstrtab + spnt[i].sh_name, ".dynamic") == 0 &&
	    spnt[i].sh_type == SHT_DYNAMIC)
        {
	    if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
            {
                Elf32_Dyn       dyn;
                char*           ptr = (char*)spnt[i].sh_addr;
                unsigned long   len;

                do
                {
                    if (!ReadProcessMemory(hProcess, ptr, &dyn, sizeof(dyn), &len) ||
                        len != sizeof(dyn) || !is_dt_flag_valid(dyn.d_tag))
                        dyn.d_tag = DT_NULL;
                    ptr += sizeof(dyn);
                } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
                if (dyn.d_tag == DT_NULL)
                {
                    dil = DIL_ERROR;
                    goto leave;
                }
                elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
            }
	}
    }

    elf_info->segments[0] = elf_info->segments[1] = elf_info->segments[2] = 0;
    if (elf_info->flags & ELF_INFO_PATH)
    {
        strncpy(elf_info->elf_path, filename, elf_info->elf_path_len);
        elf_info->elf_path[elf_info->elf_path_len - 1] = '\0';
    }

    elf_info->load_addr = (load_offset == 0) ? (void *)ehptr->e_entry : load_offset;

    if (elf_info->flags & ELF_INFO_MODULE)
    {
        DBG_MODULE* module;

        module = DEBUG_AddModule(filename, DMT_ELF, elf_info->load_addr, elf_info->size, 0);
        if (module)
        {
            if ((module->elf_dbg_info = DBG_alloc(sizeof(ELF_DBG_INFO))) == NULL) 
            {
                WINE_ERR("OOM\n");
                exit(0);
            }
            module->elf_dbg_info->elf_addr = load_offset;
            module->dil = dil = DEBUG_LoadElfStabs(module);
        }
        else dil = DIL_ERROR;
    }

leave:
    if (addr != (char*)0xffffffff) munmap((void*)addr, statbuf.st_size);
    if (fd != -1) close(fd);

    return dil;
}

static enum DbgInfoLoad DEBUG_ProcessElfFileFromPath(HANDLE hProcess,
                                                     const char * filename,
						     void *load_offset,
						     const char* path,
                                                     struct elf_info* elf_info)
{
    enum DbgInfoLoad	dil = DIL_ERROR;
    char                *s, *t, *fn;
    char*	        paths = NULL;

    if (!path) return dil;

    for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) 
    {
	t = strchr(s, ':');
	if (t) *t = '\0';
	fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
	if (!fn) break;
	strcpy(fn, s );
	strcat(fn, "/");
	strcat(fn, filename);
	dil = DEBUG_ProcessElfFile(hProcess, fn, load_offset, elf_info);
	DBG_free(fn);
	if (dil != DIL_ERROR) break;
	s = (t) ? (t+1) : NULL;
    }

    DBG_free(paths);
    return dil;
}

static enum DbgInfoLoad DEBUG_ProcessElfObject(HANDLE hProcess,
                                               const char* filename,
                                               void *load_offset,
					       struct elf_info* elf_info)
{
   enum DbgInfoLoad	dil = DIL_ERROR;

   if (filename == NULL || *filename == '\0') return DIL_ERROR;
   if (DEBUG_FindModuleByName(filename, DMT_ELF))
   {
       assert(!(elf_info->flags & ELF_INFO_PATH));
       return DIL_LOADED;
   }

   if (strstr(filename, "libstdc++")) return DIL_ERROR; /* We know we can't do it */
   dil = DEBUG_ProcessElfFile(hProcess, filename, load_offset, elf_info);
   /* if relative pathname, try some absolute base dirs */
   if (dil == DIL_ERROR && !strchr(filename, '/'))
   {
       dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset, 
                                          getenv("PATH"), elf_info);
       if (dil == DIL_ERROR)
           dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset,
                                              getenv("LD_LIBRARY_PATH"), elf_info);
       if (dil == DIL_ERROR)
           dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset,
                                              getenv("WINEDLLPATH"), elf_info);
   }

   DEBUG_ReportDIL(dil, "ELF", filename, load_offset);

   return dil;
}

static	BOOL	DEBUG_WalkList(const struct r_debug* dbg_hdr)
{
    void*               lm_addr;
    struct link_map     lm;
    char		bufstr[256];
    struct elf_info     elf_info;

    elf_info.flags = ELF_INFO_MODULE;
    /*
     * Now walk the linked list.  In all known ELF implementations,
     * the dynamic loader maintains this linked list for us.  In some
     * cases the first entry doesn't appear with a name, in other cases it
     * does.
     */
    for (lm_addr = (void *)dbg_hdr->r_map; lm_addr; lm_addr = (void *)lm.l_next)
    {
	if (!DEBUG_READ_MEM_VERBOSE(lm_addr, &lm, sizeof(lm)))
	    return FALSE;

	if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
	    lm.l_name != NULL &&
	    DEBUG_READ_MEM_VERBOSE((void*)lm.l_name, bufstr, sizeof(bufstr))) 
        {
	    bufstr[sizeof(bufstr) - 1] = '\0';
	    DEBUG_ProcessElfObject(DEBUG_CurrProcess->handle, bufstr, 
                                   (void *)lm.l_addr, &elf_info);
	}
    }

    return TRUE;
}

static BOOL DEBUG_RescanElf(void)
{
    struct r_debug        dbg_hdr;

    if (DEBUG_CurrProcess &&
	DEBUG_READ_MEM_VERBOSE((void*)DEBUG_CurrProcess->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
    {
        switch (dbg_hdr.r_state) 
        {
        case RT_CONSISTENT:
            DEBUG_WalkList(&dbg_hdr);
            DEBUG_CheckDelayedBP();
            break;
        case RT_ADD:
            break;
        case RT_DELETE:
            /* FIXME: this is not currently handled */
            break;
        }
    }
    return FALSE;
}

/******************************************************************
 *		DEBUG_ReadWineLoaderDbgInfo
 *
 * Try to find a decent wine executable which could have loader the debuggee
 */
enum DbgInfoLoad	DEBUG_ReadWineLoaderDbgInfo(HANDLE hProcess, struct elf_info* elf_info)
{
    const char*         ptr;
    enum DbgInfoLoad    dil;

    /* All binaries are loaded with WINELOADER (if run from tree) or by the
     * main executable (either wine-kthread or wine-pthread)
     * Note: the heuristic used to know whether we need to load wine-pthread or
     * wine-kthread is not 100% safe
     */
    elf_info->flags |= ELF_INFO_DEBUG_HEADER;
    if ((ptr = getenv("WINELOADER")))
        dil = DEBUG_ProcessElfObject(hProcess, ptr, 0, elf_info);
    else 
    {
        if ((dil = DEBUG_ProcessElfObject(hProcess, "wine-kthread", 0, elf_info)) == DIL_ERROR)
            dil = DEBUG_ProcessElfObject(hProcess, "wine-pthread", 0, elf_info);
    }
    return dil;
}

/******************************************************************
 *		DEBUG_SetElfSoLoadBreakpoint
 *
 * Sets a breakpoint to handle .so loading events, so we can add debug info
 * on the fly
 */
BOOL    DEBUG_SetElfSoLoadBreakpoint(const struct elf_info* elf_info)
{
    struct r_debug      dbg_hdr;
    
    /*
     * OK, now dig into the actual tables themselves.
     */
    if (!DEBUG_READ_MEM_VERBOSE((void*)elf_info->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
        return FALSE;

    assert(!DEBUG_CurrProcess->dbg_hdr_addr);
    DEBUG_CurrProcess->dbg_hdr_addr = elf_info->dbg_hdr_addr;

    if (dbg_hdr.r_brk)
    {
        DBG_VALUE	value;

        WINE_TRACE("Setting up a breakpoint on r_brk(%lx)\n", 
                   (unsigned long)dbg_hdr.r_brk);

        DEBUG_SetBreakpoints(FALSE);
        value.type = NULL;
        value.cookie = DV_TARGET;
        value.addr.seg = 0;
        value.addr.off = (DWORD)dbg_hdr.r_brk;
        DEBUG_AddBreakpoint(&value, DEBUG_RescanElf, TRUE);
        DEBUG_SetBreakpoints(TRUE);
    }
    
    return DEBUG_WalkList(&dbg_hdr);
}

#else	/* !__ELF__ */

enum DbgInfoLoad DEBUG_ReadWineLoaderDbgInfo(HANDLE hProcess, struct elf_info* elf_info)
{
    return DIL_ERROR;
}

BOOL    DEBUG_SetElfSoLoadBreakpoint(const struct elf_info* elf_info)
{
    return FALSE;
}

#endif  /* __ELF__ */
