ctf-create.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994
  1. /* CTF dict creation.
  2. Copyright (C) 2019-2022 Free Software Foundation, Inc.
  3. This file is part of libctf.
  4. libctf is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. This program is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. See the 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; see the file COPYING. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <ctf-impl.h>
  16. #include <sys/param.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #ifndef EOVERFLOW
  20. #define EOVERFLOW ERANGE
  21. #endif
  22. #ifndef roundup
  23. #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
  24. #endif
  25. /* The initial size of a dynamic type's vlen in members. Arbitrary: the bigger
  26. this is, the less allocation needs to be done for small structure
  27. initialization, and the more memory is wasted for small structures during CTF
  28. construction. No effect on generated CTF or ctf_open()ed CTF. */
  29. #define INITIAL_VLEN 16
  30. /* Make sure the ptrtab has enough space for at least one more type.
  31. We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
  32. at a time. */
  33. static int
  34. ctf_grow_ptrtab (ctf_dict_t *fp)
  35. {
  36. size_t new_ptrtab_len = fp->ctf_ptrtab_len;
  37. /* We allocate one more ptrtab entry than we need, for the initial zero,
  38. plus one because the caller will probably allocate a new type. */
  39. if (fp->ctf_ptrtab == NULL)
  40. new_ptrtab_len = 1024;
  41. else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
  42. new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
  43. if (new_ptrtab_len != fp->ctf_ptrtab_len)
  44. {
  45. uint32_t *new_ptrtab;
  46. if ((new_ptrtab = realloc (fp->ctf_ptrtab,
  47. new_ptrtab_len * sizeof (uint32_t))) == NULL)
  48. return (ctf_set_errno (fp, ENOMEM));
  49. fp->ctf_ptrtab = new_ptrtab;
  50. memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
  51. (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
  52. fp->ctf_ptrtab_len = new_ptrtab_len;
  53. }
  54. return 0;
  55. }
  56. /* Make sure a vlen has enough space: expand it otherwise. Unlike the ptrtab,
  57. which grows quite slowly, the vlen grows in big jumps because it is quite
  58. expensive to expand: the caller has to scan the old vlen for string refs
  59. first and remove them, then re-add them afterwards. The initial size is
  60. more or less arbitrary. */
  61. static int
  62. ctf_grow_vlen (ctf_dict_t *fp, ctf_dtdef_t *dtd, size_t vlen)
  63. {
  64. unsigned char *old = dtd->dtd_vlen;
  65. if (dtd->dtd_vlen_alloc > vlen)
  66. return 0;
  67. if ((dtd->dtd_vlen = realloc (dtd->dtd_vlen,
  68. dtd->dtd_vlen_alloc * 2)) == NULL)
  69. {
  70. dtd->dtd_vlen = old;
  71. return (ctf_set_errno (fp, ENOMEM));
  72. }
  73. memset (dtd->dtd_vlen + dtd->dtd_vlen_alloc, 0, dtd->dtd_vlen_alloc);
  74. dtd->dtd_vlen_alloc *= 2;
  75. return 0;
  76. }
  77. /* To create an empty CTF dict, we just declare a zeroed header and call
  78. ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new dict r/w and
  79. initialize the dynamic members. We start assigning type IDs at 1 because
  80. type ID 0 is used as a sentinel and a not-found indicator. */
  81. ctf_dict_t *
  82. ctf_create (int *errp)
  83. {
  84. static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
  85. ctf_dynhash_t *dthash;
  86. ctf_dynhash_t *dvhash;
  87. ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
  88. ctf_dynhash_t *objthash = NULL, *funchash = NULL;
  89. ctf_sect_t cts;
  90. ctf_dict_t *fp;
  91. libctf_init_debug();
  92. dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
  93. NULL, NULL);
  94. if (dthash == NULL)
  95. {
  96. ctf_set_open_errno (errp, EAGAIN);
  97. goto err;
  98. }
  99. dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  100. NULL, NULL);
  101. if (dvhash == NULL)
  102. {
  103. ctf_set_open_errno (errp, EAGAIN);
  104. goto err_dt;
  105. }
  106. structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  107. NULL, NULL);
  108. unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  109. NULL, NULL);
  110. enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  111. NULL, NULL);
  112. names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  113. NULL, NULL);
  114. objthash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  115. free, NULL);
  116. funchash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
  117. free, NULL);
  118. if (!structs || !unions || !enums || !names)
  119. {
  120. ctf_set_open_errno (errp, EAGAIN);
  121. goto err_dv;
  122. }
  123. cts.cts_name = _CTF_SECTION;
  124. cts.cts_data = &hdr;
  125. cts.cts_size = sizeof (hdr);
  126. cts.cts_entsize = 1;
  127. if ((fp = ctf_bufopen_internal (&cts, NULL, NULL, NULL, 1, errp)) == NULL)
  128. goto err_dv;
  129. fp->ctf_structs.ctn_writable = structs;
  130. fp->ctf_unions.ctn_writable = unions;
  131. fp->ctf_enums.ctn_writable = enums;
  132. fp->ctf_names.ctn_writable = names;
  133. fp->ctf_objthash = objthash;
  134. fp->ctf_funchash = funchash;
  135. fp->ctf_dthash = dthash;
  136. fp->ctf_dvhash = dvhash;
  137. fp->ctf_dtoldid = 0;
  138. fp->ctf_snapshots = 1;
  139. fp->ctf_snapshot_lu = 0;
  140. fp->ctf_flags |= LCTF_DIRTY;
  141. ctf_set_ctl_hashes (fp);
  142. ctf_setmodel (fp, CTF_MODEL_NATIVE);
  143. if (ctf_grow_ptrtab (fp) < 0)
  144. {
  145. ctf_set_open_errno (errp, ctf_errno (fp));
  146. ctf_dict_close (fp);
  147. return NULL;
  148. }
  149. return fp;
  150. err_dv:
  151. ctf_dynhash_destroy (structs);
  152. ctf_dynhash_destroy (unions);
  153. ctf_dynhash_destroy (enums);
  154. ctf_dynhash_destroy (names);
  155. ctf_dynhash_destroy (objthash);
  156. ctf_dynhash_destroy (funchash);
  157. ctf_dynhash_destroy (dvhash);
  158. err_dt:
  159. ctf_dynhash_destroy (dthash);
  160. err:
  161. return NULL;
  162. }
  163. /* Compatibility: just update the threshold for ctf_discard. */
  164. int
  165. ctf_update (ctf_dict_t *fp)
  166. {
  167. if (!(fp->ctf_flags & LCTF_RDWR))
  168. return (ctf_set_errno (fp, ECTF_RDONLY));
  169. fp->ctf_dtoldid = fp->ctf_typemax;
  170. return 0;
  171. }
  172. ctf_names_t *
  173. ctf_name_table (ctf_dict_t *fp, int kind)
  174. {
  175. switch (kind)
  176. {
  177. case CTF_K_STRUCT:
  178. return &fp->ctf_structs;
  179. case CTF_K_UNION:
  180. return &fp->ctf_unions;
  181. case CTF_K_ENUM:
  182. return &fp->ctf_enums;
  183. default:
  184. return &fp->ctf_names;
  185. }
  186. }
  187. int
  188. ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
  189. {
  190. const char *name;
  191. if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
  192. dtd) < 0)
  193. {
  194. ctf_set_errno (fp, ENOMEM);
  195. return -1;
  196. }
  197. if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
  198. && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
  199. {
  200. if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable,
  201. (char *) name, (void *) (uintptr_t)
  202. dtd->dtd_type) < 0)
  203. {
  204. ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
  205. dtd->dtd_type);
  206. ctf_set_errno (fp, ENOMEM);
  207. return -1;
  208. }
  209. }
  210. ctf_list_append (&fp->ctf_dtdefs, dtd);
  211. return 0;
  212. }
  213. void
  214. ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
  215. {
  216. int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
  217. size_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
  218. int name_kind = kind;
  219. const char *name;
  220. ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
  221. switch (kind)
  222. {
  223. case CTF_K_STRUCT:
  224. case CTF_K_UNION:
  225. {
  226. ctf_lmember_t *memb = (ctf_lmember_t *) dtd->dtd_vlen;
  227. size_t i;
  228. for (i = 0; i < vlen; i++)
  229. ctf_str_remove_ref (fp, ctf_strraw (fp, memb[i].ctlm_name),
  230. &memb[i].ctlm_name);
  231. }
  232. break;
  233. case CTF_K_ENUM:
  234. {
  235. ctf_enum_t *en = (ctf_enum_t *) dtd->dtd_vlen;
  236. size_t i;
  237. for (i = 0; i < vlen; i++)
  238. ctf_str_remove_ref (fp, ctf_strraw (fp, en[i].cte_name),
  239. &en[i].cte_name);
  240. }
  241. break;
  242. case CTF_K_FORWARD:
  243. name_kind = dtd->dtd_data.ctt_type;
  244. break;
  245. }
  246. free (dtd->dtd_vlen);
  247. dtd->dtd_vlen_alloc = 0;
  248. if (dtd->dtd_data.ctt_name
  249. && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
  250. && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
  251. {
  252. ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
  253. name);
  254. ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
  255. }
  256. ctf_list_delete (&fp->ctf_dtdefs, dtd);
  257. free (dtd);
  258. }
  259. ctf_dtdef_t *
  260. ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
  261. {
  262. return (ctf_dtdef_t *)
  263. ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
  264. }
  265. ctf_dtdef_t *
  266. ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
  267. {
  268. ctf_id_t idx;
  269. if (!(fp->ctf_flags & LCTF_RDWR))
  270. return NULL;
  271. if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
  272. fp = fp->ctf_parent;
  273. idx = LCTF_TYPE_TO_INDEX(fp, id);
  274. if ((unsigned long) idx <= fp->ctf_typemax)
  275. return ctf_dtd_lookup (fp, id);
  276. return NULL;
  277. }
  278. int
  279. ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
  280. {
  281. if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
  282. {
  283. ctf_set_errno (fp, ENOMEM);
  284. return -1;
  285. }
  286. ctf_list_append (&fp->ctf_dvdefs, dvd);
  287. return 0;
  288. }
  289. void
  290. ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
  291. {
  292. ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
  293. free (dvd->dvd_name);
  294. ctf_list_delete (&fp->ctf_dvdefs, dvd);
  295. free (dvd);
  296. }
  297. ctf_dvdef_t *
  298. ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
  299. {
  300. return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
  301. }
  302. /* Discard all of the dynamic type definitions and variable definitions that
  303. have been added to the dict since the last call to ctf_update(). We locate
  304. such types by scanning the dtd list and deleting elements that have type IDs
  305. greater than ctf_dtoldid, which is set by ctf_update(), above, and by
  306. scanning the variable list and deleting elements that have update IDs equal
  307. to the current value of the last-update snapshot count (indicating that they
  308. were added after the most recent call to ctf_update()). */
  309. int
  310. ctf_discard (ctf_dict_t *fp)
  311. {
  312. ctf_snapshot_id_t last_update =
  313. { fp->ctf_dtoldid,
  314. fp->ctf_snapshot_lu + 1 };
  315. /* Update required? */
  316. if (!(fp->ctf_flags & LCTF_DIRTY))
  317. return 0;
  318. return (ctf_rollback (fp, last_update));
  319. }
  320. ctf_snapshot_id_t
  321. ctf_snapshot (ctf_dict_t *fp)
  322. {
  323. ctf_snapshot_id_t snapid;
  324. snapid.dtd_id = fp->ctf_typemax;
  325. snapid.snapshot_id = fp->ctf_snapshots++;
  326. return snapid;
  327. }
  328. /* Like ctf_discard(), only discards everything after a particular ID. */
  329. int
  330. ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
  331. {
  332. ctf_dtdef_t *dtd, *ntd;
  333. ctf_dvdef_t *dvd, *nvd;
  334. if (!(fp->ctf_flags & LCTF_RDWR))
  335. return (ctf_set_errno (fp, ECTF_RDONLY));
  336. if (fp->ctf_snapshot_lu >= id.snapshot_id)
  337. return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
  338. for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
  339. {
  340. int kind;
  341. const char *name;
  342. ntd = ctf_list_next (dtd);
  343. if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
  344. continue;
  345. kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
  346. if (kind == CTF_K_FORWARD)
  347. kind = dtd->dtd_data.ctt_type;
  348. if (dtd->dtd_data.ctt_name
  349. && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
  350. && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
  351. {
  352. ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
  353. name);
  354. ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
  355. }
  356. ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
  357. ctf_dtd_delete (fp, dtd);
  358. }
  359. for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
  360. {
  361. nvd = ctf_list_next (dvd);
  362. if (dvd->dvd_snapshots <= id.snapshot_id)
  363. continue;
  364. ctf_dvd_delete (fp, dvd);
  365. }
  366. fp->ctf_typemax = id.dtd_id;
  367. fp->ctf_snapshots = id.snapshot_id;
  368. if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
  369. fp->ctf_flags &= ~LCTF_DIRTY;
  370. return 0;
  371. }
  372. /* Note: vlen is the amount of space *allocated* for the vlen. It may well not
  373. be the amount of space used (yet): the space used is declared in per-kind
  374. fashion in the dtd_data's info word. */
  375. static ctf_id_t
  376. ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
  377. size_t vlen, ctf_dtdef_t **rp)
  378. {
  379. ctf_dtdef_t *dtd;
  380. ctf_id_t type;
  381. if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
  382. return (ctf_set_errno (fp, EINVAL));
  383. if (!(fp->ctf_flags & LCTF_RDWR))
  384. return (ctf_set_errno (fp, ECTF_RDONLY));
  385. if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
  386. return (ctf_set_errno (fp, ECTF_FULL));
  387. if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
  388. return (ctf_set_errno (fp, ECTF_FULL));
  389. /* Make sure ptrtab always grows to be big enough for all types. */
  390. if (ctf_grow_ptrtab (fp) < 0)
  391. return CTF_ERR; /* errno is set for us. */
  392. if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
  393. return (ctf_set_errno (fp, EAGAIN));
  394. dtd->dtd_vlen_alloc = vlen;
  395. if (vlen > 0)
  396. {
  397. if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
  398. goto oom;
  399. }
  400. else
  401. dtd->dtd_vlen = NULL;
  402. type = ++fp->ctf_typemax;
  403. type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
  404. dtd->dtd_data.ctt_name = ctf_str_add_pending (fp, name,
  405. &dtd->dtd_data.ctt_name);
  406. dtd->dtd_type = type;
  407. if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
  408. goto oom;
  409. if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
  410. goto err; /* errno is set for us. */
  411. fp->ctf_flags |= LCTF_DIRTY;
  412. *rp = dtd;
  413. return type;
  414. oom:
  415. ctf_set_errno (fp, EAGAIN);
  416. err:
  417. free (dtd->dtd_vlen);
  418. free (dtd);
  419. return CTF_ERR;
  420. }
  421. /* When encoding integer sizes, we want to convert a byte count in the range
  422. 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
  423. is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
  424. static size_t
  425. clp2 (size_t x)
  426. {
  427. x--;
  428. x |= (x >> 1);
  429. x |= (x >> 2);
  430. x |= (x >> 4);
  431. x |= (x >> 8);
  432. x |= (x >> 16);
  433. return (x + 1);
  434. }
  435. ctf_id_t
  436. ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
  437. const char *name, const ctf_encoding_t *ep, uint32_t kind)
  438. {
  439. ctf_dtdef_t *dtd;
  440. ctf_id_t type;
  441. uint32_t encoding;
  442. if (ep == NULL)
  443. return (ctf_set_errno (fp, EINVAL));
  444. if (name == NULL || name[0] == '\0')
  445. return (ctf_set_errno (fp, ECTF_NONAME));
  446. if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
  447. return -1; /* errno is set for us. */
  448. if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
  449. &dtd)) == CTF_ERR)
  450. return CTF_ERR; /* errno is set for us. */
  451. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
  452. dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
  453. / CHAR_BIT);
  454. switch (kind)
  455. {
  456. case CTF_K_INTEGER:
  457. encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
  458. break;
  459. case CTF_K_FLOAT:
  460. encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
  461. break;
  462. }
  463. memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
  464. return type;
  465. }
  466. ctf_id_t
  467. ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
  468. {
  469. ctf_dtdef_t *dtd;
  470. ctf_id_t type;
  471. ctf_dict_t *tmp = fp;
  472. int child = fp->ctf_flags & LCTF_CHILD;
  473. if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
  474. return (ctf_set_errno (fp, EINVAL));
  475. if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
  476. return CTF_ERR; /* errno is set for us. */
  477. if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
  478. return CTF_ERR; /* errno is set for us. */
  479. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
  480. dtd->dtd_data.ctt_type = (uint32_t) ref;
  481. if (kind != CTF_K_POINTER)
  482. return type;
  483. /* If we are adding a pointer, update the ptrtab, pointing at this type from
  484. the type it points to. Note that ctf_typemax is at this point one higher
  485. than we want to check against, because it's just been incremented for the
  486. addition of this type. The pptrtab is lazily-updated as needed, so is not
  487. touched here. */
  488. uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
  489. uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
  490. if (LCTF_TYPE_ISCHILD (fp, ref) == child
  491. && ref_idx < fp->ctf_typemax)
  492. fp->ctf_ptrtab[ref_idx] = type_idx;
  493. return type;
  494. }
  495. ctf_id_t
  496. ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
  497. const ctf_encoding_t *ep)
  498. {
  499. ctf_dtdef_t *dtd;
  500. ctf_slice_t slice;
  501. ctf_id_t resolved_ref = ref;
  502. ctf_id_t type;
  503. int kind;
  504. const ctf_type_t *tp;
  505. ctf_dict_t *tmp = fp;
  506. if (ep == NULL)
  507. return (ctf_set_errno (fp, EINVAL));
  508. if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
  509. return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
  510. if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
  511. return (ctf_set_errno (fp, EINVAL));
  512. if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
  513. return CTF_ERR; /* errno is set for us. */
  514. /* Make sure we ultimately point to an integral type. We also allow slices to
  515. point to the unimplemented type, for now, because the compiler can emit
  516. such slices, though they're not very much use. */
  517. resolved_ref = ctf_type_resolve_unsliced (tmp, ref);
  518. kind = ctf_type_kind_unsliced (tmp, resolved_ref);
  519. if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
  520. (kind != CTF_K_ENUM)
  521. && (ref != 0))
  522. return (ctf_set_errno (fp, ECTF_NOTINTFP));
  523. if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
  524. sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
  525. return CTF_ERR; /* errno is set for us. */
  526. memset (&slice, 0, sizeof (ctf_slice_t));
  527. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
  528. dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
  529. / CHAR_BIT);
  530. slice.cts_type = (uint32_t) ref;
  531. slice.cts_bits = ep->cte_bits;
  532. slice.cts_offset = ep->cte_offset;
  533. memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
  534. return type;
  535. }
  536. ctf_id_t
  537. ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
  538. const char *name, const ctf_encoding_t *ep)
  539. {
  540. return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
  541. }
  542. ctf_id_t
  543. ctf_add_float (ctf_dict_t *fp, uint32_t flag,
  544. const char *name, const ctf_encoding_t *ep)
  545. {
  546. return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
  547. }
  548. ctf_id_t
  549. ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
  550. {
  551. return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
  552. }
  553. ctf_id_t
  554. ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
  555. {
  556. ctf_dtdef_t *dtd;
  557. ctf_array_t cta;
  558. ctf_id_t type;
  559. ctf_dict_t *tmp = fp;
  560. if (arp == NULL)
  561. return (ctf_set_errno (fp, EINVAL));
  562. if (arp->ctr_contents != 0
  563. && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
  564. return CTF_ERR; /* errno is set for us. */
  565. tmp = fp;
  566. if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
  567. return CTF_ERR; /* errno is set for us. */
  568. if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
  569. {
  570. ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
  571. _("ctf_add_array: index type %lx is incomplete"),
  572. arp->ctr_contents);
  573. return (ctf_set_errno (fp, ECTF_INCOMPLETE));
  574. }
  575. if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
  576. sizeof (ctf_array_t), &dtd)) == CTF_ERR)
  577. return CTF_ERR; /* errno is set for us. */
  578. memset (&cta, 0, sizeof (ctf_array_t));
  579. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
  580. dtd->dtd_data.ctt_size = 0;
  581. cta.cta_contents = (uint32_t) arp->ctr_contents;
  582. cta.cta_index = (uint32_t) arp->ctr_index;
  583. cta.cta_nelems = arp->ctr_nelems;
  584. memcpy (dtd->dtd_vlen, &cta, sizeof (ctf_array_t));
  585. return type;
  586. }
  587. int
  588. ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
  589. {
  590. ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
  591. ctf_array_t *vlen;
  592. if (!(fp->ctf_flags & LCTF_RDWR))
  593. return (ctf_set_errno (fp, ECTF_RDONLY));
  594. if (dtd == NULL
  595. || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
  596. return (ctf_set_errno (fp, ECTF_BADID));
  597. vlen = (ctf_array_t *) dtd->dtd_vlen;
  598. fp->ctf_flags |= LCTF_DIRTY;
  599. vlen->cta_contents = (uint32_t) arp->ctr_contents;
  600. vlen->cta_index = (uint32_t) arp->ctr_index;
  601. vlen->cta_nelems = arp->ctr_nelems;
  602. return 0;
  603. }
  604. ctf_id_t
  605. ctf_add_function (ctf_dict_t *fp, uint32_t flag,
  606. const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
  607. {
  608. ctf_dtdef_t *dtd;
  609. ctf_id_t type;
  610. uint32_t vlen;
  611. uint32_t *vdat;
  612. ctf_dict_t *tmp = fp;
  613. size_t initial_vlen;
  614. size_t i;
  615. if (!(fp->ctf_flags & LCTF_RDWR))
  616. return (ctf_set_errno (fp, ECTF_RDONLY));
  617. if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
  618. || (ctc->ctc_argc != 0 && argv == NULL))
  619. return (ctf_set_errno (fp, EINVAL));
  620. vlen = ctc->ctc_argc;
  621. if (ctc->ctc_flags & CTF_FUNC_VARARG)
  622. vlen++; /* Add trailing zero to indicate varargs (see below). */
  623. if (ctc->ctc_return != 0
  624. && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
  625. return CTF_ERR; /* errno is set for us. */
  626. if (vlen > CTF_MAX_VLEN)
  627. return (ctf_set_errno (fp, EOVERFLOW));
  628. /* One word extra allocated for padding for 4-byte alignment if need be.
  629. Not reflected in vlen: we don't want to copy anything into it, and
  630. it's in addition to (e.g.) the trailing 0 indicating varargs. */
  631. initial_vlen = (sizeof (uint32_t) * (vlen + (vlen & 1)));
  632. if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
  633. initial_vlen, &dtd)) == CTF_ERR)
  634. return CTF_ERR; /* errno is set for us. */
  635. vdat = (uint32_t *) dtd->dtd_vlen;
  636. for (i = 0; i < ctc->ctc_argc; i++)
  637. {
  638. tmp = fp;
  639. if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
  640. return CTF_ERR; /* errno is set for us. */
  641. vdat[i] = (uint32_t) argv[i];
  642. }
  643. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
  644. dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
  645. if (ctc->ctc_flags & CTF_FUNC_VARARG)
  646. vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
  647. return type;
  648. }
  649. ctf_id_t
  650. ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
  651. size_t size)
  652. {
  653. ctf_dtdef_t *dtd;
  654. ctf_id_t type = 0;
  655. size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
  656. /* Promote root-visible forwards to structs. */
  657. if (name != NULL)
  658. type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
  659. if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
  660. dtd = ctf_dtd_lookup (fp, type);
  661. else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
  662. initial_vlen, &dtd)) == CTF_ERR)
  663. return CTF_ERR; /* errno is set for us. */
  664. /* Forwards won't have any vlen yet. */
  665. if (dtd->dtd_vlen_alloc == 0)
  666. {
  667. if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
  668. return (ctf_set_errno (fp, ENOMEM));
  669. dtd->dtd_vlen_alloc = initial_vlen;
  670. }
  671. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
  672. dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
  673. dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
  674. dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
  675. return type;
  676. }
  677. ctf_id_t
  678. ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
  679. {
  680. return (ctf_add_struct_sized (fp, flag, name, 0));
  681. }
  682. ctf_id_t
  683. ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
  684. size_t size)
  685. {
  686. ctf_dtdef_t *dtd;
  687. ctf_id_t type = 0;
  688. size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
  689. /* Promote root-visible forwards to unions. */
  690. if (name != NULL)
  691. type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
  692. if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
  693. dtd = ctf_dtd_lookup (fp, type);
  694. else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
  695. initial_vlen, &dtd)) == CTF_ERR)
  696. return CTF_ERR; /* errno is set for us */
  697. /* Forwards won't have any vlen yet. */
  698. if (dtd->dtd_vlen_alloc == 0)
  699. {
  700. if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
  701. return (ctf_set_errno (fp, ENOMEM));
  702. dtd->dtd_vlen_alloc = initial_vlen;
  703. }
  704. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
  705. dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
  706. dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
  707. dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
  708. return type;
  709. }
  710. ctf_id_t
  711. ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
  712. {
  713. return (ctf_add_union_sized (fp, flag, name, 0));
  714. }
  715. ctf_id_t
  716. ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
  717. {
  718. ctf_dtdef_t *dtd;
  719. ctf_id_t type = 0;
  720. size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN;
  721. /* Promote root-visible forwards to enums. */
  722. if (name != NULL)
  723. type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
  724. if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
  725. dtd = ctf_dtd_lookup (fp, type);
  726. else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
  727. initial_vlen, &dtd)) == CTF_ERR)
  728. return CTF_ERR; /* errno is set for us. */
  729. /* Forwards won't have any vlen yet. */
  730. if (dtd->dtd_vlen_alloc == 0)
  731. {
  732. if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
  733. return (ctf_set_errno (fp, ENOMEM));
  734. dtd->dtd_vlen_alloc = initial_vlen;
  735. }
  736. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
  737. dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
  738. return type;
  739. }
  740. ctf_id_t
  741. ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
  742. const ctf_encoding_t *ep)
  743. {
  744. ctf_id_t type = 0;
  745. /* First, create the enum if need be, using most of the same machinery as
  746. ctf_add_enum(), to ensure that we do not allow things past that are not
  747. enums or forwards to them. (This includes other slices: you cannot slice a
  748. slice, which would be a useless thing to do anyway.) */
  749. if (name != NULL)
  750. type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
  751. if (type != 0)
  752. {
  753. if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
  754. (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
  755. return (ctf_set_errno (fp, ECTF_NOTINTFP));
  756. }
  757. else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
  758. return CTF_ERR; /* errno is set for us. */
  759. /* Now attach a suitable slice to it. */
  760. return ctf_add_slice (fp, flag, type, ep);
  761. }
  762. ctf_id_t
  763. ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
  764. uint32_t kind)
  765. {
  766. ctf_dtdef_t *dtd;
  767. ctf_id_t type = 0;
  768. if (!ctf_forwardable_kind (kind))
  769. return (ctf_set_errno (fp, ECTF_NOTSUE));
  770. if (name == NULL || name[0] == '\0')
  771. return (ctf_set_errno (fp, ECTF_NONAME));
  772. /* If the type is already defined or exists as a forward tag, just
  773. return the ctf_id_t of the existing definition. */
  774. type = ctf_lookup_by_rawname (fp, kind, name);
  775. if (type)
  776. return type;
  777. if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
  778. return CTF_ERR; /* errno is set for us. */
  779. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
  780. dtd->dtd_data.ctt_type = kind;
  781. return type;
  782. }
  783. ctf_id_t
  784. ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name)
  785. {
  786. ctf_dtdef_t *dtd;
  787. ctf_id_t type = 0;
  788. /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN)
  789. or just return it. */
  790. if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT
  791. && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name)))
  792. {
  793. if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN)
  794. return type;
  795. else
  796. {
  797. ctf_err_warn (fp, 1, ECTF_CONFLICT,
  798. _("ctf_add_unknown: cannot add unknown type "
  799. "named %s: type of this name already defined"),
  800. name ? name : _("(unnamed type)"));
  801. return (ctf_set_errno (fp, ECTF_CONFLICT));
  802. }
  803. }
  804. if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR)
  805. return CTF_ERR; /* errno is set for us. */
  806. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0);
  807. dtd->dtd_data.ctt_type = 0;
  808. return type;
  809. }
  810. ctf_id_t
  811. ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
  812. ctf_id_t ref)
  813. {
  814. ctf_dtdef_t *dtd;
  815. ctf_id_t type;
  816. ctf_dict_t *tmp = fp;
  817. if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
  818. return (ctf_set_errno (fp, EINVAL));
  819. if (name == NULL || name[0] == '\0')
  820. return (ctf_set_errno (fp, ECTF_NONAME));
  821. if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
  822. return CTF_ERR; /* errno is set for us. */
  823. if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
  824. &dtd)) == CTF_ERR)
  825. return CTF_ERR; /* errno is set for us. */
  826. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
  827. dtd->dtd_data.ctt_type = (uint32_t) ref;
  828. return type;
  829. }
  830. ctf_id_t
  831. ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
  832. {
  833. return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
  834. }
  835. ctf_id_t
  836. ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
  837. {
  838. return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
  839. }
  840. ctf_id_t
  841. ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
  842. {
  843. return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
  844. }
  845. int
  846. ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
  847. int value)
  848. {
  849. ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
  850. unsigned char *old_vlen;
  851. ctf_enum_t *en;
  852. size_t i;
  853. uint32_t kind, vlen, root;
  854. if (name == NULL)
  855. return (ctf_set_errno (fp, EINVAL));
  856. if (!(fp->ctf_flags & LCTF_RDWR))
  857. return (ctf_set_errno (fp, ECTF_RDONLY));
  858. if (dtd == NULL)
  859. return (ctf_set_errno (fp, ECTF_BADID));
  860. kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
  861. root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
  862. vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
  863. if (kind != CTF_K_ENUM)
  864. return (ctf_set_errno (fp, ECTF_NOTENUM));
  865. if (vlen == CTF_MAX_VLEN)
  866. return (ctf_set_errno (fp, ECTF_DTFULL));
  867. old_vlen = dtd->dtd_vlen;
  868. if (ctf_grow_vlen (fp, dtd, sizeof (ctf_enum_t) * (vlen + 1)) < 0)
  869. return -1; /* errno is set for us. */
  870. en = (ctf_enum_t *) dtd->dtd_vlen;
  871. if (dtd->dtd_vlen != old_vlen)
  872. {
  873. ptrdiff_t move = (signed char *) dtd->dtd_vlen - (signed char *) old_vlen;
  874. /* Remove pending refs in the old vlen region and reapply them. */
  875. for (i = 0; i < vlen; i++)
  876. ctf_str_move_pending (fp, &en[i].cte_name, move);
  877. }
  878. for (i = 0; i < vlen; i++)
  879. if (strcmp (ctf_strptr (fp, en[i].cte_name), name) == 0)
  880. return (ctf_set_errno (fp, ECTF_DUPLICATE));
  881. en[i].cte_name = ctf_str_add_pending (fp, name, &en[i].cte_name);
  882. en[i].cte_value = value;
  883. if (en[i].cte_name == 0 && name != NULL && name[0] != '\0')
  884. return -1; /* errno is set for us. */
  885. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  886. fp->ctf_flags |= LCTF_DIRTY;
  887. return 0;
  888. }
  889. int
  890. ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
  891. ctf_id_t type, unsigned long bit_offset)
  892. {
  893. ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
  894. ssize_t msize, malign, ssize;
  895. uint32_t kind, vlen, root;
  896. size_t i;
  897. int is_incomplete = 0;
  898. unsigned char *old_vlen;
  899. ctf_lmember_t *memb;
  900. if (!(fp->ctf_flags & LCTF_RDWR))
  901. return (ctf_set_errno (fp, ECTF_RDONLY));
  902. if (dtd == NULL)
  903. return (ctf_set_errno (fp, ECTF_BADID));
  904. if (name != NULL && name[0] == '\0')
  905. name = NULL;
  906. kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
  907. root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
  908. vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
  909. if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
  910. return (ctf_set_errno (fp, ECTF_NOTSOU));
  911. if (vlen == CTF_MAX_VLEN)
  912. return (ctf_set_errno (fp, ECTF_DTFULL));
  913. old_vlen = dtd->dtd_vlen;
  914. if (ctf_grow_vlen (fp, dtd, sizeof (ctf_lmember_t) * (vlen + 1)) < 0)
  915. return -1; /* errno is set for us. */
  916. memb = (ctf_lmember_t *) dtd->dtd_vlen;
  917. if (dtd->dtd_vlen != old_vlen)
  918. {
  919. ptrdiff_t move = (signed char *) dtd->dtd_vlen - (signed char *) old_vlen;
  920. /* Remove pending refs in the old vlen region and reapply them. */
  921. for (i = 0; i < vlen; i++)
  922. ctf_str_move_pending (fp, &memb[i].ctlm_name, move);
  923. }
  924. if (name != NULL)
  925. {
  926. for (i = 0; i < vlen; i++)
  927. if (strcmp (ctf_strptr (fp, memb[i].ctlm_name), name) == 0)
  928. return (ctf_set_errno (fp, ECTF_DUPLICATE));
  929. }
  930. if ((msize = ctf_type_size (fp, type)) < 0 ||
  931. (malign = ctf_type_align (fp, type)) < 0)
  932. {
  933. /* The unimplemented type, and any type that resolves to it, has no size
  934. and no alignment: it can correspond to any number of compiler-inserted
  935. types. We allow incomplete types through since they are routinely
  936. added to the ends of structures, and can even be added elsewhere in
  937. structures by the deduplicator. They are assumed to be zero-size with
  938. no alignment: this is often wrong, but problems can be avoided in this
  939. case by explicitly specifying the size of the structure via the _sized
  940. functions. The deduplicator always does this. */
  941. msize = 0;
  942. malign = 0;
  943. if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
  944. ctf_set_errno (fp, 0);
  945. else if (ctf_errno (fp) == ECTF_INCOMPLETE)
  946. is_incomplete = 1;
  947. else
  948. return -1; /* errno is set for us. */
  949. }
  950. memb[vlen].ctlm_name = ctf_str_add_pending (fp, name, &memb[vlen].ctlm_name);
  951. memb[vlen].ctlm_type = type;
  952. if (memb[vlen].ctlm_name == 0 && name != NULL && name[0] != '\0')
  953. return -1; /* errno is set for us. */
  954. if (kind == CTF_K_STRUCT && vlen != 0)
  955. {
  956. if (bit_offset == (unsigned long) - 1)
  957. {
  958. /* Natural alignment. */
  959. ctf_id_t ltype = ctf_type_resolve (fp, memb[vlen - 1].ctlm_type);
  960. size_t off = CTF_LMEM_OFFSET(&memb[vlen - 1]);
  961. ctf_encoding_t linfo;
  962. ssize_t lsize;
  963. /* Propagate any error from ctf_type_resolve. If the last member was
  964. of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
  965. cannot insert right after such a member without explicit offset
  966. specification, because its alignment and size is not known. */
  967. if (ltype == CTF_ERR)
  968. return -1; /* errno is set for us. */
  969. if (is_incomplete)
  970. {
  971. ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
  972. _("ctf_add_member_offset: cannot add member %s of "
  973. "incomplete type %lx to struct %lx without "
  974. "specifying explicit offset\n"),
  975. name ? name : _("(unnamed member)"), type, souid);
  976. return (ctf_set_errno (fp, ECTF_INCOMPLETE));
  977. }
  978. if (ctf_type_encoding (fp, ltype, &linfo) == 0)
  979. off += linfo.cte_bits;
  980. else if ((lsize = ctf_type_size (fp, ltype)) > 0)
  981. off += lsize * CHAR_BIT;
  982. else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
  983. {
  984. const char *lname = ctf_strraw (fp, memb[vlen - 1].ctlm_name);
  985. ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
  986. _("ctf_add_member_offset: cannot add member %s of "
  987. "type %lx to struct %lx without specifying "
  988. "explicit offset after member %s of type %lx, "
  989. "which is an incomplete type\n"),
  990. name ? name : _("(unnamed member)"), type, souid,
  991. lname ? lname : _("(unnamed member)"), ltype);
  992. return -1; /* errno is set for us. */
  993. }
  994. /* Round up the offset of the end of the last member to
  995. the next byte boundary, convert 'off' to bytes, and
  996. then round it up again to the next multiple of the
  997. alignment required by the new member. Finally,
  998. convert back to bits and store the result in
  999. dmd_offset. Technically we could do more efficient
  1000. packing if the new member is a bit-field, but we're
  1001. the "compiler" and ANSI says we can do as we choose. */
  1002. off = roundup (off, CHAR_BIT) / CHAR_BIT;
  1003. off = roundup (off, MAX (malign, 1));
  1004. memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (off * CHAR_BIT);
  1005. memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (off * CHAR_BIT);
  1006. ssize = off + msize;
  1007. }
  1008. else
  1009. {
  1010. /* Specified offset in bits. */
  1011. memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (bit_offset);
  1012. memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (bit_offset);
  1013. ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
  1014. ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. memb[vlen].ctlm_offsethi = 0;
  1020. memb[vlen].ctlm_offsetlo = 0;
  1021. ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
  1022. ssize = MAX (ssize, msize);
  1023. }
  1024. dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
  1025. dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
  1026. dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
  1027. dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  1028. fp->ctf_flags |= LCTF_DIRTY;
  1029. return 0;
  1030. }
  1031. int
  1032. ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
  1033. ctf_id_t type, unsigned long bit_offset,
  1034. const ctf_encoding_t encoding)
  1035. {
  1036. ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
  1037. int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
  1038. int otype = type;
  1039. if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
  1040. return (ctf_set_errno (fp, ECTF_NOTINTFP));
  1041. if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
  1042. return -1; /* errno is set for us. */
  1043. return ctf_add_member_offset (fp, souid, name, type, bit_offset);
  1044. }
  1045. int
  1046. ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
  1047. ctf_id_t type)
  1048. {
  1049. return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
  1050. }
  1051. int
  1052. ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
  1053. {
  1054. ctf_dvdef_t *dvd;
  1055. ctf_dict_t *tmp = fp;
  1056. if (!(fp->ctf_flags & LCTF_RDWR))
  1057. return (ctf_set_errno (fp, ECTF_RDONLY));
  1058. if (ctf_dvd_lookup (fp, name) != NULL)
  1059. return (ctf_set_errno (fp, ECTF_DUPLICATE));
  1060. if (ctf_lookup_by_id (&tmp, ref) == NULL)
  1061. return -1; /* errno is set for us. */
  1062. /* Make sure this type is representable. */
  1063. if ((ctf_type_resolve (fp, ref) == CTF_ERR)
  1064. && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
  1065. return -1;
  1066. if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
  1067. return (ctf_set_errno (fp, EAGAIN));
  1068. if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
  1069. {
  1070. free (dvd);
  1071. return (ctf_set_errno (fp, EAGAIN));
  1072. }
  1073. dvd->dvd_type = ref;
  1074. dvd->dvd_snapshots = fp->ctf_snapshots;
  1075. if (ctf_dvd_insert (fp, dvd) < 0)
  1076. {
  1077. free (dvd->dvd_name);
  1078. free (dvd);
  1079. return -1; /* errno is set for us. */
  1080. }
  1081. fp->ctf_flags |= LCTF_DIRTY;
  1082. return 0;
  1083. }
  1084. int
  1085. ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
  1086. {
  1087. ctf_dict_t *tmp = fp;
  1088. char *dupname;
  1089. ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
  1090. if (!(fp->ctf_flags & LCTF_RDWR))
  1091. return (ctf_set_errno (fp, ECTF_RDONLY));
  1092. if (ctf_dynhash_lookup (fp->ctf_objthash, name) != NULL ||
  1093. ctf_dynhash_lookup (fp->ctf_funchash, name) != NULL)
  1094. return (ctf_set_errno (fp, ECTF_DUPLICATE));
  1095. if (ctf_lookup_by_id (&tmp, id) == NULL)
  1096. return -1; /* errno is set for us. */
  1097. if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
  1098. return (ctf_set_errno (fp, ECTF_NOTFUNC));
  1099. if ((dupname = strdup (name)) == NULL)
  1100. return (ctf_set_errno (fp, ENOMEM));
  1101. if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
  1102. {
  1103. free (dupname);
  1104. return (ctf_set_errno (fp, ENOMEM));
  1105. }
  1106. return 0;
  1107. }
  1108. int
  1109. ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
  1110. {
  1111. return (ctf_add_funcobjt_sym (fp, 0, name, id));
  1112. }
  1113. int
  1114. ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
  1115. {
  1116. return (ctf_add_funcobjt_sym (fp, 1, name, id));
  1117. }
  1118. typedef struct ctf_bundle
  1119. {
  1120. ctf_dict_t *ctb_dict; /* CTF dict handle. */
  1121. ctf_id_t ctb_type; /* CTF type identifier. */
  1122. ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
  1123. } ctf_bundle_t;
  1124. static int
  1125. enumcmp (const char *name, int value, void *arg)
  1126. {
  1127. ctf_bundle_t *ctb = arg;
  1128. int bvalue;
  1129. if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
  1130. {
  1131. ctf_err_warn (ctb->ctb_dict, 0, 0,
  1132. _("conflict due to enum %s iteration error"), name);
  1133. return 1;
  1134. }
  1135. if (value != bvalue)
  1136. {
  1137. ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
  1138. _("conflict due to enum value change: %i versus %i"),
  1139. value, bvalue);
  1140. return 1;
  1141. }
  1142. return 0;
  1143. }
  1144. static int
  1145. enumadd (const char *name, int value, void *arg)
  1146. {
  1147. ctf_bundle_t *ctb = arg;
  1148. return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
  1149. name, value) < 0);
  1150. }
  1151. static int
  1152. membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
  1153. void *arg)
  1154. {
  1155. ctf_bundle_t *ctb = arg;
  1156. ctf_membinfo_t ctm;
  1157. /* Don't check nameless members (e.g. anonymous structs/unions) against each
  1158. other. */
  1159. if (name[0] == 0)
  1160. return 0;
  1161. if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
  1162. {
  1163. ctf_err_warn (ctb->ctb_dict, 0, 0,
  1164. _("conflict due to struct member %s iteration error"),
  1165. name);
  1166. return 1;
  1167. }
  1168. if (ctm.ctm_offset != offset)
  1169. {
  1170. ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
  1171. _("conflict due to struct member %s offset change: "
  1172. "%lx versus %lx"),
  1173. name, ctm.ctm_offset, offset);
  1174. return 1;
  1175. }
  1176. return 0;
  1177. }
  1178. /* Record the correspondence between a source and ctf_add_type()-added
  1179. destination type: both types are translated into parent type IDs if need be,
  1180. so they relate to the actual dictionary they are in. Outside controlled
  1181. circumstances (like linking) it is probably not useful to do more than
  1182. compare these pointers, since there is nothing stopping the user closing the
  1183. source dict whenever they want to.
  1184. Our OOM handling here is just to not do anything, because this is called deep
  1185. enough in the call stack that doing anything useful is painfully difficult:
  1186. the worst consequence if we do OOM is a bit of type duplication anyway. */
  1187. static void
  1188. ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
  1189. ctf_dict_t *dst_fp, ctf_id_t dst_type)
  1190. {
  1191. if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
  1192. src_fp = src_fp->ctf_parent;
  1193. src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
  1194. if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
  1195. dst_fp = dst_fp->ctf_parent;
  1196. dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
  1197. if (dst_fp->ctf_link_type_mapping == NULL)
  1198. {
  1199. ctf_hash_fun f = ctf_hash_type_key;
  1200. ctf_hash_eq_fun e = ctf_hash_eq_type_key;
  1201. if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
  1202. NULL)) == NULL)
  1203. return;
  1204. }
  1205. ctf_link_type_key_t *key;
  1206. key = calloc (1, sizeof (struct ctf_link_type_key));
  1207. if (!key)
  1208. return;
  1209. key->cltk_fp = src_fp;
  1210. key->cltk_idx = src_type;
  1211. /* No OOM checking needed, because if this doesn't work the worst we'll do is
  1212. add a few more duplicate types (which will probably run out of memory
  1213. anyway). */
  1214. ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
  1215. (void *) (uintptr_t) dst_type);
  1216. }
  1217. /* Look up a type mapping: return 0 if none. The DST_FP is modified to point to
  1218. the parent if need be. The ID returned is from the dst_fp's perspective. */
  1219. static ctf_id_t
  1220. ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
  1221. {
  1222. ctf_link_type_key_t key;
  1223. ctf_dict_t *target_fp = *dst_fp;
  1224. ctf_id_t dst_type = 0;
  1225. if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
  1226. src_fp = src_fp->ctf_parent;
  1227. src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
  1228. key.cltk_fp = src_fp;
  1229. key.cltk_idx = src_type;
  1230. if (target_fp->ctf_link_type_mapping)
  1231. dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
  1232. &key);
  1233. if (dst_type != 0)
  1234. {
  1235. dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
  1236. target_fp->ctf_parent != NULL);
  1237. *dst_fp = target_fp;
  1238. return dst_type;
  1239. }
  1240. if (target_fp->ctf_parent)
  1241. target_fp = target_fp->ctf_parent;
  1242. else
  1243. return 0;
  1244. if (target_fp->ctf_link_type_mapping)
  1245. dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
  1246. &key);
  1247. if (dst_type)
  1248. dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
  1249. target_fp->ctf_parent != NULL);
  1250. *dst_fp = target_fp;
  1251. return dst_type;
  1252. }
  1253. /* The ctf_add_type routine is used to copy a type from a source CTF dictionary
  1254. to a dynamic destination dictionary. This routine operates recursively by
  1255. following the source type's links and embedded member types. If the
  1256. destination dict already contains a named type which has the same attributes,
  1257. then we succeed and return this type but no changes occur. */
  1258. static ctf_id_t
  1259. ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
  1260. ctf_dict_t *proc_tracking_fp)
  1261. {
  1262. ctf_id_t dst_type = CTF_ERR;
  1263. uint32_t dst_kind = CTF_K_UNKNOWN;
  1264. ctf_dict_t *tmp_fp = dst_fp;
  1265. ctf_id_t tmp;
  1266. const char *name;
  1267. uint32_t kind, forward_kind, flag, vlen;
  1268. const ctf_type_t *src_tp, *dst_tp;
  1269. ctf_bundle_t src, dst;
  1270. ctf_encoding_t src_en, dst_en;
  1271. ctf_arinfo_t src_ar, dst_ar;
  1272. ctf_funcinfo_t ctc;
  1273. ctf_id_t orig_src_type = src_type;
  1274. if (!(dst_fp->ctf_flags & LCTF_RDWR))
  1275. return (ctf_set_errno (dst_fp, ECTF_RDONLY));
  1276. if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
  1277. return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
  1278. if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
  1279. && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
  1280. return (ctf_set_errno (dst_fp, ECTF_NONREPRESENTABLE));
  1281. name = ctf_strptr (src_fp, src_tp->ctt_name);
  1282. kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
  1283. flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
  1284. vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
  1285. /* If this is a type we are currently in the middle of adding, hand it
  1286. straight back. (This lets us handle self-referential structures without
  1287. considering forwards and empty structures the same as their completed
  1288. forms.) */
  1289. tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
  1290. if (tmp != 0)
  1291. {
  1292. if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
  1293. (void *) (uintptr_t) src_type))
  1294. return tmp;
  1295. /* If this type has already been added from this dictionary, and is the
  1296. same kind and (if a struct or union) has the same number of members,
  1297. hand it straight back. */
  1298. if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
  1299. {
  1300. if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
  1301. || kind == CTF_K_ENUM)
  1302. {
  1303. if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
  1304. if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
  1305. return tmp;
  1306. }
  1307. else
  1308. return tmp;
  1309. }
  1310. }
  1311. forward_kind = kind;
  1312. if (kind == CTF_K_FORWARD)
  1313. forward_kind = src_tp->ctt_type;
  1314. /* If the source type has a name and is a root type (visible at the top-level
  1315. scope), lookup the name in the destination dictionary and verify that it is
  1316. of the same kind before we do anything else. */
  1317. if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
  1318. && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
  1319. {
  1320. dst_type = tmp;
  1321. dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
  1322. }
  1323. /* If an identically named dst_type exists, fail with ECTF_CONFLICT
  1324. unless dst_type is a forward declaration and src_type is a struct,
  1325. union, or enum (i.e. the definition of the previous forward decl).
  1326. We also allow addition in the opposite order (addition of a forward when a
  1327. struct, union, or enum already exists), which is a NOP and returns the
  1328. already-present struct, union, or enum. */
  1329. if (dst_type != CTF_ERR && dst_kind != kind)
  1330. {
  1331. if (kind == CTF_K_FORWARD
  1332. && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
  1333. || dst_kind == CTF_K_UNION))
  1334. {
  1335. ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
  1336. return dst_type;
  1337. }
  1338. if (dst_kind != CTF_K_FORWARD
  1339. || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
  1340. && kind != CTF_K_UNION))
  1341. {
  1342. ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
  1343. _("ctf_add_type: conflict for type %s: "
  1344. "kinds differ, new: %i; old (ID %lx): %i"),
  1345. name, kind, dst_type, dst_kind);
  1346. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1347. }
  1348. }
  1349. /* We take special action for an integer, float, or slice since it is
  1350. described not only by its name but also its encoding. For integers,
  1351. bit-fields exploit this degeneracy. */
  1352. if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
  1353. {
  1354. if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
  1355. return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
  1356. if (dst_type != CTF_ERR)
  1357. {
  1358. ctf_dict_t *fp = dst_fp;
  1359. if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
  1360. return CTF_ERR;
  1361. if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
  1362. return CTF_ERR; /* errno set for us. */
  1363. if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
  1364. {
  1365. /* The type that we found in the hash is also root-visible. If
  1366. the two types match then use the existing one; otherwise,
  1367. declare a conflict. Note: slices are not certain to match
  1368. even if there is no conflict: we must check the contained type
  1369. too. */
  1370. if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
  1371. {
  1372. if (kind != CTF_K_SLICE)
  1373. {
  1374. ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
  1375. return dst_type;
  1376. }
  1377. }
  1378. else
  1379. {
  1380. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1381. }
  1382. }
  1383. else
  1384. {
  1385. /* We found a non-root-visible type in the hash. If its encoding
  1386. is the same, we can reuse it, unless it is a slice. */
  1387. if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
  1388. {
  1389. if (kind != CTF_K_SLICE)
  1390. {
  1391. ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
  1392. return dst_type;
  1393. }
  1394. }
  1395. }
  1396. }
  1397. }
  1398. src.ctb_dict = src_fp;
  1399. src.ctb_type = src_type;
  1400. src.ctb_dtd = NULL;
  1401. dst.ctb_dict = dst_fp;
  1402. dst.ctb_type = dst_type;
  1403. dst.ctb_dtd = NULL;
  1404. /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
  1405. a new type with the same properties as src_type to dst_fp. If dst_type is
  1406. not CTF_ERR, then we verify that dst_type has the same attributes as
  1407. src_type. We recurse for embedded references. Before we start, we note
  1408. that we are processing this type, to prevent infinite recursion: we do not
  1409. re-process any type that appears in this list. The list is emptied
  1410. wholesale at the end of processing everything in this recursive stack. */
  1411. if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
  1412. (void *) (uintptr_t) src_type, (void *) 1) < 0)
  1413. return ctf_set_errno (dst_fp, ENOMEM);
  1414. switch (kind)
  1415. {
  1416. case CTF_K_INTEGER:
  1417. /* If we found a match we will have either returned it or declared a
  1418. conflict. */
  1419. dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
  1420. break;
  1421. case CTF_K_FLOAT:
  1422. /* If we found a match we will have either returned it or declared a
  1423. conflict. */
  1424. dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
  1425. break;
  1426. case CTF_K_SLICE:
  1427. /* We have checked for conflicting encodings: now try to add the
  1428. contained type. */
  1429. src_type = ctf_type_reference (src_fp, src_type);
  1430. src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
  1431. proc_tracking_fp);
  1432. if (src_type == CTF_ERR)
  1433. return CTF_ERR; /* errno is set for us. */
  1434. dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
  1435. break;
  1436. case CTF_K_POINTER:
  1437. case CTF_K_VOLATILE:
  1438. case CTF_K_CONST:
  1439. case CTF_K_RESTRICT:
  1440. src_type = ctf_type_reference (src_fp, src_type);
  1441. src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
  1442. proc_tracking_fp);
  1443. if (src_type == CTF_ERR)
  1444. return CTF_ERR; /* errno is set for us. */
  1445. dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
  1446. break;
  1447. case CTF_K_ARRAY:
  1448. if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
  1449. return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
  1450. src_ar.ctr_contents =
  1451. ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
  1452. proc_tracking_fp);
  1453. src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
  1454. src_ar.ctr_index,
  1455. proc_tracking_fp);
  1456. src_ar.ctr_nelems = src_ar.ctr_nelems;
  1457. if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
  1458. return CTF_ERR; /* errno is set for us. */
  1459. if (dst_type != CTF_ERR)
  1460. {
  1461. if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
  1462. return CTF_ERR; /* errno is set for us. */
  1463. if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
  1464. {
  1465. ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
  1466. _("conflict for type %s against ID %lx: array info "
  1467. "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
  1468. name, dst_type, src_ar.ctr_contents,
  1469. src_ar.ctr_index, src_ar.ctr_nelems,
  1470. dst_ar.ctr_contents, dst_ar.ctr_index,
  1471. dst_ar.ctr_nelems);
  1472. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1473. }
  1474. }
  1475. else
  1476. dst_type = ctf_add_array (dst_fp, flag, &src_ar);
  1477. break;
  1478. case CTF_K_FUNCTION:
  1479. ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
  1480. src_tp->ctt_type,
  1481. proc_tracking_fp);
  1482. ctc.ctc_argc = 0;
  1483. ctc.ctc_flags = 0;
  1484. if (ctc.ctc_return == CTF_ERR)
  1485. return CTF_ERR; /* errno is set for us. */
  1486. dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
  1487. break;
  1488. case CTF_K_STRUCT:
  1489. case CTF_K_UNION:
  1490. {
  1491. ctf_next_t *i = NULL;
  1492. ssize_t offset;
  1493. const char *membname;
  1494. ctf_id_t src_membtype;
  1495. /* Technically to match a struct or union we need to check both
  1496. ways (src members vs. dst, dst members vs. src) but we make
  1497. this more optimal by only checking src vs. dst and comparing
  1498. the total size of the structure (which we must do anyway)
  1499. which covers the possibility of dst members not in src.
  1500. This optimization can be defeated for unions, but is so
  1501. pathological as to render it irrelevant for our purposes. */
  1502. if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
  1503. && dst_kind != CTF_K_FORWARD)
  1504. {
  1505. if (ctf_type_size (src_fp, src_type) !=
  1506. ctf_type_size (dst_fp, dst_type))
  1507. {
  1508. ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
  1509. _("conflict for type %s against ID %lx: union "
  1510. "size differs, old %li, new %li"), name,
  1511. dst_type, (long) ctf_type_size (src_fp, src_type),
  1512. (long) ctf_type_size (dst_fp, dst_type));
  1513. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1514. }
  1515. if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
  1516. {
  1517. ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
  1518. _("conflict for type %s against ID %lx: members "
  1519. "differ, see above"), name, dst_type);
  1520. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1521. }
  1522. break;
  1523. }
  1524. dst_type = ctf_add_struct_sized (dst_fp, flag, name,
  1525. ctf_type_size (src_fp, src_type));
  1526. if (dst_type == CTF_ERR)
  1527. return CTF_ERR; /* errno is set for us. */
  1528. /* Pre-emptively add this struct to the type mapping so that
  1529. structures that refer to themselves work. */
  1530. ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
  1531. while ((offset = ctf_member_next (src_fp, src_type, &i, &membname,
  1532. &src_membtype, 0)) >= 0)
  1533. {
  1534. ctf_dict_t *dst = dst_fp;
  1535. ctf_id_t dst_membtype = ctf_type_mapping (src_fp, src_membtype, &dst);
  1536. if (dst_membtype == 0)
  1537. {
  1538. dst_membtype = ctf_add_type_internal (dst_fp, src_fp,
  1539. src_membtype,
  1540. proc_tracking_fp);
  1541. if (dst_membtype == CTF_ERR)
  1542. {
  1543. if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
  1544. {
  1545. ctf_next_destroy (i);
  1546. break;
  1547. }
  1548. }
  1549. }
  1550. if (ctf_add_member_offset (dst_fp, dst_type, membname,
  1551. dst_membtype, offset) < 0)
  1552. {
  1553. ctf_next_destroy (i);
  1554. break;
  1555. }
  1556. }
  1557. if (ctf_errno (src_fp) != ECTF_NEXT_END)
  1558. return CTF_ERR; /* errno is set for us. */
  1559. break;
  1560. }
  1561. case CTF_K_ENUM:
  1562. if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
  1563. && dst_kind != CTF_K_FORWARD)
  1564. {
  1565. if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
  1566. || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
  1567. {
  1568. ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
  1569. _("conflict for enum %s against ID %lx: members "
  1570. "differ, see above"), name, dst_type);
  1571. return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
  1572. }
  1573. }
  1574. else
  1575. {
  1576. dst_type = ctf_add_enum (dst_fp, flag, name);
  1577. if ((dst.ctb_type = dst_type) == CTF_ERR
  1578. || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
  1579. return CTF_ERR; /* errno is set for us */
  1580. }
  1581. break;
  1582. case CTF_K_FORWARD:
  1583. if (dst_type == CTF_ERR)
  1584. dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
  1585. break;
  1586. case CTF_K_TYPEDEF:
  1587. src_type = ctf_type_reference (src_fp, src_type);
  1588. src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
  1589. proc_tracking_fp);
  1590. if (src_type == CTF_ERR)
  1591. return CTF_ERR; /* errno is set for us. */
  1592. /* If dst_type is not CTF_ERR at this point, we should check if
  1593. ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
  1594. ECTF_CONFLICT. However, this causes problems with bitness typedefs
  1595. that vary based on things like if 32-bit then pid_t is int otherwise
  1596. long. We therefore omit this check and assume that if the identically
  1597. named typedef already exists in dst_fp, it is correct or
  1598. equivalent. */
  1599. if (dst_type == CTF_ERR)
  1600. dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
  1601. break;
  1602. default:
  1603. return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
  1604. }
  1605. if (dst_type != CTF_ERR)
  1606. ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
  1607. return dst_type;
  1608. }
  1609. ctf_id_t
  1610. ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
  1611. {
  1612. ctf_id_t id;
  1613. if (!src_fp->ctf_add_processing)
  1614. src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
  1615. ctf_hash_eq_integer,
  1616. NULL, NULL);
  1617. /* We store the hash on the source, because it contains only source type IDs:
  1618. but callers will invariably expect errors to appear on the dest. */
  1619. if (!src_fp->ctf_add_processing)
  1620. return (ctf_set_errno (dst_fp, ENOMEM));
  1621. id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
  1622. ctf_dynhash_empty (src_fp->ctf_add_processing);
  1623. return id;
  1624. }