// SPDX-License-Identifier: GPL-2.0-only
/*
 * genelf_debug.c
 * Copyright (C) 2015, Google, Inc
 *
 * Contributed by:
 * 	Stephane Eranian <eranian@google.com>
 *
 * based on GPLv2 source code from Oprofile
 * @remark Copyright 2007 OProfile authors
 * @author Philippe Elie
 */
#include <linux/compiler.h>
#include <sys/types.h>
#include <stdio.h>
#include <getopt.h>
#include <stddef.h>
#include <libelf.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <limits.h>
#include <fcntl.h>
#include <err.h>
#include <dwarf.h>

#include "genelf.h"
#include "../util/jitdump.h"

#define BUFFER_EXT_DFL_SIZE	(4 * 1024)

typedef uint32_t uword;
typedef uint16_t uhalf;
typedef int32_t  sword;
typedef int16_t  shalf;
typedef uint8_t  ubyte;
typedef int8_t   sbyte;

struct buffer_ext {
	size_t cur_pos;
	size_t max_sz;
	void *data;
};

static void
buffer_ext_dump(struct buffer_ext *be, const char *msg)
{
	size_t i;
	warnx("DUMP for %s", msg);
	for (i = 0 ; i < be->cur_pos; i++)
		warnx("%4zu 0x%02x", i, (((char *)be->data)[i]) & 0xff);
}

static inline int
buffer_ext_add(struct buffer_ext *be, void *addr, size_t sz)
{
	void *tmp;
	size_t be_sz = be->max_sz;

retry:
	if ((be->cur_pos + sz) < be_sz) {
		memcpy(be->data + be->cur_pos, addr, sz);
		be->cur_pos += sz;
		return 0;
	}

	if (!be_sz)
		be_sz = BUFFER_EXT_DFL_SIZE;
	else
		be_sz <<= 1;

	tmp = realloc(be->data, be_sz);
	if (!tmp)
		return -1;

	be->data   = tmp;
	be->max_sz = be_sz;

	goto retry;
}

static void
buffer_ext_init(struct buffer_ext *be)
{
	be->data = NULL;
	be->cur_pos = 0;
	be->max_sz = 0;
}

static inline size_t
buffer_ext_size(struct buffer_ext *be)
{
	return be->cur_pos;
}

static inline void *
buffer_ext_addr(struct buffer_ext *be)
{
	return be->data;
}

struct debug_line_header {
	// Not counting this field
	uword total_length;
	// version number (2 currently)
	uhalf version;
	// relative offset from next field to
	// program statement
	uword prolog_length;
	ubyte minimum_instruction_length;
	ubyte default_is_stmt;
	// line_base - see DWARF 2 specs
	sbyte line_base;
	// line_range - see DWARF 2 specs
	ubyte line_range;
	// number of opcode + 1
	ubyte opcode_base;
	/* follow the array of opcode args nr: ubytes [nr_opcode_base] */
	/* follow the search directories index, zero terminated string
	 * terminated by an empty string.
	 */
	/* follow an array of { filename, LEB128, LEB128, LEB128 }, first is
	 * the directory index entry, 0 means current directory, then mtime
	 * and filesize, last entry is followed by en empty string.
	 */
	/* follow the first program statement */
} __packed;

/* DWARF 2 spec talk only about one possible compilation unit header while
 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
 * related to the used arch, an ELF 32 can hold more than 4 Go of debug
 * information. For now we handle only DWARF 2 32 bits comp unit. It'll only
 * become a problem if we generate more than 4GB of debug information.
 */
struct compilation_unit_header {
	uword total_length;
	uhalf version;
	uword debug_abbrev_offset;
	ubyte pointer_size;
} __packed;

#define DW_LNS_num_opcode (DW_LNS_set_isa + 1)

/* field filled at run time are marked with -1 */
static struct debug_line_header const default_debug_line_header = {
	.total_length = -1,
	.version = 2,
	.prolog_length = -1,
	.minimum_instruction_length = 1,	/* could be better when min instruction size != 1 */
	.default_is_stmt = 1,	/* we don't take care about basic block */
	.line_base = -5,	/* sensible value for line base ... */
	.line_range = -14,     /* ... and line range are guessed statically */
	.opcode_base = DW_LNS_num_opcode
};

