18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file debug_line.c
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * DWARF 2 debug line info creation helper
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2007 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdint.h>
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdlib.h>
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string.h>
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stddef.h>
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdio.h>
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <bfd.h>
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <limits.h>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opjitconv.h"
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "jitdump.h"
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opagent.h"
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_libiberty.h"
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_growable_buffer.h"
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Terminology comes from the TIS DWARF Debugging Information Format
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * version 2.0
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef uint32_t uword;
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef uint16_t uhalf;
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef int32_t  sword;
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef int16_t  shalf;
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef uint8_t  ubyte;
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef int8_t   sbyte;
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Many of the following enum are incomplete and define only the subset
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * of DWARF we use.
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum lns_opcode {
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_copy=1,
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_advance_pc,
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_advance_line,
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_set_file,
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_set_column,
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_negate_stmt,
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_set_basic_block,
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_const_add_pc,
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_fixed_advance_pc,
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* Adding new opcode needs an update of the standard_opcode_length
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * array */
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_max_opcode,
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum lne_opcode {
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNE_end_sequence = 1,
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNE_set_address,
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNE_define_file
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum dw_tag {
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_TAG_compile_unit = 0x11,
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum dw_at {
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_name = 0x03,
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_stmt_list = 0x10,
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_low_pc,
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_high_pc,
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_language,
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_compdir = 0x1b,
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_AT_producer = 0x25,
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum dw_children {
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_CHILDREN_no,
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_CHILDREN_yes
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddenum dw_form {
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_FORM_data4 = 0x06,
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct debug_line_header {
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// Not counting this field
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uword total_length;
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// version number (2 currently)
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uhalf version;
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// relative offset from next field to
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// program statement
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uword prolog_length;
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ubyte minimum_instruction_length;
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ubyte default_is_stmt;
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// line_base - see DWARF 2 specs
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sbyte line_base;
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// line_range - see DWARF 2 specs
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ubyte line_range;
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// number of opcode + 1
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ubyte opcode_base;
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* follow the array of opcode args nr: ubytes [nr_opcode_base] */
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* follow the search directories index, zero terminated string
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * terminated by an empty string.
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* follow an array of { filename, LEB128, LEB128, LEB128 }, first is
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * the directory index entry, 0 means current directory, then mtime
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * and filesize, last entry is followed by en empty string.
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* follow the first program statement */
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} __attribute__((packed));
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* DWARF 2 spec talk only about one possible compilation unit header while
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * related to the used arch, an ELF 32 can hold more than 4 Go of debug
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * information. For now we handle only DWARF 2 32 bits comp unit. It'll only
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * become a problem if we generate more than 4GB of debug information.
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct compilation_unit_header {
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uword total_length;
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uhalf version;
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	uword debug_abbrev_offset;
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ubyte pointer_size;
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} __attribute__((packed));
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* field filled at run time are marked with -1 */
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct debug_line_header const default_debug_line_header = {
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	-1,
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	2,
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	-1,
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	1,	/* could be better when min instruction size != 1 */
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	1,	/* we don't take care about basic block */
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	-5,	/* sensible value for line base ... */
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	14,     /* ... and line range are guessed statically */
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DW_LNS_max_opcode
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic ubyte const standard_opcode_length[DW_LNS_max_opcode - 1] =
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	0, 1, 1, 1, 1, 0, 0, 0, 1
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* field filled at run time are marked with -1 */
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct compilation_unit_header const default_comp_unit_header = {
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	-1,
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	2,
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	0,     /* we reuse the same abbrev entries for all comp unit */
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	-1
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_uword(struct growable_buffer * b, uword data)
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &data, sizeof(uword));
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_string(struct growable_buffer * b, char const * s)
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, s, strlen(s) + 1);
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_unsigned_LEB128(struct growable_buffer * b,
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 unsigned long data)
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	do {
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		ubyte cur = data & 0x7F;
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		data >>= 7;
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (data)
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			cur |= 0x80;
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		add_data(b, &cur, 1);
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} while (data);
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_signed_LEB128(struct growable_buffer * b, long data)
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int more = 1;
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int negative = data < 0;
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int size = sizeof(long) * CHAR_BIT;
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	while (more) {
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		ubyte cur = data & 0x7F;
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		data >>= 7;
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (negative)
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			data |= - (1 << (size - 7));
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if ((data == 0 && !(cur & 0x40)) ||
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		    (data == -1l && (cur & 0x40)))
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			more = 0;
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		else
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			cur |= 0x80;
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		add_data(b, &cur, 1);
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_extended_opcode(struct growable_buffer * b, ubyte opcode,
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 void * data, size_t data_len)
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, "", 1);
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, data_len + 1);
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &opcode, 1);
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, data, data_len);
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_opcode(struct growable_buffer * b, ubyte opcode)
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &opcode, 1);
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_opcode_signed(struct growable_buffer * b,
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ubyte opcode, long data)
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &opcode, 1);
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_signed_LEB128(b, data);
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_opcode_unsigned(struct growable_buffer * b, ubyte opcode,
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 unsigned long data)
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &opcode, 1);
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, data);
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_advance_pc(struct growable_buffer * b, unsigned long delta_pc)
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_opcode_unsigned(b, DW_LNS_advance_pc, delta_pc);
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_advance_lineno(struct growable_buffer * b, long delta_lineno)
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_opcode_signed(b, DW_LNS_advance_line, delta_lineno);
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_lne_end_of_sequence(struct growable_buffer * b)
2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_extended_opcode(b, DW_LNE_end_sequence, NULL, 0);
2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_set_file(struct growable_buffer * b, unsigned long index)
2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_opcode_unsigned(b, DW_LNS_set_file, index);
2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_lne_define_filename(struct growable_buffer * b,
2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				     char const * filename)
2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* emit_extended_opcode() can't be used here, we have additional
2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * data to output and the len field will be miscalculated. */
2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, "", 1);
2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* strlen(filename) + zero terminator + len field + 3 bytes for the dir
2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * entry, timestamp and filesize */
2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, strlen(filename) + 5);
2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_opcode(b, DW_LNE_define_file);
2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_string(b, filename);
2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, "\0\0\0", 3);
2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_lne_set_address(struct growable_buffer * b,
2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 void const * address)
2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_extended_opcode(b, DW_LNE_set_address, &address, sizeof(address));
2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic ubyte get_special_opcode(struct debug_line_info const * line,
2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned int last_lineno, unsigned long last_vma)
2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned int temp;
2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned long delta_addr;
2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* See TIS DWARF Debugging Information Format version 2.0 � 6.2.5.1 */
2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	temp = (line->lineno - last_lineno) -
2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		default_debug_line_header.line_base;
2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (temp >= default_debug_line_header.line_range)
2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return 0;
2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	delta_addr = (line->vma - last_vma) /
2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		default_debug_line_header.minimum_instruction_length;
2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* This is not sufficient to ensure opcode will be in [0-256] but
2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * sufficient to ensure when summing with the delta lineno we will
2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * not overflow the unsigned long opcode */
2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (delta_addr <= 256 / default_debug_line_header.line_range) {
2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		unsigned long opcode = temp +
2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			(delta_addr * default_debug_line_header.line_range) +
2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			default_debug_line_header.opcode_base;
2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return opcode <= 255 ? opcode : 0;
3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return 0;
3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void emit_lineno_info(struct growable_buffer * b,
3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct debug_line_info const * line, size_t nr_entry,
3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned long code_addr)
3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t i;
3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/*
3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Machine state at start of a statement program
3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * address = 0
3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * file    = 1
3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * line    = 1
3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * column  = 0
3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * is_stmt = default_is_stmt as given in the debug_line_header
3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * basic block = 0
3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * end sequence = 0
3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* start state of the state machine we take care of */
3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned long last_vma = code_addr;
3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned int last_lineno = 1;
3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	char const  * cur_filename = NULL;
3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned long cur_file_index = 0;
3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* FIXME: relocatable address? */
3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_lne_set_address(b, (void const *)code_addr);
3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_advance_lineno(b, line[0].lineno - last_lineno);
3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	last_lineno = line[0].lineno;
3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_lne_define_filename(b, line[0].filename);
3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cur_filename = line[0].filename;
3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_set_file(b, ++cur_file_index);
3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_opcode(b, DW_LNS_copy);
3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = 0; i < nr_entry; i++) {
3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		int need_copy = 0;
3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		ubyte special_opcode;
3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (!cur_filename || strcmp(cur_filename, line[i].filename)) {
3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			emit_lne_define_filename(b, line[i].filename);
3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			cur_filename = line[i].filename;
3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			emit_set_file(b, ++cur_file_index);
3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			need_copy = 1;
3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if ((special_opcode = get_special_opcode(&line[i],
3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				last_lineno, last_vma)) != 0) {
3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			last_lineno = line[i].lineno;
3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			last_vma = line[i].vma;
3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			emit_opcode(b, special_opcode);
3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		} else {
3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (last_lineno != line[i].lineno) {
3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				emit_advance_lineno(b,
3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					line[i].lineno - last_lineno);
3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				last_lineno = line[i].lineno;
3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				need_copy = 1;
3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (last_vma != line[i].vma) {
3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				emit_advance_pc(b, line[i].vma - last_vma);
3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				last_vma = line[i].vma;
3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				need_copy = 1;
3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (need_copy)
3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				emit_opcode(b, DW_LNS_copy);
3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void add_debug_line(struct growable_buffer * b,
3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct debug_line_info const * line, size_t nr_entry,
3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	unsigned long code_addr)
3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct debug_line_header * dbg_header;
3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t old_size;
3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	old_size = b->size;
3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &default_debug_line_header,
3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 sizeof(default_debug_line_header));
3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &standard_opcode_length,  sizeof(standard_opcode_length));
3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// empty directory entry
3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, "", 1);
3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// empty filename directory
3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, "", 1);
3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dbg_header = b->p + old_size;
3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dbg_header->prolog_length = (b->size - old_size) -
3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		offsetof(struct debug_line_header, minimum_instruction_length);
3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_lineno_info(b, line, nr_entry, code_addr);
3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_lne_end_of_sequence(b);
3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dbg_header = b->p + old_size;
4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dbg_header->total_length = (b->size - old_size) -
4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		offsetof(struct debug_line_header, version);
4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void add_compilation_unit(struct growable_buffer * b,
4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 size_t offset_debug_line)
4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct compilation_unit_header * comp_unit_header;
4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t old_size = b->size;
4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	add_data(b, &default_comp_unit_header,
4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 sizeof(default_comp_unit_header));
4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, 1);
4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_uword(b, offset_debug_line);
4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	comp_unit_header = b->p + old_size;
4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	comp_unit_header->total_length = (b->size - old_size) -
4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		offsetof(struct compilation_unit_header, version);
4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	comp_unit_header->pointer_size = sizeof(void *);
4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void create_debug_abbrev(struct growable_buffer * b)
4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, 1);
4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, DW_TAG_compile_unit);
4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, DW_CHILDREN_yes);
4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, DW_AT_stmt_list);
4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, DW_FORM_data4);
4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	emit_unsigned_LEB128(b, 0);
4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct growable_buffer b_line;
4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct growable_buffer b_debug_info;
4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct growable_buffer b_debug_abbrev;
4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint init_debug_line_info(bfd * abfd)
4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	asection * line_section, * debug_info, * debug_abbrev;
4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct jitentry_debug_line * debug_line;
4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	init_buffer(&b_line);
4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	init_buffer(&b_debug_info);
4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	init_buffer(&b_debug_abbrev);
4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (debug_line = jitentry_debug_line_list;
4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	     debug_line;
4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	     debug_line = debug_line->next) {
4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		struct jr_code_debug_info const * rec = debug_line->data;
4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (rec->nr_entry) {
4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t i;
4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			void const * data = rec + 1;
4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			struct debug_line_info * dbg_line =
4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				xmalloc(rec->nr_entry *
4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					sizeof(struct debug_line_info));
4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			for (i = 0; i < rec->nr_entry; ++i) {
4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				dbg_line[i].vma = *(unsigned long *)data;
4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				data += sizeof(unsigned long);
4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				dbg_line[i].lineno = *(unsigned int *)data;
4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				data += sizeof(unsigned int);
4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				dbg_line[i].filename = data;
4658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				data += strlen(data) + 1;
4668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
4678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			add_compilation_unit(&b_debug_info, b_line.size);
4698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			add_debug_line(&b_line, dbg_line,
4708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				       rec->nr_entry, rec->code_addr);
4718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			create_debug_abbrev(&b_debug_abbrev);
4728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			free(dbg_line);
4748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
4758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
4768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	line_section = create_section(abfd, ".debug_line", b_line.size, 0,
4788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
4798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!line_section)
4808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
4818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	debug_info = create_section(abfd, ".debug_info", b_debug_info.size, 0,
4838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
4848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 	if (!debug_info)
4858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
4868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	debug_abbrev = create_section(abfd, ".debug_abbrev",
4888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		b_debug_abbrev.size, 0,
4898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
4908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!debug_abbrev)
4918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
4928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return 0;
4948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint finalize_debug_line_info(bfd * abfd)
4988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	asection * line_section, * debug_info, * debug_abbrev;
5008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	line_section = bfd_get_section_by_name(abfd, ".debug_line");
5028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!line_section)
5038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
5048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	debug_info = bfd_get_section_by_name(abfd, ".debug_info");
5068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 	if (!debug_info)
5078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
5088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	debug_abbrev = bfd_get_section_by_name(abfd, ".debug_abbrev");
5118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!debug_abbrev)
5128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return -1;
5138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	fill_section_content(abfd, line_section, b_line.p, 0, b_line.size);
5158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	fill_section_content(abfd, debug_info, b_debug_info.p,
5168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			     0, b_debug_info.size);
5178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	fill_section_content(abfd, debug_abbrev, b_debug_abbrev.p, 0,
5188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			     b_debug_abbrev.size);
5198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	free_buffer(&b_line);
5228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	free_buffer(&b_debug_info);
5238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	free_buffer(&b_debug_abbrev);
5248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return 0;
5268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
527