ltdl.c 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513
  1. /* ltdl.c -- system independent dlopen wrapper
  2. Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc.
  3. Originally by Thomas Tanner <tanner@ffii.org>
  4. This file is part of GNU Libtool.
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. As a special exception to the GNU Lesser General Public License,
  10. if you distribute this file as part of a program or library that
  11. is built using GNU libtool, you may include it under the same
  12. distribution terms that you use for the rest of that program.
  13. This library is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. Lesser General Public License for more details.
  17. You should have received a copy of the GNU Lesser General Public
  18. License along with this library; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. 02110-1301 USA
  21. */
  22. #if HAVE_CONFIG_H
  23. # include <config.h>
  24. #endif
  25. #if HAVE_BOEHM_GC
  26. # include <gc.h>
  27. #endif
  28. #if HAVE_UNISTD_H
  29. # include <unistd.h>
  30. #endif
  31. #if HAVE_STDIO_H
  32. # include <stdio.h>
  33. #endif
  34. /* Include the header defining malloc. On K&R C compilers,
  35. that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
  36. #if HAVE_STDLIB_H
  37. # include <stdlib.h>
  38. #else
  39. # if HAVE_MALLOC_H
  40. # include <malloc.h>
  41. # endif
  42. #endif
  43. #if HAVE_STRING_H
  44. # include <string.h>
  45. #else
  46. # if HAVE_STRINGS_H
  47. # include <strings.h>
  48. # endif
  49. #endif
  50. #if HAVE_CTYPE_H
  51. # include <ctype.h>
  52. #endif
  53. #if HAVE_MEMORY_H
  54. # include <memory.h>
  55. #endif
  56. #if HAVE_ERRNO_H
  57. # include <errno.h>
  58. #endif
  59. #ifndef __WINDOWS__
  60. # ifdef __WIN32__
  61. # define __WINDOWS__
  62. # endif
  63. #endif
  64. #undef LT_USE_POSIX_DIRENT
  65. #ifdef HAVE_CLOSEDIR
  66. # ifdef HAVE_OPENDIR
  67. # ifdef HAVE_READDIR
  68. # ifdef HAVE_DIRENT_H
  69. # define LT_USE_POSIX_DIRENT
  70. # endif /* HAVE_DIRENT_H */
  71. # endif /* HAVE_READDIR */
  72. # endif /* HAVE_OPENDIR */
  73. #endif /* HAVE_CLOSEDIR */
  74. #undef LT_USE_WINDOWS_DIRENT_EMULATION
  75. #ifndef LT_USE_POSIX_DIRENT
  76. # ifdef __WINDOWS__
  77. # define LT_USE_WINDOWS_DIRENT_EMULATION
  78. # endif /* __WINDOWS__ */
  79. #endif /* LT_USE_POSIX_DIRENT */
  80. #ifdef LT_USE_POSIX_DIRENT
  81. # include <dirent.h>
  82. # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
  83. #else
  84. # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
  85. # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
  86. # else
  87. # define dirent direct
  88. # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
  89. # if HAVE_SYS_NDIR_H
  90. # include <sys/ndir.h>
  91. # endif
  92. # if HAVE_SYS_DIR_H
  93. # include <sys/dir.h>
  94. # endif
  95. # if HAVE_NDIR_H
  96. # include <ndir.h>
  97. # endif
  98. # endif
  99. #endif
  100. #if HAVE_ARGZ_H
  101. # include <argz.h>
  102. #endif
  103. #if HAVE_ASSERT_H
  104. # include <assert.h>
  105. #else
  106. # define assert(arg) ((void) 0)
  107. #endif
  108. #include "ltdl.h"
  109. #if WITH_DMALLOC
  110. # include <dmalloc.h>
  111. #endif
  112. /* --- WINDOWS SUPPORT --- */
  113. #ifdef DLL_EXPORT
  114. # define LT_GLOBAL_DATA __declspec(dllexport)
  115. #else
  116. # define LT_GLOBAL_DATA
  117. #endif
  118. /* fopen() mode flags for reading a text file */
  119. #undef LT_READTEXT_MODE
  120. #ifdef __WINDOWS__
  121. # define LT_READTEXT_MODE "rt"
  122. #else
  123. # define LT_READTEXT_MODE "r"
  124. #endif
  125. #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
  126. #include <windows.h>
  127. #define dirent lt_dirent
  128. #define DIR lt_DIR
  129. struct dirent
  130. {
  131. char d_name[2048];
  132. int d_namlen;
  133. };
  134. typedef struct _DIR
  135. {
  136. HANDLE hSearch;
  137. WIN32_FIND_DATA Win32FindData;
  138. BOOL firsttime;
  139. struct dirent file_info;
  140. } DIR;
  141. #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
  142. /* --- MANIFEST CONSTANTS --- */
  143. /* Standard libltdl search path environment variable name */
  144. #undef LTDL_SEARCHPATH_VAR
  145. #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
  146. /* Standard libtool archive file extension. */
  147. #undef LTDL_ARCHIVE_EXT
  148. #define LTDL_ARCHIVE_EXT ".la"
  149. /* max. filename length */
  150. #ifndef LT_FILENAME_MAX
  151. # define LT_FILENAME_MAX 1024
  152. #endif
  153. /* This is the maximum symbol size that won't require malloc/free */
  154. #undef LT_SYMBOL_LENGTH
  155. #define LT_SYMBOL_LENGTH 128
  156. /* This accounts for the _LTX_ separator */
  157. #undef LT_SYMBOL_OVERHEAD
  158. #define LT_SYMBOL_OVERHEAD 5
  159. /* --- MEMORY HANDLING --- */
  160. /* These are the functions used internally. In addition to making
  161. use of the associated function pointers above, they also perform
  162. error handling. */
  163. static char *lt_estrdup LT_PARAMS((const char *str));
  164. static lt_ptr lt_emalloc LT_PARAMS((size_t size));
  165. static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
  166. /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
  167. #define rpl_realloc realloc
  168. /* These are the pointers that can be changed by the caller: */
  169. LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
  170. = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
  171. LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
  172. = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
  173. LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
  174. = (void (*) LT_PARAMS((lt_ptr))) free;
  175. /* The following macros reduce the amount of typing needed to cast
  176. assigned memory. */
  177. #if WITH_DMALLOC
  178. #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
  179. #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
  180. #define LT_DLFREE(p) \
  181. LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
  182. #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
  183. #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
  184. #else
  185. #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
  186. #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
  187. #define LT_DLFREE(p) \
  188. LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
  189. #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
  190. #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
  191. #endif
  192. #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
  193. if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
  194. } LT_STMT_END
  195. /* --- REPLACEMENT FUNCTIONS --- */
  196. #undef strdup
  197. #define strdup rpl_strdup
  198. static char *strdup LT_PARAMS((const char *str));
  199. static char *
  200. strdup(str)
  201. const char *str;
  202. {
  203. char *tmp = 0;
  204. if (str)
  205. {
  206. tmp = LT_DLMALLOC (char, 1+ strlen (str));
  207. if (tmp)
  208. {
  209. strcpy(tmp, str);
  210. }
  211. }
  212. return tmp;
  213. }
  214. #if ! HAVE_STRCMP
  215. #undef strcmp
  216. #define strcmp rpl_strcmp
  217. static int strcmp LT_PARAMS((const char *str1, const char *str2));
  218. static int
  219. strcmp (str1, str2)
  220. const char *str1;
  221. const char *str2;
  222. {
  223. if (str1 == str2)
  224. return 0;
  225. if (str1 == 0)
  226. return -1;
  227. if (str2 == 0)
  228. return 1;
  229. for (;*str1 && *str2; ++str1, ++str2)
  230. {
  231. if (*str1 != *str2)
  232. break;
  233. }
  234. return (int)(*str1 - *str2);
  235. }
  236. #endif
  237. #if ! HAVE_STRCHR
  238. # if HAVE_INDEX
  239. # define strchr index
  240. # else
  241. # define strchr rpl_strchr
  242. static const char *strchr LT_PARAMS((const char *str, int ch));
  243. static const char*
  244. strchr(str, ch)
  245. const char *str;
  246. int ch;
  247. {
  248. const char *p;
  249. for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
  250. /*NOWORK*/;
  251. return (*p == (char)ch) ? p : 0;
  252. }
  253. # endif
  254. #endif /* !HAVE_STRCHR */
  255. #if ! HAVE_STRRCHR
  256. # if HAVE_RINDEX
  257. # define strrchr rindex
  258. # else
  259. # define strrchr rpl_strrchr
  260. static const char *strrchr LT_PARAMS((const char *str, int ch));
  261. static const char*
  262. strrchr(str, ch)
  263. const char *str;
  264. int ch;
  265. {
  266. const char *p, *q = 0;
  267. for (p = str; *p != LT_EOS_CHAR; ++p)
  268. {
  269. if (*p == (char) ch)
  270. {
  271. q = p;
  272. }
  273. }
  274. return q;
  275. }
  276. # endif
  277. #endif
  278. /* NOTE: Neither bcopy nor the memcpy implementation below can
  279. reliably handle copying in overlapping areas of memory. Use
  280. memmove (for which there is a fallback implmentation below)
  281. if you need that behaviour. */
  282. #if ! HAVE_MEMCPY
  283. # if HAVE_BCOPY
  284. # define memcpy(dest, src, size) bcopy (src, dest, size)
  285. # else
  286. # define memcpy rpl_memcpy
  287. static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
  288. static lt_ptr
  289. memcpy (dest, src, size)
  290. lt_ptr dest;
  291. const lt_ptr src;
  292. size_t size;
  293. {
  294. const char * s = src;
  295. char * d = dest;
  296. size_t i = 0;
  297. for (i = 0; i < size; ++i)
  298. {
  299. d[i] = s[i];
  300. }
  301. return dest;
  302. }
  303. # endif /* !HAVE_BCOPY */
  304. #endif /* !HAVE_MEMCPY */
  305. #if ! HAVE_MEMMOVE
  306. # define memmove rpl_memmove
  307. static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
  308. static lt_ptr
  309. memmove (dest, src, size)
  310. lt_ptr dest;
  311. const lt_ptr src;
  312. size_t size;
  313. {
  314. const char * s = src;
  315. char * d = dest;
  316. size_t i;
  317. if (d < s)
  318. for (i = 0; i < size; ++i)
  319. {
  320. d[i] = s[i];
  321. }
  322. else if (d > s && size > 0)
  323. for (i = size -1; ; --i)
  324. {
  325. d[i] = s[i];
  326. if (i == 0)
  327. break;
  328. }
  329. return dest;
  330. }
  331. #endif /* !HAVE_MEMMOVE */
  332. #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
  333. static void closedir LT_PARAMS((DIR *entry));
  334. static void
  335. closedir(entry)
  336. DIR *entry;
  337. {
  338. assert(entry != (DIR *) NULL);
  339. FindClose(entry->hSearch);
  340. lt_dlfree((lt_ptr)entry);
  341. }
  342. static DIR * opendir LT_PARAMS((const char *path));
  343. static DIR*
  344. opendir (path)
  345. const char *path;
  346. {
  347. char file_specification[LT_FILENAME_MAX];
  348. DIR *entry;
  349. assert(path != (char *) NULL);
  350. /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
  351. (void) strncpy (file_specification, path, LT_FILENAME_MAX-6);
  352. file_specification[LT_FILENAME_MAX-6] = LT_EOS_CHAR;
  353. (void) strcat(file_specification,"\\");
  354. entry = LT_DLMALLOC (DIR,sizeof(DIR));
  355. if (entry != (DIR *) 0)
  356. {
  357. entry->firsttime = TRUE;
  358. entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
  359. }
  360. if (entry->hSearch == INVALID_HANDLE_VALUE)
  361. {
  362. (void) strcat(file_specification,"\\*.*");
  363. entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
  364. if (entry->hSearch == INVALID_HANDLE_VALUE)
  365. {
  366. LT_DLFREE (entry);
  367. return (DIR *) 0;
  368. }
  369. }
  370. return(entry);
  371. }
  372. static struct dirent *readdir LT_PARAMS((DIR *entry));
  373. static struct dirent *readdir(entry)
  374. DIR *entry;
  375. {
  376. int
  377. status;
  378. if (entry == (DIR *) 0)
  379. return((struct dirent *) 0);
  380. if (!entry->firsttime)
  381. {
  382. status = FindNextFile(entry->hSearch,&entry->Win32FindData);
  383. if (status == 0)
  384. return((struct dirent *) 0);
  385. }
  386. entry->firsttime = FALSE;
  387. (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
  388. LT_FILENAME_MAX-1);
  389. entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR;
  390. entry->file_info.d_namlen = strlen(entry->file_info.d_name);
  391. return(&entry->file_info);
  392. }
  393. #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
  394. /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
  395. ``realloc is not entirely portable''
  396. In any case we want to use the allocator supplied by the user without
  397. burdening them with an lt_dlrealloc function pointer to maintain.
  398. Instead implement our own version (with known boundary conditions)
  399. using lt_dlmalloc and lt_dlfree. */
  400. /* #undef realloc
  401. #define realloc rpl_realloc
  402. */
  403. #if 0
  404. /* You can't (re)define realloc unless you also (re)define malloc.
  405. Right now, this code uses the size of the *destination* to decide
  406. how much to copy. That's not right, but you can't know the size
  407. of the source unless you know enough about, or wrote malloc. So
  408. this code is disabled... */
  409. static lt_ptr
  410. realloc (ptr, size)
  411. lt_ptr ptr;
  412. size_t size;
  413. {
  414. if (size == 0)
  415. {
  416. /* For zero or less bytes, free the original memory */
  417. if (ptr != 0)
  418. {
  419. lt_dlfree (ptr);
  420. }
  421. return (lt_ptr) 0;
  422. }
  423. else if (ptr == 0)
  424. {
  425. /* Allow reallocation of a NULL pointer. */
  426. return lt_dlmalloc (size);
  427. }
  428. else
  429. {
  430. /* Allocate a new block, copy and free the old block. */
  431. lt_ptr mem = lt_dlmalloc (size);
  432. if (mem)
  433. {
  434. memcpy (mem, ptr, size);
  435. lt_dlfree (ptr);
  436. }
  437. /* Note that the contents of PTR are not damaged if there is
  438. insufficient memory to realloc. */
  439. return mem;
  440. }
  441. }
  442. #endif
  443. #if ! HAVE_ARGZ_APPEND
  444. # define argz_append rpl_argz_append
  445. static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
  446. const char *buf, size_t buf_len));
  447. static error_t
  448. argz_append (pargz, pargz_len, buf, buf_len)
  449. char **pargz;
  450. size_t *pargz_len;
  451. const char *buf;
  452. size_t buf_len;
  453. {
  454. size_t argz_len;
  455. char *argz;
  456. assert (pargz);
  457. assert (pargz_len);
  458. assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
  459. /* If nothing needs to be appended, no more work is required. */
  460. if (buf_len == 0)
  461. return 0;
  462. /* Ensure there is enough room to append BUF_LEN. */
  463. argz_len = *pargz_len + buf_len;
  464. argz = LT_DLREALLOC (char, *pargz, argz_len);
  465. if (!argz)
  466. return ENOMEM;
  467. /* Copy characters from BUF after terminating '\0' in ARGZ. */
  468. memcpy (argz + *pargz_len, buf, buf_len);
  469. /* Assign new values. */
  470. *pargz = argz;
  471. *pargz_len = argz_len;
  472. return 0;
  473. }
  474. #endif /* !HAVE_ARGZ_APPEND */
  475. #if ! HAVE_ARGZ_CREATE_SEP
  476. # define argz_create_sep rpl_argz_create_sep
  477. static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
  478. char **pargz, size_t *pargz_len));
  479. static error_t
  480. argz_create_sep (str, delim, pargz, pargz_len)
  481. const char *str;
  482. int delim;
  483. char **pargz;
  484. size_t *pargz_len;
  485. {
  486. size_t argz_len;
  487. char *argz = 0;
  488. assert (str);
  489. assert (pargz);
  490. assert (pargz_len);
  491. /* Make a copy of STR, but replacing each occurence of
  492. DELIM with '\0'. */
  493. argz_len = 1+ LT_STRLEN (str);
  494. if (argz_len)
  495. {
  496. const char *p;
  497. char *q;
  498. argz = LT_DLMALLOC (char, argz_len);
  499. if (!argz)
  500. return ENOMEM;
  501. for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
  502. {
  503. if (*p == delim)
  504. {
  505. /* Ignore leading delimiters, and fold consecutive
  506. delimiters in STR into a single '\0' in ARGZ. */
  507. if ((q > argz) && (q[-1] != LT_EOS_CHAR))
  508. *q++ = LT_EOS_CHAR;
  509. else
  510. --argz_len;
  511. }
  512. else
  513. *q++ = *p;
  514. }
  515. /* Copy terminating LT_EOS_CHAR. */
  516. *q = *p;
  517. }
  518. /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
  519. if (!argz_len)
  520. LT_DLFREE (argz);
  521. /* Assign new values. */
  522. *pargz = argz;
  523. *pargz_len = argz_len;
  524. return 0;
  525. }
  526. #endif /* !HAVE_ARGZ_CREATE_SEP */
  527. #if ! HAVE_ARGZ_INSERT
  528. # define argz_insert rpl_argz_insert
  529. static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
  530. char *before, const char *entry));
  531. static error_t
  532. argz_insert (pargz, pargz_len, before, entry)
  533. char **pargz;
  534. size_t *pargz_len;
  535. char *before;
  536. const char *entry;
  537. {
  538. assert (pargz);
  539. assert (pargz_len);
  540. assert (entry && *entry);
  541. /* No BEFORE address indicates ENTRY should be inserted after the
  542. current last element. */
  543. if (!before)
  544. return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
  545. /* This probably indicates a programmer error, but to preserve
  546. semantics, scan back to the start of an entry if BEFORE points
  547. into the middle of it. */
  548. while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
  549. --before;
  550. {
  551. size_t entry_len = 1+ LT_STRLEN (entry);
  552. size_t argz_len = *pargz_len + entry_len;
  553. size_t offset = before - *pargz;
  554. char *argz = LT_DLREALLOC (char, *pargz, argz_len);
  555. if (!argz)
  556. return ENOMEM;
  557. /* Make BEFORE point to the equivalent offset in ARGZ that it
  558. used to have in *PARGZ incase realloc() moved the block. */
  559. before = argz + offset;
  560. /* Move the ARGZ entries starting at BEFORE up into the new
  561. space at the end -- making room to copy ENTRY into the
  562. resulting gap. */
  563. memmove (before + entry_len, before, *pargz_len - offset);
  564. memcpy (before, entry, entry_len);
  565. /* Assign new values. */
  566. *pargz = argz;
  567. *pargz_len = argz_len;
  568. }
  569. return 0;
  570. }
  571. #endif /* !HAVE_ARGZ_INSERT */
  572. #if ! HAVE_ARGZ_NEXT
  573. # define argz_next rpl_argz_next
  574. static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
  575. const char *entry));
  576. static char *
  577. argz_next (argz, argz_len, entry)
  578. char *argz;
  579. size_t argz_len;
  580. const char *entry;
  581. {
  582. assert ((argz && argz_len) || (!argz && !argz_len));
  583. if (entry)
  584. {
  585. /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
  586. within the ARGZ vector. */
  587. assert ((!argz && !argz_len)
  588. || ((argz <= entry) && (entry < (argz + argz_len))));
  589. /* Move to the char immediately after the terminating
  590. '\0' of ENTRY. */
  591. entry = 1+ strchr (entry, LT_EOS_CHAR);
  592. /* Return either the new ENTRY, or else NULL if ARGZ is
  593. exhausted. */
  594. return (entry >= argz + argz_len) ? 0 : (char *) entry;
  595. }
  596. else
  597. {
  598. /* This should probably be flagged as a programmer error,
  599. since starting an argz_next loop with the iterator set
  600. to ARGZ is safer. To preserve semantics, handle the NULL
  601. case by returning the start of ARGZ (if any). */
  602. if (argz_len > 0)
  603. return argz;
  604. else
  605. return 0;
  606. }
  607. }
  608. #endif /* !HAVE_ARGZ_NEXT */
  609. #if ! HAVE_ARGZ_STRINGIFY
  610. # define argz_stringify rpl_argz_stringify
  611. static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
  612. int sep));
  613. static void
  614. argz_stringify (argz, argz_len, sep)
  615. char *argz;
  616. size_t argz_len;
  617. int sep;
  618. {
  619. assert ((argz && argz_len) || (!argz && !argz_len));
  620. if (sep)
  621. {
  622. --argz_len; /* don't stringify the terminating EOS */
  623. while (--argz_len > 0)
  624. {
  625. if (argz[argz_len] == LT_EOS_CHAR)
  626. argz[argz_len] = sep;
  627. }
  628. }
  629. }
  630. #endif /* !HAVE_ARGZ_STRINGIFY */
  631. /* --- TYPE DEFINITIONS -- */
  632. /* This type is used for the array of caller data sets in each handler. */
  633. typedef struct {
  634. lt_dlcaller_id key;
  635. lt_ptr data;
  636. } lt_caller_data;
  637. /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
  638. /* Extract the diagnostic strings from the error table macro in the same
  639. order as the enumerated indices in ltdl.h. */
  640. static const char *lt_dlerror_strings[] =
  641. {
  642. #define LT_ERROR(name, diagnostic) (diagnostic),
  643. lt_dlerror_table
  644. #undef LT_ERROR
  645. 0
  646. };
  647. /* This structure is used for the list of registered loaders. */
  648. struct lt_dlloader {
  649. struct lt_dlloader *next;
  650. const char *loader_name; /* identifying name for each loader */
  651. const char *sym_prefix; /* prefix for symbols */
  652. lt_module_open *module_open;
  653. lt_module_close *module_close;
  654. lt_find_sym *find_sym;
  655. lt_dlloader_exit *dlloader_exit;
  656. lt_user_data dlloader_data;
  657. };
  658. struct lt_dlhandle_struct {
  659. struct lt_dlhandle_struct *next;
  660. lt_dlloader *loader; /* dlopening interface */
  661. lt_dlinfo info;
  662. int depcount; /* number of dependencies */
  663. lt_dlhandle *deplibs; /* dependencies */
  664. lt_module module; /* system module handle */
  665. lt_ptr system; /* system specific data */
  666. lt_caller_data *caller_data; /* per caller associated data */
  667. int flags; /* various boolean stats */
  668. };
  669. /* Various boolean flags can be stored in the flags field of an
  670. lt_dlhandle_struct... */
  671. #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
  672. #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
  673. #define LT_DLRESIDENT_FLAG (0x01 << 0)
  674. /* ...add more flags here... */
  675. #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
  676. #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
  677. static const char objdir[] = LTDL_OBJDIR;
  678. static const char archive_ext[] = LTDL_ARCHIVE_EXT;
  679. #ifdef LTDL_SHLIB_EXT
  680. static const char shlib_ext[] = LTDL_SHLIB_EXT;
  681. #endif
  682. #ifdef LTDL_SYSSEARCHPATH
  683. static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
  684. #endif
  685. /* --- MUTEX LOCKING --- */
  686. /* Macros to make it easier to run the lock functions only if they have
  687. been registered. The reason for the complicated lock macro is to
  688. ensure that the stored error message from the last error is not
  689. accidentally erased if the current function doesn't generate an
  690. error of its own. */
  691. #define LT_DLMUTEX_LOCK() LT_STMT_START { \
  692. if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
  693. } LT_STMT_END
  694. #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
  695. if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
  696. } LT_STMT_END
  697. #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
  698. if (lt_dlmutex_seterror_func) \
  699. (*lt_dlmutex_seterror_func) (errormsg); \
  700. else lt_dllast_error = (errormsg); } LT_STMT_END
  701. #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
  702. if (lt_dlmutex_seterror_func) \
  703. (errormsg) = (*lt_dlmutex_geterror_func) (); \
  704. else (errormsg) = lt_dllast_error; } LT_STMT_END
  705. /* The mutex functions stored here are global, and are necessarily the
  706. same for all threads that wish to share access to libltdl. */
  707. static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
  708. static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
  709. static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
  710. static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
  711. static const char *lt_dllast_error = 0;
  712. /* Either set or reset the mutex functions. Either all the arguments must
  713. be valid functions, or else all can be NULL to turn off locking entirely.
  714. The registered functions should be manipulating a static global lock
  715. from the lock() and unlock() callbacks, which needs to be reentrant. */
  716. int
  717. lt_dlmutex_register (lock, unlock, seterror, geterror)
  718. lt_dlmutex_lock *lock;
  719. lt_dlmutex_unlock *unlock;
  720. lt_dlmutex_seterror *seterror;
  721. lt_dlmutex_geterror *geterror;
  722. {
  723. lt_dlmutex_unlock *old_unlock = unlock;
  724. int errors = 0;
  725. /* Lock using the old lock() callback, if any. */
  726. LT_DLMUTEX_LOCK ();
  727. if ((lock && unlock && seterror && geterror)
  728. || !(lock || unlock || seterror || geterror))
  729. {
  730. lt_dlmutex_lock_func = lock;
  731. lt_dlmutex_unlock_func = unlock;
  732. lt_dlmutex_geterror_func = geterror;
  733. }
  734. else
  735. {
  736. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
  737. ++errors;
  738. }
  739. /* Use the old unlock() callback we saved earlier, if any. Otherwise
  740. record any errors using internal storage. */
  741. if (old_unlock)
  742. (*old_unlock) ();
  743. /* Return the number of errors encountered during the execution of
  744. this function. */
  745. return errors;
  746. }
  747. /* --- ERROR HANDLING --- */
  748. static const char **user_error_strings = 0;
  749. static int errorcount = LT_ERROR_MAX;
  750. int
  751. lt_dladderror (diagnostic)
  752. const char *diagnostic;
  753. {
  754. int errindex = 0;
  755. int result = -1;
  756. const char **temp = (const char **) 0;
  757. assert (diagnostic);
  758. LT_DLMUTEX_LOCK ();
  759. errindex = errorcount - LT_ERROR_MAX;
  760. temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
  761. if (temp)
  762. {
  763. user_error_strings = temp;
  764. user_error_strings[errindex] = diagnostic;
  765. result = errorcount++;
  766. }
  767. LT_DLMUTEX_UNLOCK ();
  768. return result;
  769. }
  770. int
  771. lt_dlseterror (errindex)
  772. int errindex;
  773. {
  774. int errors = 0;
  775. LT_DLMUTEX_LOCK ();
  776. if (errindex >= errorcount || errindex < 0)
  777. {
  778. /* Ack! Error setting the error message! */
  779. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
  780. ++errors;
  781. }
  782. else if (errindex < LT_ERROR_MAX)
  783. {
  784. /* No error setting the error message! */
  785. LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
  786. }
  787. else
  788. {
  789. /* No error setting the error message! */
  790. LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
  791. }
  792. LT_DLMUTEX_UNLOCK ();
  793. return errors;
  794. }
  795. static lt_ptr
  796. lt_emalloc (size)
  797. size_t size;
  798. {
  799. lt_ptr mem = lt_dlmalloc (size);
  800. if (size && !mem)
  801. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
  802. return mem;
  803. }
  804. static lt_ptr
  805. lt_erealloc (addr, size)
  806. lt_ptr addr;
  807. size_t size;
  808. {
  809. lt_ptr mem = lt_dlrealloc (addr, size);
  810. if (size && !mem)
  811. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
  812. return mem;
  813. }
  814. static char *
  815. lt_estrdup (str)
  816. const char *str;
  817. {
  818. char *copy = strdup (str);
  819. if (LT_STRLEN (str) && !copy)
  820. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
  821. return copy;
  822. }
  823. /* --- DLOPEN() INTERFACE LOADER --- */
  824. #if HAVE_LIBDL
  825. /* dynamic linking with dlopen/dlsym */
  826. #if HAVE_DLFCN_H
  827. # include <dlfcn.h>
  828. #endif
  829. #if HAVE_SYS_DL_H
  830. # include <sys/dl.h>
  831. #endif
  832. #ifdef RTLD_GLOBAL
  833. # define LT_GLOBAL RTLD_GLOBAL
  834. #else
  835. # ifdef DL_GLOBAL
  836. # define LT_GLOBAL DL_GLOBAL
  837. # endif
  838. #endif /* !RTLD_GLOBAL */
  839. #ifndef LT_GLOBAL
  840. # define LT_GLOBAL 0
  841. #endif /* !LT_GLOBAL */
  842. /* We may have to define LT_LAZY_OR_NOW in the command line if we
  843. find out it does not work in some platform. */
  844. #ifndef LT_LAZY_OR_NOW
  845. # ifdef RTLD_LAZY
  846. # define LT_LAZY_OR_NOW RTLD_LAZY
  847. # else
  848. # ifdef DL_LAZY
  849. # define LT_LAZY_OR_NOW DL_LAZY
  850. # endif
  851. # endif /* !RTLD_LAZY */
  852. #endif
  853. #ifndef LT_LAZY_OR_NOW
  854. # ifdef RTLD_NOW
  855. # define LT_LAZY_OR_NOW RTLD_NOW
  856. # else
  857. # ifdef DL_NOW
  858. # define LT_LAZY_OR_NOW DL_NOW
  859. # endif
  860. # endif /* !RTLD_NOW */
  861. #endif
  862. #ifndef LT_LAZY_OR_NOW
  863. # define LT_LAZY_OR_NOW 0
  864. #endif /* !LT_LAZY_OR_NOW */
  865. #if HAVE_DLERROR
  866. # define DLERROR(arg) dlerror ()
  867. #else
  868. # define DLERROR(arg) LT_DLSTRERROR (arg)
  869. #endif
  870. static lt_module
  871. sys_dl_open (loader_data, filename)
  872. lt_user_data loader_data;
  873. const char *filename;
  874. {
  875. lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
  876. if (!module)
  877. {
  878. LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
  879. }
  880. return module;
  881. }
  882. static int
  883. sys_dl_close (loader_data, module)
  884. lt_user_data loader_data;
  885. lt_module module;
  886. {
  887. int errors = 0;
  888. if (dlclose (module) != 0)
  889. {
  890. LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
  891. ++errors;
  892. }
  893. return errors;
  894. }
  895. static lt_ptr
  896. sys_dl_sym (loader_data, module, symbol)
  897. lt_user_data loader_data;
  898. lt_module module;
  899. const char *symbol;
  900. {
  901. lt_ptr address = dlsym (module, symbol);
  902. if (!address)
  903. {
  904. LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
  905. }
  906. return address;
  907. }
  908. static struct lt_user_dlloader sys_dl =
  909. {
  910. # ifdef NEED_USCORE
  911. "_",
  912. # else
  913. 0,
  914. # endif
  915. sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
  916. #endif /* HAVE_LIBDL */
  917. /* --- SHL_LOAD() INTERFACE LOADER --- */
  918. #if HAVE_SHL_LOAD
  919. /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
  920. #ifdef HAVE_DL_H
  921. # include <dl.h>
  922. #endif
  923. /* some flags are missing on some systems, so we provide
  924. * harmless defaults.
  925. *
  926. * Mandatory:
  927. * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
  928. * BIND_DEFERRED - Delay code symbol resolution until actual reference.
  929. *
  930. * Optionally:
  931. * BIND_FIRST - Place the library at the head of the symbol search
  932. * order.
  933. * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
  934. * unsatisfied symbols as fatal. This flag allows
  935. * binding of unsatisfied code symbols to be deferred
  936. * until use.
  937. * [Perl: For certain libraries, like DCE, deferred
  938. * binding often causes run time problems. Adding
  939. * BIND_NONFATAL to BIND_IMMEDIATE still allows
  940. * unresolved references in situations like this.]
  941. * BIND_NOSTART - Do not call the initializer for the shared library
  942. * when the library is loaded, nor on a future call to
  943. * shl_unload().
  944. * BIND_VERBOSE - Print verbose messages concerning possible
  945. * unsatisfied symbols.
  946. *
  947. * hp9000s700/hp9000s800:
  948. * BIND_RESTRICTED - Restrict symbols visible by the library to those
  949. * present at library load time.
  950. * DYNAMIC_PATH - Allow the loader to dynamically search for the
  951. * library specified by the path argument.
  952. */
  953. #ifndef DYNAMIC_PATH
  954. # define DYNAMIC_PATH 0
  955. #endif
  956. #ifndef BIND_RESTRICTED
  957. # define BIND_RESTRICTED 0
  958. #endif
  959. #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
  960. static lt_module
  961. sys_shl_open (loader_data, filename)
  962. lt_user_data loader_data;
  963. const char *filename;
  964. {
  965. static shl_t self = (shl_t) 0;
  966. lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
  967. /* Since searching for a symbol against a NULL module handle will also
  968. look in everything else that was already loaded and exported with
  969. the -E compiler flag, we always cache a handle saved before any
  970. modules are loaded. */
  971. if (!self)
  972. {
  973. lt_ptr address;
  974. shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
  975. }
  976. if (!filename)
  977. {
  978. module = self;
  979. }
  980. else
  981. {
  982. module = shl_load (filename, LT_BIND_FLAGS, 0L);
  983. if (!module)
  984. {
  985. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
  986. }
  987. }
  988. return module;
  989. }
  990. static int
  991. sys_shl_close (loader_data, module)
  992. lt_user_data loader_data;
  993. lt_module module;
  994. {
  995. int errors = 0;
  996. if (module && (shl_unload ((shl_t) (module)) != 0))
  997. {
  998. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
  999. ++errors;
  1000. }
  1001. return errors;
  1002. }
  1003. static lt_ptr
  1004. sys_shl_sym (loader_data, module, symbol)
  1005. lt_user_data loader_data;
  1006. lt_module module;
  1007. const char *symbol;
  1008. {
  1009. lt_ptr address = 0;
  1010. /* sys_shl_open should never return a NULL module handle */
  1011. if (module == (lt_module) 0)
  1012. {
  1013. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  1014. }
  1015. else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
  1016. {
  1017. if (!address)
  1018. {
  1019. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  1020. }
  1021. }
  1022. return address;
  1023. }
  1024. static struct lt_user_dlloader sys_shl = {
  1025. 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
  1026. };
  1027. #endif /* HAVE_SHL_LOAD */
  1028. /* --- LOADLIBRARY() INTERFACE LOADER --- */
  1029. #ifdef __WINDOWS__
  1030. /* dynamic linking for Win32 */
  1031. #include <windows.h>
  1032. /* Forward declaration; required to implement handle search below. */
  1033. static lt_dlhandle handles;
  1034. static lt_module
  1035. sys_wll_open (loader_data, filename)
  1036. lt_user_data loader_data;
  1037. const char *filename;
  1038. {
  1039. lt_dlhandle cur;
  1040. lt_module module = 0;
  1041. const char *errormsg = 0;
  1042. char *searchname = 0;
  1043. char *ext;
  1044. char self_name_buf[MAX_PATH];
  1045. if (!filename)
  1046. {
  1047. /* Get the name of main module */
  1048. *self_name_buf = 0;
  1049. GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
  1050. filename = ext = self_name_buf;
  1051. }
  1052. else
  1053. {
  1054. ext = strrchr (filename, '.');
  1055. }
  1056. if (ext)
  1057. {
  1058. /* FILENAME already has an extension. */
  1059. searchname = lt_estrdup (filename);
  1060. }
  1061. else
  1062. {
  1063. /* Append a `.' to stop Windows from adding an
  1064. implicit `.dll' extension. */
  1065. searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
  1066. if (searchname)
  1067. sprintf (searchname, "%s.", filename);
  1068. }
  1069. if (!searchname)
  1070. return 0;
  1071. #if __CYGWIN__
  1072. {
  1073. char wpath[MAX_PATH];
  1074. cygwin_conv_to_full_win32_path(searchname, wpath);
  1075. module = LoadLibrary(wpath);
  1076. }
  1077. #else
  1078. module = LoadLibrary (searchname);
  1079. #endif
  1080. LT_DLFREE (searchname);
  1081. /* libltdl expects this function to fail if it is unable
  1082. to physically load the library. Sadly, LoadLibrary
  1083. will search the loaded libraries for a match and return
  1084. one of them if the path search load fails.
  1085. We check whether LoadLibrary is returning a handle to
  1086. an already loaded module, and simulate failure if we
  1087. find one. */
  1088. LT_DLMUTEX_LOCK ();
  1089. cur = handles;
  1090. while (cur)
  1091. {
  1092. if (!cur->module)
  1093. {
  1094. cur = 0;
  1095. break;
  1096. }
  1097. if (cur->module == module)
  1098. {
  1099. break;
  1100. }
  1101. cur = cur->next;
  1102. }
  1103. LT_DLMUTEX_UNLOCK ();
  1104. if (cur || !module)
  1105. {
  1106. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
  1107. module = 0;
  1108. }
  1109. return module;
  1110. }
  1111. static int
  1112. sys_wll_close (loader_data, module)
  1113. lt_user_data loader_data;
  1114. lt_module module;
  1115. {
  1116. int errors = 0;
  1117. if (FreeLibrary(module) == 0)
  1118. {
  1119. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
  1120. ++errors;
  1121. }
  1122. return errors;
  1123. }
  1124. static lt_ptr
  1125. sys_wll_sym (loader_data, module, symbol)
  1126. lt_user_data loader_data;
  1127. lt_module module;
  1128. const char *symbol;
  1129. {
  1130. lt_ptr address = GetProcAddress (module, symbol);
  1131. if (!address)
  1132. {
  1133. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  1134. }
  1135. return address;
  1136. }
  1137. static struct lt_user_dlloader sys_wll = {
  1138. 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
  1139. };
  1140. #endif /* __WINDOWS__ */
  1141. /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
  1142. #ifdef __BEOS__
  1143. /* dynamic linking for BeOS */
  1144. #include <kernel/image.h>
  1145. static lt_module
  1146. sys_bedl_open (loader_data, filename)
  1147. lt_user_data loader_data;
  1148. const char *filename;
  1149. {
  1150. image_id image = 0;
  1151. if (filename)
  1152. {
  1153. image = load_add_on (filename);
  1154. }
  1155. else
  1156. {
  1157. image_info info;
  1158. int32 cookie = 0;
  1159. if (get_next_image_info (0, &cookie, &info) == B_OK)
  1160. image = load_add_on (info.name);
  1161. }
  1162. if (image <= 0)
  1163. {
  1164. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
  1165. image = 0;
  1166. }
  1167. return (lt_module) image;
  1168. }
  1169. static int
  1170. sys_bedl_close (loader_data, module)
  1171. lt_user_data loader_data;
  1172. lt_module module;
  1173. {
  1174. int errors = 0;
  1175. if (unload_add_on ((image_id) module) != B_OK)
  1176. {
  1177. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
  1178. ++errors;
  1179. }
  1180. return errors;
  1181. }
  1182. static lt_ptr
  1183. sys_bedl_sym (loader_data, module, symbol)
  1184. lt_user_data loader_data;
  1185. lt_module module;
  1186. const char *symbol;
  1187. {
  1188. lt_ptr address = 0;
  1189. image_id image = (image_id) module;
  1190. if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
  1191. {
  1192. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  1193. address = 0;
  1194. }
  1195. return address;
  1196. }
  1197. static struct lt_user_dlloader sys_bedl = {
  1198. 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
  1199. };
  1200. #endif /* __BEOS__ */
  1201. /* --- DLD_LINK() INTERFACE LOADER --- */
  1202. #if HAVE_DLD
  1203. /* dynamic linking with dld */
  1204. #if HAVE_DLD_H
  1205. #include <dld.h>
  1206. #endif
  1207. static lt_module
  1208. sys_dld_open (loader_data, filename)
  1209. lt_user_data loader_data;
  1210. const char *filename;
  1211. {
  1212. lt_module module = strdup (filename);
  1213. if (dld_link (filename) != 0)
  1214. {
  1215. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
  1216. LT_DLFREE (module);
  1217. module = 0;
  1218. }
  1219. return module;
  1220. }
  1221. static int
  1222. sys_dld_close (loader_data, module)
  1223. lt_user_data loader_data;
  1224. lt_module module;
  1225. {
  1226. int errors = 0;
  1227. if (dld_unlink_by_file ((char*)(module), 1) != 0)
  1228. {
  1229. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
  1230. ++errors;
  1231. }
  1232. else
  1233. {
  1234. LT_DLFREE (module);
  1235. }
  1236. return errors;
  1237. }
  1238. static lt_ptr
  1239. sys_dld_sym (loader_data, module, symbol)
  1240. lt_user_data loader_data;
  1241. lt_module module;
  1242. const char *symbol;
  1243. {
  1244. lt_ptr address = dld_get_func (symbol);
  1245. if (!address)
  1246. {
  1247. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  1248. }
  1249. return address;
  1250. }
  1251. static struct lt_user_dlloader sys_dld = {
  1252. 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
  1253. };
  1254. #endif /* HAVE_DLD */
  1255. /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
  1256. #if HAVE_DYLD
  1257. #if HAVE_MACH_O_DYLD_H
  1258. #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
  1259. /* Is this correct? Does it still function properly? */
  1260. #define __private_extern__ extern
  1261. #endif
  1262. # include <mach-o/dyld.h>
  1263. #endif
  1264. #include <mach-o/getsect.h>
  1265. /* We have to put some stuff here that isn't in older dyld.h files */
  1266. #ifndef ENUM_DYLD_BOOL
  1267. # define ENUM_DYLD_BOOL
  1268. # undef FALSE
  1269. # undef TRUE
  1270. enum DYLD_BOOL {
  1271. FALSE,
  1272. TRUE
  1273. };
  1274. #endif
  1275. #ifndef LC_REQ_DYLD
  1276. # define LC_REQ_DYLD 0x80000000
  1277. #endif
  1278. #ifndef LC_LOAD_WEAK_DYLIB
  1279. # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
  1280. #endif
  1281. static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
  1282. static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
  1283. static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
  1284. static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
  1285. #ifndef NSADDIMAGE_OPTION_NONE
  1286. #define NSADDIMAGE_OPTION_NONE 0x0
  1287. #endif
  1288. #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
  1289. #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
  1290. #endif
  1291. #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
  1292. #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
  1293. #endif
  1294. #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
  1295. #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
  1296. #endif
  1297. #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
  1298. #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
  1299. #endif
  1300. #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
  1301. #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
  1302. #endif
  1303. #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
  1304. #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
  1305. #endif
  1306. #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
  1307. #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
  1308. #endif
  1309. #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
  1310. #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
  1311. #endif
  1312. static const char *
  1313. lt_int_dyld_error(othererror)
  1314. char* othererror;
  1315. {
  1316. /* return the dyld error string, or the passed in error string if none */
  1317. NSLinkEditErrors ler;
  1318. int lerno;
  1319. const char *errstr;
  1320. const char *file;
  1321. NSLinkEditError(&ler,&lerno,&file,&errstr);
  1322. if (!errstr || !strlen(errstr)) errstr = othererror;
  1323. return errstr;
  1324. }
  1325. static const struct mach_header *
  1326. lt_int_dyld_get_mach_header_from_nsmodule(module)
  1327. NSModule module;
  1328. {
  1329. /* There should probably be an apple dyld api for this */
  1330. int i=_dyld_image_count();
  1331. int j;
  1332. const char *modname=NSNameOfModule(module);
  1333. const struct mach_header *mh=NULL;
  1334. if (!modname) return NULL;
  1335. for (j = 0; j < i; j++)
  1336. {
  1337. if (!strcmp(_dyld_get_image_name(j),modname))
  1338. {
  1339. mh=_dyld_get_image_header(j);
  1340. break;
  1341. }
  1342. }
  1343. return mh;
  1344. }
  1345. static const char* lt_int_dyld_lib_install_name(mh)
  1346. const struct mach_header *mh;
  1347. {
  1348. /* NSAddImage is also used to get the loaded image, but it only works if the lib
  1349. is installed, for uninstalled libs we need to check the install_names against
  1350. each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
  1351. different lib was loaded as a result
  1352. */
  1353. int j;
  1354. struct load_command *lc;
  1355. unsigned long offset = sizeof(struct mach_header);
  1356. const char* retStr=NULL;
  1357. for (j = 0; j < mh->ncmds; j++)
  1358. {
  1359. lc = (struct load_command*)(((unsigned long)mh) + offset);
  1360. if (LC_ID_DYLIB == lc->cmd)
  1361. {
  1362. retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
  1363. (unsigned long)lc);
  1364. }
  1365. offset += lc->cmdsize;
  1366. }
  1367. return retStr;
  1368. }
  1369. static const struct mach_header *
  1370. lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
  1371. {
  1372. int i=_dyld_image_count();
  1373. int j;
  1374. const struct mach_header *mh=NULL;
  1375. const char *id=NULL;
  1376. for (j = 0; j < i; j++)
  1377. {
  1378. id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
  1379. if ((id) && (!strcmp(id,name)))
  1380. {
  1381. mh=_dyld_get_image_header(j);
  1382. break;
  1383. }
  1384. }
  1385. return mh;
  1386. }
  1387. static NSSymbol
  1388. lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh)
  1389. const char *symbol;
  1390. const struct mach_header *mh;
  1391. {
  1392. /* Safe to assume our mh is good */
  1393. int j;
  1394. struct load_command *lc;
  1395. unsigned long offset = sizeof(struct mach_header);
  1396. NSSymbol retSym = 0;
  1397. const struct mach_header *mh1;
  1398. if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
  1399. {
  1400. for (j = 0; j < mh->ncmds; j++)
  1401. {
  1402. lc = (struct load_command*)(((unsigned long)mh) + offset);
  1403. if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
  1404. {
  1405. mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
  1406. (unsigned long)lc));
  1407. if (!mh1)
  1408. {
  1409. /* Maybe NSAddImage can find it */
  1410. mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
  1411. (unsigned long)lc),
  1412. NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
  1413. NSADDIMAGE_OPTION_WITH_SEARCHING +
  1414. NSADDIMAGE_OPTION_RETURN_ON_ERROR );
  1415. }
  1416. if (mh1)
  1417. {
  1418. retSym = ltdl_NSLookupSymbolInImage(mh1,
  1419. symbol,
  1420. NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
  1421. | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
  1422. );
  1423. if (retSym) break;
  1424. }
  1425. }
  1426. offset += lc->cmdsize;
  1427. }
  1428. }
  1429. return retSym;
  1430. }
  1431. static int
  1432. sys_dyld_init()
  1433. {
  1434. int retCode = 0;
  1435. int err = 0;
  1436. if (!_dyld_present()) {
  1437. retCode=1;
  1438. }
  1439. else {
  1440. err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)&ltdl_NSAddImage);
  1441. err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)&ltdl_NSLookupSymbolInImage);
  1442. err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)&ltdl_NSIsSymbolNameDefinedInImage);
  1443. err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)&ltdl_NSMakePrivateModulePublic);
  1444. }
  1445. return retCode;
  1446. }
  1447. static lt_module
  1448. sys_dyld_open (loader_data, filename)
  1449. lt_user_data loader_data;
  1450. const char *filename;
  1451. {
  1452. lt_module module = 0;
  1453. NSObjectFileImage ofi = 0;
  1454. NSObjectFileImageReturnCode ofirc;
  1455. if (!filename)
  1456. return (lt_module)-1;
  1457. ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
  1458. switch (ofirc)
  1459. {
  1460. case NSObjectFileImageSuccess:
  1461. module = NSLinkModule(ofi, filename,
  1462. NSLINKMODULE_OPTION_RETURN_ON_ERROR
  1463. | NSLINKMODULE_OPTION_PRIVATE
  1464. | NSLINKMODULE_OPTION_BINDNOW);
  1465. NSDestroyObjectFileImage(ofi);
  1466. if (module)
  1467. ltdl_NSMakePrivateModulePublic(module);
  1468. break;
  1469. case NSObjectFileImageInappropriateFile:
  1470. if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
  1471. {
  1472. module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
  1473. break;
  1474. }
  1475. default:
  1476. LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
  1477. return 0;
  1478. }
  1479. if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
  1480. return module;
  1481. }
  1482. static int
  1483. sys_dyld_close (loader_data, module)
  1484. lt_user_data loader_data;
  1485. lt_module module;
  1486. {
  1487. int retCode = 0;
  1488. int flags = 0;
  1489. if (module == (lt_module)-1) return 0;
  1490. #ifdef __BIG_ENDIAN__
  1491. if (((struct mach_header *)module)->magic == MH_MAGIC)
  1492. #else
  1493. if (((struct mach_header *)module)->magic == MH_CIGAM)
  1494. #endif
  1495. {
  1496. LT_DLMUTEX_SETERROR("Can not close a dylib");
  1497. retCode = 1;
  1498. }
  1499. else
  1500. {
  1501. #if 1
  1502. /* Currently, if a module contains c++ static destructors and it is unloaded, we
  1503. get a segfault in atexit(), due to compiler and dynamic loader differences of
  1504. opinion, this works around that.
  1505. */
  1506. if ((const struct section *)NULL !=
  1507. getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
  1508. "__DATA","__mod_term_func"))
  1509. {
  1510. flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
  1511. }
  1512. #endif
  1513. #ifdef __ppc__
  1514. flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
  1515. #endif
  1516. if (!NSUnLinkModule(module,flags))
  1517. {
  1518. retCode=1;
  1519. LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
  1520. }
  1521. }
  1522. return retCode;
  1523. }
  1524. static lt_ptr
  1525. sys_dyld_sym (loader_data, module, symbol)
  1526. lt_user_data loader_data;
  1527. lt_module module;
  1528. const char *symbol;
  1529. {
  1530. lt_ptr address = 0;
  1531. NSSymbol *nssym = 0;
  1532. void *unused;
  1533. const struct mach_header *mh=NULL;
  1534. char saveError[256] = "Symbol not found";
  1535. if (module == (lt_module)-1)
  1536. {
  1537. _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
  1538. return address;
  1539. }
  1540. #ifdef __BIG_ENDIAN__
  1541. if (((struct mach_header *)module)->magic == MH_MAGIC)
  1542. #else
  1543. if (((struct mach_header *)module)->magic == MH_CIGAM)
  1544. #endif
  1545. {
  1546. if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
  1547. {
  1548. mh=module;
  1549. if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
  1550. {
  1551. nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
  1552. symbol,
  1553. NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
  1554. | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
  1555. );
  1556. }
  1557. }
  1558. }
  1559. else {
  1560. nssym = NSLookupSymbolInModule(module, symbol);
  1561. }
  1562. if (!nssym)
  1563. {
  1564. strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
  1565. saveError[255] = 0;
  1566. if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
  1567. nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
  1568. }
  1569. if (!nssym)
  1570. {
  1571. LT_DLMUTEX_SETERROR (saveError);
  1572. return NULL;
  1573. }
  1574. return NSAddressOfSymbol(nssym);
  1575. }
  1576. static struct lt_user_dlloader sys_dyld =
  1577. { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
  1578. #endif /* HAVE_DYLD */
  1579. /* --- DLPREOPEN() INTERFACE LOADER --- */
  1580. /* emulate dynamic linking using preloaded_symbols */
  1581. typedef struct lt_dlsymlists_t
  1582. {
  1583. struct lt_dlsymlists_t *next;
  1584. const lt_dlsymlist *syms;
  1585. } lt_dlsymlists_t;
  1586. static const lt_dlsymlist *default_preloaded_symbols = 0;
  1587. static lt_dlsymlists_t *preloaded_symbols = 0;
  1588. static int
  1589. presym_init (loader_data)
  1590. lt_user_data loader_data;
  1591. {
  1592. int errors = 0;
  1593. LT_DLMUTEX_LOCK ();
  1594. preloaded_symbols = 0;
  1595. if (default_preloaded_symbols)
  1596. {
  1597. errors = lt_dlpreload (default_preloaded_symbols);
  1598. }
  1599. LT_DLMUTEX_UNLOCK ();
  1600. return errors;
  1601. }
  1602. static int
  1603. presym_free_symlists ()
  1604. {
  1605. lt_dlsymlists_t *lists;
  1606. LT_DLMUTEX_LOCK ();
  1607. lists = preloaded_symbols;
  1608. while (lists)
  1609. {
  1610. lt_dlsymlists_t *tmp = lists;
  1611. lists = lists->next;
  1612. LT_DLFREE (tmp);
  1613. }
  1614. preloaded_symbols = 0;
  1615. LT_DLMUTEX_UNLOCK ();
  1616. return 0;
  1617. }
  1618. static int
  1619. presym_exit (loader_data)
  1620. lt_user_data loader_data;
  1621. {
  1622. presym_free_symlists ();
  1623. return 0;
  1624. }
  1625. static int
  1626. presym_add_symlist (preloaded)
  1627. const lt_dlsymlist *preloaded;
  1628. {
  1629. lt_dlsymlists_t *tmp;
  1630. lt_dlsymlists_t *lists;
  1631. int errors = 0;
  1632. LT_DLMUTEX_LOCK ();
  1633. lists = preloaded_symbols;
  1634. while (lists)
  1635. {
  1636. if (lists->syms == preloaded)
  1637. {
  1638. goto done;
  1639. }
  1640. lists = lists->next;
  1641. }
  1642. tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
  1643. if (tmp)
  1644. {
  1645. memset (tmp, 0, sizeof(lt_dlsymlists_t));
  1646. tmp->syms = preloaded;
  1647. tmp->next = preloaded_symbols;
  1648. preloaded_symbols = tmp;
  1649. }
  1650. else
  1651. {
  1652. ++errors;
  1653. }
  1654. done:
  1655. LT_DLMUTEX_UNLOCK ();
  1656. return errors;
  1657. }
  1658. static lt_module
  1659. presym_open (loader_data, filename)
  1660. lt_user_data loader_data;
  1661. const char *filename;
  1662. {
  1663. lt_dlsymlists_t *lists;
  1664. lt_module module = (lt_module) 0;
  1665. LT_DLMUTEX_LOCK ();
  1666. lists = preloaded_symbols;
  1667. if (!lists)
  1668. {
  1669. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
  1670. goto done;
  1671. }
  1672. /* Can't use NULL as the reflective symbol header, as NULL is
  1673. used to mark the end of the entire symbol list. Self-dlpreopened
  1674. symbols follow this magic number, chosen to be an unlikely
  1675. clash with a real module name. */
  1676. if (!filename)
  1677. {
  1678. filename = "@PROGRAM@";
  1679. }
  1680. while (lists)
  1681. {
  1682. const lt_dlsymlist *syms = lists->syms;
  1683. while (syms->name)
  1684. {
  1685. if (!syms->address && strcmp(syms->name, filename) == 0)
  1686. {
  1687. module = (lt_module) syms;
  1688. goto done;
  1689. }
  1690. ++syms;
  1691. }
  1692. lists = lists->next;
  1693. }
  1694. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
  1695. done:
  1696. LT_DLMUTEX_UNLOCK ();
  1697. return module;
  1698. }
  1699. static int
  1700. presym_close (loader_data, module)
  1701. lt_user_data loader_data;
  1702. lt_module module;
  1703. {
  1704. /* Just to silence gcc -Wall */
  1705. module = 0;
  1706. return 0;
  1707. }
  1708. static lt_ptr
  1709. presym_sym (loader_data, module, symbol)
  1710. lt_user_data loader_data;
  1711. lt_module module;
  1712. const char *symbol;
  1713. {
  1714. lt_dlsymlist *syms = (lt_dlsymlist*) module;
  1715. ++syms;
  1716. while (syms->address)
  1717. {
  1718. if (strcmp(syms->name, symbol) == 0)
  1719. {
  1720. return syms->address;
  1721. }
  1722. ++syms;
  1723. }
  1724. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  1725. return 0;
  1726. }
  1727. static struct lt_user_dlloader presym = {
  1728. 0, presym_open, presym_close, presym_sym, presym_exit, 0
  1729. };
  1730. /* --- DYNAMIC MODULE LOADING --- */
  1731. /* The type of a function used at each iteration of foreach_dirinpath(). */
  1732. typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
  1733. lt_ptr data2));
  1734. static int foreach_dirinpath LT_PARAMS((const char *search_path,
  1735. const char *base_name,
  1736. foreach_callback_func *func,
  1737. lt_ptr data1, lt_ptr data2));
  1738. static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
  1739. lt_ptr ignored));
  1740. static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
  1741. lt_ptr ignored));
  1742. static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
  1743. lt_ptr data2));
  1744. static int canonicalize_path LT_PARAMS((const char *path,
  1745. char **pcanonical));
  1746. static int argzize_path LT_PARAMS((const char *path,
  1747. char **pargz,
  1748. size_t *pargz_len));
  1749. static FILE *find_file LT_PARAMS((const char *search_path,
  1750. const char *base_name,
  1751. char **pdir));
  1752. static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
  1753. const char *base_name,
  1754. lt_dlhandle *handle));
  1755. static int find_module LT_PARAMS((lt_dlhandle *handle,
  1756. const char *dir,
  1757. const char *libdir,
  1758. const char *dlname,
  1759. const char *old_name,
  1760. int installed));
  1761. static int free_vars LT_PARAMS((char *dlname, char *oldname,
  1762. char *libdir, char *deplibs));
  1763. static int load_deplibs LT_PARAMS((lt_dlhandle handle,
  1764. char *deplibs));
  1765. static int trim LT_PARAMS((char **dest,
  1766. const char *str));
  1767. static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
  1768. const char *filename));
  1769. static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
  1770. const char *filename,
  1771. const char * useloader));
  1772. static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
  1773. static int lt_argz_insert LT_PARAMS((char **pargz,
  1774. size_t *pargz_len,
  1775. char *before,
  1776. const char *entry));
  1777. static int lt_argz_insertinorder LT_PARAMS((char **pargz,
  1778. size_t *pargz_len,
  1779. const char *entry));
  1780. static int lt_argz_insertdir LT_PARAMS((char **pargz,
  1781. size_t *pargz_len,
  1782. const char *dirnam,
  1783. struct dirent *dp));
  1784. static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
  1785. char *before,
  1786. const char *dir));
  1787. static int list_files_by_dir LT_PARAMS((const char *dirnam,
  1788. char **pargz,
  1789. size_t *pargz_len));
  1790. static int file_not_found LT_PARAMS((void));
  1791. static char *user_search_path= 0;
  1792. static lt_dlloader *loaders = 0;
  1793. static lt_dlhandle handles = 0;
  1794. static int initialized = 0;
  1795. /* Initialize libltdl. */
  1796. int
  1797. lt_dlinit ()
  1798. {
  1799. int errors = 0;
  1800. LT_DLMUTEX_LOCK ();
  1801. /* Initialize only at first call. */
  1802. if (++initialized == 1)
  1803. {
  1804. handles = 0;
  1805. user_search_path = 0; /* empty search path */
  1806. #if HAVE_LIBDL
  1807. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
  1808. #endif
  1809. #if HAVE_SHL_LOAD
  1810. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
  1811. #endif
  1812. #ifdef __WINDOWS__
  1813. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
  1814. #endif
  1815. #ifdef __BEOS__
  1816. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
  1817. #endif
  1818. #if HAVE_DLD
  1819. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
  1820. #endif
  1821. #if HAVE_DYLD
  1822. errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
  1823. errors += sys_dyld_init();
  1824. #endif
  1825. errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
  1826. if (presym_init (presym.dlloader_data))
  1827. {
  1828. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
  1829. ++errors;
  1830. }
  1831. else if (errors != 0)
  1832. {
  1833. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
  1834. ++errors;
  1835. }
  1836. }
  1837. LT_DLMUTEX_UNLOCK ();
  1838. return errors;
  1839. }
  1840. int
  1841. lt_dlpreload (preloaded)
  1842. const lt_dlsymlist *preloaded;
  1843. {
  1844. int errors = 0;
  1845. if (preloaded)
  1846. {
  1847. errors = presym_add_symlist (preloaded);
  1848. }
  1849. else
  1850. {
  1851. presym_free_symlists();
  1852. LT_DLMUTEX_LOCK ();
  1853. if (default_preloaded_symbols)
  1854. {
  1855. errors = lt_dlpreload (default_preloaded_symbols);
  1856. }
  1857. LT_DLMUTEX_UNLOCK ();
  1858. }
  1859. return errors;
  1860. }
  1861. int
  1862. lt_dlpreload_default (preloaded)
  1863. const lt_dlsymlist *preloaded;
  1864. {
  1865. LT_DLMUTEX_LOCK ();
  1866. default_preloaded_symbols = preloaded;
  1867. LT_DLMUTEX_UNLOCK ();
  1868. return 0;
  1869. }
  1870. int
  1871. lt_dlexit ()
  1872. {
  1873. /* shut down libltdl */
  1874. lt_dlloader *loader;
  1875. int errors = 0;
  1876. LT_DLMUTEX_LOCK ();
  1877. loader = loaders;
  1878. if (!initialized)
  1879. {
  1880. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
  1881. ++errors;
  1882. goto done;
  1883. }
  1884. /* shut down only at last call. */
  1885. if (--initialized == 0)
  1886. {
  1887. int level;
  1888. while (handles && LT_DLIS_RESIDENT (handles))
  1889. {
  1890. handles = handles->next;
  1891. }
  1892. /* close all modules */
  1893. for (level = 1; handles; ++level)
  1894. {
  1895. lt_dlhandle cur = handles;
  1896. int saw_nonresident = 0;
  1897. while (cur)
  1898. {
  1899. lt_dlhandle tmp = cur;
  1900. cur = cur->next;
  1901. if (!LT_DLIS_RESIDENT (tmp))
  1902. saw_nonresident = 1;
  1903. if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
  1904. {
  1905. if (lt_dlclose (tmp))
  1906. {
  1907. ++errors;
  1908. }
  1909. }
  1910. }
  1911. /* done if only resident modules are left */
  1912. if (!saw_nonresident)
  1913. break;
  1914. }
  1915. /* close all loaders */
  1916. while (loader)
  1917. {
  1918. lt_dlloader *next = loader->next;
  1919. lt_user_data data = loader->dlloader_data;
  1920. if (loader->dlloader_exit && loader->dlloader_exit (data))
  1921. {
  1922. ++errors;
  1923. }
  1924. LT_DLMEM_REASSIGN (loader, next);
  1925. }
  1926. loaders = 0;
  1927. }
  1928. done:
  1929. LT_DLMUTEX_UNLOCK ();
  1930. return errors;
  1931. }
  1932. static int
  1933. tryall_dlopen (handle, filename, useloader)
  1934. lt_dlhandle *handle;
  1935. const char *filename;
  1936. const char *useloader;
  1937. {
  1938. lt_dlhandle cur;
  1939. lt_dlloader *loader;
  1940. const char *saved_error;
  1941. int errors = 0;
  1942. LT_DLMUTEX_GETERROR (saved_error);
  1943. LT_DLMUTEX_LOCK ();
  1944. cur = handles;
  1945. loader = loaders;
  1946. /* check whether the module was already opened */
  1947. while (cur)
  1948. {
  1949. /* try to dlopen the program itself? */
  1950. if (!cur->info.filename && !filename)
  1951. {
  1952. break;
  1953. }
  1954. if (cur->info.filename && filename
  1955. && strcmp (cur->info.filename, filename) == 0)
  1956. {
  1957. break;
  1958. }
  1959. cur = cur->next;
  1960. }
  1961. if (cur)
  1962. {
  1963. ++cur->info.ref_count;
  1964. *handle = cur;
  1965. goto done;
  1966. }
  1967. cur = *handle;
  1968. if (filename)
  1969. {
  1970. /* Comment out the check of file permissions using access.
  1971. This call seems to always return -1 with error EACCES.
  1972. */
  1973. /* We need to catch missing file errors early so that
  1974. file_not_found() can detect what happened.
  1975. if (access (filename, R_OK) != 0)
  1976. {
  1977. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
  1978. ++errors;
  1979. goto done;
  1980. } */
  1981. cur->info.filename = lt_estrdup (filename);
  1982. if (!cur->info.filename)
  1983. {
  1984. ++errors;
  1985. goto done;
  1986. }
  1987. }
  1988. else
  1989. {
  1990. cur->info.filename = 0;
  1991. }
  1992. while (loader)
  1993. {
  1994. if (useloader && strcmp(loader->loader_name, useloader))
  1995. {
  1996. loader = loader->next;
  1997. continue;
  1998. }
  1999. lt_user_data data = loader->dlloader_data;
  2000. cur->module = loader->module_open (data, filename);
  2001. if (cur->module != 0)
  2002. {
  2003. break;
  2004. }
  2005. loader = loader->next;
  2006. }
  2007. if (!loader)
  2008. {
  2009. LT_DLFREE (cur->info.filename);
  2010. ++errors;
  2011. goto done;
  2012. }
  2013. cur->loader = loader;
  2014. LT_DLMUTEX_SETERROR (saved_error);
  2015. done:
  2016. LT_DLMUTEX_UNLOCK ();
  2017. return errors;
  2018. }
  2019. static int
  2020. tryall_dlopen_module (handle, prefix, dirname, dlname)
  2021. lt_dlhandle *handle;
  2022. const char *prefix;
  2023. const char *dirname;
  2024. const char *dlname;
  2025. {
  2026. int error = 0;
  2027. char *filename = 0;
  2028. size_t filename_len = 0;
  2029. size_t dirname_len = LT_STRLEN (dirname);
  2030. assert (handle);
  2031. assert (dirname);
  2032. assert (dlname);
  2033. #ifdef LT_DIRSEP_CHAR
  2034. /* Only canonicalized names (i.e. with DIRSEP chars already converted)
  2035. should make it into this function: */
  2036. assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
  2037. #endif
  2038. if (dirname_len > 0)
  2039. if (dirname[dirname_len -1] == '/')
  2040. --dirname_len;
  2041. filename_len = dirname_len + 1 + LT_STRLEN (dlname);
  2042. /* Allocate memory, and combine DIRNAME and MODULENAME into it.
  2043. The PREFIX (if any) is handled below. */
  2044. filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
  2045. if (!filename)
  2046. return 1;
  2047. sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
  2048. /* Now that we have combined DIRNAME and MODULENAME, if there is
  2049. also a PREFIX to contend with, simply recurse with the arguments
  2050. shuffled. Otherwise, attempt to open FILENAME as a module. */
  2051. if (prefix)
  2052. {
  2053. error += tryall_dlopen_module (handle,
  2054. (const char *) 0, prefix, filename);
  2055. }
  2056. else if (tryall_dlopen (handle, filename, NULL) != 0)
  2057. {
  2058. ++error;
  2059. }
  2060. LT_DLFREE (filename);
  2061. return error;
  2062. }
  2063. static int
  2064. find_module (handle, dir, libdir, dlname, old_name, installed)
  2065. lt_dlhandle *handle;
  2066. const char *dir;
  2067. const char *libdir;
  2068. const char *dlname;
  2069. const char *old_name;
  2070. int installed;
  2071. {
  2072. /* Try to open the old library first; if it was dlpreopened,
  2073. we want the preopened version of it, even if a dlopenable
  2074. module is available. */
  2075. if (old_name && tryall_dlopen (handle, old_name, "dlpreload") == 0)
  2076. {
  2077. return 0;
  2078. }
  2079. /* Try to open the dynamic library. */
  2080. if (dlname)
  2081. {
  2082. /* try to open the installed module */
  2083. if (installed && libdir)
  2084. {
  2085. if (tryall_dlopen_module (handle,
  2086. (const char *) 0, libdir, dlname) == 0)
  2087. return 0;
  2088. }
  2089. /* try to open the not-installed module */
  2090. if (!installed)
  2091. {
  2092. if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
  2093. return 0;
  2094. }
  2095. /* maybe it was moved to another directory */
  2096. {
  2097. if (tryall_dlopen_module (handle,
  2098. (const char *) 0, dir, dlname) == 0)
  2099. return 0;
  2100. }
  2101. }
  2102. return 1;
  2103. }
  2104. static int
  2105. canonicalize_path (path, pcanonical)
  2106. const char *path;
  2107. char **pcanonical;
  2108. {
  2109. char *canonical = 0;
  2110. assert (path && *path);
  2111. assert (pcanonical);
  2112. canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
  2113. if (!canonical)
  2114. return 1;
  2115. {
  2116. size_t dest = 0;
  2117. size_t src;
  2118. for (src = 0; path[src] != LT_EOS_CHAR; ++src)
  2119. {
  2120. /* Path separators are not copied to the beginning or end of
  2121. the destination, or if another separator would follow
  2122. immediately. */
  2123. if (path[src] == LT_PATHSEP_CHAR)
  2124. {
  2125. if ((dest == 0)
  2126. || (path[1+ src] == LT_PATHSEP_CHAR)
  2127. || (path[1+ src] == LT_EOS_CHAR))
  2128. continue;
  2129. }
  2130. /* Anything other than a directory separator is copied verbatim. */
  2131. if ((path[src] != '/')
  2132. #ifdef LT_DIRSEP_CHAR
  2133. && (path[src] != LT_DIRSEP_CHAR)
  2134. #endif
  2135. )
  2136. {
  2137. canonical[dest++] = path[src];
  2138. }
  2139. /* Directory separators are converted and copied only if they are
  2140. not at the end of a path -- i.e. before a path separator or
  2141. NULL terminator. */
  2142. else if ((path[1+ src] != LT_PATHSEP_CHAR)
  2143. && (path[1+ src] != LT_EOS_CHAR)
  2144. #ifdef LT_DIRSEP_CHAR
  2145. && (path[1+ src] != LT_DIRSEP_CHAR)
  2146. #endif
  2147. && (path[1+ src] != '/'))
  2148. {
  2149. canonical[dest++] = '/';
  2150. }
  2151. }
  2152. /* Add an end-of-string marker at the end. */
  2153. canonical[dest] = LT_EOS_CHAR;
  2154. }
  2155. /* Assign new value. */
  2156. *pcanonical = canonical;
  2157. return 0;
  2158. }
  2159. static int
  2160. argzize_path (path, pargz, pargz_len)
  2161. const char *path;
  2162. char **pargz;
  2163. size_t *pargz_len;
  2164. {
  2165. error_t error;
  2166. assert (path);
  2167. assert (pargz);
  2168. assert (pargz_len);
  2169. if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
  2170. {
  2171. switch (error)
  2172. {
  2173. case ENOMEM:
  2174. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
  2175. break;
  2176. default:
  2177. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
  2178. break;
  2179. }
  2180. return 1;
  2181. }
  2182. return 0;
  2183. }
  2184. /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
  2185. of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
  2186. non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
  2187. it is appended to each SEARCH_PATH element before FUNC is called. */
  2188. static int
  2189. foreach_dirinpath (search_path, base_name, func, data1, data2)
  2190. const char *search_path;
  2191. const char *base_name;
  2192. foreach_callback_func *func;
  2193. lt_ptr data1;
  2194. lt_ptr data2;
  2195. {
  2196. int result = 0;
  2197. int filenamesize = 0;
  2198. size_t lenbase = LT_STRLEN (base_name);
  2199. size_t argz_len = 0;
  2200. char *argz = 0;
  2201. char *filename = 0;
  2202. char *canonical = 0;
  2203. LT_DLMUTEX_LOCK ();
  2204. if (!search_path || !*search_path)
  2205. {
  2206. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
  2207. goto cleanup;
  2208. }
  2209. if (canonicalize_path (search_path, &canonical) != 0)
  2210. goto cleanup;
  2211. if (argzize_path (canonical, &argz, &argz_len) != 0)
  2212. goto cleanup;
  2213. {
  2214. char *dir_name = 0;
  2215. while ((dir_name = argz_next (argz, argz_len, dir_name)))
  2216. {
  2217. size_t lendir = LT_STRLEN (dir_name);
  2218. if (lendir +1 +lenbase >= filenamesize)
  2219. {
  2220. LT_DLFREE (filename);
  2221. filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
  2222. filename = LT_EMALLOC (char, filenamesize);
  2223. if (!filename)
  2224. goto cleanup;
  2225. }
  2226. assert (filenamesize > lendir);
  2227. strcpy (filename, dir_name);
  2228. if (base_name && *base_name)
  2229. {
  2230. if (filename[lendir -1] != '/')
  2231. filename[lendir++] = '/';
  2232. strcpy (filename +lendir, base_name);
  2233. }
  2234. if ((result = (*func) (filename, data1, data2)))
  2235. {
  2236. break;
  2237. }
  2238. }
  2239. }
  2240. cleanup:
  2241. LT_DLFREE (argz);
  2242. LT_DLFREE (canonical);
  2243. LT_DLFREE (filename);
  2244. LT_DLMUTEX_UNLOCK ();
  2245. return result;
  2246. }
  2247. /* If FILEPATH can be opened, store the name of the directory component
  2248. in DATA1, and the opened FILE* structure address in DATA2. Otherwise
  2249. DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
  2250. static int
  2251. find_file_callback (filename, data1, data2)
  2252. char *filename;
  2253. lt_ptr data1;
  2254. lt_ptr data2;
  2255. {
  2256. char **pdir = (char **) data1;
  2257. FILE **pfile = (FILE **) data2;
  2258. int is_done = 0;
  2259. assert (filename && *filename);
  2260. assert (pdir);
  2261. assert (pfile);
  2262. if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
  2263. {
  2264. char *dirend = strrchr (filename, '/');
  2265. if (dirend > filename)
  2266. *dirend = LT_EOS_CHAR;
  2267. LT_DLFREE (*pdir);
  2268. *pdir = lt_estrdup (filename);
  2269. is_done = (*pdir == 0) ? -1 : 1;
  2270. }
  2271. return is_done;
  2272. }
  2273. static FILE *
  2274. find_file (search_path, base_name, pdir)
  2275. const char *search_path;
  2276. const char *base_name;
  2277. char **pdir;
  2278. {
  2279. FILE *file = 0;
  2280. foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
  2281. return file;
  2282. }
  2283. static int
  2284. find_handle_callback (filename, data, ignored)
  2285. char *filename;
  2286. lt_ptr data;
  2287. lt_ptr ignored;
  2288. {
  2289. lt_dlhandle *handle = (lt_dlhandle *) data;
  2290. int notfound = access (filename, R_OK);
  2291. /* Bail out if file cannot be read... */
  2292. if (notfound)
  2293. return 0;
  2294. /* Try to dlopen the file, but do not continue searching in any
  2295. case. */
  2296. if (tryall_dlopen (handle, filename,NULL) != 0)
  2297. *handle = 0;
  2298. return 1;
  2299. }
  2300. /* If HANDLE was found return it, otherwise return 0. If HANDLE was
  2301. found but could not be opened, *HANDLE will be set to 0. */
  2302. static lt_dlhandle *
  2303. find_handle (search_path, base_name, handle)
  2304. const char *search_path;
  2305. const char *base_name;
  2306. lt_dlhandle *handle;
  2307. {
  2308. if (!search_path)
  2309. return 0;
  2310. if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
  2311. handle, 0))
  2312. return 0;
  2313. return handle;
  2314. }
  2315. static int
  2316. load_deplibs (handle, deplibs)
  2317. lt_dlhandle handle;
  2318. char *deplibs;
  2319. {
  2320. #if LTDL_DLOPEN_DEPLIBS
  2321. char *p, *save_search_path = 0;
  2322. int depcount = 0;
  2323. int i;
  2324. char **names = 0;
  2325. #endif
  2326. int errors = 0;
  2327. handle->depcount = 0;
  2328. #if LTDL_DLOPEN_DEPLIBS
  2329. if (!deplibs)
  2330. {
  2331. return errors;
  2332. }
  2333. ++errors;
  2334. LT_DLMUTEX_LOCK ();
  2335. if (user_search_path)
  2336. {
  2337. save_search_path = lt_estrdup (user_search_path);
  2338. if (!save_search_path)
  2339. goto cleanup;
  2340. }
  2341. /* extract search paths and count deplibs */
  2342. p = deplibs;
  2343. while (*p)
  2344. {
  2345. if (!isspace ((int) *p))
  2346. {
  2347. char *end = p+1;
  2348. while (*end && !isspace((int) *end))
  2349. {
  2350. ++end;
  2351. }
  2352. if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
  2353. {
  2354. char save = *end;
  2355. *end = 0; /* set a temporary string terminator */
  2356. if (lt_dladdsearchdir(p+2))
  2357. {
  2358. goto cleanup;
  2359. }
  2360. *end = save;
  2361. }
  2362. else
  2363. {
  2364. ++depcount;
  2365. }
  2366. p = end;
  2367. }
  2368. else
  2369. {
  2370. ++p;
  2371. }
  2372. }
  2373. /* restore the old search path */
  2374. LT_DLFREE (user_search_path);
  2375. user_search_path = save_search_path;
  2376. LT_DLMUTEX_UNLOCK ();
  2377. if (!depcount)
  2378. {
  2379. errors = 0;
  2380. goto cleanup;
  2381. }
  2382. names = LT_EMALLOC (char *, depcount * sizeof (char*));
  2383. if (!names)
  2384. goto cleanup;
  2385. /* now only extract the actual deplibs */
  2386. depcount = 0;
  2387. p = deplibs;
  2388. while (*p)
  2389. {
  2390. if (isspace ((int) *p))
  2391. {
  2392. ++p;
  2393. }
  2394. else
  2395. {
  2396. char *end = p+1;
  2397. while (*end && !isspace ((int) *end))
  2398. {
  2399. ++end;
  2400. }
  2401. if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
  2402. {
  2403. char *name;
  2404. char save = *end;
  2405. *end = 0; /* set a temporary string terminator */
  2406. if (strncmp(p, "-l", 2) == 0)
  2407. {
  2408. size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
  2409. name = LT_EMALLOC (char, 1+ name_len);
  2410. if (name)
  2411. sprintf (name, "lib%s", p+2);
  2412. }
  2413. else
  2414. name = lt_estrdup(p);
  2415. if (!name)
  2416. goto cleanup_names;
  2417. names[depcount++] = name;
  2418. *end = save;
  2419. }
  2420. p = end;
  2421. }
  2422. }
  2423. /* load the deplibs (in reverse order)
  2424. At this stage, don't worry if the deplibs do not load correctly,
  2425. they may already be statically linked into the loading application
  2426. for instance. There will be a more enlightening error message
  2427. later on if the loaded module cannot resolve all of its symbols. */
  2428. if (depcount)
  2429. {
  2430. int j = 0;
  2431. handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
  2432. if (!handle->deplibs)
  2433. goto cleanup;
  2434. for (i = 0; i < depcount; ++i)
  2435. {
  2436. handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
  2437. if (handle->deplibs[j])
  2438. {
  2439. ++j;
  2440. }
  2441. }
  2442. handle->depcount = j; /* Number of successfully loaded deplibs */
  2443. errors = 0;
  2444. }
  2445. cleanup_names:
  2446. for (i = 0; i < depcount; ++i)
  2447. {
  2448. LT_DLFREE (names[i]);
  2449. }
  2450. cleanup:
  2451. LT_DLFREE (names);
  2452. #endif
  2453. return errors;
  2454. }
  2455. static int
  2456. unload_deplibs (handle)
  2457. lt_dlhandle handle;
  2458. {
  2459. int i;
  2460. int errors = 0;
  2461. if (handle->depcount)
  2462. {
  2463. for (i = 0; i < handle->depcount; ++i)
  2464. {
  2465. if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
  2466. {
  2467. errors += lt_dlclose (handle->deplibs[i]);
  2468. }
  2469. }
  2470. }
  2471. return errors;
  2472. }
  2473. static int
  2474. trim (dest, str)
  2475. char **dest;
  2476. const char *str;
  2477. {
  2478. /* remove the leading and trailing "'" from str
  2479. and store the result in dest */
  2480. const char *end = strrchr (str, '\'');
  2481. size_t len = LT_STRLEN (str);
  2482. char *tmp;
  2483. LT_DLFREE (*dest);
  2484. if (!end)
  2485. return 1;
  2486. if (len > 3 && str[0] == '\'')
  2487. {
  2488. tmp = LT_EMALLOC (char, end - str);
  2489. if (!tmp)
  2490. return 1;
  2491. strncpy(tmp, &str[1], (end - str) - 1);
  2492. tmp[len-3] = LT_EOS_CHAR;
  2493. *dest = tmp;
  2494. }
  2495. else
  2496. {
  2497. *dest = 0;
  2498. }
  2499. return 0;
  2500. }
  2501. static int
  2502. free_vars (dlname, oldname, libdir, deplibs)
  2503. char *dlname;
  2504. char *oldname;
  2505. char *libdir;
  2506. char *deplibs;
  2507. {
  2508. LT_DLFREE (dlname);
  2509. LT_DLFREE (oldname);
  2510. LT_DLFREE (libdir);
  2511. LT_DLFREE (deplibs);
  2512. return 0;
  2513. }
  2514. static int
  2515. try_dlopen (phandle, filename)
  2516. lt_dlhandle *phandle;
  2517. const char *filename;
  2518. {
  2519. const char * ext = 0;
  2520. const char * saved_error = 0;
  2521. char * canonical = 0;
  2522. char * base_name = 0;
  2523. char * dir = 0;
  2524. char * name = 0;
  2525. int errors = 0;
  2526. lt_dlhandle newhandle;
  2527. assert (phandle);
  2528. assert (*phandle == 0);
  2529. LT_DLMUTEX_GETERROR (saved_error);
  2530. /* dlopen self? */
  2531. if (!filename)
  2532. {
  2533. *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
  2534. if (*phandle == 0)
  2535. return 1;
  2536. memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
  2537. newhandle = *phandle;
  2538. /* lt_dlclose()ing yourself is very bad! Disallow it. */
  2539. LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
  2540. if (tryall_dlopen (&newhandle, 0, NULL) != 0)
  2541. {
  2542. LT_DLFREE (*phandle);
  2543. return 1;
  2544. }
  2545. goto register_handle;
  2546. }
  2547. assert (filename && *filename);
  2548. /* Doing this immediately allows internal functions to safely
  2549. assume only canonicalized paths are passed. */
  2550. if (canonicalize_path (filename, &canonical) != 0)
  2551. {
  2552. ++errors;
  2553. goto cleanup;
  2554. }
  2555. /* If the canonical module name is a path (relative or absolute)
  2556. then split it into a directory part and a name part. */
  2557. base_name = strrchr (canonical, '/');
  2558. if (base_name)
  2559. {
  2560. size_t dirlen = (1+ base_name) - canonical;
  2561. dir = LT_EMALLOC (char, 1+ dirlen);
  2562. if (!dir)
  2563. {
  2564. ++errors;
  2565. goto cleanup;
  2566. }
  2567. strncpy (dir, canonical, dirlen);
  2568. dir[dirlen] = LT_EOS_CHAR;
  2569. ++base_name;
  2570. }
  2571. else
  2572. base_name = canonical;
  2573. assert (base_name && *base_name);
  2574. /* Check whether we are opening a libtool module (.la extension). */
  2575. ext = strrchr (base_name, '.');
  2576. if (ext && strcmp (ext, archive_ext) == 0)
  2577. {
  2578. /* this seems to be a libtool module */
  2579. FILE * file = 0;
  2580. char * dlname = 0;
  2581. char * old_name = 0;
  2582. char * libdir = 0;
  2583. char * deplibs = 0;
  2584. char * line = 0;
  2585. size_t line_len;
  2586. /* if we can't find the installed flag, it is probably an
  2587. installed libtool archive, produced with an old version
  2588. of libtool */
  2589. int installed = 1;
  2590. /* extract the module name from the file name */
  2591. name = LT_EMALLOC (char, ext - base_name + 1);
  2592. if (!name)
  2593. {
  2594. ++errors;
  2595. goto cleanup;
  2596. }
  2597. /* canonicalize the module name */
  2598. {
  2599. size_t i;
  2600. for (i = 0; i < ext - base_name; ++i)
  2601. {
  2602. if (isalnum ((int)(base_name[i])))
  2603. {
  2604. name[i] = base_name[i];
  2605. }
  2606. else
  2607. {
  2608. name[i] = '_';
  2609. }
  2610. }
  2611. name[ext - base_name] = LT_EOS_CHAR;
  2612. }
  2613. /* Now try to open the .la file. If there is no directory name
  2614. component, try to find it first in user_search_path and then other
  2615. prescribed paths. Otherwise (or in any case if the module was not
  2616. yet found) try opening just the module name as passed. */
  2617. if (!dir)
  2618. {
  2619. const char *search_path;
  2620. LT_DLMUTEX_LOCK ();
  2621. search_path = user_search_path;
  2622. if (search_path)
  2623. file = find_file (user_search_path, base_name, &dir);
  2624. LT_DLMUTEX_UNLOCK ();
  2625. if (!file)
  2626. {
  2627. search_path = getenv (LTDL_SEARCHPATH_VAR);
  2628. if (search_path)
  2629. file = find_file (search_path, base_name, &dir);
  2630. }
  2631. #ifdef LTDL_SHLIBPATH_VAR
  2632. if (!file)
  2633. {
  2634. search_path = getenv (LTDL_SHLIBPATH_VAR);
  2635. if (search_path)
  2636. file = find_file (search_path, base_name, &dir);
  2637. }
  2638. #endif
  2639. #ifdef LTDL_SYSSEARCHPATH
  2640. if (!file && sys_search_path)
  2641. {
  2642. file = find_file (sys_search_path, base_name, &dir);
  2643. }
  2644. #endif
  2645. }
  2646. else
  2647. {
  2648. file = fopen (filename, LT_READTEXT_MODE);
  2649. }
  2650. /* If we didn't find the file by now, it really isn't there. Set
  2651. the status flag, and bail out. */
  2652. if (!file)
  2653. {
  2654. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
  2655. ++errors;
  2656. goto cleanup;
  2657. }
  2658. line_len = LT_FILENAME_MAX;
  2659. line = LT_EMALLOC (char, line_len);
  2660. if (!line)
  2661. {
  2662. fclose (file);
  2663. ++errors;
  2664. goto cleanup;
  2665. }
  2666. /* read the .la file */
  2667. while (!feof (file))
  2668. {
  2669. if (!fgets (line, (int) line_len, file))
  2670. {
  2671. break;
  2672. }
  2673. /* Handle the case where we occasionally need to read a line
  2674. that is longer than the initial buffer size. */
  2675. while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
  2676. {
  2677. line = LT_DLREALLOC (char, line, line_len *2);
  2678. if (!fgets (&line[line_len -1], (int) line_len +1, file))
  2679. {
  2680. break;
  2681. }
  2682. line_len *= 2;
  2683. }
  2684. if (line[0] == '\n' || line[0] == '#')
  2685. {
  2686. continue;
  2687. }
  2688. #undef STR_DLNAME
  2689. #define STR_DLNAME "dlname="
  2690. if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
  2691. {
  2692. errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
  2693. }
  2694. #undef STR_OLD_LIBRARY
  2695. #define STR_OLD_LIBRARY "old_library="
  2696. else if (strncmp (line, STR_OLD_LIBRARY,
  2697. sizeof (STR_OLD_LIBRARY) - 1) == 0)
  2698. {
  2699. errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
  2700. }
  2701. #undef STR_LIBDIR
  2702. #define STR_LIBDIR "libdir="
  2703. else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
  2704. {
  2705. errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
  2706. }
  2707. #undef STR_DL_DEPLIBS
  2708. #define STR_DL_DEPLIBS "dependency_libs="
  2709. else if (strncmp (line, STR_DL_DEPLIBS,
  2710. sizeof (STR_DL_DEPLIBS) - 1) == 0)
  2711. {
  2712. errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
  2713. }
  2714. else if (strcmp (line, "installed=yes\n") == 0)
  2715. {
  2716. installed = 1;
  2717. }
  2718. else if (strcmp (line, "installed=no\n") == 0)
  2719. {
  2720. installed = 0;
  2721. }
  2722. #undef STR_LIBRARY_NAMES
  2723. #define STR_LIBRARY_NAMES "library_names="
  2724. else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
  2725. sizeof (STR_LIBRARY_NAMES) - 1) == 0)
  2726. {
  2727. char *last_libname;
  2728. errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
  2729. if (!errors
  2730. && dlname
  2731. && (last_libname = strrchr (dlname, ' ')) != 0)
  2732. {
  2733. last_libname = lt_estrdup (last_libname + 1);
  2734. if (!last_libname)
  2735. {
  2736. ++errors;
  2737. goto cleanup;
  2738. }
  2739. LT_DLMEM_REASSIGN (dlname, last_libname);
  2740. }
  2741. }
  2742. if (errors)
  2743. break;
  2744. }
  2745. fclose (file);
  2746. LT_DLFREE (line);
  2747. /* allocate the handle */
  2748. *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
  2749. if (*phandle == 0)
  2750. ++errors;
  2751. if (errors)
  2752. {
  2753. free_vars (dlname, old_name, libdir, deplibs);
  2754. LT_DLFREE (*phandle);
  2755. goto cleanup;
  2756. }
  2757. assert (*phandle);
  2758. memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
  2759. if (load_deplibs (*phandle, deplibs) == 0)
  2760. {
  2761. newhandle = *phandle;
  2762. /* find_module may replace newhandle */
  2763. if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
  2764. {
  2765. unload_deplibs (*phandle);
  2766. ++errors;
  2767. }
  2768. }
  2769. else
  2770. {
  2771. ++errors;
  2772. }
  2773. free_vars (dlname, old_name, libdir, deplibs);
  2774. if (errors)
  2775. {
  2776. LT_DLFREE (*phandle);
  2777. goto cleanup;
  2778. }
  2779. if (*phandle != newhandle)
  2780. {
  2781. unload_deplibs (*phandle);
  2782. }
  2783. }
  2784. else
  2785. {
  2786. /* not a libtool module */
  2787. *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
  2788. if (*phandle == 0)
  2789. {
  2790. ++errors;
  2791. goto cleanup;
  2792. }
  2793. memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
  2794. newhandle = *phandle;
  2795. /* If the module has no directory name component, try to find it
  2796. first in user_search_path and then other prescribed paths.
  2797. Otherwise (or in any case if the module was not yet found) try
  2798. opening just the module name as passed. */
  2799. if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
  2800. && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
  2801. &newhandle)
  2802. #ifdef LTDL_SHLIBPATH_VAR
  2803. && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
  2804. &newhandle)
  2805. #endif
  2806. #ifdef LTDL_SYSSEARCHPATH
  2807. && !find_handle (sys_search_path, base_name, &newhandle)
  2808. #endif
  2809. )))
  2810. {
  2811. if (tryall_dlopen (&newhandle, filename, NULL) != 0)
  2812. {
  2813. newhandle = NULL;
  2814. }
  2815. }
  2816. if (!newhandle)
  2817. {
  2818. LT_DLFREE (*phandle);
  2819. ++errors;
  2820. goto cleanup;
  2821. }
  2822. }
  2823. register_handle:
  2824. LT_DLMEM_REASSIGN (*phandle, newhandle);
  2825. if ((*phandle)->info.ref_count == 0)
  2826. {
  2827. (*phandle)->info.ref_count = 1;
  2828. LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
  2829. LT_DLMUTEX_LOCK ();
  2830. (*phandle)->next = handles;
  2831. handles = *phandle;
  2832. LT_DLMUTEX_UNLOCK ();
  2833. }
  2834. LT_DLMUTEX_SETERROR (saved_error);
  2835. cleanup:
  2836. LT_DLFREE (dir);
  2837. LT_DLFREE (name);
  2838. LT_DLFREE (canonical);
  2839. return errors;
  2840. }
  2841. lt_dlhandle
  2842. lt_dlopen (filename)
  2843. const char *filename;
  2844. {
  2845. lt_dlhandle handle = 0;
  2846. /* Just incase we missed a code path in try_dlopen() that reports
  2847. an error, but forgets to reset handle... */
  2848. if (try_dlopen (&handle, filename) != 0)
  2849. return 0;
  2850. return handle;
  2851. }
  2852. /* If the last error messge store was `FILE_NOT_FOUND', then return
  2853. non-zero. */
  2854. static int
  2855. file_not_found ()
  2856. {
  2857. const char *error = 0;
  2858. LT_DLMUTEX_GETERROR (error);
  2859. if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
  2860. return 1;
  2861. return 0;
  2862. }
  2863. /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
  2864. open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
  2865. and if a file is still not found try again with SHLIB_EXT appended
  2866. instead. */
  2867. lt_dlhandle
  2868. lt_dlopenext (filename)
  2869. const char *filename;
  2870. {
  2871. lt_dlhandle handle = 0;
  2872. char * tmp = 0;
  2873. char * ext = 0;
  2874. size_t len;
  2875. int errors = 0;
  2876. if (!filename)
  2877. {
  2878. return lt_dlopen (filename);
  2879. }
  2880. assert (filename);
  2881. len = LT_STRLEN (filename);
  2882. ext = strrchr (filename, '.');
  2883. /* If FILENAME already bears a suitable extension, there is no need
  2884. to try appending additional extensions. */
  2885. if (ext && ((strcmp (ext, archive_ext) == 0)
  2886. #ifdef LTDL_SHLIB_EXT
  2887. || (strcmp (ext, shlib_ext) == 0)
  2888. #endif
  2889. ))
  2890. {
  2891. return lt_dlopen (filename);
  2892. }
  2893. /* First try appending ARCHIVE_EXT. */
  2894. tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
  2895. if (!tmp)
  2896. return 0;
  2897. strcpy (tmp, filename);
  2898. strcat (tmp, archive_ext);
  2899. errors = try_dlopen (&handle, tmp);
  2900. /* If we found FILENAME, stop searching -- whether we were able to
  2901. load the file as a module or not. If the file exists but loading
  2902. failed, it is better to return an error message here than to
  2903. report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
  2904. in the module search path. */
  2905. if (handle || ((errors > 0) && !file_not_found ()))
  2906. {
  2907. LT_DLFREE (tmp);
  2908. return handle;
  2909. }
  2910. #ifdef LTDL_SHLIB_EXT
  2911. /* Try appending SHLIB_EXT. */
  2912. if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
  2913. {
  2914. LT_DLFREE (tmp);
  2915. tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
  2916. if (!tmp)
  2917. return 0;
  2918. strcpy (tmp, filename);
  2919. }
  2920. else
  2921. {
  2922. tmp[len] = LT_EOS_CHAR;
  2923. }
  2924. strcat(tmp, shlib_ext);
  2925. errors = try_dlopen (&handle, tmp);
  2926. /* As before, if the file was found but loading failed, return now
  2927. with the current error message. */
  2928. if (handle || ((errors > 0) && !file_not_found ()))
  2929. {
  2930. LT_DLFREE (tmp);
  2931. return handle;
  2932. }
  2933. #endif
  2934. /* Still here? Then we really did fail to locate any of the file
  2935. names we tried. */
  2936. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
  2937. LT_DLFREE (tmp);
  2938. return 0;
  2939. }
  2940. static int
  2941. lt_argz_insert (pargz, pargz_len, before, entry)
  2942. char **pargz;
  2943. size_t *pargz_len;
  2944. char *before;
  2945. const char *entry;
  2946. {
  2947. error_t error;
  2948. if ((error = argz_insert (pargz, pargz_len, before, entry)))
  2949. {
  2950. switch (error)
  2951. {
  2952. case ENOMEM:
  2953. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
  2954. break;
  2955. default:
  2956. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
  2957. break;
  2958. }
  2959. return 1;
  2960. }
  2961. return 0;
  2962. }
  2963. static int
  2964. lt_argz_insertinorder (pargz, pargz_len, entry)
  2965. char **pargz;
  2966. size_t *pargz_len;
  2967. const char *entry;
  2968. {
  2969. char *before = 0;
  2970. assert (pargz);
  2971. assert (pargz_len);
  2972. assert (entry && *entry);
  2973. if (*pargz)
  2974. while ((before = argz_next (*pargz, *pargz_len, before)))
  2975. {
  2976. int cmp = strcmp (entry, before);
  2977. if (cmp < 0) break;
  2978. if (cmp == 0) return 0; /* No duplicates! */
  2979. }
  2980. return lt_argz_insert (pargz, pargz_len, before, entry);
  2981. }
  2982. static int
  2983. lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
  2984. char **pargz;
  2985. size_t *pargz_len;
  2986. const char *dirnam;
  2987. struct dirent *dp;
  2988. {
  2989. char *buf = 0;
  2990. size_t buf_len = 0;
  2991. char *end = 0;
  2992. size_t end_offset = 0;
  2993. size_t dir_len = 0;
  2994. int errors = 0;
  2995. assert (pargz);
  2996. assert (pargz_len);
  2997. assert (dp);
  2998. dir_len = LT_STRLEN (dirnam);
  2999. end = dp->d_name + LT_D_NAMLEN(dp);
  3000. /* Ignore version numbers. */
  3001. {
  3002. char *p;
  3003. for (p = end; p -1 > dp->d_name; --p)
  3004. if (strchr (".0123456789", p[-1]) == 0)
  3005. break;
  3006. if (*p == '.')
  3007. end = p;
  3008. }
  3009. /* Ignore filename extension. */
  3010. {
  3011. char *p;
  3012. for (p = end -1; p > dp->d_name; --p)
  3013. if (*p == '.')
  3014. {
  3015. end = p;
  3016. break;
  3017. }
  3018. }
  3019. /* Prepend the directory name. */
  3020. end_offset = end - dp->d_name;
  3021. buf_len = dir_len + 1+ end_offset;
  3022. buf = LT_EMALLOC (char, 1+ buf_len);
  3023. if (!buf)
  3024. return ++errors;
  3025. assert (buf);
  3026. strcpy (buf, dirnam);
  3027. strcat (buf, "/");
  3028. strncat (buf, dp->d_name, end_offset);
  3029. buf[buf_len] = LT_EOS_CHAR;
  3030. /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
  3031. if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
  3032. ++errors;
  3033. LT_DLFREE (buf);
  3034. return errors;
  3035. }
  3036. static int
  3037. list_files_by_dir (dirnam, pargz, pargz_len)
  3038. const char *dirnam;
  3039. char **pargz;
  3040. size_t *pargz_len;
  3041. {
  3042. DIR *dirp = 0;
  3043. int errors = 0;
  3044. assert (dirnam && *dirnam);
  3045. assert (pargz);
  3046. assert (pargz_len);
  3047. assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
  3048. dirp = opendir (dirnam);
  3049. if (dirp)
  3050. {
  3051. struct dirent *dp = 0;
  3052. while ((dp = readdir (dirp)))
  3053. if (dp->d_name[0] != '.')
  3054. if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
  3055. {
  3056. ++errors;
  3057. break;
  3058. }
  3059. closedir (dirp);
  3060. }
  3061. else
  3062. ++errors;
  3063. return errors;
  3064. }
  3065. /* If there are any files in DIRNAME, call the function passed in
  3066. DATA1 (with the name of each file and DATA2 as arguments). */
  3067. static int
  3068. foreachfile_callback (dirname, data1, data2)
  3069. char *dirname;
  3070. lt_ptr data1;
  3071. lt_ptr data2;
  3072. {
  3073. int (*func) LT_PARAMS((const char *filename, lt_ptr data))
  3074. = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
  3075. int is_done = 0;
  3076. char *argz = 0;
  3077. size_t argz_len = 0;
  3078. if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
  3079. goto cleanup;
  3080. if (!argz)
  3081. goto cleanup;
  3082. {
  3083. char *filename = 0;
  3084. while ((filename = argz_next (argz, argz_len, filename)))
  3085. if ((is_done = (*func) (filename, data2)))
  3086. break;
  3087. }
  3088. cleanup:
  3089. LT_DLFREE (argz);
  3090. return is_done;
  3091. }
  3092. /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
  3093. with DATA. The filenames passed to FUNC would be suitable for
  3094. passing to lt_dlopenext. The extensions are stripped so that
  3095. individual modules do not generate several entries (e.g. libfoo.la,
  3096. libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
  3097. then the same directories that lt_dlopen would search are examined. */
  3098. int
  3099. lt_dlforeachfile (search_path, func, data)
  3100. const char *search_path;
  3101. int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
  3102. lt_ptr data;
  3103. {
  3104. int is_done = 0;
  3105. if (search_path)
  3106. {
  3107. /* If a specific path was passed, search only the directories
  3108. listed in it. */
  3109. is_done = foreach_dirinpath (search_path, 0,
  3110. foreachfile_callback, func, data);
  3111. }
  3112. else
  3113. {
  3114. /* Otherwise search the default paths. */
  3115. is_done = foreach_dirinpath (user_search_path, 0,
  3116. foreachfile_callback, func, data);
  3117. if (!is_done)
  3118. {
  3119. is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
  3120. foreachfile_callback, func, data);
  3121. }
  3122. #ifdef LTDL_SHLIBPATH_VAR
  3123. if (!is_done)
  3124. {
  3125. is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
  3126. foreachfile_callback, func, data);
  3127. }
  3128. #endif
  3129. #ifdef LTDL_SYSSEARCHPATH
  3130. if (!is_done)
  3131. {
  3132. is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
  3133. foreachfile_callback, func, data);
  3134. }
  3135. #endif
  3136. }
  3137. return is_done;
  3138. }
  3139. int
  3140. lt_dlclose (handle)
  3141. lt_dlhandle handle;
  3142. {
  3143. lt_dlhandle cur, last;
  3144. int errors = 0;
  3145. LT_DLMUTEX_LOCK ();
  3146. /* check whether the handle is valid */
  3147. last = cur = handles;
  3148. while (cur && handle != cur)
  3149. {
  3150. last = cur;
  3151. cur = cur->next;
  3152. }
  3153. if (!cur)
  3154. {
  3155. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  3156. ++errors;
  3157. goto done;
  3158. }
  3159. handle->info.ref_count--;
  3160. /* Note that even with resident modules, we must track the ref_count
  3161. correctly incase the user decides to reset the residency flag
  3162. later (even though the API makes no provision for that at the
  3163. moment). */
  3164. if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
  3165. {
  3166. lt_user_data data = handle->loader->dlloader_data;
  3167. if (handle != handles)
  3168. {
  3169. last->next = handle->next;
  3170. }
  3171. else
  3172. {
  3173. handles = handle->next;
  3174. }
  3175. errors += handle->loader->module_close (data, handle->module);
  3176. errors += unload_deplibs(handle);
  3177. /* It is up to the callers to free the data itself. */
  3178. LT_DLFREE (handle->caller_data);
  3179. LT_DLFREE (handle->info.filename);
  3180. LT_DLFREE (handle->info.name);
  3181. LT_DLFREE (handle);
  3182. goto done;
  3183. }
  3184. if (LT_DLIS_RESIDENT (handle))
  3185. {
  3186. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
  3187. ++errors;
  3188. }
  3189. done:
  3190. LT_DLMUTEX_UNLOCK ();
  3191. return errors;
  3192. }
  3193. lt_ptr
  3194. lt_dlsym (handle, symbol)
  3195. lt_dlhandle handle;
  3196. const char *symbol;
  3197. {
  3198. size_t lensym;
  3199. char lsym[LT_SYMBOL_LENGTH];
  3200. char *sym;
  3201. lt_ptr address;
  3202. lt_user_data data;
  3203. if (!handle)
  3204. {
  3205. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  3206. return 0;
  3207. }
  3208. if (!symbol)
  3209. {
  3210. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
  3211. return 0;
  3212. }
  3213. lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
  3214. + LT_STRLEN (handle->info.name);
  3215. if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
  3216. {
  3217. sym = lsym;
  3218. }
  3219. else
  3220. {
  3221. sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
  3222. if (!sym)
  3223. {
  3224. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
  3225. return 0;
  3226. }
  3227. }
  3228. data = handle->loader->dlloader_data;
  3229. if (handle->info.name)
  3230. {
  3231. const char *saved_error;
  3232. LT_DLMUTEX_GETERROR (saved_error);
  3233. /* this is a libtool module */
  3234. if (handle->loader->sym_prefix)
  3235. {
  3236. strcpy(sym, handle->loader->sym_prefix);
  3237. strcat(sym, handle->info.name);
  3238. }
  3239. else
  3240. {
  3241. strcpy(sym, handle->info.name);
  3242. }
  3243. strcat(sym, "_LTX_");
  3244. strcat(sym, symbol);
  3245. /* try "modulename_LTX_symbol" */
  3246. address = handle->loader->find_sym (data, handle->module, sym);
  3247. if (address)
  3248. {
  3249. if (sym != lsym)
  3250. {
  3251. LT_DLFREE (sym);
  3252. }
  3253. return address;
  3254. }
  3255. LT_DLMUTEX_SETERROR (saved_error);
  3256. }
  3257. /* otherwise try "symbol" */
  3258. if (handle->loader->sym_prefix)
  3259. {
  3260. strcpy(sym, handle->loader->sym_prefix);
  3261. strcat(sym, symbol);
  3262. }
  3263. else
  3264. {
  3265. strcpy(sym, symbol);
  3266. }
  3267. address = handle->loader->find_sym (data, handle->module, sym);
  3268. if (sym != lsym)
  3269. {
  3270. LT_DLFREE (sym);
  3271. }
  3272. return address;
  3273. }
  3274. const char *
  3275. lt_dlerror ()
  3276. {
  3277. const char *error;
  3278. LT_DLMUTEX_GETERROR (error);
  3279. LT_DLMUTEX_SETERROR (0);
  3280. return error ? error : NULL;
  3281. }
  3282. static int
  3283. lt_dlpath_insertdir (ppath, before, dir)
  3284. char **ppath;
  3285. char *before;
  3286. const char *dir;
  3287. {
  3288. int errors = 0;
  3289. char *canonical = 0;
  3290. char *argz = 0;
  3291. size_t argz_len = 0;
  3292. assert (ppath);
  3293. assert (dir && *dir);
  3294. if (canonicalize_path (dir, &canonical) != 0)
  3295. {
  3296. ++errors;
  3297. goto cleanup;
  3298. }
  3299. assert (canonical && *canonical);
  3300. /* If *PPATH is empty, set it to DIR. */
  3301. if (*ppath == 0)
  3302. {
  3303. assert (!before); /* BEFORE cannot be set without PPATH. */
  3304. assert (dir); /* Without DIR, don't call this function! */
  3305. *ppath = lt_estrdup (dir);
  3306. if (*ppath == 0)
  3307. ++errors;
  3308. return errors;
  3309. }
  3310. assert (ppath && *ppath);
  3311. if (argzize_path (*ppath, &argz, &argz_len) != 0)
  3312. {
  3313. ++errors;
  3314. goto cleanup;
  3315. }
  3316. /* Convert BEFORE into an equivalent offset into ARGZ. This only works
  3317. if *PPATH is already canonicalized, and hence does not change length
  3318. with respect to ARGZ. We canonicalize each entry as it is added to
  3319. the search path, and don't call this function with (uncanonicalized)
  3320. user paths, so this is a fair assumption. */
  3321. if (before)
  3322. {
  3323. assert (*ppath <= before);
  3324. assert (before - *ppath <= strlen (*ppath));
  3325. before = before - *ppath + argz;
  3326. }
  3327. if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
  3328. {
  3329. ++errors;
  3330. goto cleanup;
  3331. }
  3332. argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
  3333. LT_DLMEM_REASSIGN (*ppath, argz);
  3334. cleanup:
  3335. LT_DLFREE (canonical);
  3336. LT_DLFREE (argz);
  3337. return errors;
  3338. }
  3339. int
  3340. lt_dladdsearchdir (search_dir)
  3341. const char *search_dir;
  3342. {
  3343. int errors = 0;
  3344. if (search_dir && *search_dir)
  3345. {
  3346. LT_DLMUTEX_LOCK ();
  3347. if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
  3348. ++errors;
  3349. LT_DLMUTEX_UNLOCK ();
  3350. }
  3351. return errors;
  3352. }
  3353. int
  3354. lt_dlinsertsearchdir (before, search_dir)
  3355. const char *before;
  3356. const char *search_dir;
  3357. {
  3358. int errors = 0;
  3359. if (before)
  3360. {
  3361. LT_DLMUTEX_LOCK ();
  3362. if ((before < user_search_path)
  3363. || (before >= user_search_path + LT_STRLEN (user_search_path)))
  3364. {
  3365. LT_DLMUTEX_UNLOCK ();
  3366. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
  3367. return 1;
  3368. }
  3369. LT_DLMUTEX_UNLOCK ();
  3370. }
  3371. if (search_dir && *search_dir)
  3372. {
  3373. LT_DLMUTEX_LOCK ();
  3374. if (lt_dlpath_insertdir (&user_search_path,
  3375. (char *) before, search_dir) != 0)
  3376. {
  3377. ++errors;
  3378. }
  3379. LT_DLMUTEX_UNLOCK ();
  3380. }
  3381. return errors;
  3382. }
  3383. int
  3384. lt_dlsetsearchpath (search_path)
  3385. const char *search_path;
  3386. {
  3387. int errors = 0;
  3388. LT_DLMUTEX_LOCK ();
  3389. LT_DLFREE (user_search_path);
  3390. LT_DLMUTEX_UNLOCK ();
  3391. if (!search_path || !LT_STRLEN (search_path))
  3392. {
  3393. return errors;
  3394. }
  3395. LT_DLMUTEX_LOCK ();
  3396. if (canonicalize_path (search_path, &user_search_path) != 0)
  3397. ++errors;
  3398. LT_DLMUTEX_UNLOCK ();
  3399. return errors;
  3400. }
  3401. const char *
  3402. lt_dlgetsearchpath ()
  3403. {
  3404. const char *saved_path;
  3405. LT_DLMUTEX_LOCK ();
  3406. saved_path = user_search_path;
  3407. LT_DLMUTEX_UNLOCK ();
  3408. return saved_path;
  3409. }
  3410. int
  3411. lt_dlmakeresident (handle)
  3412. lt_dlhandle handle;
  3413. {
  3414. int errors = 0;
  3415. if (!handle)
  3416. {
  3417. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  3418. ++errors;
  3419. }
  3420. else
  3421. {
  3422. LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
  3423. }
  3424. return errors;
  3425. }
  3426. int
  3427. lt_dlisresident (handle)
  3428. lt_dlhandle handle;
  3429. {
  3430. if (!handle)
  3431. {
  3432. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  3433. return -1;
  3434. }
  3435. return LT_DLIS_RESIDENT (handle);
  3436. }
  3437. /* --- MODULE INFORMATION --- */
  3438. const lt_dlinfo *
  3439. lt_dlgetinfo (handle)
  3440. lt_dlhandle handle;
  3441. {
  3442. if (!handle)
  3443. {
  3444. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
  3445. return 0;
  3446. }
  3447. return &(handle->info);
  3448. }
  3449. lt_dlhandle
  3450. lt_dlhandle_next (place)
  3451. lt_dlhandle place;
  3452. {
  3453. return place ? place->next : handles;
  3454. }
  3455. int
  3456. lt_dlforeach (func, data)
  3457. int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
  3458. lt_ptr data;
  3459. {
  3460. int errors = 0;
  3461. lt_dlhandle cur;
  3462. LT_DLMUTEX_LOCK ();
  3463. cur = handles;
  3464. while (cur)
  3465. {
  3466. lt_dlhandle tmp = cur;
  3467. cur = cur->next;
  3468. if ((*func) (tmp, data))
  3469. {
  3470. ++errors;
  3471. break;
  3472. }
  3473. }
  3474. LT_DLMUTEX_UNLOCK ();
  3475. return errors;
  3476. }
  3477. lt_dlcaller_id
  3478. lt_dlcaller_register ()
  3479. {
  3480. static lt_dlcaller_id last_caller_id = 0;
  3481. int result;
  3482. LT_DLMUTEX_LOCK ();
  3483. result = ++last_caller_id;
  3484. LT_DLMUTEX_UNLOCK ();
  3485. return result;
  3486. }
  3487. lt_ptr
  3488. lt_dlcaller_set_data (key, handle, data)
  3489. lt_dlcaller_id key;
  3490. lt_dlhandle handle;
  3491. lt_ptr data;
  3492. {
  3493. int n_elements = 0;
  3494. lt_ptr stale = (lt_ptr) 0;
  3495. int i;
  3496. /* This needs to be locked so that the caller data can be updated
  3497. simultaneously by different threads. */
  3498. LT_DLMUTEX_LOCK ();
  3499. if (handle->caller_data)
  3500. while (handle->caller_data[n_elements].key)
  3501. ++n_elements;
  3502. for (i = 0; i < n_elements; ++i)
  3503. {
  3504. if (handle->caller_data[i].key == key)
  3505. {
  3506. stale = handle->caller_data[i].data;
  3507. break;
  3508. }
  3509. }
  3510. /* Ensure that there is enough room in this handle's caller_data
  3511. array to accept a new element (and an empty end marker). */
  3512. if (i == n_elements)
  3513. {
  3514. lt_caller_data *temp
  3515. = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
  3516. if (!temp)
  3517. {
  3518. stale = 0;
  3519. goto done;
  3520. }
  3521. handle->caller_data = temp;
  3522. /* We only need this if we needed to allocate a new caller_data. */
  3523. handle->caller_data[i].key = key;
  3524. handle->caller_data[1+ i].key = 0;
  3525. }
  3526. handle->caller_data[i].data = data;
  3527. done:
  3528. LT_DLMUTEX_UNLOCK ();
  3529. return stale;
  3530. }
  3531. lt_ptr
  3532. lt_dlcaller_get_data (key, handle)
  3533. lt_dlcaller_id key;
  3534. lt_dlhandle handle;
  3535. {
  3536. lt_ptr result = (lt_ptr) 0;
  3537. /* This needs to be locked so that the caller data isn't updated by
  3538. another thread part way through this function. */
  3539. LT_DLMUTEX_LOCK ();
  3540. /* Locate the index of the element with a matching KEY. */
  3541. {
  3542. int i;
  3543. for (i = 0; handle->caller_data[i].key; ++i)
  3544. {
  3545. if (handle->caller_data[i].key == key)
  3546. {
  3547. result = handle->caller_data[i].data;
  3548. break;
  3549. }
  3550. }
  3551. }
  3552. LT_DLMUTEX_UNLOCK ();
  3553. return result;
  3554. }
  3555. /* --- USER MODULE LOADER API --- */
  3556. int
  3557. lt_dlloader_add (place, dlloader, loader_name)
  3558. lt_dlloader *place;
  3559. const struct lt_user_dlloader *dlloader;
  3560. const char *loader_name;
  3561. {
  3562. int errors = 0;
  3563. lt_dlloader *node = 0, *ptr = 0;
  3564. if ((dlloader == 0) /* diagnose null parameters */
  3565. || (dlloader->module_open == 0)
  3566. || (dlloader->module_close == 0)
  3567. || (dlloader->find_sym == 0))
  3568. {
  3569. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
  3570. return 1;
  3571. }
  3572. /* Create a new dlloader node with copies of the user callbacks. */
  3573. node = LT_EMALLOC (lt_dlloader, 1);
  3574. if (!node)
  3575. return 1;
  3576. node->next = 0;
  3577. node->loader_name = loader_name;
  3578. node->sym_prefix = dlloader->sym_prefix;
  3579. node->dlloader_exit = dlloader->dlloader_exit;
  3580. node->module_open = dlloader->module_open;
  3581. node->module_close = dlloader->module_close;
  3582. node->find_sym = dlloader->find_sym;
  3583. node->dlloader_data = dlloader->dlloader_data;
  3584. LT_DLMUTEX_LOCK ();
  3585. if (!loaders)
  3586. {
  3587. /* If there are no loaders, NODE becomes the list! */
  3588. loaders = node;
  3589. }
  3590. else if (!place)
  3591. {
  3592. /* If PLACE is not set, add NODE to the end of the
  3593. LOADERS list. */
  3594. for (ptr = loaders; ptr->next; ptr = ptr->next)
  3595. {
  3596. /*NOWORK*/;
  3597. }
  3598. ptr->next = node;
  3599. }
  3600. else if (loaders == place)
  3601. {
  3602. /* If PLACE is the first loader, NODE goes first. */
  3603. node->next = place;
  3604. loaders = node;
  3605. }
  3606. else
  3607. {
  3608. /* Find the node immediately preceding PLACE. */
  3609. for (ptr = loaders; ptr->next != place; ptr = ptr->next)
  3610. {
  3611. /*NOWORK*/;
  3612. }
  3613. if (ptr->next != place)
  3614. {
  3615. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
  3616. ++errors;
  3617. }
  3618. else
  3619. {
  3620. /* Insert NODE between PTR and PLACE. */
  3621. node->next = place;
  3622. ptr->next = node;
  3623. }
  3624. }
  3625. LT_DLMUTEX_UNLOCK ();
  3626. return errors;
  3627. }
  3628. int
  3629. lt_dlloader_remove (loader_name)
  3630. const char *loader_name;
  3631. {
  3632. lt_dlloader *place = lt_dlloader_find (loader_name);
  3633. lt_dlhandle handle;
  3634. int errors = 0;
  3635. if (!place)
  3636. {
  3637. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
  3638. return 1;
  3639. }
  3640. LT_DLMUTEX_LOCK ();
  3641. /* Fail if there are any open modules which use this loader. */
  3642. for (handle = handles; handle; handle = handle->next)
  3643. {
  3644. if (handle->loader == place)
  3645. {
  3646. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
  3647. ++errors;
  3648. goto done;
  3649. }
  3650. }
  3651. if (place == loaders)
  3652. {
  3653. /* PLACE is the first loader in the list. */
  3654. loaders = loaders->next;
  3655. }
  3656. else
  3657. {
  3658. /* Find the loader before the one being removed. */
  3659. lt_dlloader *prev;
  3660. for (prev = loaders; prev->next; prev = prev->next)
  3661. {
  3662. if (!strcmp (prev->next->loader_name, loader_name))
  3663. {
  3664. break;
  3665. }
  3666. }
  3667. place = prev->next;
  3668. prev->next = prev->next->next;
  3669. }
  3670. if (place->dlloader_exit)
  3671. {
  3672. errors = place->dlloader_exit (place->dlloader_data);
  3673. }
  3674. LT_DLFREE (place);
  3675. done:
  3676. LT_DLMUTEX_UNLOCK ();
  3677. return errors;
  3678. }
  3679. lt_dlloader *
  3680. lt_dlloader_next (place)
  3681. lt_dlloader *place;
  3682. {
  3683. lt_dlloader *next;
  3684. LT_DLMUTEX_LOCK ();
  3685. next = place ? place->next : loaders;
  3686. LT_DLMUTEX_UNLOCK ();
  3687. return next;
  3688. }
  3689. const char *
  3690. lt_dlloader_name (place)
  3691. lt_dlloader *place;
  3692. {
  3693. const char *name = 0;
  3694. if (place)
  3695. {
  3696. LT_DLMUTEX_LOCK ();
  3697. name = place ? place->loader_name : 0;
  3698. LT_DLMUTEX_UNLOCK ();
  3699. }
  3700. else
  3701. {
  3702. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
  3703. }
  3704. return name;
  3705. }
  3706. lt_user_data *
  3707. lt_dlloader_data (place)
  3708. lt_dlloader *place;
  3709. {
  3710. lt_user_data *data = 0;
  3711. if (place)
  3712. {
  3713. LT_DLMUTEX_LOCK ();
  3714. data = place ? &(place->dlloader_data) : 0;
  3715. LT_DLMUTEX_UNLOCK ();
  3716. }
  3717. else
  3718. {
  3719. LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
  3720. }
  3721. return data;
  3722. }
  3723. lt_dlloader *
  3724. lt_dlloader_find (loader_name)
  3725. const char *loader_name;
  3726. {
  3727. lt_dlloader *place = 0;
  3728. LT_DLMUTEX_LOCK ();
  3729. for (place = loaders; place; place = place->next)
  3730. {
  3731. if (strcmp (place->loader_name, loader_name) == 0)
  3732. {
  3733. break;
  3734. }
  3735. }
  3736. LT_DLMUTEX_UNLOCK ();
  3737. return place;
  3738. }