static ubyte standard_opcode_length[] =
{
	0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1
};
#if 0
{
	[DW_LNS_advance_pc]   = 1,
	[DW_LNS_advance_line] = 1,
	[DW_LNS_set_file] =  1,
	[DW_LNS_set_column] = 1,
	[DW_LNS_fixed_advance_pc] = 1,
	[DW_LNS_set_isa] = 1,
};
#endif

/* field filled at run time are marked with -1 */
static struct compilation_unit_header default_comp_unit_header = {
	.total_length = -1,
	.version = 2,
	.debug_abbrev_offset = 0,     /* we reuse the same abbrev entries for all comp unit */
	.pointer_size = sizeof(void *)
};

static void emit_uword(struct buffer_ext *be, uword data)
{
	buffer_ext_add(be, &data, sizeof(uword));
}

static void emit_string(struct buffer_ext *be, const char *s)
{
	buffer_ext_add(be, (void *)s, strlen(s) + 1);
}

static void emit_unsigned_LEB128(struct buffer_ext *be,
				 unsigned long data)
{
	do {
		ubyte cur = data & 0x7F;
		data >>= 7;
		if (data)
			cur |= 0x80;
		buffer_ext_add(be, &cur, 1);
	} while (data);
}

static void emit_signed_LEB128(struct buffer_ext *be, long data)
{
	int more = 1;
	int negative = data < 0;
	int size = sizeof(long) * CHAR_BIT;
	while (more) {
		ubyte cur = data & 0x7F;
		data >>= 7;
		if (negative)
			data |= - (1 << (size - 7));
		if ((data == 0 && !(cur & 0x40)) ||
		    (data == -1l && (cur & 0x40)))
			more = 0;
		else
			cur |= 0x80;
		buffer_ext_add(be, &cur, 1);
	}
}

static void emit_extended_opcode(struct buffer_ext *be, ubyte opcode,
				 void *data, size_t data_len)
{
	buffer_ext_add(be, (char *)"", 1);

	emit_unsigned_LEB128(be, data_len + 1);

	buffer_ext_add(be, &opcode, 1);
	buffer_ext_add(be, data, data_len);
}

static void emit_opcode(struct buffer_ext *be, ubyte opcode)
{
	buffer_ext_add(be, &opcode, 1);
}

static void emit_opcode_signed(struct buffer_ext  *be,
			       ubyte opcode, long data)
{
	buffer_ext_add(be, &opcode, 1);
	emit_signed_LEB128(be, data);
}

static void emit_opcode_unsigned(struct buffer_ext *be, ubyte opcode,
				 unsigned long data)
{
	buffer_ext_add(be, &opcode, 1);
	emit_unsigned_LEB128(be, data);
}

static void emit_advance_pc(struct buffer_ext *be, unsigned long delta_pc)
{
	emit_opcode_unsigned(be, DW_LNS_advance_pc, delta_pc);
}

static void emit_advance_lineno(struct buffer_ext  *be, long delta_lineno)
{
	emit_opcode_signed(be, DW_LNS_advance_line, delta_lineno);
}

static void emit_lne_end_of_sequence(struct buffer_ext *be)
{
	emit_extended_opcode(be, DW_LNE_end_sequence, NULL, 0);
}

static void emit_set_file(struct buffer_ext *be, unsigned long idx)
{
	emit_opcode_unsigned(be, DW_LNS_set_file, idx);
}

static void emit_lne_define_filename(struct buffer_ext *be,
				     const char *filename)
{
	buffer_ext_add(be, (void *)"", 1);

	/* LNE field, strlen(filename) + zero termination, 3 bytes for: the dir entry, timestamp, filesize */
	emit_unsigned_LEB128(be, strlen(filename) + 5);
	emit_opcode(be, DW_LNE_define_file);
	emit_string(be, filename);
	/* directory index 0=do not know */
        emit_unsigned_LEB128(be, 0);
	/* last modification date on file 0=do not know */
        emit_unsigned_LEB128(be, 0);
	/* filesize 0=do not know */
        emit_unsigned_LEB128(be, 0);
}

static void emit_lne_set_address(struct buffer_ext *be,
				 void *address)
{
	emit_extended_opcode(be, DW_LNE_set_address, &address, sizeof(unsigned long));
}

