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