1/**
2 * @file debug_line.c
3 * DWARF 2 debug line info creation helper
4 *
5 * @remark Copyright 2007 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 */
10
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14#include <stddef.h>
15#include <stdio.h>
16#include <bfd.h>
17#include <limits.h>
18
19#include "opjitconv.h"
20#include "jitdump.h"
21#include "opagent.h"
22#include "op_libiberty.h"
23#include "op_growable_buffer.h"
24
25/*
26 * Terminology comes from the TIS DWARF Debugging Information Format
27 * version 2.0
28 */
29
30typedef uint32_t uword;
31typedef uint16_t uhalf;
32typedef int32_t  sword;
33typedef int16_t  shalf;
34typedef uint8_t  ubyte;
35typedef int8_t   sbyte;
36
37/*
38 * Many of the following enum are incomplete and define only the subset
39 * of DWARF we use.
40 */
41enum lns_opcode {
42	DW_LNS_copy=1,
43	DW_LNS_advance_pc,
44	DW_LNS_advance_line,
45	DW_LNS_set_file,
46	DW_LNS_set_column,
47	DW_LNS_negate_stmt,
48	DW_LNS_set_basic_block,
49	DW_LNS_const_add_pc,
50	DW_LNS_fixed_advance_pc,
51
52	/* Adding new opcode needs an update of the standard_opcode_length
53	 * array */
54
55	DW_LNS_max_opcode,
56};
57
58enum lne_opcode {
59	DW_LNE_end_sequence = 1,
60	DW_LNE_set_address,
61	DW_LNE_define_file
62};
63
64enum dw_tag {
65	DW_TAG_compile_unit = 0x11,
66};
67
68enum dw_at {
69	DW_AT_name = 0x03,
70	DW_AT_stmt_list = 0x10,
71	DW_AT_low_pc,
72	DW_AT_high_pc,
73	DW_AT_language,
74	DW_AT_compdir = 0x1b,
75	DW_AT_producer = 0x25,
76};
77
78enum dw_children {
79	DW_CHILDREN_no,
80	DW_CHILDREN_yes
81};
82
83enum dw_form {
84	DW_FORM_data4 = 0x06,
85};
86
87struct debug_line_header {
88	// Not counting this field
89	uword total_length;
90	// version number (2 currently)
91	uhalf version;
92	// relative offset from next field to
93	// program statement
94	uword prolog_length;
95	ubyte minimum_instruction_length;
96	ubyte default_is_stmt;
97	// line_base - see DWARF 2 specs
98	sbyte line_base;
99	// line_range - see DWARF 2 specs
100	ubyte line_range;
101	// number of opcode + 1
102	ubyte opcode_base;
103	/* follow the array of opcode args nr: ubytes [nr_opcode_base] */
104	/* follow the search directories index, zero terminated string
105	 * terminated by an empty string.
106	 */
107	/* follow an array of { filename, LEB128, LEB128, LEB128 }, first is
108	 * the directory index entry, 0 means current directory, then mtime
109	 * and filesize, last entry is followed by en empty string.
110	 */
111	/* follow the first program statement */
112} __attribute__((packed));
113
114/* DWARF 2 spec talk only about one possible compilation unit header while
115 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
116 * related to the used arch, an ELF 32 can hold more than 4 Go of debug
117 * information. For now we handle only DWARF 2 32 bits comp unit. It'll only
118 * become a problem if we generate more than 4GB of debug information.
119 */
120struct compilation_unit_header {
121	uword total_length;
122	uhalf version;
123	uword debug_abbrev_offset;
124	ubyte pointer_size;
125} __attribute__((packed));
126
127/* field filled at run time are marked with -1 */
128static struct debug_line_header const default_debug_line_header = {
129	-1,
130	2,
131	-1,
132	1,	/* could be better when min instruction size != 1 */
133	1,	/* we don't take care about basic block */
134	-5,	/* sensible value for line base ... */
135	14,     /* ... and line range are guessed statically */
136	DW_LNS_max_opcode
137};
138
139static ubyte const standard_opcode_length[DW_LNS_max_opcode - 1] =
140{
141	0, 1, 1, 1, 1, 0, 0, 0, 1
142};
143
144/* field filled at run time are marked with -1 */
145static struct compilation_unit_header const default_comp_unit_header = {
146	-1,
147	2,
148	0,     /* we reuse the same abbrev entries for all comp unit */
149	-1
150};
151
152
153static void emit_uword(struct growable_buffer * b, uword data)
154{
155	add_data(b, &data, sizeof(uword));
156}
157
158
159static void emit_string(struct growable_buffer * b, char const * s)
160{
161	add_data(b, s, strlen(s) + 1);
162}
163
164
165static void emit_unsigned_LEB128(struct growable_buffer * b,
166				 unsigned long data)
167{
168	do {
169		ubyte cur = data & 0x7F;
170		data >>= 7;
171		if (data)
172			cur |= 0x80;
173		add_data(b, &cur, 1);
174	} while (data);
175}
176
177
178static void emit_signed_LEB128(struct growable_buffer * b, long data)
179{
180	int more = 1;
181	int negative = data < 0;
182	int size = sizeof(long) * CHAR_BIT;
183	while (more) {
184		ubyte cur = data & 0x7F;
185		data >>= 7;
186		if (negative)
187			data |= - (1 << (size - 7));
188		if ((data == 0 && !(cur & 0x40)) ||
189		    (data == -1l && (cur & 0x40)))
190			more = 0;
191		else
192			cur |= 0x80;
193		add_data(b, &cur, 1);
194	}
195}
196
197
198static void emit_extended_opcode(struct growable_buffer * b, ubyte opcode,
199				 void * data, size_t data_len)
200{
201	add_data(b, "", 1);
202	emit_unsigned_LEB128(b, data_len + 1);
203	add_data(b, &opcode, 1);
204	add_data(b, data, data_len);
205}
206
207
208static void emit_opcode(struct growable_buffer * b, ubyte opcode)
209{
210	add_data(b, &opcode, 1);
211}
212
213
214static void emit_opcode_signed(struct growable_buffer * b,
215			       ubyte opcode, long data)
216{
217	add_data(b, &opcode, 1);
218	emit_signed_LEB128(b, data);
219}
220
221
222static void emit_opcode_unsigned(struct growable_buffer * b, ubyte opcode,
223				 unsigned long data)
224{
225	add_data(b, &opcode, 1);
226	emit_unsigned_LEB128(b, data);
227}
228
229
230static void emit_advance_pc(struct growable_buffer * b, unsigned long delta_pc)
231{
232	emit_opcode_unsigned(b, DW_LNS_advance_pc, delta_pc);
233}
234
235
236static void emit_advance_lineno(struct growable_buffer * b, long delta_lineno)
237{
238	emit_opcode_signed(b, DW_LNS_advance_line, delta_lineno);
239}
240
241
242static void emit_lne_end_of_sequence(struct growable_buffer * b)
243{
244	emit_extended_opcode(b, DW_LNE_end_sequence, NULL, 0);
245}
246
247
248static void emit_set_file(struct growable_buffer * b, unsigned long index)
249{
250	emit_opcode_unsigned(b, DW_LNS_set_file, index);
251}
252
253
254static void emit_lne_define_filename(struct growable_buffer * b,
255				     char const * filename)
256{
257	/* emit_extended_opcode() can't be used here, we have additional
258	 * data to output and the len field will be miscalculated. */
259	add_data(b, "", 1);
260	/* strlen(filename) + zero terminator + len field + 3 bytes for the dir
261	 * entry, timestamp and filesize */
262	emit_unsigned_LEB128(b, strlen(filename) + 5);
263	emit_opcode(b, DW_LNE_define_file);
264	emit_string(b, filename);
265	add_data(b, "\0\0\0", 3);
266}
267
268
269static void emit_lne_set_address(struct growable_buffer * b,
270				 void const * address)
271{
272	emit_extended_opcode(b, DW_LNE_set_address, &address, sizeof(address));
273}
274
275
276static ubyte get_special_opcode(struct debug_line_info const * line,
277	unsigned int last_lineno, unsigned long last_vma)
278{
279	unsigned int temp;
280	unsigned long delta_addr;
281
282	/* See TIS DWARF Debugging Information Format version 2.0 � 6.2.5.1 */
283
284	temp = (line->lineno - last_lineno) -
285		default_debug_line_header.line_base;
286	if (temp >= default_debug_line_header.line_range)
287		return 0;
288
289	delta_addr = (line->vma - last_vma) /
290		default_debug_line_header.minimum_instruction_length;
291	/* This is not sufficient to ensure opcode will be in [0-256] but
292	 * sufficient to ensure when summing with the delta lineno we will
293	 * not overflow the unsigned long opcode */
294	if (delta_addr <= 256 / default_debug_line_header.line_range) {
295		unsigned long opcode = temp +
296			(delta_addr * default_debug_line_header.line_range) +
297			default_debug_line_header.opcode_base;
298
299		return opcode <= 255 ? opcode : 0;
300	}
301
302	return 0;
303}
304
305
306static void emit_lineno_info(struct growable_buffer * b,
307	struct debug_line_info const * line, size_t nr_entry,
308	unsigned long code_addr)
309{
310	size_t i;
311
312	/*
313	 * Machine state at start of a statement program
314	 * address = 0
315	 * file    = 1
316	 * line    = 1
317	 * column  = 0
318	 * is_stmt = default_is_stmt as given in the debug_line_header
319	 * basic block = 0
320	 * end sequence = 0
321	 */
322
323	/* start state of the state machine we take care of */
324	unsigned long last_vma = code_addr;
325	unsigned int last_lineno = 1;
326	char const  * cur_filename = NULL;
327	unsigned long cur_file_index = 0;
328
329	/* FIXME: relocatable address? */
330	emit_lne_set_address(b, (void const *)code_addr);
331	emit_advance_lineno(b, line[0].lineno - last_lineno);
332	last_lineno = line[0].lineno;
333	emit_lne_define_filename(b, line[0].filename);
334	cur_filename = line[0].filename;
335	emit_set_file(b, ++cur_file_index);
336	emit_opcode(b, DW_LNS_copy);
337
338
339	for (i = 0; i < nr_entry; i++) {
340		int need_copy = 0;
341		ubyte special_opcode;
342
343		if (!cur_filename || strcmp(cur_filename, line[i].filename)) {
344			emit_lne_define_filename(b, line[i].filename);
345			cur_filename = line[i].filename;
346			emit_set_file(b, ++cur_file_index);
347			need_copy = 1;
348		}
349		if ((special_opcode = get_special_opcode(&line[i],
350				last_lineno, last_vma)) != 0) {
351			last_lineno = line[i].lineno;
352			last_vma = line[i].vma;
353			emit_opcode(b, special_opcode);
354		} else {
355			if (last_lineno != line[i].lineno) {
356				emit_advance_lineno(b,
357					line[i].lineno - last_lineno);
358				last_lineno = line[i].lineno;
359				need_copy = 1;
360			}
361			if (last_vma != line[i].vma) {
362				emit_advance_pc(b, line[i].vma - last_vma);
363				last_vma = line[i].vma;
364				need_copy = 1;
365			}
366			if (need_copy)
367				emit_opcode(b, DW_LNS_copy);
368		}
369	}
370}
371
372
373static void add_debug_line(struct growable_buffer * b,
374	struct debug_line_info const * line, size_t nr_entry,
375	unsigned long code_addr)
376{
377	struct debug_line_header * dbg_header;
378	size_t old_size;
379
380	old_size = b->size;
381
382	add_data(b, &default_debug_line_header,
383		 sizeof(default_debug_line_header));
384	add_data(b, &standard_opcode_length,  sizeof(standard_opcode_length));
385
386	// empty directory entry
387	add_data(b, "", 1);
388
389	// empty filename directory
390	add_data(b, "", 1);
391
392	dbg_header = b->p + old_size;
393	dbg_header->prolog_length = (b->size - old_size) -
394		offsetof(struct debug_line_header, minimum_instruction_length);
395
396	emit_lineno_info(b, line, nr_entry, code_addr);
397
398	emit_lne_end_of_sequence(b);
399
400	dbg_header = b->p + old_size;
401	dbg_header->total_length = (b->size - old_size) -
402		offsetof(struct debug_line_header, version);
403}
404
405
406static void add_compilation_unit(struct growable_buffer * b,
407				 size_t offset_debug_line)
408{
409	struct compilation_unit_header * comp_unit_header;
410
411	size_t old_size = b->size;
412
413	add_data(b, &default_comp_unit_header,
414		 sizeof(default_comp_unit_header));
415
416	emit_unsigned_LEB128(b, 1);
417	emit_uword(b, offset_debug_line);
418
419	comp_unit_header = b->p + old_size;
420	comp_unit_header->total_length = (b->size - old_size) -
421		offsetof(struct compilation_unit_header, version);
422	comp_unit_header->pointer_size = sizeof(void *);
423}
424
425
426static void create_debug_abbrev(struct growable_buffer * b)
427{
428	emit_unsigned_LEB128(b, 1);
429	emit_unsigned_LEB128(b, DW_TAG_compile_unit);
430	emit_unsigned_LEB128(b, DW_CHILDREN_yes);
431	emit_unsigned_LEB128(b, DW_AT_stmt_list);
432	emit_unsigned_LEB128(b, DW_FORM_data4);
433	emit_unsigned_LEB128(b, 0);
434}
435
436static struct growable_buffer b_line;
437static struct growable_buffer b_debug_info;
438static struct growable_buffer b_debug_abbrev;
439
440int init_debug_line_info(bfd * abfd)
441{
442	asection * line_section, * debug_info, * debug_abbrev;
443	struct jitentry_debug_line * debug_line;
444
445	init_buffer(&b_line);
446	init_buffer(&b_debug_info);
447	init_buffer(&b_debug_abbrev);
448
449	for (debug_line = jitentry_debug_line_list;
450	     debug_line;
451	     debug_line = debug_line->next) {
452		struct jr_code_debug_info const * rec = debug_line->data;
453		if (rec->nr_entry) {
454			size_t i;
455			void const * data = rec + 1;
456			struct debug_line_info * dbg_line =
457				xmalloc(rec->nr_entry *
458					sizeof(struct debug_line_info));
459			for (i = 0; i < rec->nr_entry; ++i) {
460				dbg_line[i].vma = *(unsigned long *)data;
461				data += sizeof(unsigned long);
462				dbg_line[i].lineno = *(unsigned int *)data;
463				data += sizeof(unsigned int);
464				dbg_line[i].filename = data;
465				data += strlen(data) + 1;
466			}
467
468			add_compilation_unit(&b_debug_info, b_line.size);
469			add_debug_line(&b_line, dbg_line,
470				       rec->nr_entry, rec->code_addr);
471			create_debug_abbrev(&b_debug_abbrev);
472
473			free(dbg_line);
474		}
475	}
476
477	line_section = create_section(abfd, ".debug_line", b_line.size, 0,
478		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
479	if (!line_section)
480		return -1;
481
482	debug_info = create_section(abfd, ".debug_info", b_debug_info.size, 0,
483		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
484 	if (!debug_info)
485		return -1;
486
487	debug_abbrev = create_section(abfd, ".debug_abbrev",
488		b_debug_abbrev.size, 0,
489		SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
490	if (!debug_abbrev)
491		return -1;
492
493	return 0;
494}
495
496
497int finalize_debug_line_info(bfd * abfd)
498{
499	asection * line_section, * debug_info, * debug_abbrev;
500
501	line_section = bfd_get_section_by_name(abfd, ".debug_line");
502	if (!line_section)
503		return -1;
504
505	debug_info = bfd_get_section_by_name(abfd, ".debug_info");
506 	if (!debug_info)
507		return -1;
508
509
510	debug_abbrev = bfd_get_section_by_name(abfd, ".debug_abbrev");
511	if (!debug_abbrev)
512		return -1;
513
514	fill_section_content(abfd, line_section, b_line.p, 0, b_line.size);
515	fill_section_content(abfd, debug_info, b_debug_info.p,
516			     0, b_debug_info.size);
517	fill_section_content(abfd, debug_abbrev, b_debug_abbrev.p, 0,
518			     b_debug_abbrev.size);
519
520
521	free_buffer(&b_line);
522	free_buffer(&b_debug_info);
523	free_buffer(&b_debug_abbrev);
524
525	return 0;
526}
527