static ubyte get_special_opcode(struct debug_entry *ent,
				unsigned int last_line,
				unsigned long last_vma)
{
	unsigned int temp;
	unsigned long delta_addr;

	/*
	 * delta from line_base
	 */
	temp = (ent->lineno - last_line) - default_debug_line_header.line_base;

	if (temp >= default_debug_line_header.line_range)
		return 0;

	/*
	 * delta of addresses
	 */
	delta_addr = (ent->addr - last_vma) / default_debug_line_header.minimum_instruction_length;

	/* This is not sufficient to ensure opcode will be in [0-256] but
	 * sufficient to ensure when summing with the delta lineno we will
	 * not overflow the unsigned long opcode */

	if (delta_addr <= 256 / default_debug_line_header.line_range) {
		unsigned long opcode = temp +
			(delta_addr * default_debug_line_header.line_range) +
			default_debug_line_header.opcode_base;

		return opcode <= 255 ? opcode : 0;
	}
	return 0;
}

static void emit_lineno_info(struct buffer_ext *be,
			     struct debug_entry *ent, size_t nr_entry,
			     unsigned long code_addr)
{
	size_t i;

	/*
	 * Machine state at start of a statement program
	 * address = 0
	 * file    = 1
	 * line    = 1
	 * column  = 0
	 * is_stmt = default_is_stmt as given in the debug_line_header
	 * basic block = 0
	 * end sequence = 0
	 */

	/* start state of the state machine we take care of */
	unsigned long last_vma = 0;
	char const  *cur_filename = NULL;
	unsigned long cur_file_idx = 0;
	int last_line = 1;

	emit_lne_set_address(be, (void *)code_addr);

	for (i = 0; i < nr_entry; i++, ent = debug_entry_next(ent)) {
		int need_copy = 0;
		ubyte special_opcode;

		/*
		 * check if filename changed, if so add it
		 */
		if (!cur_filename || strcmp(cur_filename, ent->name)) {
			emit_lne_define_filename(be, ent->name);
			cur_filename = ent->name;
			emit_set_file(be, ++cur_file_idx);
			need_copy = 1;
		}

		special_opcode = get_special_opcode(ent, last_line, last_vma);
		if (special_opcode != 0) {
			last_line = ent->lineno;
			last_vma  = ent->addr;
			emit_opcode(be, special_opcode);
		} else {
			/*
			 * lines differ, emit line delta
			 */
			if (last_line != ent->lineno) {
				emit_advance_lineno(be, ent->lineno - last_line);
				last_line = ent->lineno;
				need_copy = 1;
			}
			/*
			 * addresses differ, emit address delta
			 */
			if (last_vma != ent->addr) {
				emit_advance_pc(be, ent->addr - last_vma);
				last_vma = ent->addr;
				need_copy = 1;
			}
			/*
			 * add new row to matrix
			 */
			if (need_copy)
				emit_opcode(be, DW_LNS_copy);
		}
	}
}

static void add_debug_line(struct buffer_ext *be,
	struct debug_entry *ent, size_t nr_entry,
	unsigned long code_addr)
{
	struct debug_line_header * dbg_header;
	size_t old_size;

	old_size = buffer_ext_size(be);

	buffer_ext_add(be, (void *)&default_debug_line_header,
		 sizeof(default_debug_line_header));

	buffer_ext_add(be, &standard_opcode_length,  sizeof(standard_opcode_length));

	// empty directory entry
	buffer_ext_add(be, (void *)"", 1);

	// empty filename directory
	buffer_ext_add(be, (void *)"", 1);

	dbg_header = buffer_ext_addr(be) + old_size;
	dbg_header->prolog_length = (buffer_ext_size(be) - old_size) -
		offsetof(struct debug_line_header, minimum_instruction_length);

	emit_lineno_info(be, ent, nr_entry, code_addr);

	emit_lne_end_of_sequence(be);

	dbg_header = buffer_ext_addr(be) + old_size;
	dbg_header->total_length = (buffer_ext_size(be) - old_size) -
		offsetof(struct debug_line_header, version);
}

static void
add_debug_abbrev(struct buffer_ext *be)
{
        emit_unsigned_LEB128(be, 1);
        emit_unsigned_LEB128(be, DW_TAG_compile_unit);
        emit_unsigned_LEB128(be, DW_CHILDREN_yes);
        emit_unsigned_LEB128(be, DW_AT_stmt_list);
        emit_unsigned_LEB128(be, DW_FORM_data4);
        emit_unsigned_LEB128(be, 0);
        emit_unsigned_LEB128(be, 0);
        emit_unsigned_LEB128(be, 0);
}

