xref: /openbmc/linux/tools/perf/util/genelf_debug.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * genelf_debug.c
4   * Copyright (C) 2015, Google, Inc
5   *
6   * Contributed by:
7   * 	Stephane Eranian <eranian@google.com>
8   *
9   * based on GPLv2 source code from Oprofile
10   * @remark Copyright 2007 OProfile authors
11   * @author Philippe Elie
12   */
13  #include <linux/compiler.h>
14  #include <linux/zalloc.h>
15  #include <sys/types.h>
16  #include <stdio.h>
17  #include <getopt.h>
18  #include <stddef.h>
19  #include <libelf.h>
20  #include <string.h>
21  #include <stdlib.h>
22  #include <inttypes.h>
23  #include <limits.h>
24  #include <fcntl.h>
25  #include <err.h>
26  #include <dwarf.h>
27  
28  #include "genelf.h"
29  #include "../util/jitdump.h"
30  
31  #define BUFFER_EXT_DFL_SIZE	(4 * 1024)
32  
33  typedef uint32_t uword;
34  typedef uint16_t uhalf;
35  typedef int32_t  sword;
36  typedef int16_t  shalf;
37  typedef uint8_t  ubyte;
38  typedef int8_t   sbyte;
39  
40  struct buffer_ext {
41  	size_t cur_pos;
42  	size_t max_sz;
43  	void *data;
44  };
45  
46  static void
buffer_ext_dump(struct buffer_ext * be,const char * msg)47  buffer_ext_dump(struct buffer_ext *be, const char *msg)
48  {
49  	size_t i;
50  	warnx("DUMP for %s", msg);
51  	for (i = 0 ; i < be->cur_pos; i++)
52  		warnx("%4zu 0x%02x", i, (((char *)be->data)[i]) & 0xff);
53  }
54  
55  static inline int
buffer_ext_add(struct buffer_ext * be,void * addr,size_t sz)56  buffer_ext_add(struct buffer_ext *be, void *addr, size_t sz)
57  {
58  	void *tmp;
59  	size_t be_sz = be->max_sz;
60  
61  retry:
62  	if ((be->cur_pos + sz) < be_sz) {
63  		memcpy(be->data + be->cur_pos, addr, sz);
64  		be->cur_pos += sz;
65  		return 0;
66  	}
67  
68  	if (!be_sz)
69  		be_sz = BUFFER_EXT_DFL_SIZE;
70  	else
71  		be_sz <<= 1;
72  
73  	tmp = realloc(be->data, be_sz);
74  	if (!tmp)
75  		return -1;
76  
77  	be->data   = tmp;
78  	be->max_sz = be_sz;
79  
80  	goto retry;
81  }
82  
83  static void
buffer_ext_init(struct buffer_ext * be)84  buffer_ext_init(struct buffer_ext *be)
85  {
86  	be->data = NULL;
87  	be->cur_pos = 0;
88  	be->max_sz = 0;
89  }
90  
91  static void
buffer_ext_exit(struct buffer_ext * be)92  buffer_ext_exit(struct buffer_ext *be)
93  {
94  	zfree(&be->data);
95  }
96  
97  static inline size_t
buffer_ext_size(struct buffer_ext * be)98  buffer_ext_size(struct buffer_ext *be)
99  {
100  	return be->cur_pos;
101  }
102  
103  static inline void *
buffer_ext_addr(struct buffer_ext * be)104  buffer_ext_addr(struct buffer_ext *be)
105  {
106  	return be->data;
107  }
108  
109  struct debug_line_header {
110  	// Not counting this field
111  	uword total_length;
112  	// version number (2 currently)
113  	uhalf version;
114  	// relative offset from next field to
115  	// program statement
116  	uword prolog_length;
117  	ubyte minimum_instruction_length;
118  	ubyte default_is_stmt;
119  	// line_base - see DWARF 2 specs
120  	sbyte line_base;
121  	// line_range - see DWARF 2 specs
122  	ubyte line_range;
123  	// number of opcode + 1
124  	ubyte opcode_base;
125  	/* follow the array of opcode args nr: ubytes [nr_opcode_base] */
126  	/* follow the search directories index, zero terminated string
127  	 * terminated by an empty string.
128  	 */
129  	/* follow an array of { filename, LEB128, LEB128, LEB128 }, first is
130  	 * the directory index entry, 0 means current directory, then mtime
131  	 * and filesize, last entry is followed by en empty string.
132  	 */
133  	/* follow the first program statement */
134  } __packed;
135  
136  /* DWARF 2 spec talk only about one possible compilation unit header while
137   * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
138   * related to the used arch, an ELF 32 can hold more than 4 Go of debug
139   * information. For now we handle only DWARF 2 32 bits comp unit. It'll only
140   * become a problem if we generate more than 4GB of debug information.
141   */
142  struct compilation_unit_header {
143  	uword total_length;
144  	uhalf version;
145  	uword debug_abbrev_offset;
146  	ubyte pointer_size;
147  } __packed;
148  
149  #define DW_LNS_num_opcode (DW_LNS_set_isa + 1)
150  
151  /* field filled at run time are marked with -1 */
152  static struct debug_line_header const default_debug_line_header = {
153  	.total_length = -1,
154  	.version = 2,
155  	.prolog_length = -1,
156  	.minimum_instruction_length = 1,	/* could be better when min instruction size != 1 */
157  	.default_is_stmt = 1,	/* we don't take care about basic block */
158  	.line_base = -5,	/* sensible value for line base ... */
159  	.line_range = -14,     /* ... and line range are guessed statically */
160  	.opcode_base = DW_LNS_num_opcode
161  };
162  
163  static ubyte standard_opcode_length[] =
164  {
165  	0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1
166  };
167  #if 0
168  {
169  	[DW_LNS_advance_pc]   = 1,
170  	[DW_LNS_advance_line] = 1,
171  	[DW_LNS_set_file] =  1,
172  	[DW_LNS_set_column] = 1,
173  	[DW_LNS_fixed_advance_pc] = 1,
174  	[DW_LNS_set_isa] = 1,
175  };
176  #endif
177  
178  /* field filled at run time are marked with -1 */
179  static struct compilation_unit_header default_comp_unit_header = {
180  	.total_length = -1,
181  	.version = 2,
182  	.debug_abbrev_offset = 0,     /* we reuse the same abbrev entries for all comp unit */
183  	.pointer_size = sizeof(void *)
184  };
185  
emit_uword(struct buffer_ext * be,uword data)186  static void emit_uword(struct buffer_ext *be, uword data)
187  {
188  	buffer_ext_add(be, &data, sizeof(uword));
189  }
190  
emit_string(struct buffer_ext * be,const char * s)191  static void emit_string(struct buffer_ext *be, const char *s)
192  {
193  	buffer_ext_add(be, (void *)s, strlen(s) + 1);
194  }
195  
emit_unsigned_LEB128(struct buffer_ext * be,unsigned long data)196  static void emit_unsigned_LEB128(struct buffer_ext *be,
197  				 unsigned long data)
198  {
199  	do {
200  		ubyte cur = data & 0x7F;
201  		data >>= 7;
202  		if (data)
203  			cur |= 0x80;
204  		buffer_ext_add(be, &cur, 1);
205  	} while (data);
206  }
207  
emit_signed_LEB128(struct buffer_ext * be,long data)208  static void emit_signed_LEB128(struct buffer_ext *be, long data)
209  {
210  	int more = 1;
211  	int negative = data < 0;
212  	int size = sizeof(long) * CHAR_BIT;
213  	while (more) {
214  		ubyte cur = data & 0x7F;
215  		data >>= 7;
216  		if (negative)
217  			data |= - (1 << (size - 7));
218  		if ((data == 0 && !(cur & 0x40)) ||
219  		    (data == -1l && (cur & 0x40)))
220  			more = 0;
221  		else
222  			cur |= 0x80;
223  		buffer_ext_add(be, &cur, 1);
224  	}
225  }
226  
emit_extended_opcode(struct buffer_ext * be,ubyte opcode,void * data,size_t data_len)227  static void emit_extended_opcode(struct buffer_ext *be, ubyte opcode,
228  				 void *data, size_t data_len)
229  {
230  	buffer_ext_add(be, (char *)"", 1);
231  
232  	emit_unsigned_LEB128(be, data_len + 1);
233  
234  	buffer_ext_add(be, &opcode, 1);
235  	buffer_ext_add(be, data, data_len);
236  }
237  
emit_opcode(struct buffer_ext * be,ubyte opcode)238  static void emit_opcode(struct buffer_ext *be, ubyte opcode)
239  {
240  	buffer_ext_add(be, &opcode, 1);
241  }
242  
emit_opcode_signed(struct buffer_ext * be,ubyte opcode,long data)243  static void emit_opcode_signed(struct buffer_ext  *be,
244  			       ubyte opcode, long data)
245  {
246  	buffer_ext_add(be, &opcode, 1);
247  	emit_signed_LEB128(be, data);
248  }
249  
emit_opcode_unsigned(struct buffer_ext * be,ubyte opcode,unsigned long data)250  static void emit_opcode_unsigned(struct buffer_ext *be, ubyte opcode,
251  				 unsigned long data)
252  {
253  	buffer_ext_add(be, &opcode, 1);
254  	emit_unsigned_LEB128(be, data);
255  }
256  
emit_advance_pc(struct buffer_ext * be,unsigned long delta_pc)257  static void emit_advance_pc(struct buffer_ext *be, unsigned long delta_pc)
258  {
259  	emit_opcode_unsigned(be, DW_LNS_advance_pc, delta_pc);
260  }
261  
emit_advance_lineno(struct buffer_ext * be,long delta_lineno)262  static void emit_advance_lineno(struct buffer_ext  *be, long delta_lineno)
263  {
264  	emit_opcode_signed(be, DW_LNS_advance_line, delta_lineno);
265  }
266  
emit_lne_end_of_sequence(struct buffer_ext * be)267  static void emit_lne_end_of_sequence(struct buffer_ext *be)
268  {
269  	emit_extended_opcode(be, DW_LNE_end_sequence, NULL, 0);
270  }
271  
emit_set_file(struct buffer_ext * be,unsigned long idx)272  static void emit_set_file(struct buffer_ext *be, unsigned long idx)
273  {
274  	emit_opcode_unsigned(be, DW_LNS_set_file, idx);
275  }
276  
emit_lne_define_filename(struct buffer_ext * be,const char * filename)277  static void emit_lne_define_filename(struct buffer_ext *be,
278  				     const char *filename)
279  {
280  	buffer_ext_add(be, (void *)"", 1);
281  
282  	/* LNE field, strlen(filename) + zero termination, 3 bytes for: the dir entry, timestamp, filesize */
283  	emit_unsigned_LEB128(be, strlen(filename) + 5);
284  	emit_opcode(be, DW_LNE_define_file);
285  	emit_string(be, filename);
286  	/* directory index 0=do not know */
287          emit_unsigned_LEB128(be, 0);
288  	/* last modification date on file 0=do not know */
289          emit_unsigned_LEB128(be, 0);
290  	/* filesize 0=do not know */
291          emit_unsigned_LEB128(be, 0);
292  }
293  
emit_lne_set_address(struct buffer_ext * be,void * address)294  static void emit_lne_set_address(struct buffer_ext *be,
295  				 void *address)
296  {
297  	emit_extended_opcode(be, DW_LNE_set_address, &address, sizeof(unsigned long));
298  }
299  
get_special_opcode(struct debug_entry * ent,unsigned int last_line,unsigned long last_vma)300  static ubyte get_special_opcode(struct debug_entry *ent,
301  				unsigned int last_line,
302  				unsigned long last_vma)
303  {
304  	unsigned int temp;
305  	unsigned long delta_addr;
306  
307  	/*
308  	 * delta from line_base
309  	 */
310  	temp = (ent->lineno - last_line) - default_debug_line_header.line_base;
311  
312  	if (temp >= default_debug_line_header.line_range)
313  		return 0;
314  
315  	/*
316  	 * delta of addresses
317  	 */
318  	delta_addr = (ent->addr - last_vma) / default_debug_line_header.minimum_instruction_length;
319  
320  	/* This is not sufficient to ensure opcode will be in [0-256] but
321  	 * sufficient to ensure when summing with the delta lineno we will
322  	 * not overflow the unsigned long opcode */
323  
324  	if (delta_addr <= 256 / default_debug_line_header.line_range) {
325  		unsigned long opcode = temp +
326  			(delta_addr * default_debug_line_header.line_range) +
327  			default_debug_line_header.opcode_base;
328  
329  		return opcode <= 255 ? opcode : 0;
330  	}
331  	return 0;
332  }
333  
emit_lineno_info(struct buffer_ext * be,struct debug_entry * ent,size_t nr_entry,unsigned long code_addr)334  static void emit_lineno_info(struct buffer_ext *be,
335  			     struct debug_entry *ent, size_t nr_entry,
336  			     unsigned long code_addr)
337  {
338  	size_t i;
339  
340  	/* as described in the jitdump format */
341  	const char repeated_name_marker[] = {'\xff', '\0'};
342  
343  	/*
344  	 * Machine state at start of a statement program
345  	 * address = 0
346  	 * file    = 1
347  	 * line    = 1
348  	 * column  = 0
349  	 * is_stmt = default_is_stmt as given in the debug_line_header
350  	 * basic block = 0
351  	 * end sequence = 0
352  	 */
353  
354  	/* start state of the state machine we take care of */
355  	unsigned long last_vma = 0;
356  	char const  *cur_filename = NULL;
357  	unsigned long cur_file_idx = 0;
358  	int last_line = 1;
359  
360  	emit_lne_set_address(be, (void *)code_addr);
361  
362  	for (i = 0; i < nr_entry; i++, ent = debug_entry_next(ent)) {
363  		int need_copy = 0;
364  		ubyte special_opcode;
365  
366  		/*
367  		 * check if filename changed, if so add it
368  		 */
369  		if ((!cur_filename || strcmp(cur_filename, ent->name)) &&
370  			strcmp(repeated_name_marker, ent->name)) {
371  			emit_lne_define_filename(be, ent->name);
372  			cur_filename = ent->name;
373  			emit_set_file(be, ++cur_file_idx);
374  			need_copy = 1;
375  		}
376  
377  		special_opcode = get_special_opcode(ent, last_line, last_vma);
378  		if (special_opcode != 0) {
379  			last_line = ent->lineno;
380  			last_vma  = ent->addr;
381  			emit_opcode(be, special_opcode);
382  		} else {
383  			/*
384  			 * lines differ, emit line delta
385  			 */
386  			if (last_line != ent->lineno) {
387  				emit_advance_lineno(be, ent->lineno - last_line);
388  				last_line = ent->lineno;
389  				need_copy = 1;
390  			}
391  			/*
392  			 * addresses differ, emit address delta
393  			 */
394  			if (last_vma != ent->addr) {
395  				emit_advance_pc(be, ent->addr - last_vma);
396  				last_vma = ent->addr;
397  				need_copy = 1;
398  			}
399  			/*
400  			 * add new row to matrix
401  			 */
402  			if (need_copy)
403  				emit_opcode(be, DW_LNS_copy);
404  		}
405  	}
406  }
407  
add_debug_line(struct buffer_ext * be,struct debug_entry * ent,size_t nr_entry,unsigned long code_addr)408  static void add_debug_line(struct buffer_ext *be,
409  	struct debug_entry *ent, size_t nr_entry,
410  	unsigned long code_addr)
411  {
412  	struct debug_line_header * dbg_header;
413  	size_t old_size;
414  
415  	old_size = buffer_ext_size(be);
416  
417  	buffer_ext_add(be, (void *)&default_debug_line_header,
418  		 sizeof(default_debug_line_header));
419  
420  	buffer_ext_add(be, &standard_opcode_length,  sizeof(standard_opcode_length));
421  
422  	// empty directory entry
423  	buffer_ext_add(be, (void *)"", 1);
424  
425  	// empty filename directory
426  	buffer_ext_add(be, (void *)"", 1);
427  
428  	dbg_header = buffer_ext_addr(be) + old_size;
429  	dbg_header->prolog_length = (buffer_ext_size(be) - old_size) -
430  		offsetof(struct debug_line_header, minimum_instruction_length);
431  
432  	emit_lineno_info(be, ent, nr_entry, code_addr);
433  
434  	emit_lne_end_of_sequence(be);
435  
436  	dbg_header = buffer_ext_addr(be) + old_size;
437  	dbg_header->total_length = (buffer_ext_size(be) - old_size) -
438  		offsetof(struct debug_line_header, version);
439  }
440  
441  static void
add_debug_abbrev(struct buffer_ext * be)442  add_debug_abbrev(struct buffer_ext *be)
443  {
444          emit_unsigned_LEB128(be, 1);
445          emit_unsigned_LEB128(be, DW_TAG_compile_unit);
446          emit_unsigned_LEB128(be, DW_CHILDREN_yes);
447          emit_unsigned_LEB128(be, DW_AT_stmt_list);
448          emit_unsigned_LEB128(be, DW_FORM_data4);
449          emit_unsigned_LEB128(be, 0);
450          emit_unsigned_LEB128(be, 0);
451          emit_unsigned_LEB128(be, 0);
452  }
453  
454  static void
add_compilation_unit(struct buffer_ext * be,size_t offset_debug_line)455  add_compilation_unit(struct buffer_ext *be,
456  		     size_t offset_debug_line)
457  {
458  	struct compilation_unit_header *comp_unit_header;
459  	size_t old_size = buffer_ext_size(be);
460  
461  	buffer_ext_add(be, &default_comp_unit_header,
462  		       sizeof(default_comp_unit_header));
463  
464  	emit_unsigned_LEB128(be, 1);
465  	emit_uword(be, offset_debug_line);
466  
467  	comp_unit_header = buffer_ext_addr(be) + old_size;
468  	comp_unit_header->total_length = (buffer_ext_size(be) - old_size) -
469  		offsetof(struct compilation_unit_header, version);
470  }
471  
472  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)473  jit_process_debug_info(uint64_t code_addr,
474  		       void *debug, int nr_debug_entries,
475  		       struct buffer_ext *dl,
476  		       struct buffer_ext *da,
477  		       struct buffer_ext *di)
478  {
479  	struct debug_entry *ent = debug;
480  	int i;
481  
482  	for (i = 0; i < nr_debug_entries; i++) {
483  		ent->addr = ent->addr - code_addr;
484  		ent = debug_entry_next(ent);
485  	}
486  	add_compilation_unit(di, buffer_ext_size(dl));
487  	add_debug_line(dl, debug, nr_debug_entries, GEN_ELF_TEXT_OFFSET);
488  	add_debug_abbrev(da);
489  	if (0) buffer_ext_dump(da, "abbrev");
490  
491  	return 0;
492  }
493  
494  int
jit_add_debug_info(Elf * e,uint64_t code_addr,void * debug,int nr_debug_entries)495  jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries)
496  {
497  	Elf_Data *d;
498  	Elf_Scn *scn;
499  	Elf_Shdr *shdr;
500  	struct buffer_ext dl, di, da;
501  	int ret = -1;
502  
503  	buffer_ext_init(&dl);
504  	buffer_ext_init(&di);
505  	buffer_ext_init(&da);
506  
507  	if (jit_process_debug_info(code_addr, debug, nr_debug_entries, &dl, &da, &di))
508  		goto out;
509  
510  	/*
511  	 * setup .debug_line section
512  	 */
513  	scn = elf_newscn(e);
514  	if (!scn) {
515  		warnx("cannot create section");
516  		goto out;
517  	}
518  
519  	d = elf_newdata(scn);
520  	if (!d) {
521  		warnx("cannot get new data");
522  		goto out;
523  	}
524  
525  	d->d_align = 1;
526  	d->d_off = 0LL;
527  	d->d_buf = buffer_ext_addr(&dl);
528  	d->d_type = ELF_T_BYTE;
529  	d->d_size = buffer_ext_size(&dl);
530  	d->d_version = EV_CURRENT;
531  
532  	shdr = elf_getshdr(scn);
533  	if (!shdr) {
534  		warnx("cannot get section header");
535  		goto out;
536  	}
537  
538  	shdr->sh_name = 52; /* .debug_line */
539  	shdr->sh_type = SHT_PROGBITS;
540  	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
541  	shdr->sh_flags = 0;
542  	shdr->sh_entsize = 0;
543  
544  	/*
545  	 * setup .debug_info section
546  	 */
547  	scn = elf_newscn(e);
548  	if (!scn) {
549  		warnx("cannot create section");
550  		goto out;
551  	}
552  
553  	d = elf_newdata(scn);
554  	if (!d) {
555  		warnx("cannot get new data");
556  		goto out;
557  	}
558  
559  	d->d_align = 1;
560  	d->d_off = 0LL;
561  	d->d_buf = buffer_ext_addr(&di);
562  	d->d_type = ELF_T_BYTE;
563  	d->d_size = buffer_ext_size(&di);
564  	d->d_version = EV_CURRENT;
565  
566  	shdr = elf_getshdr(scn);
567  	if (!shdr) {
568  		warnx("cannot get section header");
569  		goto out;
570  	}
571  
572  	shdr->sh_name = 64; /* .debug_info */
573  	shdr->sh_type = SHT_PROGBITS;
574  	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
575  	shdr->sh_flags = 0;
576  	shdr->sh_entsize = 0;
577  
578  	/*
579  	 * setup .debug_abbrev section
580  	 */
581  	scn = elf_newscn(e);
582  	if (!scn) {
583  		warnx("cannot create section");
584  		goto out;
585  	}
586  
587  	d = elf_newdata(scn);
588  	if (!d) {
589  		warnx("cannot get new data");
590  		goto out;
591  	}
592  
593  	d->d_align = 1;
594  	d->d_off = 0LL;
595  	d->d_buf = buffer_ext_addr(&da);
596  	d->d_type = ELF_T_BYTE;
597  	d->d_size = buffer_ext_size(&da);
598  	d->d_version = EV_CURRENT;
599  
600  	shdr = elf_getshdr(scn);
601  	if (!shdr) {
602  		warnx("cannot get section header");
603  		goto out;
604  	}
605  
606  	shdr->sh_name = 76; /* .debug_info */
607  	shdr->sh_type = SHT_PROGBITS;
608  	shdr->sh_addr = 0; /* must be zero or == sh_offset -> dynamic object */
609  	shdr->sh_flags = 0;
610  	shdr->sh_entsize = 0;
611  
612  	/*
613  	 * now we update the ELF image with all the sections
614  	 */
615  	if (elf_update(e, ELF_C_WRITE) < 0)
616  		warnx("elf_update debug failed");
617  	else
618  		ret = 0;
619  
620  out:
621  	buffer_ext_exit(&dl);
622  	buffer_ext_exit(&di);
623  	buffer_ext_exit(&da);
624  	return ret;
625  }
626