charset.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  1. /* Character set conversion support for GDB.
  2. Copyright (C) 2001-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #include "defs.h"
  15. #include "charset.h"
  16. #include "gdbcmd.h"
  17. #include "gdbsupport/gdb_obstack.h"
  18. #include "gdbsupport/gdb_wait.h"
  19. #include "charset-list.h"
  20. #include "gdbsupport/environ.h"
  21. #include "arch-utils.h"
  22. #include "gdbsupport/gdb_vecs.h"
  23. #include <ctype.h>
  24. #ifdef USE_WIN32API
  25. #include <windows.h>
  26. #endif
  27. /* How GDB's character set support works
  28. GDB has three global settings:
  29. - The `current host character set' is the character set GDB should
  30. use in talking to the user, and which (hopefully) the user's
  31. terminal knows how to display properly. Most users should not
  32. change this.
  33. - The `current target character set' is the character set the
  34. program being debugged uses.
  35. - The `current target wide character set' is the wide character set
  36. the program being debugged uses, that is, the encoding used for
  37. wchar_t.
  38. There are commands to set each of these, and mechanisms for
  39. choosing reasonable default values. GDB has a global list of
  40. character sets that it can use as its host or target character
  41. sets.
  42. The header file `charset.h' declares various functions that
  43. different pieces of GDB need to perform tasks like:
  44. - printing target strings and characters to the user's terminal
  45. (mostly target->host conversions),
  46. - building target-appropriate representations of strings and
  47. characters the user enters in expressions (mostly host->target
  48. conversions),
  49. and so on.
  50. To avoid excessive code duplication and maintenance efforts,
  51. GDB simply requires a capable iconv function. Users on platforms
  52. without a suitable iconv can use the GNU iconv library. */
  53. #ifdef PHONY_ICONV
  54. /* Provide a phony iconv that does as little as possible. Also,
  55. arrange for there to be a single available character set. */
  56. #undef GDB_DEFAULT_HOST_CHARSET
  57. #ifdef USE_WIN32API
  58. # define GDB_DEFAULT_HOST_CHARSET "CP1252"
  59. #else
  60. # define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
  61. #endif
  62. #define GDB_DEFAULT_TARGET_CHARSET GDB_DEFAULT_HOST_CHARSET
  63. #define GDB_DEFAULT_TARGET_WIDE_CHARSET "UTF-32"
  64. #undef DEFAULT_CHARSET_NAMES
  65. #define DEFAULT_CHARSET_NAMES GDB_DEFAULT_HOST_CHARSET ,
  66. #undef iconv_t
  67. #define iconv_t int
  68. #undef iconv_open
  69. #define iconv_open phony_iconv_open
  70. #undef iconv
  71. #define iconv phony_iconv
  72. #undef iconv_close
  73. #define iconv_close phony_iconv_close
  74. #undef ICONV_CONST
  75. #define ICONV_CONST const
  76. /* We allow conversions from UTF-32, wchar_t, and the host charset.
  77. We allow conversions to wchar_t and the host charset.
  78. Return 1 if we are converting from UTF-32BE, 2 if from UTF32-LE,
  79. 0 otherwise. This is used as a flag in calls to iconv. */
  80. static iconv_t
  81. phony_iconv_open (const char *to, const char *from)
  82. {
  83. if (strcmp (to, "wchar_t") && strcmp (to, GDB_DEFAULT_HOST_CHARSET))
  84. return -1;
  85. if (!strcmp (from, "UTF-32BE") || !strcmp (from, "UTF-32"))
  86. return 1;
  87. if (!strcmp (from, "UTF-32LE"))
  88. return 2;
  89. if (strcmp (from, "wchar_t") && strcmp (from, GDB_DEFAULT_HOST_CHARSET))
  90. return -1;
  91. return 0;
  92. }
  93. static int
  94. phony_iconv_close (iconv_t arg)
  95. {
  96. return 0;
  97. }
  98. static size_t
  99. phony_iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
  100. char **outbuf, size_t *outbytesleft)
  101. {
  102. if (utf_flag)
  103. {
  104. enum bfd_endian endian
  105. = utf_flag == 1 ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
  106. while (*inbytesleft >= 4)
  107. {
  108. unsigned long c
  109. = extract_unsigned_integer ((const gdb_byte *)*inbuf, 4, endian);
  110. if (c >= 256)
  111. {
  112. errno = EILSEQ;
  113. return -1;
  114. }
  115. if (*outbytesleft < 1)
  116. {
  117. errno = E2BIG;
  118. return -1;
  119. }
  120. **outbuf = c & 0xff;
  121. ++*outbuf;
  122. --*outbytesleft;
  123. *inbuf += 4;
  124. *inbytesleft -= 4;
  125. }
  126. if (*inbytesleft)
  127. {
  128. /* Partial sequence on input. */
  129. errno = EINVAL;
  130. return -1;
  131. }
  132. }
  133. else
  134. {
  135. /* In all other cases we simply copy input bytes to the
  136. output. */
  137. size_t amt = *inbytesleft;
  138. if (amt > *outbytesleft)
  139. amt = *outbytesleft;
  140. memcpy (*outbuf, *inbuf, amt);
  141. *inbuf += amt;
  142. *outbuf += amt;
  143. *inbytesleft -= amt;
  144. *outbytesleft -= amt;
  145. if (*inbytesleft)
  146. {
  147. errno = E2BIG;
  148. return -1;
  149. }
  150. }
  151. /* The number of non-reversible conversions -- but they were all
  152. reversible. */
  153. return 0;
  154. }
  155. #else /* PHONY_ICONV */
  156. /* On systems that don't have EILSEQ, GNU iconv's iconv.h defines it
  157. to ENOENT, while gnulib defines it to a different value. Always
  158. map ENOENT to gnulib's EILSEQ, leaving callers agnostic. */
  159. static size_t
  160. gdb_iconv (iconv_t utf_flag, ICONV_CONST char **inbuf, size_t *inbytesleft,
  161. char **outbuf, size_t *outbytesleft)
  162. {
  163. size_t ret;
  164. ret = iconv (utf_flag, inbuf, inbytesleft, outbuf, outbytesleft);
  165. if (errno == ENOENT)
  166. errno = EILSEQ;
  167. return ret;
  168. }
  169. #undef iconv
  170. #define iconv gdb_iconv
  171. #endif /* PHONY_ICONV */
  172. /* The global lists of character sets and translations. */
  173. #ifndef GDB_DEFAULT_TARGET_CHARSET
  174. #define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
  175. #endif
  176. #ifndef GDB_DEFAULT_TARGET_WIDE_CHARSET
  177. #define GDB_DEFAULT_TARGET_WIDE_CHARSET "UTF-32"
  178. #endif
  179. static const char *auto_host_charset_name = GDB_DEFAULT_HOST_CHARSET;
  180. static const char *host_charset_name = "auto";
  181. static void
  182. show_host_charset_name (struct ui_file *file, int from_tty,
  183. struct cmd_list_element *c,
  184. const char *value)
  185. {
  186. if (!strcmp (value, "auto"))
  187. gdb_printf (file,
  188. _("The host character set is \"auto; currently %s\".\n"),
  189. auto_host_charset_name);
  190. else
  191. gdb_printf (file, _("The host character set is \"%s\".\n"), value);
  192. }
  193. static const char *target_charset_name = "auto";
  194. static void
  195. show_target_charset_name (struct ui_file *file, int from_tty,
  196. struct cmd_list_element *c, const char *value)
  197. {
  198. if (!strcmp (value, "auto"))
  199. gdb_printf (file,
  200. _("The target character set is \"auto; "
  201. "currently %s\".\n"),
  202. gdbarch_auto_charset (get_current_arch ()));
  203. else
  204. gdb_printf (file, _("The target character set is \"%s\".\n"),
  205. value);
  206. }
  207. static const char *target_wide_charset_name = "auto";
  208. static void
  209. show_target_wide_charset_name (struct ui_file *file,
  210. int from_tty,
  211. struct cmd_list_element *c,
  212. const char *value)
  213. {
  214. if (!strcmp (value, "auto"))
  215. gdb_printf (file,
  216. _("The target wide character set is \"auto; "
  217. "currently %s\".\n"),
  218. gdbarch_auto_wide_charset (get_current_arch ()));
  219. else
  220. gdb_printf (file, _("The target wide character set is \"%s\".\n"),
  221. value);
  222. }
  223. static const char * const default_charset_names[] =
  224. {
  225. DEFAULT_CHARSET_NAMES
  226. 0
  227. };
  228. static const char * const *charset_enum;
  229. /* If the target wide character set has big- or little-endian
  230. variants, these are the corresponding names. */
  231. static const char *target_wide_charset_be_name;
  232. static const char *target_wide_charset_le_name;
  233. /* The architecture for which the BE- and LE-names are valid. */
  234. static struct gdbarch *be_le_arch;
  235. /* A helper function which sets the target wide big- and little-endian
  236. character set names, if possible. */
  237. static void
  238. set_be_le_names (struct gdbarch *gdbarch)
  239. {
  240. if (be_le_arch == gdbarch)
  241. return;
  242. be_le_arch = gdbarch;
  243. #ifdef PHONY_ICONV
  244. /* Match the wide charset names recognized by phony_iconv_open. */
  245. target_wide_charset_le_name = "UTF-32LE";
  246. target_wide_charset_be_name = "UTF-32BE";
  247. #else
  248. int i, len;
  249. const char *target_wide;
  250. target_wide_charset_le_name = NULL;
  251. target_wide_charset_be_name = NULL;
  252. target_wide = target_wide_charset_name;
  253. if (!strcmp (target_wide, "auto"))
  254. target_wide = gdbarch_auto_wide_charset (gdbarch);
  255. len = strlen (target_wide);
  256. for (i = 0; charset_enum[i]; ++i)
  257. {
  258. if (strncmp (target_wide, charset_enum[i], len))
  259. continue;
  260. if ((charset_enum[i][len] == 'B'
  261. || charset_enum[i][len] == 'L')
  262. && charset_enum[i][len + 1] == 'E'
  263. && charset_enum[i][len + 2] == '\0')
  264. {
  265. if (charset_enum[i][len] == 'B')
  266. target_wide_charset_be_name = charset_enum[i];
  267. else
  268. target_wide_charset_le_name = charset_enum[i];
  269. }
  270. }
  271. # endif /* PHONY_ICONV */
  272. }
  273. /* 'Set charset', 'set host-charset', 'set target-charset', 'set
  274. target-wide-charset', 'set charset' sfunc's. */
  275. static void
  276. validate (struct gdbarch *gdbarch)
  277. {
  278. iconv_t desc;
  279. const char *host_cset = host_charset ();
  280. const char *target_cset = target_charset (gdbarch);
  281. const char *target_wide_cset = target_wide_charset_name;
  282. if (!strcmp (target_wide_cset, "auto"))
  283. target_wide_cset = gdbarch_auto_wide_charset (gdbarch);
  284. desc = iconv_open (target_wide_cset, host_cset);
  285. if (desc == (iconv_t) -1)
  286. error (_("Cannot convert between character sets `%s' and `%s'"),
  287. target_wide_cset, host_cset);
  288. iconv_close (desc);
  289. desc = iconv_open (target_cset, host_cset);
  290. if (desc == (iconv_t) -1)
  291. error (_("Cannot convert between character sets `%s' and `%s'"),
  292. target_cset, host_cset);
  293. iconv_close (desc);
  294. /* Clear the cache. */
  295. be_le_arch = NULL;
  296. }
  297. /* This is the sfunc for the 'set charset' command. */
  298. static void
  299. set_charset_sfunc (const char *charset, int from_tty,
  300. struct cmd_list_element *c)
  301. {
  302. /* CAREFUL: set the target charset here as well. */
  303. target_charset_name = host_charset_name;
  304. validate (get_current_arch ());
  305. }
  306. /* 'set host-charset' command sfunc. We need a wrapper here because
  307. the function needs to have a specific signature. */
  308. static void
  309. set_host_charset_sfunc (const char *charset, int from_tty,
  310. struct cmd_list_element *c)
  311. {
  312. validate (get_current_arch ());
  313. }
  314. /* Wrapper for the 'set target-charset' command. */
  315. static void
  316. set_target_charset_sfunc (const char *charset, int from_tty,
  317. struct cmd_list_element *c)
  318. {
  319. validate (get_current_arch ());
  320. }
  321. /* Wrapper for the 'set target-wide-charset' command. */
  322. static void
  323. set_target_wide_charset_sfunc (const char *charset, int from_tty,
  324. struct cmd_list_element *c)
  325. {
  326. validate (get_current_arch ());
  327. }
  328. /* sfunc for the 'show charset' command. */
  329. static void
  330. show_charset (struct ui_file *file, int from_tty,
  331. struct cmd_list_element *c,
  332. const char *name)
  333. {
  334. show_host_charset_name (file, from_tty, c, host_charset_name);
  335. show_target_charset_name (file, from_tty, c, target_charset_name);
  336. show_target_wide_charset_name (file, from_tty, c,
  337. target_wide_charset_name);
  338. }
  339. /* Accessor functions. */
  340. const char *
  341. host_charset (void)
  342. {
  343. if (!strcmp (host_charset_name, "auto"))
  344. return auto_host_charset_name;
  345. return host_charset_name;
  346. }
  347. const char *
  348. target_charset (struct gdbarch *gdbarch)
  349. {
  350. if (!strcmp (target_charset_name, "auto"))
  351. return gdbarch_auto_charset (gdbarch);
  352. return target_charset_name;
  353. }
  354. const char *
  355. target_wide_charset (struct gdbarch *gdbarch)
  356. {
  357. enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  358. set_be_le_names (gdbarch);
  359. if (byte_order == BFD_ENDIAN_BIG)
  360. {
  361. if (target_wide_charset_be_name)
  362. return target_wide_charset_be_name;
  363. }
  364. else
  365. {
  366. if (target_wide_charset_le_name)
  367. return target_wide_charset_le_name;
  368. }
  369. if (!strcmp (target_wide_charset_name, "auto"))
  370. return gdbarch_auto_wide_charset (gdbarch);
  371. return target_wide_charset_name;
  372. }
  373. /* Host character set management. For the time being, we assume that
  374. the host character set is some superset of ASCII. */
  375. char
  376. host_letter_to_control_character (char c)
  377. {
  378. if (c == '?')
  379. return 0177;
  380. return c & 0237;
  381. }
  382. /* Public character management functions. */
  383. class iconv_wrapper
  384. {
  385. public:
  386. iconv_wrapper (const char *to, const char *from)
  387. {
  388. m_desc = iconv_open (to, from);
  389. if (m_desc == (iconv_t) -1)
  390. perror_with_name (_("Converting character sets"));
  391. }
  392. ~iconv_wrapper ()
  393. {
  394. iconv_close (m_desc);
  395. }
  396. size_t convert (ICONV_CONST char **inp, size_t *inleft, char **outp,
  397. size_t *outleft)
  398. {
  399. return iconv (m_desc, inp, inleft, outp, outleft);
  400. }
  401. private:
  402. iconv_t m_desc;
  403. };
  404. void
  405. convert_between_encodings (const char *from, const char *to,
  406. const gdb_byte *bytes, unsigned int num_bytes,
  407. int width, struct obstack *output,
  408. enum transliterations translit)
  409. {
  410. size_t inleft;
  411. ICONV_CONST char *inp;
  412. unsigned int space_request;
  413. /* Often, the host and target charsets will be the same. */
  414. if (!strcmp (from, to))
  415. {
  416. obstack_grow (output, bytes, num_bytes);
  417. return;
  418. }
  419. iconv_wrapper desc (to, from);
  420. inleft = num_bytes;
  421. inp = (ICONV_CONST char *) bytes;
  422. space_request = num_bytes;
  423. while (inleft > 0)
  424. {
  425. char *outp;
  426. size_t outleft, r;
  427. int old_size;
  428. old_size = obstack_object_size (output);
  429. obstack_blank (output, space_request);
  430. outp = (char *) obstack_base (output) + old_size;
  431. outleft = space_request;
  432. r = desc.convert (&inp, &inleft, &outp, &outleft);
  433. /* Now make sure that the object on the obstack only includes
  434. bytes we have converted. */
  435. obstack_blank_fast (output, -(ssize_t) outleft);
  436. if (r == (size_t) -1)
  437. {
  438. switch (errno)
  439. {
  440. case EILSEQ:
  441. {
  442. int i;
  443. /* Invalid input sequence. */
  444. if (translit == translit_none)
  445. error (_("Could not convert character "
  446. "to `%s' character set"), to);
  447. /* We emit escape sequence for the bytes, skip them,
  448. and try again. */
  449. for (i = 0; i < width; ++i)
  450. {
  451. char octal[5];
  452. xsnprintf (octal, sizeof (octal), "\\%.3o", *inp & 0xff);
  453. obstack_grow_str (output, octal);
  454. ++inp;
  455. --inleft;
  456. }
  457. }
  458. break;
  459. case E2BIG:
  460. /* We ran out of space in the output buffer. Make it
  461. bigger next time around. */
  462. space_request *= 2;
  463. break;
  464. case EINVAL:
  465. /* Incomplete input sequence. FIXME: ought to report this
  466. to the caller somehow. */
  467. inleft = 0;
  468. break;
  469. default:
  470. perror_with_name (_("Internal error while "
  471. "converting character sets"));
  472. }
  473. }
  474. }
  475. }
  476. /* Create a new iterator. */
  477. wchar_iterator::wchar_iterator (const gdb_byte *input, size_t bytes,
  478. const char *charset, size_t width)
  479. : m_input (input),
  480. m_bytes (bytes),
  481. m_width (width),
  482. m_out (1)
  483. {
  484. m_desc = iconv_open (INTERMEDIATE_ENCODING, charset);
  485. if (m_desc == (iconv_t) -1)
  486. perror_with_name (_("Converting character sets"));
  487. }
  488. wchar_iterator::~wchar_iterator ()
  489. {
  490. if (m_desc != (iconv_t) -1)
  491. iconv_close (m_desc);
  492. }
  493. int
  494. wchar_iterator::iterate (enum wchar_iterate_result *out_result,
  495. gdb_wchar_t **out_chars,
  496. const gdb_byte **ptr,
  497. size_t *len)
  498. {
  499. size_t out_request;
  500. /* Try to convert some characters. At first we try to convert just
  501. a single character. The reason for this is that iconv does not
  502. necessarily update its outgoing arguments when it encounters an
  503. invalid input sequence -- but we want to reliably report this to
  504. our caller so it can emit an escape sequence. */
  505. out_request = 1;
  506. while (m_bytes > 0)
  507. {
  508. ICONV_CONST char *inptr = (ICONV_CONST char *) m_input;
  509. char *outptr = (char *) m_out.data ();
  510. const gdb_byte *orig_inptr = m_input;
  511. size_t orig_in = m_bytes;
  512. size_t out_avail = out_request * sizeof (gdb_wchar_t);
  513. size_t num;
  514. size_t r = iconv (m_desc, &inptr, &m_bytes, &outptr, &out_avail);
  515. m_input = (gdb_byte *) inptr;
  516. if (r == (size_t) -1)
  517. {
  518. switch (errno)
  519. {
  520. case EILSEQ:
  521. /* Invalid input sequence. We still might have
  522. converted a character; if so, return it. */
  523. if (out_avail < out_request * sizeof (gdb_wchar_t))
  524. break;
  525. /* Otherwise skip the first invalid character, and let
  526. the caller know about it. */
  527. *out_result = wchar_iterate_invalid;
  528. *ptr = m_input;
  529. *len = m_width;
  530. m_input += m_width;
  531. m_bytes -= m_width;
  532. return 0;
  533. case E2BIG:
  534. /* We ran out of space. We still might have converted a
  535. character; if so, return it. Otherwise, grow the
  536. buffer and try again. */
  537. if (out_avail < out_request * sizeof (gdb_wchar_t))
  538. break;
  539. ++out_request;
  540. if (out_request > m_out.size ())
  541. m_out.resize (out_request);
  542. continue;
  543. case EINVAL:
  544. /* Incomplete input sequence. Let the caller know, and
  545. arrange for future calls to see EOF. */
  546. *out_result = wchar_iterate_incomplete;
  547. *ptr = m_input;
  548. *len = m_bytes;
  549. m_bytes = 0;
  550. return 0;
  551. default:
  552. perror_with_name (_("Internal error while "
  553. "converting character sets"));
  554. }
  555. }
  556. /* We converted something. */
  557. num = out_request - out_avail / sizeof (gdb_wchar_t);
  558. *out_result = wchar_iterate_ok;
  559. *out_chars = m_out.data ();
  560. *ptr = orig_inptr;
  561. *len = orig_in - m_bytes;
  562. return num;
  563. }
  564. /* Really done. */
  565. *out_result = wchar_iterate_eof;
  566. return -1;
  567. }
  568. struct charset_vector
  569. {
  570. ~charset_vector ()
  571. {
  572. clear ();
  573. }
  574. void clear ()
  575. {
  576. for (char *c : charsets)
  577. xfree (c);
  578. charsets.clear ();
  579. }
  580. std::vector<char *> charsets;
  581. };
  582. static charset_vector charsets;
  583. #ifdef PHONY_ICONV
  584. static void
  585. find_charset_names (void)
  586. {
  587. charsets.charsets.push_back (xstrdup (GDB_DEFAULT_HOST_CHARSET));
  588. charsets.charsets.push_back (NULL);
  589. }
  590. #else /* PHONY_ICONV */
  591. /* Sometimes, libiconv redefines iconvlist as libiconvlist -- but
  592. provides different symbols in the static and dynamic libraries.
  593. So, configure may see libiconvlist but not iconvlist. But, calling
  594. iconvlist is the right thing to do and will work. Hence we do a
  595. check here but unconditionally call iconvlist below. */
  596. #if defined (HAVE_ICONVLIST) || defined (HAVE_LIBICONVLIST)
  597. /* A helper function that adds some character sets to the vector of
  598. all character sets. This is a callback function for iconvlist. */
  599. static int
  600. add_one (unsigned int count, const char *const *names, void *data)
  601. {
  602. unsigned int i;
  603. for (i = 0; i < count; ++i)
  604. charsets.charsets.push_back (xstrdup (names[i]));
  605. return 0;
  606. }
  607. static void
  608. find_charset_names (void)
  609. {
  610. iconvlist (add_one, NULL);
  611. charsets.charsets.push_back (NULL);
  612. }
  613. #else
  614. /* Return non-zero if LINE (output from iconv) should be ignored.
  615. Older iconv programs (e.g. 2.2.2) include the human readable
  616. introduction even when stdout is not a tty. Newer versions omit
  617. the intro if stdout is not a tty. */
  618. static int
  619. ignore_line_p (const char *line)
  620. {
  621. /* This table is used to filter the output. If this text appears
  622. anywhere in the line, it is ignored (strstr is used). */
  623. static const char * const ignore_lines[] =
  624. {
  625. "The following",
  626. "not necessarily",
  627. "the FROM and TO",
  628. "listed with several",
  629. NULL
  630. };
  631. int i;
  632. for (i = 0; ignore_lines[i] != NULL; ++i)
  633. {
  634. if (strstr (line, ignore_lines[i]) != NULL)
  635. return 1;
  636. }
  637. return 0;
  638. }
  639. static void
  640. find_charset_names (void)
  641. {
  642. struct pex_obj *child;
  643. const char *args[3];
  644. int err, status;
  645. int fail = 1;
  646. int flags;
  647. gdb_environ iconv_env = gdb_environ::from_host_environ ();
  648. char *iconv_program;
  649. /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is
  650. not a tty. We need to recognize it and ignore it. This text is
  651. subject to translation, so force LANGUAGE=C. */
  652. iconv_env.set ("LANGUAGE", "C");
  653. iconv_env.set ("LC_ALL", "C");
  654. child = pex_init (PEX_USE_PIPES, "iconv", NULL);
  655. #ifdef ICONV_BIN
  656. {
  657. std::string iconv_dir = relocate_gdb_directory (ICONV_BIN,
  658. ICONV_BIN_RELOCATABLE);
  659. iconv_program
  660. = concat (iconv_dir.c_str(), SLASH_STRING, "iconv", (char *) NULL);
  661. }
  662. #else
  663. iconv_program = xstrdup ("iconv");
  664. #endif
  665. args[0] = iconv_program;
  666. args[1] = "-l";
  667. args[2] = NULL;
  668. flags = PEX_STDERR_TO_STDOUT;
  669. #ifndef ICONV_BIN
  670. flags |= PEX_SEARCH;
  671. #endif
  672. /* Note that we simply ignore errors here. */
  673. if (!pex_run_in_environment (child, flags,
  674. args[0], const_cast<char **> (args),
  675. iconv_env.envp (),
  676. NULL, NULL, &err))
  677. {
  678. FILE *in = pex_read_output (child, 0);
  679. /* POSIX says that iconv -l uses an unspecified format. We
  680. parse the glibc and libiconv formats; feel free to add others
  681. as needed. */
  682. while (in != NULL && !feof (in))
  683. {
  684. /* The size of buf is chosen arbitrarily. */
  685. char buf[1024];
  686. char *start, *r;
  687. int len;
  688. r = fgets (buf, sizeof (buf), in);
  689. if (!r)
  690. break;
  691. len = strlen (r);
  692. if (len <= 3)
  693. continue;
  694. if (ignore_line_p (r))
  695. continue;
  696. /* Strip off the newline. */
  697. --len;
  698. /* Strip off one or two '/'s. glibc will print lines like
  699. "8859_7//", but also "10646-1:1993/UCS4/". */
  700. if (buf[len - 1] == '/')
  701. --len;
  702. if (buf[len - 1] == '/')
  703. --len;
  704. buf[len] = '\0';
  705. /* libiconv will print multiple entries per line, separated
  706. by spaces. Older iconvs will print multiple entries per
  707. line, indented by two spaces, and separated by ", "
  708. (i.e. the human readable form). */
  709. start = buf;
  710. while (1)
  711. {
  712. int keep_going;
  713. char *p;
  714. /* Skip leading blanks. */
  715. for (p = start; *p && *p == ' '; ++p)
  716. ;
  717. start = p;
  718. /* Find the next space, comma, or end-of-line. */
  719. for ( ; *p && *p != ' ' && *p != ','; ++p)
  720. ;
  721. /* Ignore an empty result. */
  722. if (p == start)
  723. break;
  724. keep_going = *p;
  725. *p = '\0';
  726. charsets.charsets.push_back (xstrdup (start));
  727. if (!keep_going)
  728. break;
  729. /* Skip any extra spaces. */
  730. for (start = p + 1; *start && *start == ' '; ++start)
  731. ;
  732. }
  733. }
  734. if (pex_get_status (child, 1, &status)
  735. && WIFEXITED (status) && !WEXITSTATUS (status))
  736. fail = 0;
  737. }
  738. xfree (iconv_program);
  739. pex_free (child);
  740. if (fail)
  741. {
  742. /* Some error occurred, so drop the vector. */
  743. charsets.clear ();
  744. }
  745. else
  746. charsets.charsets.push_back (NULL);
  747. }
  748. #endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
  749. #endif /* PHONY_ICONV */
  750. /* The "auto" target charset used by default_auto_charset. */
  751. static const char *auto_target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
  752. const char *
  753. default_auto_charset (void)
  754. {
  755. return auto_target_charset_name;
  756. }
  757. const char *
  758. default_auto_wide_charset (void)
  759. {
  760. return GDB_DEFAULT_TARGET_WIDE_CHARSET;
  761. }
  762. #ifdef USE_INTERMEDIATE_ENCODING_FUNCTION
  763. /* Macro used for UTF or UCS endianness suffix. */
  764. #if WORDS_BIGENDIAN
  765. #define ENDIAN_SUFFIX "BE"
  766. #else
  767. #define ENDIAN_SUFFIX "LE"
  768. #endif
  769. /* GDB cannot handle strings correctly if this size is different. */
  770. gdb_static_assert (sizeof (gdb_wchar_t) == 2 || sizeof (gdb_wchar_t) == 4);
  771. /* intermediate_encoding returns the charset used internally by
  772. GDB to convert between target and host encodings. As the test above
  773. compiled, sizeof (gdb_wchar_t) is either 2 or 4 bytes.
  774. UTF-16/32 is tested first, UCS-2/4 is tested as a second option,
  775. otherwise an error is generated. */
  776. const char *
  777. intermediate_encoding (void)
  778. {
  779. iconv_t desc;
  780. static const char *stored_result = NULL;
  781. gdb::unique_xmalloc_ptr<char> result;
  782. if (stored_result)
  783. return stored_result;
  784. result = xstrprintf ("UTF-%d%s", (int) (sizeof (gdb_wchar_t) * 8),
  785. ENDIAN_SUFFIX);
  786. /* Check that the name is supported by iconv_open. */
  787. desc = iconv_open (result.get (), host_charset ());
  788. if (desc != (iconv_t) -1)
  789. {
  790. iconv_close (desc);
  791. stored_result = result.release ();
  792. return stored_result;
  793. }
  794. /* Second try, with UCS-2 type. */
  795. result = xstrprintf ("UCS-%d%s", (int) sizeof (gdb_wchar_t),
  796. ENDIAN_SUFFIX);
  797. /* Check that the name is supported by iconv_open. */
  798. desc = iconv_open (result.get (), host_charset ());
  799. if (desc != (iconv_t) -1)
  800. {
  801. iconv_close (desc);
  802. stored_result = result.release ();
  803. return stored_result;
  804. }
  805. /* No valid charset found, generate error here. */
  806. error (_("Unable to find a valid charset for string conversions"));
  807. }
  808. #endif /* USE_INTERMEDIATE_ENCODING_FUNCTION */
  809. void _initialize_charset ();
  810. void
  811. _initialize_charset ()
  812. {
  813. /* The first element is always "auto". */
  814. charsets.charsets.push_back (xstrdup ("auto"));
  815. find_charset_names ();
  816. if (charsets.charsets.size () > 1)
  817. charset_enum = (const char * const *) charsets.charsets.data ();
  818. else
  819. charset_enum = default_charset_names;
  820. #ifndef PHONY_ICONV
  821. #ifdef HAVE_LANGINFO_CODESET
  822. /* The result of nl_langinfo may be overwritten later. This may
  823. leak a little memory, if the user later changes the host charset,
  824. but that doesn't matter much. */
  825. auto_host_charset_name = xstrdup (nl_langinfo (CODESET));
  826. /* Solaris will return `646' here -- but the Solaris iconv then does
  827. not accept this. Darwin (and maybe FreeBSD) may return "" here,
  828. which GNU libiconv doesn't like (infinite loop). */
  829. if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
  830. auto_host_charset_name = "ASCII";
  831. auto_target_charset_name = auto_host_charset_name;
  832. #elif defined (USE_WIN32API)
  833. {
  834. /* "CP" + x<=5 digits + paranoia. */
  835. static char w32_host_default_charset[16];
  836. snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
  837. "CP%d", GetACP());
  838. auto_host_charset_name = w32_host_default_charset;
  839. auto_target_charset_name = auto_host_charset_name;
  840. }
  841. #endif
  842. #endif
  843. /* Recall that the first element is always "auto". */
  844. host_charset_name = charset_enum[0];
  845. gdb_assert (strcmp (host_charset_name, "auto") == 0);
  846. add_setshow_enum_cmd ("charset", class_support,
  847. charset_enum, &host_charset_name, _("\
  848. Set the host and target character sets."), _("\
  849. Show the host and target character sets."), _("\
  850. The `host character set' is the one used by the system GDB is running on.\n\
  851. The `target character set' is the one used by the program being debugged.\n\
  852. You may only use supersets of ASCII for your host character set; GDB does\n\
  853. not support any others.\n\
  854. To see a list of the character sets GDB supports, type `set charset <TAB>'."),
  855. /* Note that the sfunc below needs to set
  856. target_charset_name, because the 'set
  857. charset' command sets two variables. */
  858. set_charset_sfunc,
  859. show_charset,
  860. &setlist, &showlist);
  861. add_setshow_enum_cmd ("host-charset", class_support,
  862. charset_enum, &host_charset_name, _("\
  863. Set the host character set."), _("\
  864. Show the host character set."), _("\
  865. The `host character set' is the one used by the system GDB is running on.\n\
  866. You may only use supersets of ASCII for your host character set; GDB does\n\
  867. not support any others.\n\
  868. To see a list of the character sets GDB supports, type `set host-charset <TAB>'."),
  869. set_host_charset_sfunc,
  870. show_host_charset_name,
  871. &setlist, &showlist);
  872. /* Recall that the first element is always "auto". */
  873. target_charset_name = charset_enum[0];
  874. gdb_assert (strcmp (target_charset_name, "auto") == 0);
  875. add_setshow_enum_cmd ("target-charset", class_support,
  876. charset_enum, &target_charset_name, _("\
  877. Set the target character set."), _("\
  878. Show the target character set."), _("\
  879. The `target character set' is the one used by the program being debugged.\n\
  880. GDB translates characters and strings between the host and target\n\
  881. character sets as needed.\n\
  882. To see a list of the character sets GDB supports, type `set target-charset'<TAB>"),
  883. set_target_charset_sfunc,
  884. show_target_charset_name,
  885. &setlist, &showlist);
  886. /* Recall that the first element is always "auto". */
  887. target_wide_charset_name = charset_enum[0];
  888. gdb_assert (strcmp (target_wide_charset_name, "auto") == 0);
  889. add_setshow_enum_cmd ("target-wide-charset", class_support,
  890. charset_enum, &target_wide_charset_name,
  891. _("\
  892. Set the target wide character set."), _("\
  893. Show the target wide character set."), _("\
  894. The `target wide character set' is the one used by the program being debugged.\
  895. \nIn particular it is the encoding used by `wchar_t'.\n\
  896. GDB translates characters and strings between the host and target\n\
  897. character sets as needed.\n\
  898. To see a list of the character sets GDB supports, type\n\
  899. `set target-wide-charset'<TAB>"),
  900. set_target_wide_charset_sfunc,
  901. show_target_wide_charset_name,
  902. &setlist, &showlist);
  903. }