dwarf2-line.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156
  1. /*
  2. * DWARF2 debugging format - line information
  3. *
  4. * Copyright (C) 2006-2007 Peter Johnson
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the author nor the names of other contributors
  15. * may be used to endorse or promote products derived from this
  16. * software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <util.h>
  31. #include <libyasm.h>
  32. #include "dwarf2-dbgfmt.h"
  33. /* DWARF line number opcodes */
  34. typedef enum {
  35. DW_LNS_extended_op = 0,
  36. DW_LNS_copy,
  37. DW_LNS_advance_pc,
  38. DW_LNS_advance_line,
  39. DW_LNS_set_file,
  40. DW_LNS_set_column,
  41. DW_LNS_negate_stmt,
  42. DW_LNS_set_basic_block,
  43. DW_LNS_const_add_pc,
  44. DW_LNS_fixed_advance_pc,
  45. #ifdef WITH_DWARF3
  46. /* DWARF 3 extensions */
  47. DW_LNS_set_prologue_end,
  48. DW_LNS_set_epilogue_begin,
  49. DW_LNS_set_isa,
  50. #endif
  51. DWARF2_LINE_OPCODE_BASE
  52. } dwarf_line_number_op;
  53. /* # of LEB128 operands needed for each of the above opcodes */
  54. static unsigned char line_opcode_num_operands[DWARF2_LINE_OPCODE_BASE-1] = {
  55. 0, /* DW_LNS_copy */
  56. 1, /* DW_LNS_advance_pc */
  57. 1, /* DW_LNS_advance_line */
  58. 1, /* DW_LNS_set_file */
  59. 1, /* DW_LNS_set_column */
  60. 0, /* DW_LNS_negate_stmt */
  61. 0, /* DW_LNS_set_basic_block */
  62. 0, /* DW_LNS_const_add_pc */
  63. 1, /* DW_LNS_fixed_advance_pc */
  64. #ifdef WITH_DWARF3
  65. 0, /* DW_LNS_set_prologue_end */
  66. 0, /* DW_LNS_set_epilogue_begin */
  67. 1 /* DW_LNS_set_isa */
  68. #endif
  69. };
  70. /* Line number extended opcodes */
  71. typedef enum {
  72. DW_LNE_end_sequence = 1,
  73. DW_LNE_set_address,
  74. DW_LNE_define_file,
  75. DW_LNE_set_discriminator
  76. } dwarf_line_number_ext_op;
  77. /* Base and range for line offsets in special opcodes */
  78. #define DWARF2_LINE_BASE -5
  79. #define DWARF2_LINE_RANGE 14
  80. #define DWARF2_MAX_SPECIAL_ADDR_DELTA \
  81. (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\
  82. dbgfmt_dwarf2->min_insn_len)
  83. /* Initial value of is_stmt register */
  84. #define DWARF2_LINE_DEFAULT_IS_STMT 1
  85. /* Line number state machine register state */
  86. typedef struct dwarf2_line_state {
  87. /* static configuration */
  88. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
  89. /* DWARF2 state machine registers */
  90. unsigned long address;
  91. unsigned long file;
  92. unsigned long line;
  93. unsigned long column;
  94. unsigned long isa;
  95. int is_stmt;
  96. /* other state information */
  97. /*@null@*/ yasm_bytecode *precbc;
  98. } dwarf2_line_state;
  99. typedef struct dwarf2_spp {
  100. yasm_bytecode *line_start_prevbc;
  101. yasm_bytecode *line_end_prevbc;
  102. } dwarf2_spp;
  103. typedef struct dwarf2_line_op {
  104. dwarf_line_number_op opcode;
  105. /*@owned@*/ /*@null@*/ yasm_intnum *operand;
  106. /* extended opcode */
  107. dwarf_line_number_ext_op ext_opcode;
  108. /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */
  109. /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */
  110. unsigned long ext_operandsize;
  111. } dwarf2_line_op;
  112. /* Bytecode callback function prototypes */
  113. static void dwarf2_spp_bc_destroy(void *contents);
  114. static void dwarf2_spp_bc_print(const void *contents, FILE *f,
  115. int indent_level);
  116. static int dwarf2_spp_bc_calc_len
  117. (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
  118. static int dwarf2_spp_bc_tobytes
  119. (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
  120. yasm_output_value_func output_value,
  121. /*@null@*/ yasm_output_reloc_func output_reloc);
  122. static void dwarf2_line_op_bc_destroy(void *contents);
  123. static void dwarf2_line_op_bc_print(const void *contents, FILE *f,
  124. int indent_level);
  125. static int dwarf2_line_op_bc_calc_len
  126. (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
  127. static int dwarf2_line_op_bc_tobytes
  128. (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
  129. yasm_output_value_func output_value,
  130. /*@null@*/ yasm_output_reloc_func output_reloc);
  131. /* Bytecode callback structures */
  132. static const yasm_bytecode_callback dwarf2_spp_bc_callback = {
  133. dwarf2_spp_bc_destroy,
  134. dwarf2_spp_bc_print,
  135. yasm_bc_finalize_common,
  136. NULL,
  137. dwarf2_spp_bc_calc_len,
  138. yasm_bc_expand_common,
  139. dwarf2_spp_bc_tobytes,
  140. 0
  141. };
  142. static const yasm_bytecode_callback dwarf2_line_op_bc_callback = {
  143. dwarf2_line_op_bc_destroy,
  144. dwarf2_line_op_bc_print,
  145. yasm_bc_finalize_common,
  146. NULL,
  147. dwarf2_line_op_bc_calc_len,
  148. yasm_bc_expand_common,
  149. dwarf2_line_op_bc_tobytes,
  150. 0
  151. };
  152. static size_t
  153. dwarf2_dbgfmt_add_file(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, unsigned long filenum,
  154. const char *pathname)
  155. {
  156. size_t dirlen;
  157. const char *filename;
  158. unsigned long i, dir;
  159. /* Put the directory into the directory table */
  160. dir = 0;
  161. dirlen = yasm__splitpath(pathname, &filename);
  162. if (dirlen > 0) {
  163. /* Look to see if we already have that dir in the table */
  164. for (dir=1; dir<dbgfmt_dwarf2->dirs_size+1; dir++) {
  165. if (strncmp(dbgfmt_dwarf2->dirs[dir-1], pathname, dirlen) == 0
  166. && dbgfmt_dwarf2->dirs[dir-1][dirlen] == '\0')
  167. break;
  168. }
  169. if (dir >= dbgfmt_dwarf2->dirs_size+1) {
  170. /* Not found in table, add to end, reallocing if necessary */
  171. if (dir >= dbgfmt_dwarf2->dirs_allocated+1) {
  172. dbgfmt_dwarf2->dirs_allocated = dir+32;
  173. dbgfmt_dwarf2->dirs = yasm_xrealloc(dbgfmt_dwarf2->dirs,
  174. sizeof(char *)*dbgfmt_dwarf2->dirs_allocated);
  175. }
  176. dbgfmt_dwarf2->dirs[dir-1] = yasm__xstrndup(pathname, dirlen);
  177. dbgfmt_dwarf2->dirs_size = dir;
  178. }
  179. }
  180. /* Put the filename into the filename table */
  181. if (filenum == 0) {
  182. /* Look to see if we already have that filename in the table */
  183. for (; filenum<dbgfmt_dwarf2->filenames_size; filenum++) {
  184. if (!dbgfmt_dwarf2->filenames[filenum].filename ||
  185. (dbgfmt_dwarf2->filenames[filenum].dir == dir
  186. && strcmp(dbgfmt_dwarf2->filenames[filenum].filename,
  187. filename) == 0))
  188. break;
  189. }
  190. } else
  191. filenum--; /* array index is 0-based */
  192. /* Realloc table if necessary */
  193. if (filenum >= dbgfmt_dwarf2->filenames_allocated) {
  194. unsigned long old_allocated = dbgfmt_dwarf2->filenames_allocated;
  195. dbgfmt_dwarf2->filenames_allocated = filenum+32;
  196. dbgfmt_dwarf2->filenames = yasm_xrealloc(dbgfmt_dwarf2->filenames,
  197. sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated);
  198. for (i=old_allocated; i<dbgfmt_dwarf2->filenames_allocated; i++) {
  199. dbgfmt_dwarf2->filenames[i].pathname = NULL;
  200. dbgfmt_dwarf2->filenames[i].filename = NULL;
  201. dbgfmt_dwarf2->filenames[i].dir = 0;
  202. }
  203. }
  204. /* Actually save in table */
  205. if (dbgfmt_dwarf2->filenames[filenum].pathname)
  206. yasm_xfree(dbgfmt_dwarf2->filenames[filenum].pathname);
  207. if (dbgfmt_dwarf2->filenames[filenum].filename)
  208. yasm_xfree(dbgfmt_dwarf2->filenames[filenum].filename);
  209. dbgfmt_dwarf2->filenames[filenum].pathname = yasm__xstrdup(pathname);
  210. dbgfmt_dwarf2->filenames[filenum].filename = yasm__xstrdup(filename);
  211. dbgfmt_dwarf2->filenames[filenum].dir = dir;
  212. /* Update table size */
  213. if (filenum >= dbgfmt_dwarf2->filenames_size)
  214. dbgfmt_dwarf2->filenames_size = filenum + 1;
  215. return filenum;
  216. }
  217. /* Create and add a new line opcode to a section, updating offset on insertion;
  218. * no optimization necessary.
  219. */
  220. static yasm_bytecode *
  221. dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode,
  222. /*@only@*/ /*@null@*/ yasm_intnum *operand)
  223. {
  224. dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
  225. yasm_bytecode *bc;
  226. line_op->opcode = opcode;
  227. line_op->operand = operand;
  228. line_op->ext_opcode = 0;
  229. line_op->ext_operand = NULL;
  230. line_op->ext_operand_int = NULL;
  231. line_op->ext_operandsize = 0;
  232. bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
  233. bc->len = 1;
  234. if (operand)
  235. bc->len += yasm_intnum_size_leb128(operand,
  236. opcode == DW_LNS_advance_line);
  237. yasm_dwarf2__append_bc(sect, bc);
  238. return bc;
  239. }
  240. /* Create and add a new extended line opcode to a section, updating offset on
  241. * insertion; no optimization necessary.
  242. */
  243. static yasm_bytecode *
  244. dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect,
  245. dwarf_line_number_ext_op ext_opcode,
  246. unsigned long ext_operandsize,
  247. /*@null@*/ yasm_symrec *ext_operand)
  248. {
  249. dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
  250. yasm_bytecode *bc;
  251. line_op->opcode = DW_LNS_extended_op;
  252. line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
  253. line_op->ext_opcode = ext_opcode;
  254. line_op->ext_operand = ext_operand;
  255. line_op->ext_operand_int = NULL;
  256. line_op->ext_operandsize = ext_operandsize;
  257. bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
  258. bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
  259. ext_operandsize;
  260. yasm_dwarf2__append_bc(sect, bc);
  261. return bc;
  262. }
  263. static yasm_bytecode *
  264. dwarf2_dbgfmt_append_line_ext_op_int(yasm_section *sect,
  265. dwarf_line_number_ext_op ext_opcode,
  266. /*@only@*/ yasm_intnum *ext_operand)
  267. {
  268. dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op));
  269. unsigned long ext_operandsize = yasm_intnum_size_leb128(ext_operand, 0);
  270. yasm_bytecode *bc;
  271. line_op->opcode = DW_LNS_extended_op;
  272. line_op->operand = yasm_intnum_create_uint(ext_operandsize+1);
  273. line_op->ext_opcode = ext_opcode;
  274. line_op->ext_operand = NULL;
  275. line_op->ext_operand_int = ext_operand;
  276. line_op->ext_operandsize = ext_operandsize;
  277. bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0);
  278. bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) +
  279. ext_operandsize;
  280. yasm_dwarf2__append_bc(sect, bc);
  281. return bc;
  282. }
  283. static void
  284. dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd)
  285. {
  286. /*@dependent@*/ yasm_symrec *lastsym = NULL;
  287. /*@null@*/ yasm_bytecode *bc;
  288. /*@null@*/ dwarf2_loc *loc;
  289. bc = yasm_section_bcs_first(sect);
  290. STAILQ_FOREACH(loc, &dsd->locs, link) {
  291. /* Find the first bytecode following this loc by looking at
  292. * the virtual line numbers. XXX: this assumes the source file
  293. * order will be the same as the actual section order. If we ever
  294. * implement subsegs this will NOT necessarily be true and this logic
  295. * will need to be fixed to handle it!
  296. *
  297. * Keep track of last symbol seen prior to the loc.
  298. */
  299. while (bc && bc->line <= loc->vline) {
  300. if (bc->symrecs) {
  301. int i = 0;
  302. while (bc->symrecs[i]) {
  303. lastsym = bc->symrecs[i];
  304. i++;
  305. }
  306. }
  307. bc = yasm_bc__next(bc);
  308. }
  309. loc->sym = lastsym;
  310. loc->bc = bc;
  311. }
  312. }
  313. static int
  314. dwarf2_dbgfmt_gen_line_op(yasm_section *debug_line, dwarf2_line_state *state,
  315. const dwarf2_loc *loc,
  316. /*@null@*/ const dwarf2_loc *nextloc)
  317. {
  318. unsigned long addr_delta;
  319. long line_delta;
  320. int opcode1, opcode2;
  321. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = state->dbgfmt_dwarf2;
  322. if (state->file != loc->file) {
  323. state->file = loc->file;
  324. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file,
  325. yasm_intnum_create_uint(state->file));
  326. }
  327. if (state->column != loc->column) {
  328. state->column = loc->column;
  329. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column,
  330. yasm_intnum_create_uint(state->column));
  331. }
  332. if (loc->discriminator != 0) {
  333. dwarf2_dbgfmt_append_line_ext_op_int(debug_line,
  334. DW_LNE_set_discriminator,
  335. yasm_intnum_create_uint(loc->discriminator));
  336. }
  337. #ifdef WITH_DWARF3
  338. if (loc->isa_change) {
  339. state->isa = loc->isa;
  340. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa,
  341. yasm_intnum_create_uint(state->isa));
  342. }
  343. #endif
  344. if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) {
  345. state->is_stmt = 1;
  346. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
  347. } else if (state->is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) {
  348. state->is_stmt = 0;
  349. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL);
  350. }
  351. if (loc->basic_block) {
  352. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_basic_block, NULL);
  353. }
  354. #ifdef WITH_DWARF3
  355. if (loc->prologue_end) {
  356. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_prologue_end, NULL);
  357. }
  358. if (loc->epilogue_begin) {
  359. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_epilogue_begin,
  360. NULL);
  361. }
  362. #endif
  363. /* If multiple loc for the same location, use last */
  364. if (nextloc && nextloc->bc->offset == loc->bc->offset)
  365. return 0;
  366. if (!state->precbc) {
  367. /* Set the starting address for the section */
  368. if (!loc->sym) {
  369. /* shouldn't happen! */
  370. yasm_error_set(YASM_ERROR_GENERAL,
  371. N_("could not find label prior to loc"));
  372. return 1;
  373. }
  374. dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address,
  375. dbgfmt_dwarf2->sizeof_address, loc->sym);
  376. addr_delta = 0;
  377. } else if (loc->bc) {
  378. if (state->precbc->offset > loc->bc->offset)
  379. yasm_internal_error(N_("dwarf2 address went backwards?"));
  380. addr_delta = loc->bc->offset - state->precbc->offset;
  381. } else
  382. return 0; /* ran out of bytecodes! XXX: do something? */
  383. /* Generate appropriate opcode(s). Address can only increment,
  384. * whereas line number can go backwards.
  385. */
  386. line_delta = loc->line - state->line;
  387. state->line = loc->line;
  388. /* First handle the line delta */
  389. if (line_delta < DWARF2_LINE_BASE
  390. || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) {
  391. /* Won't fit in special opcode, use (signed) line advance */
  392. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_line,
  393. yasm_intnum_create_int(line_delta));
  394. line_delta = 0;
  395. }
  396. /* Next handle the address delta */
  397. opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
  398. DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len);
  399. opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE +
  400. DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) /
  401. dbgfmt_dwarf2->min_insn_len);
  402. if (line_delta == 0 && addr_delta == 0) {
  403. /* Both line and addr deltas are 0: do DW_LNS_copy */
  404. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
  405. } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA && opcode1 <= 255) {
  406. /* Addr delta in range of special opcode */
  407. dwarf2_dbgfmt_append_line_op(debug_line, opcode1, NULL);
  408. } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA
  409. && opcode2 <= 255) {
  410. /* Addr delta in range of const_add_pc + special */
  411. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_const_add_pc, NULL);
  412. dwarf2_dbgfmt_append_line_op(debug_line, opcode2, NULL);
  413. } else {
  414. /* Need advance_pc */
  415. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_pc,
  416. yasm_intnum_create_uint(addr_delta));
  417. /* Take care of any remaining line_delta and add entry to matrix */
  418. if (line_delta == 0)
  419. dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL);
  420. else {
  421. unsigned int opcode;
  422. opcode = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE;
  423. dwarf2_dbgfmt_append_line_op(debug_line, opcode, NULL);
  424. }
  425. }
  426. state->precbc = loc->bc;
  427. return 0;
  428. }
  429. typedef struct dwarf2_line_bc_info {
  430. yasm_section *debug_line;
  431. yasm_object *object;
  432. yasm_linemap *linemap;
  433. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
  434. dwarf2_line_state *state;
  435. dwarf2_loc loc;
  436. unsigned long lastfile;
  437. } dwarf2_line_bc_info;
  438. static int
  439. dwarf2_filename_equals(const dwarf2_filename *fn,
  440. char **dirs,
  441. const char *pathname,
  442. unsigned long dirlen,
  443. const char *filename)
  444. {
  445. /* check directory */
  446. if (fn->dir == 0) {
  447. if (dirlen != 0)
  448. return 0;
  449. } else {
  450. if (strncmp(dirs[fn->dir-1], pathname, dirlen) != 0 ||
  451. dirs[fn->dir-1][dirlen] != '\0')
  452. return 0;
  453. }
  454. /* check filename */
  455. return strcmp(fn->filename, filename) == 0;
  456. }
  457. static int
  458. dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d)
  459. {
  460. dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d;
  461. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
  462. unsigned long i;
  463. size_t dirlen;
  464. const char *pathname, *filename;
  465. /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc);
  466. if (nextbc && bc->offset == nextbc->offset)
  467. return 0;
  468. info->loc.vline = bc->line;
  469. info->loc.bc = bc;
  470. /* Keep track of last symbol seen */
  471. if (bc->symrecs) {
  472. i = 0;
  473. while (bc->symrecs[i]) {
  474. info->loc.sym = bc->symrecs[i];
  475. i++;
  476. }
  477. }
  478. yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line);
  479. dirlen = yasm__splitpath(pathname, &filename);
  480. char * new_dir_name = yasm_replace_path(
  481. dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
  482. pathname, dirlen);
  483. dirlen = strlen(new_dir_name);
  484. /* Find file index; just linear search it unless it was the last used */
  485. if (info->lastfile > 0
  486. && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1],
  487. dbgfmt_dwarf2->dirs, new_dir_name, dirlen,
  488. filename))
  489. info->loc.file = info->lastfile;
  490. else {
  491. for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
  492. if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i],
  493. dbgfmt_dwarf2->dirs, new_dir_name, dirlen,
  494. filename))
  495. break;
  496. }
  497. if (i >= dbgfmt_dwarf2->filenames_size)
  498. yasm_internal_error(N_("could not find filename in table"));
  499. info->loc.file = i+1;
  500. info->lastfile = i+1;
  501. }
  502. yasm_xfree(new_dir_name);
  503. if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc,
  504. NULL))
  505. return 1;
  506. return 0;
  507. }
  508. typedef struct dwarf2_line_info {
  509. yasm_section *debug_line; /* section to which line number info goes */
  510. yasm_object *object;
  511. yasm_linemap *linemap;
  512. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
  513. yasm_errwarns *errwarns;
  514. /* Generate based on bytecodes (1) or locs (0)? Use bytecodes if we're
  515. * generating line numbers for the actual assembly source file.
  516. */
  517. int asm_source;
  518. /* number of sections line number info generated for */
  519. size_t num_sections;
  520. /* last section line number info generated for */
  521. /*@null@*/ yasm_section *last_code;
  522. } dwarf2_line_info;
  523. static int
  524. dwarf2_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
  525. {
  526. dwarf2_line_info *info = (dwarf2_line_info *)d;
  527. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
  528. /*@null@*/ dwarf2_section_data *dsd;
  529. /*@null@*/ yasm_bytecode *bc;
  530. dwarf2_line_state state;
  531. unsigned long addr_delta;
  532. dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
  533. if (!dsd) {
  534. if (info->asm_source && yasm_section_is_code(sect)) {
  535. /* Create line data for asm code sections */
  536. dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
  537. STAILQ_INIT(&dsd->locs);
  538. yasm_section_add_data(sect, &yasm_dwarf2__section_data_cb, dsd);
  539. } else
  540. return 0; /* no line data for this section */
  541. }
  542. info->num_sections++;
  543. info->last_code = sect;
  544. /* initialize state machine registers for each sequence */
  545. state.dbgfmt_dwarf2 = dbgfmt_dwarf2;
  546. state.address = 0;
  547. state.file = 1;
  548. state.line = 1;
  549. state.column = 0;
  550. state.isa = 0;
  551. state.is_stmt = DWARF2_LINE_DEFAULT_IS_STMT;
  552. state.precbc = NULL;
  553. if (info->asm_source) {
  554. dwarf2_line_bc_info bcinfo;
  555. bcinfo.debug_line = info->debug_line;
  556. bcinfo.object = info->object;
  557. bcinfo.linemap = info->linemap;
  558. bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2;
  559. bcinfo.state = &state;
  560. bcinfo.lastfile = 0;
  561. bcinfo.loc.isa_change = 0;
  562. bcinfo.loc.column = 0;
  563. bcinfo.loc.discriminator = 0;
  564. bcinfo.loc.is_stmt = IS_STMT_NOCHANGE;
  565. bcinfo.loc.basic_block = 0;
  566. bcinfo.loc.prologue_end = 0;
  567. bcinfo.loc.epilogue_begin = 0;
  568. bcinfo.loc.sym = NULL;
  569. /* bcs_traverse() skips first "dummy" bytecode, so look at it
  570. * separately to determine the initial symrec.
  571. */
  572. bc = yasm_section_bcs_first(sect);
  573. if (bc->symrecs) {
  574. size_t i = 0;
  575. while (bc->symrecs[i]) {
  576. bcinfo.loc.sym = bc->symrecs[i];
  577. i++;
  578. }
  579. }
  580. yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo,
  581. dwarf2_generate_line_bc);
  582. } else {
  583. /*@null@*/ dwarf2_loc *loc;
  584. dwarf2_dbgfmt_finalize_locs(sect, dsd);
  585. STAILQ_FOREACH(loc, &dsd->locs, link) {
  586. if (dwarf2_dbgfmt_gen_line_op(info->debug_line, &state, loc,
  587. STAILQ_NEXT(loc, link)))
  588. return 1;
  589. }
  590. }
  591. /* End sequence: bring address to end of section, then output end
  592. * sequence opcode. Don't use a special opcode to do this as we don't
  593. * want an extra entry in the line matrix.
  594. */
  595. if (!state.precbc)
  596. state.precbc = yasm_section_bcs_first(sect);
  597. bc = yasm_section_bcs_last(sect);
  598. addr_delta = yasm_bc_next_offset(bc) - state.precbc->offset;
  599. if (addr_delta == DWARF2_MAX_SPECIAL_ADDR_DELTA)
  600. dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc,
  601. NULL);
  602. else if (addr_delta > 0)
  603. dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_pc,
  604. yasm_intnum_create_uint(addr_delta));
  605. dwarf2_dbgfmt_append_line_ext_op(info->debug_line, DW_LNE_end_sequence, 0,
  606. NULL);
  607. return 0;
  608. }
  609. static int
  610. dwarf2_generate_filename(const char *filename, void *d)
  611. {
  612. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)d;
  613. char *deb_name = yasm_replace_path(
  614. dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
  615. filename, strlen(filename));
  616. dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, 0, deb_name);
  617. yasm_xfree(deb_name);
  618. return 0;
  619. }
  620. yasm_section *
  621. yasm_dwarf2__generate_line(yasm_object *object, yasm_linemap *linemap,
  622. yasm_errwarns *errwarns, int asm_source,
  623. /*@out@*/ yasm_section **main_code,
  624. /*@out@*/ size_t *num_line_sections)
  625. {
  626. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
  627. dwarf2_line_info info;
  628. int new;
  629. size_t i;
  630. yasm_bytecode *sppbc;
  631. dwarf2_spp *spp;
  632. dwarf2_head *head;
  633. if (asm_source) {
  634. /* Generate dirs and filenames based on linemap */
  635. yasm_linemap_traverse_filenames(linemap, dbgfmt_dwarf2,
  636. dwarf2_generate_filename);
  637. }
  638. info.num_sections = 0;
  639. info.last_code = NULL;
  640. info.asm_source = asm_source;
  641. info.object = object;
  642. info.linemap = linemap;
  643. info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
  644. info.debug_line = yasm_object_get_general(object, ".debug_line", 1, 0, 0,
  645. &new, 0);
  646. /* header */
  647. head = yasm_dwarf2__add_head(dbgfmt_dwarf2, info.debug_line, NULL, 0, 0);
  648. /* statement program prologue */
  649. spp = yasm_xmalloc(sizeof(dwarf2_spp));
  650. sppbc = yasm_bc_create_common(&dwarf2_spp_bc_callback, spp, 0);
  651. sppbc->len = dbgfmt_dwarf2->sizeof_offset + 5 +
  652. NELEMS(line_opcode_num_operands);
  653. /* directory list */
  654. for (i=0; i<dbgfmt_dwarf2->dirs_size; i++)
  655. sppbc->len += (unsigned long)strlen(dbgfmt_dwarf2->dirs[i])+1;
  656. sppbc->len++;
  657. /* filename list */
  658. for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
  659. if (!dbgfmt_dwarf2->filenames[i].filename) {
  660. yasm_error_set(YASM_ERROR_GENERAL,
  661. N_("dwarf2 file number %d unassigned"), i+1);
  662. yasm_errwarn_propagate(errwarns, 0);
  663. continue;
  664. }
  665. sppbc->len +=
  666. (unsigned long)strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 +
  667. yasm_size_uleb128(dbgfmt_dwarf2->filenames[i].dir) + 2;
  668. }
  669. sppbc->len++;
  670. yasm_dwarf2__append_bc(info.debug_line, sppbc);
  671. /* statement program */
  672. yasm_object_sections_traverse(object, (void *)&info,
  673. dwarf2_generate_line_section);
  674. /* mark end of line information */
  675. yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(info.debug_line));
  676. *num_line_sections = info.num_sections;
  677. if (info.num_sections == 1)
  678. *main_code = info.last_code;
  679. else
  680. *main_code = NULL;
  681. return info.debug_line;
  682. }
  683. static void
  684. dwarf2_spp_bc_destroy(void *contents)
  685. {
  686. yasm_xfree(contents);
  687. }
  688. static void
  689. dwarf2_spp_bc_print(const void *contents, FILE *f, int indent_level)
  690. {
  691. /* TODO */
  692. }
  693. static int
  694. dwarf2_spp_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  695. void *add_span_data)
  696. {
  697. yasm_internal_error(N_("tried to calc_len a dwarf2 spp bytecode"));
  698. /*@notreached@*/
  699. return 0;
  700. }
  701. static int
  702. dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  703. unsigned char *bufstart, void *d,
  704. yasm_output_value_func output_value,
  705. yasm_output_reloc_func output_reloc)
  706. {
  707. yasm_object *object = yasm_section_get_object(bc->section);
  708. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
  709. unsigned char *buf = *bufp;
  710. yasm_intnum *cval;
  711. size_t i, len;
  712. /* Prologue length (following this field) */
  713. cval = yasm_intnum_create_uint(bc->len - (unsigned long)(buf-*bufp) -
  714. dbgfmt_dwarf2->sizeof_offset);
  715. yasm_arch_intnum_tobytes(object->arch, cval, buf,
  716. dbgfmt_dwarf2->sizeof_offset,
  717. dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
  718. buf += dbgfmt_dwarf2->sizeof_offset;
  719. YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len); /* minimum_instr_len */
  720. YASM_WRITE_8(buf, DWARF2_LINE_DEFAULT_IS_STMT); /* default_is_stmt */
  721. YASM_WRITE_8(buf, DWARF2_LINE_BASE); /* line_base */
  722. YASM_WRITE_8(buf, DWARF2_LINE_RANGE); /* line_range */
  723. YASM_WRITE_8(buf, DWARF2_LINE_OPCODE_BASE); /* opcode_base */
  724. /* Standard opcode # operands array */
  725. for (i=0; i<NELEMS(line_opcode_num_operands); i++)
  726. YASM_WRITE_8(buf, line_opcode_num_operands[i]);
  727. /* directory list */
  728. for (i=0; i<dbgfmt_dwarf2->dirs_size; i++) {
  729. len = strlen(dbgfmt_dwarf2->dirs[i])+1;
  730. memcpy(buf, dbgfmt_dwarf2->dirs[i], len);
  731. buf += len;
  732. }
  733. /* finish with single 0 byte */
  734. YASM_WRITE_8(buf, 0);
  735. /* filename list */
  736. for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
  737. len = strlen(dbgfmt_dwarf2->filenames[i].filename)+1;
  738. memcpy(buf, dbgfmt_dwarf2->filenames[i].filename, len);
  739. buf += len;
  740. /* dir */
  741. buf += yasm_get_uleb128(dbgfmt_dwarf2->filenames[i].dir, buf);
  742. YASM_WRITE_8(buf, 0); /* time */
  743. YASM_WRITE_8(buf, 0); /* length */
  744. }
  745. /* finish with single 0 byte */
  746. YASM_WRITE_8(buf, 0);
  747. *bufp = buf;
  748. yasm_intnum_destroy(cval);
  749. return 0;
  750. }
  751. static void
  752. dwarf2_line_op_bc_destroy(void *contents)
  753. {
  754. dwarf2_line_op *line_op = (dwarf2_line_op *)contents;
  755. if (line_op->operand)
  756. yasm_intnum_destroy(line_op->operand);
  757. if (line_op->ext_operand_int)
  758. yasm_intnum_destroy(line_op->ext_operand_int);
  759. yasm_xfree(contents);
  760. }
  761. static void
  762. dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level)
  763. {
  764. /* TODO */
  765. }
  766. static int
  767. dwarf2_line_op_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  768. void *add_span_data)
  769. {
  770. yasm_internal_error(N_("tried to calc_len a dwarf2 line_op bytecode"));
  771. /*@notreached@*/
  772. return 0;
  773. }
  774. static int
  775. dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  776. unsigned char *bufstart, void *d,
  777. yasm_output_value_func output_value,
  778. yasm_output_reloc_func output_reloc)
  779. {
  780. dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents;
  781. unsigned char *buf = *bufp;
  782. YASM_WRITE_8(buf, line_op->opcode);
  783. if (line_op->operand)
  784. buf += yasm_intnum_get_leb128(line_op->operand, buf,
  785. line_op->opcode == DW_LNS_advance_line);
  786. if (line_op->ext_opcode > 0) {
  787. YASM_WRITE_8(buf, line_op->ext_opcode);
  788. if (line_op->ext_operand) {
  789. yasm_value value;
  790. yasm_value_init_sym(&value, line_op->ext_operand,
  791. line_op->ext_operandsize*8);
  792. output_value(&value, buf, line_op->ext_operandsize,
  793. (unsigned long)(buf-bufstart), bc, 0, d);
  794. buf += line_op->ext_operandsize;
  795. }
  796. if (line_op->ext_operand_int) {
  797. buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0);
  798. }
  799. }
  800. *bufp = buf;
  801. return 0;
  802. }
  803. void
  804. yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
  805. yasm_valparamhead *objext_valparams, unsigned long line)
  806. {
  807. yasm_valparam *vp;
  808. int in_is_stmt = 0, in_isa = 0, in_discriminator = 0;
  809. /*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
  810. dwarf2_section_data *dsd;
  811. dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc));
  812. /* File number (required) */
  813. if (!valparams || !(vp = yasm_vps_first(valparams)) ||
  814. vp->val || vp->type != YASM_PARAM_EXPR) {
  815. yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
  816. yasm_xfree(loc);
  817. return;
  818. }
  819. intn = yasm_expr_get_intnum(&vp->param.e, 0);
  820. if (!intn) {
  821. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  822. N_("file number is not a constant"));
  823. yasm_xfree(loc);
  824. return;
  825. }
  826. if (yasm_intnum_sign(intn) != 1) {
  827. yasm_error_set(YASM_ERROR_VALUE, N_("file number less than one"));
  828. yasm_xfree(loc);
  829. return;
  830. }
  831. loc->file = yasm_intnum_get_uint(intn);
  832. /* Line number (required) */
  833. vp = yasm_vps_next(vp);
  834. if (!vp || vp->val || vp->type != YASM_PARAM_EXPR) {
  835. yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
  836. yasm_xfree(loc);
  837. return;
  838. }
  839. intn = yasm_expr_get_intnum(&vp->param.e, 0);
  840. if (!intn) {
  841. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  842. N_("line number is not a constant"));
  843. yasm_xfree(loc);
  844. return;
  845. }
  846. loc->line = yasm_intnum_get_uint(intn);
  847. /* Generate new section data if it doesn't already exist */
  848. if (!object->cur_section) {
  849. yasm_error_set(YASM_ERROR_SYNTAX,
  850. N_("[%s] can only be used inside of a section"), "loc");
  851. yasm_xfree(loc);
  852. return;
  853. }
  854. dsd = yasm_section_get_data(object->cur_section,
  855. &yasm_dwarf2__section_data_cb);
  856. if (!dsd) {
  857. dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
  858. STAILQ_INIT(&dsd->locs);
  859. yasm_section_add_data(object->cur_section,
  860. &yasm_dwarf2__section_data_cb, dsd);
  861. }
  862. /* Defaults for optional settings */
  863. loc->column = 0;
  864. loc->discriminator = 0;
  865. loc->isa_change = 0;
  866. loc->isa = 0;
  867. loc->is_stmt = IS_STMT_NOCHANGE;
  868. loc->basic_block = 0;
  869. loc->prologue_end = 0;
  870. loc->epilogue_begin = 0;
  871. /* Optional column number */
  872. vp = yasm_vps_next(vp);
  873. if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) {
  874. intn = yasm_expr_get_intnum(&vp->param.e, 0);
  875. if (!intn) {
  876. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  877. N_("column number is not a constant"));
  878. yasm_xfree(loc);
  879. return;
  880. }
  881. loc->column = yasm_intnum_get_uint(intn);
  882. vp = yasm_vps_next(vp);
  883. }
  884. /* Other options; note for GAS compatibility we need to support both:
  885. * is_stmt=1 (NASM) and
  886. * is_stmt 1 (GAS)
  887. */
  888. while (vp) {
  889. /*@null@*/ /*@dependent@*/ const char *s;
  890. /*@null@*/ /*@only@*/ yasm_expr *e;
  891. restart:
  892. if (in_is_stmt) {
  893. in_is_stmt = 0;
  894. if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
  895. !(intn = yasm_expr_get_intnum(&e, 0))) {
  896. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  897. N_("is_stmt value is not a constant"));
  898. yasm_xfree(loc);
  899. if (e)
  900. yasm_expr_destroy(e);
  901. return;
  902. }
  903. if (yasm_intnum_is_zero(intn))
  904. loc->is_stmt = IS_STMT_SET;
  905. else if (yasm_intnum_is_pos1(intn))
  906. loc->is_stmt = IS_STMT_CLEAR;
  907. else {
  908. yasm_error_set(YASM_ERROR_VALUE,
  909. N_("is_stmt value not 0 or 1"));
  910. yasm_xfree(loc);
  911. yasm_expr_destroy(e);
  912. return;
  913. }
  914. yasm_expr_destroy(e);
  915. } else if (in_isa) {
  916. in_isa = 0;
  917. if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
  918. !(intn = yasm_expr_get_intnum(&e, 0))) {
  919. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  920. N_("isa value is not a constant"));
  921. yasm_xfree(loc);
  922. if (e)
  923. yasm_expr_destroy(e);
  924. return;
  925. }
  926. if (yasm_intnum_sign(intn) < 0) {
  927. yasm_error_set(YASM_ERROR_VALUE,
  928. N_("isa value less than zero"));
  929. yasm_xfree(loc);
  930. yasm_expr_destroy(e);
  931. return;
  932. }
  933. loc->isa_change = 1;
  934. loc->isa = yasm_intnum_get_uint(intn);
  935. yasm_expr_destroy(e);
  936. } else if (in_discriminator) {
  937. in_discriminator = 0;
  938. if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
  939. !(intn = yasm_expr_get_intnum(&e, 0))) {
  940. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  941. N_("discriminator value is not a constant"));
  942. yasm_xfree(loc);
  943. if (e)
  944. yasm_expr_destroy(e);
  945. return;
  946. }
  947. if (yasm_intnum_sign(intn) < 0) {
  948. yasm_error_set(YASM_ERROR_VALUE,
  949. N_("discriminator value less than zero"));
  950. yasm_xfree(loc);
  951. yasm_expr_destroy(e);
  952. return;
  953. }
  954. loc->discriminator = yasm_intnum_get_uint(intn);
  955. yasm_expr_destroy(e);
  956. } else if (!vp->val && (s = yasm_vp_id(vp))) {
  957. if (yasm__strcasecmp(s, "is_stmt") == 0)
  958. in_is_stmt = 1;
  959. else if (yasm__strcasecmp(s, "isa") == 0)
  960. in_isa = 1;
  961. else if (yasm__strcasecmp(s, "discriminator") == 0)
  962. in_discriminator = 1;
  963. else if (yasm__strcasecmp(s, "basic_block") == 0)
  964. loc->basic_block = 1;
  965. else if (yasm__strcasecmp(s, "prologue_end") == 0)
  966. loc->prologue_end = 1;
  967. else if (yasm__strcasecmp(s, "epilogue_begin") == 0)
  968. loc->epilogue_begin = 1;
  969. else
  970. yasm_warn_set(YASM_WARN_GENERAL,
  971. N_("unrecognized loc option `%s'"), s);
  972. } else if (!vp->val) {
  973. yasm_warn_set(YASM_WARN_GENERAL,
  974. N_("unrecognized numeric qualifier"));
  975. } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
  976. in_is_stmt = 1;
  977. goto restart; /* don't go to the next valparam */
  978. } else if (yasm__strcasecmp(vp->val, "isa") == 0) {
  979. in_isa = 1;
  980. goto restart; /* don't go to the next valparam */
  981. } else if (yasm__strcasecmp(vp->val, "discriminator") == 0) {
  982. in_discriminator = 1;
  983. goto restart; /* don't go to the next valparam */
  984. } else
  985. yasm_warn_set(YASM_WARN_GENERAL,
  986. N_("unrecognized loc option `%s'"), vp->val);
  987. vp = yasm_vps_next(vp);
  988. }
  989. if (in_is_stmt || in_isa || in_discriminator) {
  990. yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"),
  991. in_is_stmt ? "is_stmt" :
  992. (in_isa ? "isa" : "discriminator"));
  993. yasm_xfree(loc);
  994. return;
  995. }
  996. /* Append new location */
  997. loc->vline = line;
  998. loc->bc = NULL;
  999. loc->sym = NULL;
  1000. STAILQ_INSERT_TAIL(&dsd->locs, loc, link);
  1001. }
  1002. void
  1003. yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
  1004. yasm_valparamhead *objext_valparams, unsigned long line)
  1005. {
  1006. yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
  1007. yasm_valparam *vp;
  1008. /*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn;
  1009. unsigned long filenum;
  1010. if (!valparams) {
  1011. yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
  1012. "FILE");
  1013. return;
  1014. }
  1015. vp = yasm_vps_first(valparams);
  1016. if (yasm_vp_string(vp)) {
  1017. /* Just a bare filename */
  1018. yasm_object_set_source_fn(object, yasm_vp_string(vp));
  1019. object->deb_filename = yasm_replace_path(
  1020. dbgfmt_dwarf2->dbgfmt.module->replace_map, dbgfmt_dwarf2->dbgfmt.module->replace_map_size,
  1021. yasm_vp_string(vp), strlen(yasm_vp_string(vp)));
  1022. return;
  1023. }
  1024. /* Otherwise.. first vp is the file number */
  1025. if (vp->type != YASM_PARAM_EXPR ||
  1026. !(file_intn = yasm_expr_get_intnum(&vp->param.e, 0))) {
  1027. yasm_error_set(YASM_ERROR_NOT_CONSTANT,
  1028. N_("file number is not a constant"));
  1029. return;
  1030. }
  1031. filenum = yasm_intnum_get_uint(file_intn);
  1032. vp = yasm_vps_next(vp);
  1033. if (!yasm_vp_string(vp)) {
  1034. yasm_error_set(YASM_ERROR_SYNTAX,
  1035. N_("file number given but no filename"));
  1036. return;
  1037. }
  1038. dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp));
  1039. }