pecoff.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. /* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
  2. Copyright (C) 2015-2021 Free Software Foundation, Inc.
  3. Adapted from elf.c by Tristan Gingold, AdaCore.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are
  6. met:
  7. (1) Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. (2) Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in
  11. the documentation and/or other materials provided with the
  12. distribution.
  13. (3) The name of the author may not be used to
  14. endorse or promote products derived from this software without
  15. specific prior written permission.
  16. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  20. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  24. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  25. IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. POSSIBILITY OF SUCH DAMAGE. */
  27. #include "config.h"
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <sys/types.h>
  31. #include "backtrace.h"
  32. #include "internal.h"
  33. /* Coff file header. */
  34. typedef struct {
  35. uint16_t machine;
  36. uint16_t number_of_sections;
  37. uint32_t time_date_stamp;
  38. uint32_t pointer_to_symbol_table;
  39. uint32_t number_of_symbols;
  40. uint16_t size_of_optional_header;
  41. uint16_t characteristics;
  42. } b_coff_file_header;
  43. /* Coff optional header. */
  44. typedef struct {
  45. uint16_t magic;
  46. uint8_t major_linker_version;
  47. uint8_t minor_linker_version;
  48. uint32_t size_of_code;
  49. uint32_t size_of_initialized_data;
  50. uint32_t size_of_uninitialized_data;
  51. uint32_t address_of_entry_point;
  52. uint32_t base_of_code;
  53. union {
  54. struct {
  55. uint32_t base_of_data;
  56. uint32_t image_base;
  57. } pe;
  58. struct {
  59. uint64_t image_base;
  60. } pep;
  61. } u;
  62. } b_coff_optional_header;
  63. /* Values of magic in optional header. */
  64. #define PE_MAGIC 0x10b /* PE32 executable. */
  65. #define PEP_MAGIC 0x20b /* PE32+ executable (for 64bit targets). */
  66. /* Coff section header. */
  67. typedef struct {
  68. char name[8];
  69. uint32_t virtual_size;
  70. uint32_t virtual_address;
  71. uint32_t size_of_raw_data;
  72. uint32_t pointer_to_raw_data;
  73. uint32_t pointer_to_relocations;
  74. uint32_t pointer_to_line_numbers;
  75. uint16_t number_of_relocations;
  76. uint16_t number_of_line_numbers;
  77. uint32_t characteristics;
  78. } b_coff_section_header;
  79. /* Coff symbol name. */
  80. typedef union {
  81. char short_name[8];
  82. struct {
  83. unsigned char zeroes[4];
  84. unsigned char off[4];
  85. } long_name;
  86. } b_coff_name;
  87. /* Coff symbol (external representation which is unaligned). */
  88. typedef struct {
  89. b_coff_name name;
  90. unsigned char value[4];
  91. unsigned char section_number[2];
  92. unsigned char type[2];
  93. unsigned char storage_class;
  94. unsigned char number_of_aux_symbols;
  95. } b_coff_external_symbol;
  96. /* Symbol types. */
  97. #define N_TBSHFT 4 /* Shift for the derived type. */
  98. #define IMAGE_SYM_DTYPE_FUNCTION 2 /* Function derived type. */
  99. /* Size of a coff symbol. */
  100. #define SYM_SZ 18
  101. /* Coff symbol, internal representation (aligned). */
  102. typedef struct {
  103. const char *name;
  104. uint32_t value;
  105. int16_t sec;
  106. uint16_t type;
  107. uint16_t sc;
  108. } b_coff_internal_symbol;
  109. /* Names of sections, indexed by enum dwarf_section in internal.h. */
  110. static const char * const debug_section_names[DEBUG_MAX] =
  111. {
  112. ".debug_info",
  113. ".debug_line",
  114. ".debug_abbrev",
  115. ".debug_ranges",
  116. ".debug_str",
  117. ".debug_addr",
  118. ".debug_str_offsets",
  119. ".debug_line_str",
  120. ".debug_rnglists"
  121. };
  122. /* Information we gather for the sections we care about. */
  123. struct debug_section_info
  124. {
  125. /* Section file offset. */
  126. off_t offset;
  127. /* Section size. */
  128. size_t size;
  129. };
  130. /* Information we keep for an coff symbol. */
  131. struct coff_symbol
  132. {
  133. /* The name of the symbol. */
  134. const char *name;
  135. /* The address of the symbol. */
  136. uintptr_t address;
  137. };
  138. /* Information to pass to coff_syminfo. */
  139. struct coff_syminfo_data
  140. {
  141. /* Symbols for the next module. */
  142. struct coff_syminfo_data *next;
  143. /* The COFF symbols, sorted by address. */
  144. struct coff_symbol *symbols;
  145. /* The number of symbols. */
  146. size_t count;
  147. };
  148. /* A dummy callback function used when we can't find any debug info. */
  149. static int
  150. coff_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
  151. uintptr_t pc ATTRIBUTE_UNUSED,
  152. backtrace_full_callback callback ATTRIBUTE_UNUSED,
  153. backtrace_error_callback error_callback, void *data)
  154. {
  155. error_callback (data, "no debug info in PE/COFF executable", -1);
  156. return 0;
  157. }
  158. /* A dummy callback function used when we can't find a symbol
  159. table. */
  160. static void
  161. coff_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
  162. uintptr_t addr ATTRIBUTE_UNUSED,
  163. backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
  164. backtrace_error_callback error_callback, void *data)
  165. {
  166. error_callback (data, "no symbol table in PE/COFF executable", -1);
  167. }
  168. /* Read a potentially unaligned 4 byte word at P, using native endianness. */
  169. static uint32_t
  170. coff_read4 (const unsigned char *p)
  171. {
  172. uint32_t res;
  173. memcpy (&res, p, 4);
  174. return res;
  175. }
  176. /* Read a potentially unaligned 2 byte word at P, using native endianness.
  177. All 2 byte word in symbols are always aligned, but for coherency all
  178. fields are declared as char arrays. */
  179. static uint16_t
  180. coff_read2 (const unsigned char *p)
  181. {
  182. uint16_t res;
  183. memcpy (&res, p, sizeof (res));
  184. return res;
  185. }
  186. /* Return the length (without the trailing 0) of a COFF short name. */
  187. static size_t
  188. coff_short_name_len (const char *name)
  189. {
  190. int i;
  191. for (i = 0; i < 8; i++)
  192. if (name[i] == 0)
  193. return i;
  194. return 8;
  195. }
  196. /* Return true iff COFF short name CNAME is the same as NAME (a NUL-terminated
  197. string). */
  198. static int
  199. coff_short_name_eq (const char *name, const char *cname)
  200. {
  201. int i;
  202. for (i = 0; i < 8; i++)
  203. {
  204. if (name[i] != cname[i])
  205. return 0;
  206. if (name[i] == 0)
  207. return 1;
  208. }
  209. return name[8] == 0;
  210. }
  211. /* Return true iff NAME is the same as string at offset OFF. */
  212. static int
  213. coff_long_name_eq (const char *name, unsigned int off,
  214. struct backtrace_view *str_view)
  215. {
  216. if (off >= str_view->len)
  217. return 0;
  218. return strcmp (name, (const char *)str_view->data + off) == 0;
  219. }
  220. /* Compare struct coff_symbol for qsort. */
  221. static int
  222. coff_symbol_compare (const void *v1, const void *v2)
  223. {
  224. const struct coff_symbol *e1 = (const struct coff_symbol *) v1;
  225. const struct coff_symbol *e2 = (const struct coff_symbol *) v2;
  226. if (e1->address < e2->address)
  227. return -1;
  228. else if (e1->address > e2->address)
  229. return 1;
  230. else
  231. return 0;
  232. }
  233. /* Convert SYM to internal (and aligned) format ISYM, using string table
  234. from STRTAB and STRTAB_SIZE, and number of sections SECTS_NUM.
  235. Return -1 in case of error (invalid section number or string index). */
  236. static int
  237. coff_expand_symbol (b_coff_internal_symbol *isym,
  238. const b_coff_external_symbol *sym,
  239. uint16_t sects_num,
  240. const unsigned char *strtab, size_t strtab_size)
  241. {
  242. isym->type = coff_read2 (sym->type);
  243. isym->sec = coff_read2 (sym->section_number);
  244. isym->sc = sym->storage_class;
  245. if (isym->sec > 0 && (uint16_t) isym->sec > sects_num)
  246. return -1;
  247. if (sym->name.short_name[0] != 0)
  248. isym->name = sym->name.short_name;
  249. else
  250. {
  251. uint32_t off = coff_read4 (sym->name.long_name.off);
  252. if (off >= strtab_size)
  253. return -1;
  254. isym->name = (const char *) strtab + off;
  255. }
  256. return 0;
  257. }
  258. /* Return true iff SYM is a defined symbol for a function. Data symbols
  259. aren't considered because they aren't easily identified (same type as
  260. section names, presence of symbols defined by the linker script). */
  261. static int
  262. coff_is_function_symbol (const b_coff_internal_symbol *isym)
  263. {
  264. return (isym->type >> N_TBSHFT) == IMAGE_SYM_DTYPE_FUNCTION
  265. && isym->sec > 0;
  266. }
  267. /* Initialize the symbol table info for coff_syminfo. */
  268. static int
  269. coff_initialize_syminfo (struct backtrace_state *state,
  270. uintptr_t base_address, int is_64,
  271. const b_coff_section_header *sects, size_t sects_num,
  272. const b_coff_external_symbol *syms, size_t syms_size,
  273. const unsigned char *strtab, size_t strtab_size,
  274. backtrace_error_callback error_callback,
  275. void *data, struct coff_syminfo_data *sdata)
  276. {
  277. size_t syms_count;
  278. char *coff_symstr;
  279. size_t coff_symstr_len;
  280. size_t coff_symbol_count;
  281. size_t coff_symbol_size;
  282. struct coff_symbol *coff_symbols;
  283. struct coff_symbol *coff_sym;
  284. char *coff_str;
  285. size_t i;
  286. syms_count = syms_size / SYM_SZ;
  287. /* We only care about function symbols. Count them. Also count size of
  288. strings for in-symbol names. */
  289. coff_symbol_count = 0;
  290. coff_symstr_len = 0;
  291. for (i = 0; i < syms_count; ++i)
  292. {
  293. const b_coff_external_symbol *asym = &syms[i];
  294. b_coff_internal_symbol isym;
  295. if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size) < 0)
  296. {
  297. error_callback (data, "invalid section or offset in coff symbol", 0);
  298. return 0;
  299. }
  300. if (coff_is_function_symbol (&isym))
  301. {
  302. ++coff_symbol_count;
  303. if (asym->name.short_name[0] != 0)
  304. coff_symstr_len += coff_short_name_len (asym->name.short_name) + 1;
  305. }
  306. i += asym->number_of_aux_symbols;
  307. }
  308. coff_symbol_size = (coff_symbol_count + 1) * sizeof (struct coff_symbol);
  309. coff_symbols = ((struct coff_symbol *)
  310. backtrace_alloc (state, coff_symbol_size, error_callback,
  311. data));
  312. if (coff_symbols == NULL)
  313. return 0;
  314. /* Allocate memory for symbols strings. */
  315. if (coff_symstr_len > 0)
  316. {
  317. coff_symstr = ((char *)
  318. backtrace_alloc (state, coff_symstr_len, error_callback,
  319. data));
  320. if (coff_symstr == NULL)
  321. {
  322. backtrace_free (state, coff_symbols, coff_symbol_size,
  323. error_callback, data);
  324. return 0;
  325. }
  326. }
  327. else
  328. coff_symstr = NULL;
  329. /* Copy symbols. */
  330. coff_sym = coff_symbols;
  331. coff_str = coff_symstr;
  332. for (i = 0; i < syms_count; ++i)
  333. {
  334. const b_coff_external_symbol *asym = &syms[i];
  335. b_coff_internal_symbol isym;
  336. if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size))
  337. {
  338. /* Should not fail, as it was already tested in the previous
  339. loop. */
  340. abort ();
  341. }
  342. if (coff_is_function_symbol (&isym))
  343. {
  344. const char *name;
  345. int16_t secnum;
  346. if (asym->name.short_name[0] != 0)
  347. {
  348. size_t len = coff_short_name_len (isym.name);
  349. name = coff_str;
  350. memcpy (coff_str, isym.name, len);
  351. coff_str[len] = 0;
  352. coff_str += len + 1;
  353. }
  354. else
  355. name = isym.name;
  356. if (!is_64)
  357. {
  358. /* Strip leading '_'. */
  359. if (name[0] == '_')
  360. name++;
  361. }
  362. /* Symbol value is section relative, so we need to read the address
  363. of its section. */
  364. secnum = coff_read2 (asym->section_number);
  365. coff_sym->name = name;
  366. coff_sym->address = (coff_read4 (asym->value)
  367. + sects[secnum - 1].virtual_address
  368. + base_address);
  369. coff_sym++;
  370. }
  371. i += asym->number_of_aux_symbols;
  372. }
  373. /* End of symbols marker. */
  374. coff_sym->name = NULL;
  375. coff_sym->address = -1;
  376. backtrace_qsort (coff_symbols, coff_symbol_count,
  377. sizeof (struct coff_symbol), coff_symbol_compare);
  378. sdata->next = NULL;
  379. sdata->symbols = coff_symbols;
  380. sdata->count = coff_symbol_count;
  381. return 1;
  382. }
  383. /* Add EDATA to the list in STATE. */
  384. static void
  385. coff_add_syminfo_data (struct backtrace_state *state,
  386. struct coff_syminfo_data *sdata)
  387. {
  388. if (!state->threaded)
  389. {
  390. struct coff_syminfo_data **pp;
  391. for (pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
  392. *pp != NULL;
  393. pp = &(*pp)->next)
  394. ;
  395. *pp = sdata;
  396. }
  397. else
  398. {
  399. while (1)
  400. {
  401. struct coff_syminfo_data **pp;
  402. pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
  403. while (1)
  404. {
  405. struct coff_syminfo_data *p;
  406. p = backtrace_atomic_load_pointer (pp);
  407. if (p == NULL)
  408. break;
  409. pp = &p->next;
  410. }
  411. if (__sync_bool_compare_and_swap (pp, NULL, sdata))
  412. break;
  413. }
  414. }
  415. }
  416. /* Compare an ADDR against an elf_symbol for bsearch. We allocate one
  417. extra entry in the array so that this can look safely at the next
  418. entry. */
  419. static int
  420. coff_symbol_search (const void *vkey, const void *ventry)
  421. {
  422. const uintptr_t *key = (const uintptr_t *) vkey;
  423. const struct coff_symbol *entry = (const struct coff_symbol *) ventry;
  424. uintptr_t addr;
  425. addr = *key;
  426. if (addr < entry->address)
  427. return -1;
  428. else if (addr >= entry[1].address)
  429. return 1;
  430. else
  431. return 0;
  432. }
  433. /* Return the symbol name and value for an ADDR. */
  434. static void
  435. coff_syminfo (struct backtrace_state *state, uintptr_t addr,
  436. backtrace_syminfo_callback callback,
  437. backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
  438. void *data)
  439. {
  440. struct coff_syminfo_data *sdata;
  441. struct coff_symbol *sym = NULL;
  442. if (!state->threaded)
  443. {
  444. for (sdata = (struct coff_syminfo_data *) state->syminfo_data;
  445. sdata != NULL;
  446. sdata = sdata->next)
  447. {
  448. sym = ((struct coff_symbol *)
  449. bsearch (&addr, sdata->symbols, sdata->count,
  450. sizeof (struct coff_symbol), coff_symbol_search));
  451. if (sym != NULL)
  452. break;
  453. }
  454. }
  455. else
  456. {
  457. struct coff_syminfo_data **pp;
  458. pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
  459. while (1)
  460. {
  461. sdata = backtrace_atomic_load_pointer (pp);
  462. if (sdata == NULL)
  463. break;
  464. sym = ((struct coff_symbol *)
  465. bsearch (&addr, sdata->symbols, sdata->count,
  466. sizeof (struct coff_symbol), coff_symbol_search));
  467. if (sym != NULL)
  468. break;
  469. pp = &sdata->next;
  470. }
  471. }
  472. if (sym == NULL)
  473. callback (data, addr, NULL, 0, 0);
  474. else
  475. callback (data, addr, sym->name, sym->address, 0);
  476. }
  477. /* Add the backtrace data for one PE/COFF file. Returns 1 on success,
  478. 0 on failure (in both cases descriptor is closed). */
  479. static int
  480. coff_add (struct backtrace_state *state, int descriptor,
  481. backtrace_error_callback error_callback, void *data,
  482. fileline *fileline_fn, int *found_sym, int *found_dwarf)
  483. {
  484. struct backtrace_view fhdr_view;
  485. off_t fhdr_off;
  486. int magic_ok;
  487. b_coff_file_header fhdr;
  488. off_t opt_sects_off;
  489. size_t opt_sects_size;
  490. unsigned int sects_num;
  491. struct backtrace_view sects_view;
  492. int sects_view_valid;
  493. const b_coff_optional_header *opt_hdr;
  494. const b_coff_section_header *sects;
  495. struct backtrace_view str_view;
  496. int str_view_valid;
  497. size_t str_size;
  498. off_t str_off;
  499. struct backtrace_view syms_view;
  500. off_t syms_off;
  501. size_t syms_size;
  502. int syms_view_valid;
  503. unsigned int syms_num;
  504. unsigned int i;
  505. struct debug_section_info sections[DEBUG_MAX];
  506. off_t min_offset;
  507. off_t max_offset;
  508. struct backtrace_view debug_view;
  509. int debug_view_valid;
  510. int is_64;
  511. uintptr_t image_base;
  512. struct dwarf_sections dwarf_sections;
  513. *found_sym = 0;
  514. *found_dwarf = 0;
  515. sects_view_valid = 0;
  516. syms_view_valid = 0;
  517. str_view_valid = 0;
  518. debug_view_valid = 0;
  519. /* Map the MS-DOS stub (if any) and extract file header offset. */
  520. if (!backtrace_get_view (state, descriptor, 0, 0x40, error_callback,
  521. data, &fhdr_view))
  522. goto fail;
  523. {
  524. const unsigned char *vptr = fhdr_view.data;
  525. if (vptr[0] == 'M' && vptr[1] == 'Z')
  526. fhdr_off = coff_read4 (vptr + 0x3c);
  527. else
  528. fhdr_off = 0;
  529. }
  530. backtrace_release_view (state, &fhdr_view, error_callback, data);
  531. /* Map the coff file header. */
  532. if (!backtrace_get_view (state, descriptor, fhdr_off,
  533. sizeof (b_coff_file_header) + 4,
  534. error_callback, data, &fhdr_view))
  535. goto fail;
  536. if (fhdr_off != 0)
  537. {
  538. const char *magic = (const char *) fhdr_view.data;
  539. magic_ok = memcmp (magic, "PE\0", 4) == 0;
  540. fhdr_off += 4;
  541. memcpy (&fhdr, fhdr_view.data + 4, sizeof fhdr);
  542. }
  543. else
  544. {
  545. memcpy (&fhdr, fhdr_view.data, sizeof fhdr);
  546. /* TODO: test fhdr.machine for coff but non-PE platforms. */
  547. magic_ok = 0;
  548. }
  549. backtrace_release_view (state, &fhdr_view, error_callback, data);
  550. if (!magic_ok)
  551. {
  552. error_callback (data, "executable file is not COFF", 0);
  553. goto fail;
  554. }
  555. sects_num = fhdr.number_of_sections;
  556. syms_num = fhdr.number_of_symbols;
  557. opt_sects_off = fhdr_off + sizeof (fhdr);
  558. opt_sects_size = (fhdr.size_of_optional_header
  559. + sects_num * sizeof (b_coff_section_header));
  560. /* To translate PC to file/line when using DWARF, we need to find
  561. the .debug_info and .debug_line sections. */
  562. /* Read the optional header and the section headers. */
  563. if (!backtrace_get_view (state, descriptor, opt_sects_off, opt_sects_size,
  564. error_callback, data, &sects_view))
  565. goto fail;
  566. sects_view_valid = 1;
  567. opt_hdr = (const b_coff_optional_header *) sects_view.data;
  568. sects = (const b_coff_section_header *)
  569. (sects_view.data + fhdr.size_of_optional_header);
  570. is_64 = 0;
  571. if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
  572. {
  573. if (opt_hdr->magic == PE_MAGIC)
  574. image_base = opt_hdr->u.pe.image_base;
  575. else if (opt_hdr->magic == PEP_MAGIC)
  576. {
  577. image_base = opt_hdr->u.pep.image_base;
  578. is_64 = 1;
  579. }
  580. else
  581. {
  582. error_callback (data, "bad magic in PE optional header", 0);
  583. goto fail;
  584. }
  585. }
  586. else
  587. image_base = 0;
  588. /* Read the symbol table and the string table. */
  589. if (fhdr.pointer_to_symbol_table == 0)
  590. {
  591. /* No symbol table, no string table. */
  592. str_off = 0;
  593. str_size = 0;
  594. syms_num = 0;
  595. syms_size = 0;
  596. }
  597. else
  598. {
  599. /* Symbol table is followed by the string table. The string table
  600. starts with its length (on 4 bytes).
  601. Map the symbol table and the length of the string table. */
  602. syms_off = fhdr.pointer_to_symbol_table;
  603. syms_size = syms_num * SYM_SZ;
  604. if (!backtrace_get_view (state, descriptor, syms_off, syms_size + 4,
  605. error_callback, data, &syms_view))
  606. goto fail;
  607. syms_view_valid = 1;
  608. str_size = coff_read4 (syms_view.data + syms_size);
  609. str_off = syms_off + syms_size;
  610. if (str_size > 4)
  611. {
  612. /* Map string table (including the length word). */
  613. if (!backtrace_get_view (state, descriptor, str_off, str_size,
  614. error_callback, data, &str_view))
  615. goto fail;
  616. str_view_valid = 1;
  617. }
  618. }
  619. memset (sections, 0, sizeof sections);
  620. /* Look for the symbol table. */
  621. for (i = 0; i < sects_num; ++i)
  622. {
  623. const b_coff_section_header *s = sects + i;
  624. unsigned int str_off;
  625. int j;
  626. if (s->name[0] == '/')
  627. {
  628. /* Extended section name. */
  629. str_off = atoi (s->name + 1);
  630. }
  631. else
  632. str_off = 0;
  633. for (j = 0; j < (int) DEBUG_MAX; ++j)
  634. {
  635. const char *dbg_name = debug_section_names[j];
  636. int match;
  637. if (str_off != 0)
  638. match = coff_long_name_eq (dbg_name, str_off, &str_view);
  639. else
  640. match = coff_short_name_eq (dbg_name, s->name);
  641. if (match)
  642. {
  643. sections[j].offset = s->pointer_to_raw_data;
  644. sections[j].size = s->virtual_size <= s->size_of_raw_data ?
  645. s->virtual_size : s->size_of_raw_data;
  646. break;
  647. }
  648. }
  649. }
  650. if (syms_num != 0)
  651. {
  652. struct coff_syminfo_data *sdata;
  653. sdata = ((struct coff_syminfo_data *)
  654. backtrace_alloc (state, sizeof *sdata, error_callback, data));
  655. if (sdata == NULL)
  656. goto fail;
  657. if (!coff_initialize_syminfo (state, image_base, is_64,
  658. sects, sects_num,
  659. syms_view.data, syms_size,
  660. str_view.data, str_size,
  661. error_callback, data, sdata))
  662. {
  663. backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
  664. goto fail;
  665. }
  666. *found_sym = 1;
  667. coff_add_syminfo_data (state, sdata);
  668. }
  669. backtrace_release_view (state, &sects_view, error_callback, data);
  670. sects_view_valid = 0;
  671. if (syms_view_valid)
  672. {
  673. backtrace_release_view (state, &syms_view, error_callback, data);
  674. syms_view_valid = 0;
  675. }
  676. /* Read all the debug sections in a single view, since they are
  677. probably adjacent in the file. We never release this view. */
  678. min_offset = 0;
  679. max_offset = 0;
  680. for (i = 0; i < (int) DEBUG_MAX; ++i)
  681. {
  682. off_t end;
  683. if (sections[i].size == 0)
  684. continue;
  685. if (min_offset == 0 || sections[i].offset < min_offset)
  686. min_offset = sections[i].offset;
  687. end = sections[i].offset + sections[i].size;
  688. if (end > max_offset)
  689. max_offset = end;
  690. }
  691. if (min_offset == 0 || max_offset == 0)
  692. {
  693. if (!backtrace_close (descriptor, error_callback, data))
  694. goto fail;
  695. *fileline_fn = coff_nodebug;
  696. return 1;
  697. }
  698. if (!backtrace_get_view (state, descriptor, min_offset,
  699. max_offset - min_offset,
  700. error_callback, data, &debug_view))
  701. goto fail;
  702. debug_view_valid = 1;
  703. /* We've read all we need from the executable. */
  704. if (!backtrace_close (descriptor, error_callback, data))
  705. goto fail;
  706. descriptor = -1;
  707. for (i = 0; i < (int) DEBUG_MAX; ++i)
  708. {
  709. size_t size = sections[i].size;
  710. dwarf_sections.size[i] = size;
  711. if (size == 0)
  712. dwarf_sections.data[i] = NULL;
  713. else
  714. dwarf_sections.data[i] = ((const unsigned char *) debug_view.data
  715. + (sections[i].offset - min_offset));
  716. }
  717. if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
  718. 0, /* FIXME: is_bigendian */
  719. NULL, /* altlink */
  720. error_callback, data, fileline_fn,
  721. NULL /* returned fileline_entry */))
  722. goto fail;
  723. *found_dwarf = 1;
  724. return 1;
  725. fail:
  726. if (sects_view_valid)
  727. backtrace_release_view (state, &sects_view, error_callback, data);
  728. if (str_view_valid)
  729. backtrace_release_view (state, &str_view, error_callback, data);
  730. if (syms_view_valid)
  731. backtrace_release_view (state, &syms_view, error_callback, data);
  732. if (debug_view_valid)
  733. backtrace_release_view (state, &debug_view, error_callback, data);
  734. if (descriptor != -1)
  735. backtrace_close (descriptor, error_callback, data);
  736. return 0;
  737. }
  738. /* Initialize the backtrace data we need from an ELF executable. At
  739. the ELF level, all we need to do is find the debug info
  740. sections. */
  741. int
  742. backtrace_initialize (struct backtrace_state *state,
  743. const char *filename ATTRIBUTE_UNUSED, int descriptor,
  744. backtrace_error_callback error_callback,
  745. void *data, fileline *fileline_fn)
  746. {
  747. int ret;
  748. int found_sym;
  749. int found_dwarf;
  750. fileline coff_fileline_fn;
  751. ret = coff_add (state, descriptor, error_callback, data,
  752. &coff_fileline_fn, &found_sym, &found_dwarf);
  753. if (!ret)
  754. return 0;
  755. if (!state->threaded)
  756. {
  757. if (found_sym)
  758. state->syminfo_fn = coff_syminfo;
  759. else if (state->syminfo_fn == NULL)
  760. state->syminfo_fn = coff_nosyms;
  761. }
  762. else
  763. {
  764. if (found_sym)
  765. backtrace_atomic_store_pointer (&state->syminfo_fn, coff_syminfo);
  766. else
  767. (void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
  768. coff_nosyms);
  769. }
  770. if (!state->threaded)
  771. {
  772. if (state->fileline_fn == NULL || state->fileline_fn == coff_nodebug)
  773. *fileline_fn = coff_fileline_fn;
  774. }
  775. else
  776. {
  777. fileline current_fn;
  778. current_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
  779. if (current_fn == NULL || current_fn == coff_nodebug)
  780. *fileline_fn = coff_fileline_fn;
  781. }
  782. return 1;
  783. }