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
30 typedef uint32_t uword;
31 typedef uint16_t uhalf;
32 typedef int32_t sword;
33 typedef int16_t shalf;
34 typedef uint8_t ubyte;
35 typedef int8_t sbyte;
36
37 /*
38 * Many of the following enum are incomplete and define only the subset
39 * of DWARF we use.
40 */
41 enum 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
58 enum lne_opcode {
59 DW_LNE_end_sequence = 1,
60 DW_LNE_set_address,
61 DW_LNE_define_file
62 };
63
64 enum dw_tag {
65 DW_TAG_compile_unit = 0x11,
66 };
67
68 enum 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
78 enum dw_children {
79 DW_CHILDREN_no,
80 DW_CHILDREN_yes
81 };
82
83 enum dw_form {
84 DW_FORM_data4 = 0x06,
85 };
86
87 struct 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 */
120 struct 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 */
128 static 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
139 static 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 */
145 static 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
emit_uword(struct growable_buffer * b,uword data)153 static void emit_uword(struct growable_buffer * b, uword data)
154 {
155 add_data(b, &data, sizeof(uword));
156 }
157
158
emit_string(struct growable_buffer * b,char const * s)159 static void emit_string(struct growable_buffer * b, char const * s)
160 {
161 add_data(b, s, strlen(s) + 1);
162 }
163
164
emit_unsigned_LEB128(struct growable_buffer * b,unsigned long data)165 static 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
emit_signed_LEB128(struct growable_buffer * b,long data)178 static 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
emit_extended_opcode(struct growable_buffer * b,ubyte opcode,void * data,size_t data_len)198 static 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
emit_opcode(struct growable_buffer * b,ubyte opcode)208 static void emit_opcode(struct growable_buffer * b, ubyte opcode)
209 {
210 add_data(b, &opcode, 1);
211 }
212
213
emit_opcode_signed(struct growable_buffer * b,ubyte opcode,long data)214 static 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
emit_opcode_unsigned(struct growable_buffer * b,ubyte opcode,unsigned long data)222 static 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
emit_advance_pc(struct growable_buffer * b,unsigned long delta_pc)230 static 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
emit_advance_lineno(struct growable_buffer * b,long delta_lineno)236 static 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
emit_lne_end_of_sequence(struct growable_buffer * b)242 static 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
emit_set_file(struct growable_buffer * b,unsigned long index)248 static 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
emit_lne_define_filename(struct growable_buffer * b,char const * filename)254 static 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
emit_lne_set_address(struct growable_buffer * b,void const * address)269 static 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
get_special_opcode(struct debug_line_info const * line,unsigned int last_lineno,unsigned long last_vma)276 static 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
emit_lineno_info(struct growable_buffer * b,struct debug_line_info const * line,size_t nr_entry,unsigned long code_addr)306 static 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
add_debug_line(struct growable_buffer * b,struct debug_line_info const * line,size_t nr_entry,unsigned long code_addr)373 static 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
add_compilation_unit(struct growable_buffer * b,size_t offset_debug_line)406 static 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
create_debug_abbrev(struct growable_buffer * b)426 static 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
436 static struct growable_buffer b_line;
437 static struct growable_buffer b_debug_info;
438 static struct growable_buffer b_debug_abbrev;
439
init_debug_line_info(bfd * abfd)440 int 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
finalize_debug_line_info(bfd * abfd)497 int 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