static void
add_compilation_unit(struct buffer_ext *be,
		     size_t offset_debug_line)
{
	struct compilation_unit_header *comp_unit_header;
	size_t old_size = buffer_ext_size(be);

	buffer_ext_add(be, &default_comp_unit_header,
		       sizeof(default_comp_unit_header));

	emit_unsigned_LEB128(be, 1);
	emit_uword(be, offset_debug_line);

	comp_unit_header = buffer_ext_addr(be) + old_size;
	comp_unit_header->total_length = (buffer_ext_size(be) - old_size) -
		offsetof(struct compilation_unit_header, version);
}

static int
jit_process_debug_info(uint64_t code_addr,
		       void *debug, int nr_debug_entries,
		       struct buffer_ext *dl,
		       struct buffer_ext *da,
		       struct buffer_ext *di)
{
	struct debug_entry *ent = debug;
	int i;

	for (i = 0; i < nr_debug_entries; i++) {
		ent->addr = ent->addr - code_addr;
		ent = debug_entry_next(ent);
	}
	add_compilation_unit(di, buffer_ext_size(dl));
	add_debug_line(dl, debug, nr_debug_entries, GEN_ELF_TEXT_OFFSET);
	add_debug_abbrev(da);
	if (0) buffer_ext_dump(da, "abbrev");

	return 0;
}

int
jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries)
{
	Elf_Data *d;
	Elf_Scn *scn;
	Elf_Shdr *shdr;
	struct buffer_ext dl, di, da;
	int ret;

	buffer_ext_init(&dl);
	buffer_ext_init(&di);
	buffer_ext_init(&da);

	ret = jit_process_debug_info(code_addr, debug, nr_debug_entries, &dl, &da, &di);
	if (ret)
		return -1;
	/*
	 * setup .debug_line section
	 */
	scn = elf_newscn(e);
	if (!scn) {
		warnx("cannot create section");
		return -1;
	}

	d = elf_newdata(scn);
	if (!d) {
		warnx("cannot get new data");
		return -1;
	}

	d->d_align = 1;
	d->d_off = 0LL;
	d->d_buf = buffer_ext_addr(&dl);
	d->d_type = ELF_T_BYTE;
	d->d_size = buffer_ext_size(&dl);
	d->d_version = EV_CURRENT;

	shdr = elf_getshdr(scn);
	if (!shdr) {
		warnx("cannot get section header");
		return -1;
	}

	shdr->sh_name = 52; /* .debug_line */
	shdr->sh_type = SHT_PROGBITS;
	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
	shdr->sh_flags = 0;
	shdr->sh_entsize = 0;

	/*
	 * setup .debug_info section
	 */
	scn = elf_newscn(e);
	if (!scn) {
		warnx("cannot create section");
		return -1;
	}

	d = elf_newdata(scn);
	if (!d) {
		warnx("cannot get new data");
		return -1;
	}

	d->d_align = 1;
	d->d_off = 0LL;
	d->d_buf = buffer_ext_addr(&di);
	d->d_type = ELF_T_BYTE;
	d->d_size = buffer_ext_size(&di);
	d->d_version = EV_CURRENT;

	shdr = elf_getshdr(scn);
	if (!shdr) {
		warnx("cannot get section header");
		return -1;
	}

	shdr->sh_name = 64; /* .debug_info */
	shdr->sh_type = SHT_PROGBITS;
	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
	shdr->sh_flags = 0;
	shdr->sh_entsize = 0;

	/*
	 * setup .debug_abbrev section
	 */
	scn = elf_newscn(e);
	if (!scn) {
		warnx("cannot create section");
		return -1;
	}

	d = elf_newdata(scn);
	if (!d) {
		warnx("cannot get new data");
		return -1;
	}

	d->d_align = 1;
	d->d_off = 0LL;
	d->d_buf = buffer_ext_addr(&da);
	d->d_type = ELF_T_BYTE;
	d->d_size = buffer_ext_size(&da);
	d->d_version = EV_CURRENT;

	shdr = elf_getshdr(scn);
	if (!shdr) {
		warnx("cannot get section header");
		return -1;
	}

	shdr->sh_name = 76; /* .debug_info */
	shdr->sh_type = SHT_PROGBITS;
	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
	shdr->sh_flags = 0;
	shdr->sh_entsize = 0;

	/*
	 * now we update the ELF image with all the sections
	 */
	if (elf_update(e, ELF_C_WRITE) < 0) {
		warnx("elf_update debug failed");
		return -1;
	}
	return 0;
}
