/*******************************************************************************
 * Copyright (c) 2010 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/

/*
 * This module implements ELF relocation records handling for reading DWARF debug information.
 *
 * Functions in this module use exceptions to report errors, see exceptions.h
 */

#include <config.h>

#if ENABLE_ELF

#include <assert.h>
#include <framework/exceptions.h>
#include <services/dwarfreloc.h>

static ELF_Section * section = NULL;
static ELF_Section * relocs = NULL;
static ELF_Section * symbols = NULL;
static ELF_Section ** destination_section = NULL;

static U8_T reloc_offset = 0;
static U4_T reloc_type = 0;
static U8_T reloc_addend = 0;
static U4_T sym_index = 0;
static U8_T sym_value = 0;

static void * data_buf = NULL;
static size_t data_size = 0;

typedef struct ElfRelocateFunc {
    int machine;
    void (*func)(void);
} ElfRelocateFunc;

#include <machine/elf-mdep.h>

static void relocate(void * r) {
    ElfRelocateFunc * func;
    if (!relocs->file->elf64) {
        if (relocs->type == SHT_REL) {
            Elf32_Rel bf = *(Elf32_Rel *)r;
            if (relocs->file->byte_swap) {
                SWAP(bf.r_offset);
                SWAP(bf.r_info);
            }
            sym_index = ELF32_R_SYM(bf.r_info);
            reloc_type = ELF32_R_TYPE(bf.r_info);
            reloc_addend = 0;
        }
        else {
            Elf32_Rela bf = *(Elf32_Rela *)r;
            if (relocs->file->byte_swap) {
                SWAP(bf.r_offset);
                SWAP(bf.r_info);
                SWAP(bf.r_addend);
            }
            sym_index = ELF32_R_SYM(bf.r_info);
            reloc_type = ELF32_R_TYPE(bf.r_info);
            reloc_addend = bf.r_addend;
        }
        if (sym_index != STN_UNDEF) {
            Elf32_Sym bf = ((Elf32_Sym *)symbols->data)[sym_index];
            if (symbols->file->byte_swap) {
                SWAP(bf.st_name);
                SWAP(bf.st_value);
                SWAP(bf.st_size);
                SWAP(bf.st_info);
                SWAP(bf.st_other);
                SWAP(bf.st_shndx);
            }
            if (symbols->file->type != ET_EXEC) {
                switch (bf.st_shndx) {
                case SHN_ABS:
                    sym_value = bf.st_value;
                    break;
                case SHN_COMMON:
                case SHN_UNDEF:
                    str_exception(ERR_INV_FORMAT, "Invalid relocation record");
                    break;
                default:
                    if (bf.st_shndx >= symbols->file->section_cnt) str_exception(ERR_INV_FORMAT, "Invalid relocation record");
                    sym_value = (symbols->file->sections + bf.st_shndx)->addr + bf.st_value;
                    *destination_section = symbols->file->sections + bf.st_shndx;
                    break;
                }
            }
            else {
                sym_value = bf.st_value;
            }
        }
    }
    else {
        if (relocs->type == SHT_REL) {
            Elf64_Rel bf = *(Elf64_Rel *)r;
            if (relocs->file->byte_swap) {
                SWAP(bf.r_offset);
                SWAP(bf.r_info);
            }
            sym_index = ELF64_R_SYM(bf.r_info);
            reloc_type = ELF64_R_TYPE(bf.r_info);
            reloc_addend = 0;
        }
        else {
            Elf64_Rela bf = *(Elf64_Rela *)r;
            if (relocs->file->byte_swap) {
                SWAP(bf.r_offset);
                SWAP(bf.r_info);
                SWAP(bf.r_addend);
            }
            sym_index = ELF64_R_SYM(bf.r_info);
            reloc_type = ELF64_R_TYPE(bf.r_info);
            reloc_addend = bf.r_addend;
        }
        if (sym_index != STN_UNDEF) {
            Elf64_Sym bf = ((Elf64_Sym *)symbols->data)[sym_index];
            if (symbols->file->byte_swap) {
                SWAP(bf.st_name);
                SWAP(bf.st_value);
                SWAP(bf.st_size);
                SWAP(bf.st_info);
                SWAP(bf.st_other);
                SWAP(bf.st_shndx);
            }
            if (symbols->file->type != ET_EXEC) {
                switch (bf.st_shndx) {
                case SHN_ABS:
                    sym_value = bf.st_value;
                    break;
                case SHN_COMMON:
                case SHN_UNDEF:
                    str_exception(ERR_INV_FORMAT, "Invalid relocation record");
                    break;
                default:
                    if (bf.st_shndx >= symbols->file->section_cnt) str_exception(ERR_INV_FORMAT, "Invalid relocation record");
                    sym_value = (symbols->file->sections + bf.st_shndx)->addr + bf.st_value;
                    *destination_section = symbols->file->sections + bf.st_shndx;
                    break;
                }
            }
            else {
                sym_value = bf.st_value;
            }
        }
    }

    /* For executable file we don't need to apply the relocation,
     * all we need is destination_section */
    if (section->file->type != ET_REL) return;

    func = elf_relocate_funcs;
    while (func->machine != section->file->machine) {
        if (func->func == NULL) str_exception(ERR_INV_FORMAT, "Unsupported ELF machine code");
        func++;
    }
    func->func();
}

void drl_relocate(ELF_Section * s, U8_T offset, void * buf, size_t size, ELF_Section ** dst) {
    unsigned i;
    ELF_Section * d = NULL;

    if (dst == NULL) dst = &d;
    else *dst = NULL;
    if (!s->relocate) return;

    section = s;
    destination_section = dst;
    reloc_offset = offset;
    data_buf = buf;
    data_size = size;
    for (i = 1; i < s->file->section_cnt; i++) {
        ELF_Section * r = s->file->sections + i;
        if (r->size == 0) continue;
        if (r->type != SHT_REL && r->type != SHT_RELA) continue;
        if (r->info == s->index) {
            uint8_t * p;
            uint8_t * q;
            relocs = r;
            symbols = s->file->sections + r->link;
            if (elf_load(relocs) < 0) exception(errno);
            if (elf_load(symbols) < 0) exception(errno);
            if (r->entsize == 0 || r->size % r->entsize != 0) str_exception(ERR_INV_FORMAT, "Invalid sh_entsize");
            p = (uint8_t *)r->data;
            q = p + r->size;
            while (p < q) {
                unsigned n = (q - p) / r->entsize / 2;
                uint8_t * x = p + n * r->entsize;
                assert(x < q);
                if (r->file->elf64) {
                    U8_T offs = *(U8_T *)x;
                    if (r->file->byte_swap) SWAP(offs);
                    if (s->file->type != ET_REL) offs -= s->addr;
                    if (offset > offs) {
                        p = x + r->entsize;
                        continue;
                    }
                    if (offset < offs) {
                        q = x;
                        continue;
                    }
                }
                else {
                    U4_T offs = *(U4_T *)x;
                    if (r->file->byte_swap) SWAP(offs);
                    if (s->file->type != ET_REL) offs -= (U4_T)s->addr;
                    if (offset > offs) {
                        p = x + r->entsize;
                        continue;
                    }
                    if (offset < offs) {
                        q = x;
                        continue;
                    }
                }
                relocate(x);
                return;
            }
        }
    }
}

#endif /* ENABLE_ELF */
