struct debug_line_header { // Not counting this field
uword total_length; // version number (2 currently)
uhalf version; // relative offset from next field to // program statement
uword prolog_length;
ubyte minimum_instruction_length;
ubyte default_is_stmt; // line_base - see DWARF 2 specs
sbyte line_base; // line_range - see DWARF 2 specs
ubyte line_range; // number of opcode + 1
ubyte opcode_base; /* follow the array of opcode args nr: ubytes [nr_opcode_base] */ /* follow the search directories index, zero terminated string *terminatedbyanemptystring.
*/ /* follow an array of { filename, LEB128, LEB128, LEB128 }, first is *thedirectoryindexentry,0meanscurrentdirectory,thenmtime *andfilesize,lastentryisfollowedbyenemptystring.
*/ /* follow the first program statement */
} __packed;
/* DWARF 2 spec talk only about one possible compilation unit header while *binutilscanhandletwoflavoursofdwarf2,32and64bits,thisisnot *relatedtotheusedarch,anELF32canholdmorethan4Goofdebug *information.FornowwehandleonlyDWARF232bitscompunit.It'llonly *becomeaproblemifwegeneratemorethan4GBofdebuginformation.
*/ struct compilation_unit_header {
uword total_length;
uhalf version;
uword debug_abbrev_offset;
ubyte pointer_size;
} __packed;
#define DW_LNS_num_opcode (DW_LNS_set_isa + 1)
/* field filled at run time are marked with -1 */ staticstruct debug_line_header const default_debug_line_header = {
.total_length = -1,
.version = 2,
.prolog_length = -1,
.minimum_instruction_length = 1, /* could be better when min instruction size != 1 */
.default_is_stmt = 1, /* we don't take care about basic block */
.line_base = -5, /* sensible value for line base ... */
.line_range = -14, /* ... and line range are guessed statically */
.opcode_base = DW_LNS_num_opcode
};
/* field filled at run time are marked with -1 */ staticstruct compilation_unit_header default_comp_unit_header = {
.total_length = -1,
.version = 2,
.debug_abbrev_offset = 0, /* we reuse the same abbrev entries for all comp unit */
.pointer_size = sizeof(void *)
};
staticvoid emit_unsigned_LEB128(struct buffer_ext *be, unsignedlong data)
{ do {
ubyte cur = data & 0x7F;
data >>= 7; if (data)
cur |= 0x80;
buffer_ext_add(be, &cur, 1);
} while (data);
}
staticvoid emit_signed_LEB128(struct buffer_ext *be, long data)
{ int more = 1; int negative = data < 0; int size = sizeof(long) * CHAR_BIT; while (more) {
ubyte cur = data & 0x7F;
data >>= 7; if (negative)
data |= - (1 << (size - 7)); if ((data == 0 && !(cur & 0x40)) ||
(data == -1l && (cur & 0x40)))
more = 0; else
cur |= 0x80;
buffer_ext_add(be, &cur, 1);
}
}
/* This is not sufficient to ensure opcode will be in [0-256] but *sufficienttoensurewhensummingwiththedeltalinenowewill
* not overflow the unsigned long opcode */
/* start state of the state machine we take care of */ unsignedlong last_vma = 0; charconst *cur_filename = NULL; unsignedlong cur_file_idx = 0; int last_line = 1;
emit_lne_set_address(be, (void *)code_addr);
for (i = 0; i < nr_entry; i++, ent = debug_entry_next(ent)) { int need_copy = 0;
ubyte special_opcode;
for (i = 0; i < nr_debug_entries; i++) {
ent->addr = ent->addr - code_addr;
ent = debug_entry_next(ent);
}
add_compilation_unit(di, buffer_ext_size(dl));
add_debug_line(dl, debug, nr_debug_entries, GEN_ELF_TEXT_OFFSET);
add_debug_abbrev(da); if (0) buffer_ext_dump(da, "abbrev");
return0;
}
int
jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries)
{
Elf_Data *d;
Elf_Scn *scn;
Elf_Shdr *shdr; struct buffer_ext dl, di, da; int ret = -1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.