elf.c 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. elf.c
  5. Abstract:
  6. This module implements support for handling the ELF file format.
  7. Author:
  8. Evan Green 13-Oct-2012
  9. Environment:
  10. Any
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "imp.h"
  16. #include "elf.h"
  17. #include "elfn.h"
  18. #include "elfcomm.h"
  19. //
  20. // ---------------------------------------------------------------- Definitions
  21. //
  22. //
  23. // Define the function names here to 32 and 64 bit specific function names,
  24. // since this file may be compiled twice in the same executable.
  25. //
  26. #if defined(WANT_ELF64)
  27. //
  28. // Define structure aliases.
  29. //
  30. #define ELF_LOADING_IMAGE ELF64_LOADING_IMAGE
  31. #define _ELF_LOADING_IMAGE _ELF64_LOADING_IMAGE
  32. #define PELF_LOADING_IMAGE PELF64_LOADING_IMAGE
  33. //
  34. // Define function aliases.
  35. //
  36. #define ImpElfLoadImportsForImage ImpElf64LoadImportsForImage
  37. #define ImpElfLoadImport ImpElf64LoadImport
  38. #define ImpElfGatherExportInformation ImpElf64GatherExportInformation
  39. #define ImpElfGetDynamicEntry ImpElf64GetDynamicEntry
  40. #define ImpElfRelocateImage ImpElf64RelocateImage
  41. #define ImpElfProcessRelocateSection ImpElf64ProcessRelocateSection
  42. #define ImpElfAdjustJumpSlots ImpElf64AdjustJumpSlots
  43. #define ImpElfGetSymbolValue ImpElf64GetSymbolValue
  44. #define ImpElfGetSymbol ImpElf64GetSymbol
  45. #define ImpElfApplyRelocation ImpElf64ApplyRelocation
  46. #define ImpElfFreeContext ImpElf64FreeContext
  47. #else
  48. //
  49. // Define structure aliases.
  50. //
  51. #define ELF_LOADING_IMAGE ELF32_LOADING_IMAGE
  52. #define _ELF_LOADING_IMAGE _ELF32_LOADING_IMAGE
  53. #define PELF_LOADING_IMAGE PELF32_LOADING_IMAGE
  54. //
  55. // Define function aliases.
  56. //
  57. #define ImpElfLoadImportsForImage ImpElf32LoadImportsForImage
  58. #define ImpElfLoadImport ImpElf32LoadImport
  59. #define ImpElfGatherExportInformation ImpElf32GatherExportInformation
  60. #define ImpElfGetDynamicEntry ImpElf32GetDynamicEntry
  61. #define ImpElfRelocateImage ImpElf32RelocateImage
  62. #define ImpElfProcessRelocateSection ImpElf32ProcessRelocateSection
  63. #define ImpElfAdjustJumpSlots ImpElf32AdjustJumpSlots
  64. #define ImpElfGetSymbolValue ImpElf32GetSymbolValue
  65. #define ImpElfGetSymbol ImpElf32GetSymbol
  66. #define ImpElfApplyRelocation ImpElf32ApplyRelocation
  67. #define ImpElfFreeContext ImpElf32FreeContext
  68. #endif
  69. //
  70. // Try some magically built-in library paths.
  71. //
  72. #define ELF_BUILTIN_LIBRARY_PATH "/lib:/usr/lib:/usr/local/lib"
  73. //
  74. // Define an invalid address value for image relocation tracking.
  75. //
  76. #define ELF_INVALID_RELOCATION (PVOID)-1
  77. #define ELF_INVALID_ADDRESS (ELF_ADDR)-1ULL
  78. //
  79. // Define the maximum number of program headers before it's just silly.
  80. //
  81. #define ELF_MAX_PROGRAM_HEADERS 50
  82. //
  83. // ------------------------------------------------------ Data Type Definitions
  84. //
  85. /*++
  86. Structure Description:
  87. This structure stores state variables used while loading an ELF image.
  88. Members:
  89. Buffer - Stores the loaded image buffer.
  90. ElfHeader - Stores a pointer pointing inside the file buffer where the
  91. main ELF header resides.
  92. RelocationStart - Stores the lowest address to be modified during image
  93. relocation.
  94. RelocationEnd - Stores the address at the end of the highest image
  95. relocation.
  96. --*/
  97. typedef struct _ELF_LOADING_IMAGE {
  98. IMAGE_BUFFER Buffer;
  99. PELF_HEADER ElfHeader;
  100. PVOID RelocationStart;
  101. PVOID RelocationEnd;
  102. } ELF_LOADING_IMAGE, *PELF_LOADING_IMAGE;
  103. //
  104. // ----------------------------------------------- Internal Function Prototypes
  105. //
  106. KSTATUS
  107. ImpElfLoadImportsForImage (
  108. PLIST_ENTRY ListHead,
  109. PLOADED_IMAGE Image
  110. );
  111. KSTATUS
  112. ImpElfGatherExportInformation (
  113. PLOADED_IMAGE Image,
  114. BOOL UseLoadedAddress
  115. );
  116. PELF_DYNAMIC_ENTRY
  117. ImpElfGetDynamicEntry (
  118. PLOADED_IMAGE Image,
  119. ELF_SXWORD Tag
  120. );
  121. KSTATUS
  122. ImpElfRelocateImage (
  123. PLIST_ENTRY ListHead,
  124. PLOADED_IMAGE Image
  125. );
  126. KSTATUS
  127. ImpElfProcessRelocateSection (
  128. PLIST_ENTRY ListHead,
  129. PLOADED_IMAGE Image,
  130. PVOID Relocations,
  131. ELF_XWORD RelocationsSize,
  132. BOOL Addends
  133. );
  134. VOID
  135. ImpElfAdjustJumpSlots (
  136. PLOADED_IMAGE Image,
  137. PVOID Relocations,
  138. ELF_XWORD RelocationsSize,
  139. BOOL Addends
  140. );
  141. ELF_ADDR
  142. ImpElfGetSymbolValue (
  143. PLIST_ENTRY ListHead,
  144. PLOADED_IMAGE Image,
  145. PELF_SYMBOL Symbol,
  146. PLOADED_IMAGE *FoundImage,
  147. PLOADED_IMAGE SkipImage
  148. );
  149. PELF_SYMBOL
  150. ImpElfGetSymbol (
  151. PLOADED_IMAGE Image,
  152. ULONG Hash,
  153. PSTR SymbolName
  154. );
  155. BOOL
  156. ImpElfApplyRelocation (
  157. PLIST_ENTRY ListHead,
  158. PLOADED_IMAGE Image,
  159. PELF_RELOCATION_ADDEND_ENTRY RelocationEntry,
  160. BOOL AddendEntry,
  161. PVOID *FinalSymbolValue
  162. );
  163. VOID
  164. ImpElfFreeContext (
  165. PLOADED_IMAGE Image
  166. );
  167. //
  168. // -------------------------------------------------------------------- Globals
  169. //
  170. //
  171. // ------------------------------------------------------------------ Functions
  172. //
  173. KSTATUS
  174. ImpElfOpenLibrary (
  175. PLIST_ENTRY ListHead,
  176. PLOADED_IMAGE Parent,
  177. PSTR LibraryName,
  178. PIMAGE_FILE_INFORMATION File,
  179. PSTR *Path
  180. )
  181. /*++
  182. Routine Description:
  183. This routine attempts to open a dynamic library.
  184. Arguments:
  185. ListHead - Supplies an optional pointer to the head of the list of loaded
  186. images.
  187. Parent - Supplies a pointer to the parent image requiring this image for
  188. load.
  189. LibraryName - Supplies the name of the library to open.
  190. File - Supplies a pointer where the information for the file including its
  191. open handle will be returned.
  192. Path - Supplies a pointer where the real path to the opened file will be
  193. returned. The caller is responsible for freeing this memory.
  194. Return Value:
  195. Status code.
  196. --*/
  197. {
  198. PSTR PathList;
  199. PLOADED_IMAGE PrimaryExecutable;
  200. ULONG PrimaryLoad;
  201. PELF_DYNAMIC_ENTRY RPath;
  202. PLOADED_IMAGE RPathParent;
  203. PELF_DYNAMIC_ENTRY RunPath;
  204. PSTR Slash;
  205. KSTATUS Status;
  206. //
  207. // If there's a slash, then just load the library without paths.
  208. //
  209. Slash = RtlStringFindCharacter(LibraryName, '/', -1);
  210. if (Slash != NULL) {
  211. Status = ImpElfOpenWithPathList(Parent, LibraryName, "", File, Path);
  212. goto OpenLibraryEnd;
  213. }
  214. //
  215. // First find a DT_RUNPATH. If both DT_RUNPATH and DT_RPATH are found,
  216. // ignore the older DT_RPATH. DT_RPATH goes up the chain of imports.
  217. //
  218. PrimaryLoad = 0;
  219. RunPath = ImpElfGetDynamicEntry(Parent, ELF_DYNAMIC_RUN_PATH);
  220. if (RunPath == NULL) {
  221. RPathParent = Parent;
  222. while (RPathParent != NULL) {
  223. PrimaryLoad |= RPathParent->LoadFlags;
  224. RPath = ImpElfGetDynamicEntry(RPathParent, ELF_DYNAMIC_RPATH);
  225. if (RPath != NULL) {
  226. PathList = RPathParent->ExportStringTable + RPath->Value;
  227. Status = ImpElfOpenWithPathList(Parent,
  228. LibraryName,
  229. PathList,
  230. File,
  231. Path);
  232. if (KSUCCESS(Status)) {
  233. goto OpenLibraryEnd;
  234. }
  235. }
  236. RPathParent = RPathParent->Parent;
  237. }
  238. //
  239. // Try the DT_RPATH of the primary executable if provided and not
  240. // already searched.
  241. //
  242. if ((PrimaryLoad & IMAGE_LOAD_FLAG_PRIMARY_LOAD) == 0) {
  243. PrimaryExecutable = ImpGetPrimaryExecutable(ListHead);
  244. if ((PrimaryExecutable != NULL) &&
  245. (PrimaryExecutable != Parent) &&
  246. (PrimaryExecutable->DynamicSection != NULL)) {
  247. RPath = ImpElfGetDynamicEntry(PrimaryExecutable,
  248. ELF_DYNAMIC_RPATH);
  249. if (RPath != NULL) {
  250. PathList = PrimaryExecutable->ExportStringTable +
  251. RPath->Value;
  252. Status = ImpElfOpenWithPathList(Parent,
  253. LibraryName,
  254. PathList,
  255. File,
  256. Path);
  257. if (KSUCCESS(Status)) {
  258. goto OpenLibraryEnd;
  259. }
  260. }
  261. }
  262. }
  263. }
  264. //
  265. // Get the library search path variable and use that.
  266. //
  267. PathList = ImpElfGetEnvironmentVariable(IMAGE_LOAD_LIBRARY_PATH_VARIABLE);
  268. if (PathList != NULL) {
  269. Status = ImpElfOpenWithPathList(Parent,
  270. LibraryName,
  271. PathList,
  272. File,
  273. Path);
  274. if (KSUCCESS(Status)) {
  275. goto OpenLibraryEnd;
  276. }
  277. }
  278. //
  279. // Try DT_RUNPATH.
  280. //
  281. if (RunPath != NULL) {
  282. PathList = Parent->ExportStringTable + RunPath->Value;
  283. Status = ImpElfOpenWithPathList(Parent,
  284. LibraryName,
  285. PathList,
  286. File,
  287. Path);
  288. if (KSUCCESS(Status)) {
  289. goto OpenLibraryEnd;
  290. }
  291. }
  292. //
  293. // Try some hard coded paths.
  294. //
  295. PathList = ELF_BUILTIN_LIBRARY_PATH;
  296. Status = ImpElfOpenWithPathList(Parent, LibraryName, PathList, File, Path);
  297. if (KSUCCESS(Status)) {
  298. goto OpenLibraryEnd;
  299. }
  300. OpenLibraryEnd:
  301. return Status;
  302. }
  303. KSTATUS
  304. ImpElfGetImageSize (
  305. PLIST_ENTRY ListHead,
  306. PLOADED_IMAGE Image,
  307. PIMAGE_BUFFER Buffer,
  308. PSTR *InterpreterPath
  309. )
  310. /*++
  311. Routine Description:
  312. This routine determines the size of an ELF executable image. The image size,
  313. preferred lowest address, and relocatable flag will all be filled in.
  314. Arguments:
  315. ListHead - Supplies a pointer to the head of the list of loaded images.
  316. Image - Supplies a pointer to the image to get the size of.
  317. Buffer - Supplies a pointer to the loaded image buffer.
  318. InterpreterPath - Supplies a pointer where the interpreter name will be
  319. returned if the program is requesting an interpreter.
  320. Return Value:
  321. Returns the size of the expanded image in memory on success.
  322. 0 on failure.
  323. --*/
  324. {
  325. PELF_HEADER ElfHeader;
  326. PELF_PROGRAM_HEADER FirstProgramHeader;
  327. ELF_WORD HeaderSize;
  328. ELF_ADDR HighestVirtualAddress;
  329. ELF_ADDR ImageSize;
  330. PSTR InterpreterName;
  331. ELF_ADDR LowestVirtualAddress;
  332. PELF_PROGRAM_HEADER ProgramHeader;
  333. BOOL Result;
  334. ELF_ADDR SegmentBase;
  335. ELF_OFF SegmentCount;
  336. ELF_ADDR SegmentEnd;
  337. UINTN SegmentIndex;
  338. KSTATUS Status;
  339. ImageSize = 0;
  340. if (InterpreterPath != NULL) {
  341. *InterpreterPath = NULL;
  342. }
  343. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  344. //
  345. // Get the ELF headers.
  346. //
  347. Result = ImpElfGetHeader(Buffer, &ElfHeader);
  348. if (Result == FALSE) {
  349. goto GetImageSizeEnd;
  350. }
  351. SegmentCount = ElfHeader->ProgramHeaderCount;
  352. if (SegmentCount > ELF_MAX_PROGRAM_HEADERS) {
  353. goto GetImageSizeEnd;
  354. }
  355. FirstProgramHeader = ImpReadBuffer(
  356. &(Image->File),
  357. Buffer,
  358. ElfHeader->ProgramHeaderOffset,
  359. ElfHeader->ProgramHeaderSize * SegmentCount);
  360. if (FirstProgramHeader == NULL) {
  361. goto GetImageSizeEnd;
  362. }
  363. if (ElfHeader->ImageType == ELF_IMAGE_SHARED_OBJECT) {
  364. Image->Flags |= IMAGE_FLAG_RELOCATABLE;
  365. } else if (ElfHeader->ImageType == ELF_IMAGE_EXECUTABLE) {
  366. Image->Flags &= ~IMAGE_FLAG_RELOCATABLE;
  367. } else {
  368. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  369. goto GetImageSizeEnd;
  370. }
  371. switch (ElfHeader->Machine) {
  372. case ELF_MACHINE_ARM:
  373. Image->Machine = ImageMachineTypeArm32;
  374. break;
  375. case ELF_MACHINE_I386:
  376. Image->Machine = ImageMachineTypeX86;
  377. break;
  378. case ELF_MACHINE_X86_64:
  379. Image->Machine = ImageMachineTypeX64;
  380. break;
  381. case ELF_MACHINE_AARCH64:
  382. Image->Machine = ImageMachineTypeArm64;
  383. break;
  384. default:
  385. Image->Machine = ImageMachineTypeUnknown;
  386. break;
  387. }
  388. Image->EntryPoint = (PVOID)(UINTN)(ElfHeader->EntryPoint);
  389. //
  390. // Loop through the program headers once to get the image size and base
  391. // address.
  392. //
  393. LowestVirtualAddress = (ELF_ADDR)-1ULL;
  394. HighestVirtualAddress = 0;
  395. for (SegmentIndex = 0; SegmentIndex < SegmentCount; SegmentIndex += 1) {
  396. ProgramHeader =
  397. (PELF_PROGRAM_HEADER)(((PUCHAR)FirstProgramHeader) +
  398. (SegmentIndex * ElfHeader->ProgramHeaderSize));
  399. //
  400. // If this image is requesting an interpreter, go load the interpreter
  401. // instead of this image.
  402. //
  403. if ((ProgramHeader->Type == ELF_SEGMENT_TYPE_INTERPRETER) &&
  404. (ProgramHeader->FileSize != 0) &&
  405. (InterpreterPath != NULL) &&
  406. ((Image->LoadFlags & IMAGE_LOAD_FLAG_IGNORE_INTERPRETER) == 0)) {
  407. ASSERT(Image->ImportDepth == 0);
  408. HeaderSize = ProgramHeader->FileSize;
  409. InterpreterName = ImpReadBuffer(&(Image->File),
  410. Buffer,
  411. ProgramHeader->Offset,
  412. HeaderSize);
  413. if ((InterpreterName == NULL) ||
  414. (HeaderSize == 0) ||
  415. (InterpreterName[HeaderSize - 1] != '\0')) {
  416. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  417. goto GetImageSizeEnd;
  418. }
  419. *InterpreterPath = InterpreterName;
  420. }
  421. //
  422. // Skip non-loading segments.
  423. //
  424. if (ProgramHeader->Type != ELF_SEGMENT_TYPE_LOAD) {
  425. continue;
  426. }
  427. //
  428. // Determine where in memory this segment would start and end.
  429. //
  430. SegmentBase = ProgramHeader->VirtualAddress;
  431. SegmentEnd = ProgramHeader->VirtualAddress + ProgramHeader->MemorySize;
  432. //
  433. // Update the lowest and highest addresses seen so far.
  434. //
  435. if (SegmentBase < LowestVirtualAddress) {
  436. LowestVirtualAddress = SegmentBase;
  437. }
  438. if (SegmentEnd > HighestVirtualAddress) {
  439. HighestVirtualAddress = SegmentEnd;
  440. }
  441. }
  442. if (LowestVirtualAddress >= HighestVirtualAddress) {
  443. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  444. goto GetImageSizeEnd;
  445. }
  446. ImageSize = HighestVirtualAddress - LowestVirtualAddress;
  447. Image->PreferredLowestAddress = (PVOID)(UINTN)LowestVirtualAddress;
  448. Status = STATUS_SUCCESS;
  449. GetImageSizeEnd:
  450. Image->Size = ImageSize;
  451. return Status;
  452. }
  453. KSTATUS
  454. ImpElfLoadImage (
  455. PLIST_ENTRY ListHead,
  456. PLOADED_IMAGE Image,
  457. PIMAGE_BUFFER Buffer
  458. )
  459. /*++
  460. Routine Description:
  461. This routine loads an ELF image into its executable form.
  462. Arguments:
  463. ListHead - Supplies a pointer to the head of the list of loaded images.
  464. Image - Supplies a pointer to the loaded image. This must be partially
  465. filled out. Notable fields that must be filled out by the caller
  466. include the loaded virtual address and image size. This routine will
  467. fill out many other fields.
  468. Buffer - Supplies a pointer to the image buffer.
  469. Return Value:
  470. STATUS_SUCCESS on success.
  471. STATUS_FILE_CORRUPT if the file headers were corrupt or unexpected.
  472. Other errors on failure.
  473. --*/
  474. {
  475. ELF_ADDR BaseDifference;
  476. PELF_HEADER ElfHeader;
  477. PELF_PROGRAM_HEADER FirstProgramHeader;
  478. BOOL ImageInserted;
  479. ULONG ImportIndex;
  480. PELF_LOADING_IMAGE LoadingImage;
  481. BOOL NotifyLoadCalled;
  482. PIMAGE_SEGMENT PreviousSegment;
  483. PELF_PROGRAM_HEADER ProgramHeader;
  484. BOOL Result;
  485. PIMAGE_SEGMENT Segment;
  486. ELF_ADDR SegmentBase;
  487. ELF_HALF SegmentCount;
  488. ELF_HALF SegmentIndex;
  489. KSTATUS Status;
  490. ImageInserted = FALSE;
  491. NotifyLoadCalled = FALSE;
  492. SegmentCount = 0;
  493. LoadingImage = ImAllocateMemory(sizeof(ELF_LOADING_IMAGE),
  494. IM_ALLOCATION_TAG);
  495. if (LoadingImage == NULL) {
  496. Status = STATUS_INSUFFICIENT_RESOURCES;
  497. goto LoadImageEnd;
  498. }
  499. Image->ImageContext = LoadingImage;
  500. RtlZeroMemory(LoadingImage, sizeof(ELF_LOADING_IMAGE));
  501. RtlCopyMemory(&(LoadingImage->Buffer), Buffer, sizeof(IMAGE_BUFFER));
  502. //
  503. // Get the ELF headers.
  504. //
  505. Result = ImpElfGetHeader(Buffer, &ElfHeader);
  506. if (Result == FALSE) {
  507. Status = STATUS_FILE_CORRUPT;
  508. goto LoadImageEnd;
  509. }
  510. LoadingImage->ElfHeader = ElfHeader;
  511. SegmentCount = ElfHeader->ProgramHeaderCount;
  512. FirstProgramHeader = ImpReadBuffer(
  513. &(Image->File),
  514. Buffer,
  515. ElfHeader->ProgramHeaderOffset,
  516. ElfHeader->ProgramHeaderSize * SegmentCount);
  517. if (FirstProgramHeader == NULL) {
  518. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  519. goto LoadImageEnd;
  520. }
  521. //
  522. // Reload the ELF header if reading the program headers caused the buffer
  523. // to change.
  524. //
  525. if (Buffer->Data != ElfHeader) {
  526. Result = ImpElfGetHeader(Buffer, &ElfHeader);
  527. if (Result == FALSE) {
  528. Status = STATUS_FILE_CORRUPT;
  529. goto LoadImageEnd;
  530. }
  531. LoadingImage->ElfHeader = ElfHeader;
  532. }
  533. //
  534. // Allocate space for the image segment structures.
  535. //
  536. ASSERT(Image->Segments == NULL);
  537. if (SegmentCount == 0) {
  538. Status = STATUS_FILE_CORRUPT;
  539. goto LoadImageEnd;
  540. }
  541. Image->SegmentCount = SegmentCount;
  542. Image->Segments = ImAllocateMemory(SegmentCount * sizeof(IMAGE_SEGMENT),
  543. IM_ALLOCATION_TAG);
  544. if (Image->Segments == NULL) {
  545. Status = STATUS_INSUFFICIENT_RESOURCES;
  546. goto LoadImageEnd;
  547. }
  548. RtlZeroMemory(Image->Segments, SegmentCount * sizeof(IMAGE_SEGMENT));
  549. //
  550. // Loop through and load all program headers.
  551. //
  552. PreviousSegment = NULL;
  553. BaseDifference = Image->BaseDifference;
  554. ProgramHeader = FirstProgramHeader;
  555. for (SegmentIndex = 0; SegmentIndex < SegmentCount; SegmentIndex += 1) {
  556. Segment = &(Image->Segments[SegmentIndex]);
  557. //
  558. // Remember the TLS segment.
  559. //
  560. if (ProgramHeader->Type == ELF_SEGMENT_TYPE_TLS) {
  561. Image->TlsImage = (PVOID)(UINTN)(ProgramHeader->VirtualAddress) +
  562. BaseDifference;
  563. Image->TlsImageSize = ProgramHeader->FileSize;
  564. Image->TlsSize = ProgramHeader->MemorySize;
  565. Image->TlsAlignment = ProgramHeader->Alignment;
  566. }
  567. //
  568. // Skip non-loading segments.
  569. //
  570. if (ProgramHeader->Type != ELF_SEGMENT_TYPE_LOAD) {
  571. ProgramHeader += 1;
  572. continue;
  573. }
  574. //
  575. // Determine where in memory this segment will start.
  576. //
  577. SegmentBase = ProgramHeader->VirtualAddress;
  578. //
  579. // Convert the flags.
  580. //
  581. if ((ProgramHeader->Flags & ELF_PROGRAM_HEADER_FLAG_WRITE) != 0) {
  582. Segment->Flags |= IMAGE_MAP_FLAG_WRITE;
  583. }
  584. if ((ProgramHeader->Flags & ELF_PROGRAM_HEADER_FLAG_EXECUTE) != 0) {
  585. Segment->Flags |= IMAGE_MAP_FLAG_EXECUTE;
  586. }
  587. //
  588. // The mapping is fixed if it's not the first program header or its
  589. // not an image that can be relocated.
  590. //
  591. if ((PreviousSegment != NULL) ||
  592. ((Image->Flags & IMAGE_FLAG_RELOCATABLE) == 0)) {
  593. Segment->Flags |= IMAGE_MAP_FLAG_FIXED;
  594. }
  595. //
  596. // Set up and map the segment.
  597. //
  598. Segment->VirtualAddress = (PVOID)(UINTN)SegmentBase + BaseDifference;
  599. Segment->FileSize = ProgramHeader->FileSize;
  600. Segment->MemorySize = ProgramHeader->MemorySize;
  601. //
  602. // The segments should always be in increasing virtual address order.
  603. //
  604. if ((PreviousSegment != NULL) &&
  605. (PreviousSegment->VirtualAddress + PreviousSegment->MemorySize >
  606. Segment->VirtualAddress)) {
  607. Status = STATUS_FILE_CORRUPT;
  608. goto LoadImageEnd;
  609. }
  610. Status = ImMapImageSegment(
  611. Image->AllocatorHandle,
  612. Image->PreferredLowestAddress + BaseDifference,
  613. &(Image->File),
  614. ProgramHeader->Offset,
  615. Segment,
  616. PreviousSegment);
  617. if (!KSUCCESS(Status)) {
  618. goto LoadImageEnd;
  619. }
  620. //
  621. // If this was the first section to get slapped down and address space
  622. // wasn't predetermined, update it now.
  623. //
  624. if ((PreviousSegment == NULL) &&
  625. (Image->AllocatorHandle == INVALID_HANDLE)) {
  626. Image->BaseDifference = Segment->VirtualAddress -
  627. Image->PreferredLowestAddress;
  628. Image->LoadedImageBuffer = Segment->VirtualAddress;
  629. BaseDifference = Image->BaseDifference;
  630. }
  631. Segment->Type = ImageSegmentFileSection;
  632. PreviousSegment = Segment;
  633. ProgramHeader = (PELF_PROGRAM_HEADER)((PUCHAR)ProgramHeader +
  634. ElfHeader->ProgramHeaderSize);
  635. }
  636. Image->EntryPoint =
  637. (PVOID)(UINTN)(LoadingImage->ElfHeader->EntryPoint + BaseDifference);
  638. INSERT_BEFORE(&(Image->ListEntry), ListHead);
  639. ImageInserted = TRUE;
  640. Status = ImNotifyImageLoad(Image);
  641. if (!KSUCCESS(Status)) {
  642. goto LoadImageEnd;
  643. }
  644. NotifyLoadCalled = TRUE;
  645. //
  646. // If only loading, don't process the dynamic section.
  647. //
  648. if ((Image->LoadFlags & IMAGE_LOAD_FLAG_LOAD_ONLY) != 0) {
  649. ImpElfFreeContext(Image);
  650. goto LoadImageEnd;
  651. }
  652. //
  653. // Gather information not in the loaded part of the file needed for
  654. // resolving exports from this image.
  655. //
  656. Status = ImpElfGatherExportInformation(Image, FALSE);
  657. if (!KSUCCESS(Status)) {
  658. goto LoadImageEnd;
  659. }
  660. //
  661. // If the import count is non-zero, then this is an import being loaded.
  662. // Do nothing else, as relocations and imports happen at the base level.
  663. //
  664. if (Image->ImportDepth != 0) {
  665. Status = STATUS_SUCCESS;
  666. goto LoadImageEnd;
  667. }
  668. //
  669. // Load imports for all images.
  670. //
  671. Status = ImpElfLoadAllImports(ListHead);
  672. if (!KSUCCESS(Status)) {
  673. goto LoadImageEnd;
  674. }
  675. if ((Image->LoadFlags & IMAGE_LOAD_FLAG_NO_RELOCATIONS) == 0) {
  676. //
  677. // Loop through the list again and perform the final relocations now
  678. // that the complete symbol table is built.
  679. //
  680. Status = ImpElfRelocateImages(ListHead);
  681. if (!KSUCCESS(Status)) {
  682. goto LoadImageEnd;
  683. }
  684. }
  685. Status = STATUS_SUCCESS;
  686. LoadImageEnd:
  687. if (!KSUCCESS(Status)) {
  688. if (Image->ImageContext != NULL) {
  689. ImFreeMemory(Image->ImageContext);
  690. Image->ImageContext = NULL;
  691. }
  692. if (NotifyLoadCalled != FALSE) {
  693. //
  694. // Unload any imports.
  695. //
  696. for (ImportIndex = 0;
  697. ImportIndex < Image->ImportCount;
  698. ImportIndex += 1) {
  699. if (Image->Imports[ImportIndex] != NULL) {
  700. ImImageReleaseReference(Image->Imports[ImportIndex]);
  701. }
  702. }
  703. if (Image->Imports != NULL) {
  704. ImFreeMemory(Image->Imports);
  705. }
  706. ImNotifyImageUnload(Image);
  707. }
  708. if (ImageInserted != FALSE) {
  709. LIST_REMOVE(&(Image->ListEntry));
  710. }
  711. if (Image->Segments != NULL) {
  712. //
  713. // Unmap all mapped segments.
  714. //
  715. for (SegmentIndex = 0;
  716. SegmentIndex < SegmentCount;
  717. SegmentIndex += 1) {
  718. Segment = &(Image->Segments[SegmentIndex]);
  719. if (Segment->Type != ImageSegmentInvalid) {
  720. ImUnmapImageSegment(Image->AllocatorHandle, Segment);
  721. }
  722. }
  723. ImFreeMemory(Image->Segments);
  724. Image->Segments = NULL;
  725. Image->SegmentCount = 0;
  726. }
  727. if (Image->StaticFunctions != NULL) {
  728. ImFreeMemory(Image->StaticFunctions);
  729. }
  730. }
  731. return Status;
  732. }
  733. KSTATUS
  734. ImpElfAddImage (
  735. PIMAGE_BUFFER ImageBuffer,
  736. PLOADED_IMAGE Image
  737. )
  738. /*++
  739. Routine Description:
  740. This routine adds the accounting structures for an image that has already
  741. been loaded into memory.
  742. Arguments:
  743. ImageBuffer - Supplies a pointer to the loaded image buffer.
  744. Image - Supplies a pointer to the image to initialize.
  745. Return Value:
  746. Status code.
  747. --*/
  748. {
  749. ELF_ADDR BaseDifference;
  750. PELF_HEADER ElfHeader;
  751. PELF_PROGRAM_HEADER FirstProgramHeader;
  752. ELF_ADDR HighestVirtualAddress;
  753. ELF_ADDR ImageSize;
  754. UINTN Index;
  755. PELF_LOADING_IMAGE LoadingImage;
  756. ELF_ADDR LowestVirtualAddress;
  757. PELF_PROGRAM_HEADER ProgramHeader;
  758. ELF_HALF SegmentCount;
  759. ELF_ADDR SegmentEnd;
  760. KSTATUS Status;
  761. ElfHeader = Image->LoadedImageBuffer;
  762. Image->Size = ImageBuffer->Size;
  763. LoadingImage = ImAllocateMemory(sizeof(ELF_LOADING_IMAGE),
  764. IM_ALLOCATION_TAG);
  765. if (LoadingImage == NULL) {
  766. Status = STATUS_INSUFFICIENT_RESOURCES;
  767. goto AddImageEnd;
  768. }
  769. Image->ImageContext = LoadingImage;
  770. RtlZeroMemory(LoadingImage, sizeof(ELF_LOADING_IMAGE));
  771. RtlCopyMemory(&(LoadingImage->Buffer), ImageBuffer, sizeof(IMAGE_BUFFER));
  772. LoadingImage->ElfHeader = ElfHeader;
  773. if (ElfHeader->ImageType == ELF_IMAGE_SHARED_OBJECT) {
  774. Image->Flags |= IMAGE_FLAG_RELOCATABLE;
  775. } else if (ElfHeader->ImageType == ELF_IMAGE_EXECUTABLE) {
  776. Image->Flags &= ~IMAGE_FLAG_RELOCATABLE;
  777. } else {
  778. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  779. goto AddImageEnd;
  780. }
  781. switch (ElfHeader->Machine) {
  782. case ELF_MACHINE_ARM:
  783. Image->Machine = ImageMachineTypeArm32;
  784. break;
  785. case ELF_MACHINE_I386:
  786. Image->Machine = ImageMachineTypeX86;
  787. break;
  788. case ELF_MACHINE_X86_64:
  789. Image->Machine = ImageMachineTypeX64;
  790. break;
  791. case ELF_MACHINE_AARCH64:
  792. Image->Machine = ImageMachineTypeArm64;
  793. break;
  794. default:
  795. Image->Machine = ImageMachineTypeUnknown;
  796. break;
  797. }
  798. SegmentCount = ElfHeader->ProgramHeaderCount;
  799. FirstProgramHeader = ImpReadBuffer(
  800. &(Image->File),
  801. ImageBuffer,
  802. ElfHeader->ProgramHeaderOffset,
  803. ElfHeader->ProgramHeaderSize * SegmentCount);
  804. if (FirstProgramHeader == NULL) {
  805. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  806. goto AddImageEnd;
  807. }
  808. //
  809. // Loop through the program headers.
  810. //
  811. LowestVirtualAddress = (ELF_ADDR)-1ULL;
  812. HighestVirtualAddress = 0;
  813. ProgramHeader = FirstProgramHeader;
  814. for (Index = 0; Index < SegmentCount; Index += 1) {
  815. //
  816. // Remember the TLS segment.
  817. //
  818. if (ProgramHeader->Type == ELF_SEGMENT_TYPE_TLS) {
  819. Image->TlsImage = (PVOID)(UINTN)(ProgramHeader->VirtualAddress);
  820. Image->TlsImageSize = ProgramHeader->FileSize;
  821. Image->TlsSize = ProgramHeader->MemorySize;
  822. Image->TlsAlignment = ProgramHeader->Alignment;
  823. } else if (ProgramHeader->Type == ELF_SEGMENT_TYPE_LOAD) {
  824. if (ProgramHeader->VirtualAddress < LowestVirtualAddress) {
  825. LowestVirtualAddress = ProgramHeader->VirtualAddress;
  826. }
  827. SegmentEnd = ProgramHeader->VirtualAddress +
  828. ProgramHeader->MemorySize;
  829. if (SegmentEnd > HighestVirtualAddress) {
  830. HighestVirtualAddress = SegmentEnd;
  831. }
  832. }
  833. ProgramHeader = (PELF_PROGRAM_HEADER)((PUCHAR)ProgramHeader +
  834. ElfHeader->ProgramHeaderSize);
  835. }
  836. if (LowestVirtualAddress >= HighestVirtualAddress) {
  837. Status = STATUS_UNKNOWN_IMAGE_FORMAT;
  838. goto AddImageEnd;
  839. }
  840. ImageSize = HighestVirtualAddress - LowestVirtualAddress;
  841. ASSERT((Image->Size == MAX_UINTN) || (Image->Size == ImageSize));
  842. Image->Size = ImageSize;
  843. Image->PreferredLowestAddress = (PVOID)(UINTN)LowestVirtualAddress;
  844. BaseDifference = Image->LoadedImageBuffer - Image->PreferredLowestAddress;
  845. Image->BaseDifference = BaseDifference;
  846. if (Image->TlsImage != NULL) {
  847. Image->TlsImage += BaseDifference;
  848. }
  849. Image->EntryPoint = (PVOID)(UINTN)(ElfHeader->EntryPoint + BaseDifference);
  850. Status = ImpElfGatherExportInformation(Image, TRUE);
  851. if (!KSUCCESS(Status)) {
  852. goto AddImageEnd;
  853. }
  854. AddImageEnd:
  855. if (!KSUCCESS(Status)) {
  856. if (Image != NULL) {
  857. if (Image->ImageContext != NULL) {
  858. ImFreeMemory(Image->ImageContext);
  859. Image->ImageContext = NULL;
  860. }
  861. if (Image->StaticFunctions != NULL) {
  862. ImFreeMemory(Image->StaticFunctions);
  863. }
  864. }
  865. }
  866. return Status;
  867. }
  868. VOID
  869. ImpElfUnloadImage (
  870. PLOADED_IMAGE Image
  871. )
  872. /*++
  873. Routine Description:
  874. This routine unloads an ELF executable.
  875. Arguments:
  876. Image - Supplies a pointer to the loaded image.
  877. Return Value:
  878. None.
  879. --*/
  880. {
  881. UINTN ImportIndex;
  882. UINTN SegmentIndex;
  883. ASSERT((Image->ImportCount == 0) || (Image->Imports != NULL));
  884. ImpElfFreeContext(Image);
  885. //
  886. // Unload all imports.
  887. //
  888. for (ImportIndex = 0; ImportIndex < Image->ImportCount; ImportIndex += 1) {
  889. ASSERT(Image->Imports[ImportIndex] != NULL);
  890. ImImageReleaseReference(Image->Imports[ImportIndex]);
  891. }
  892. if (Image->Imports != NULL) {
  893. ImFreeMemory(Image->Imports);
  894. }
  895. ASSERT((Image->Segments != NULL) || (Image->SegmentCount == 0));
  896. for (SegmentIndex = 0;
  897. SegmentIndex < Image->SegmentCount;
  898. SegmentIndex += 1) {
  899. if (Image->Segments[SegmentIndex].Type != ImageSegmentInvalid) {
  900. ImUnmapImageSegment(Image->AllocatorHandle,
  901. &(Image->Segments[SegmentIndex]));
  902. }
  903. }
  904. if (Image->Segments != NULL) {
  905. ImFreeMemory(Image->Segments);
  906. Image->Segments = NULL;
  907. }
  908. if (Image->StaticFunctions != NULL) {
  909. ImFreeMemory(Image->StaticFunctions);
  910. Image->StaticFunctions = NULL;
  911. }
  912. return;
  913. }
  914. BOOL
  915. ImpElfGetHeader (
  916. PIMAGE_BUFFER Buffer,
  917. PELF_HEADER *ElfHeader
  918. )
  919. /*++
  920. Routine Description:
  921. This routine returns a pointer to the ELF image header given a buffer
  922. containing the executable image mapped in memory.
  923. Arguments:
  924. Buffer - Supplies a pointer to the loaded image buffer.
  925. ElfHeader - Supplies a pointer where the location of the ELF header will
  926. be returned.
  927. Return Value:
  928. TRUE on success.
  929. FALSE otherwise.
  930. --*/
  931. {
  932. UCHAR Class;
  933. PELF_HEADER Header;
  934. *ElfHeader = NULL;
  935. Header = ImpReadBuffer(NULL, Buffer, 0, sizeof(ELF_HEADER));
  936. if (Header == NULL) {
  937. return FALSE;
  938. }
  939. if ((Header->Identification[0] != ELF_MAGIC0) ||
  940. (Header->Identification[1] != ELF_MAGIC1) ||
  941. (Header->Identification[2] != ELF_MAGIC2) ||
  942. (Header->Identification[3] != ELF_MAGIC3)) {
  943. return FALSE;
  944. }
  945. //
  946. // Check that the 32/64 bitness agrees.
  947. //
  948. Class = Header->Identification[ELF_CLASS_OFFSET];
  949. if (sizeof(ELF_HEADER) == sizeof(ELF64_HEADER)) {
  950. if (Class != ELF_64BIT) {
  951. return FALSE;
  952. }
  953. } else {
  954. if (Class != ELF_32BIT) {
  955. return FALSE;
  956. }
  957. }
  958. //
  959. // Only little endian images are supported.
  960. //
  961. if (Header->Identification[ELF_ENDIANNESS_OFFSET] != ELF_LITTLE_ENDIAN) {
  962. return FALSE;
  963. }
  964. //
  965. // Ensure that the program header and section header sizes are consistent.
  966. //
  967. if ((Header->ProgramHeaderSize != sizeof(ELF_PROGRAM_HEADER)) ||
  968. (Header->SectionHeaderSize != sizeof(ELF_SECTION_HEADER))) {
  969. return FALSE;
  970. }
  971. *ElfHeader = Header;
  972. return TRUE;
  973. }
  974. BOOL
  975. ImpElfGetSection (
  976. PIMAGE_BUFFER Buffer,
  977. PSTR SectionName,
  978. PVOID *Section,
  979. PULONGLONG VirtualAddress,
  980. PULONG SectionSizeInFile,
  981. PULONG SectionSizeInMemory
  982. )
  983. /*++
  984. Routine Description:
  985. This routine gets a pointer to the given section in an ELF image given a
  986. memory mapped file.
  987. Arguments:
  988. Buffer - Supplies a pointer to the image buffer.
  989. SectionName - Supplies the name of the desired section.
  990. Section - Supplies a pointer where the pointer to the section will be
  991. returned.
  992. VirtualAddress - Supplies a pointer where the virtual address of the section
  993. will be returned, if applicable.
  994. SectionSizeInFile - Supplies a pointer where the size of the section as it
  995. appears in the file will be returned.
  996. SectionSizeInMemory - Supplies a pointer where the size of the section as it
  997. appears after being loaded in memory will be returned.
  998. Return Value:
  999. TRUE on success.
  1000. FALSE otherwise.
  1001. --*/
  1002. {
  1003. PSTR CurrentSectionName;
  1004. PELF_HEADER ElfHeader;
  1005. BOOL Match;
  1006. BOOL Result;
  1007. PVOID ReturnSection;
  1008. ELF_WORD ReturnSectionFileSize;
  1009. ELF_WORD ReturnSectionMemorySize;
  1010. ELF_ADDR ReturnSectionVirtualAddress;
  1011. PELF_SECTION_HEADER SectionHeader;
  1012. ELF_HALF SectionIndex;
  1013. PSTR StringTable;
  1014. PELF_SECTION_HEADER StringTableHeader;
  1015. ReturnSection = NULL;
  1016. ReturnSectionFileSize = 0;
  1017. ReturnSectionMemorySize = 0;
  1018. ReturnSectionVirtualAddress = (UINTN)NULL;
  1019. if (SectionName == NULL) {
  1020. Result = FALSE;
  1021. goto GetSectionEnd;
  1022. }
  1023. Result = ImpElfGetHeader(Buffer, &ElfHeader);
  1024. if (Result == FALSE) {
  1025. goto GetSectionEnd;
  1026. }
  1027. //
  1028. // Get the beginning of the section array, and then get the string table.
  1029. //
  1030. SectionHeader = ImpReadBuffer(
  1031. NULL,
  1032. Buffer,
  1033. ElfHeader->SectionHeaderOffset,
  1034. sizeof(ELF_SECTION_HEADER) * ElfHeader->SectionHeaderCount);
  1035. if (SectionHeader == NULL) {
  1036. Result = FALSE;
  1037. goto GetSectionEnd;
  1038. }
  1039. StringTableHeader = SectionHeader + ElfHeader->StringSectionIndex;
  1040. StringTable = ImpReadBuffer(NULL,
  1041. Buffer,
  1042. StringTableHeader->Offset,
  1043. StringTableHeader->Size);
  1044. if (StringTable == NULL) {
  1045. Result = FALSE;
  1046. goto GetSectionEnd;
  1047. }
  1048. //
  1049. // Loop through all sections looking for the desired one.
  1050. //
  1051. for (SectionIndex = 0;
  1052. SectionIndex < ElfHeader->SectionHeaderCount;
  1053. SectionIndex += 1) {
  1054. //
  1055. // Skip null sections.
  1056. //
  1057. if (SectionHeader->SectionType == ELF_SECTION_TYPE_NULL) {
  1058. SectionHeader += 1;
  1059. continue;
  1060. }
  1061. if (SectionHeader->NameOffset >= StringTableHeader->Size) {
  1062. Result = FALSE;
  1063. goto GetSectionEnd;
  1064. }
  1065. CurrentSectionName = StringTable + SectionHeader->NameOffset;
  1066. Match = RtlAreStringsEqual(CurrentSectionName, SectionName, -1);
  1067. //
  1068. // If the name matches, return that section. Sections have no relevance
  1069. // on what is loaded into memory, so all sections have a memory size of
  1070. // zero.
  1071. //
  1072. if (Match != FALSE) {
  1073. ReturnSection = ImpReadBuffer(NULL,
  1074. Buffer,
  1075. SectionHeader->Offset,
  1076. SectionHeader->Size);
  1077. if (ReturnSection == NULL) {
  1078. Result = FALSE;
  1079. goto GetSectionEnd;
  1080. }
  1081. ReturnSectionFileSize = SectionHeader->Size;
  1082. ReturnSectionMemorySize = 0;
  1083. ReturnSectionVirtualAddress = SectionHeader->VirtualAddress;
  1084. break;
  1085. }
  1086. SectionHeader += 1;
  1087. }
  1088. GetSectionEnd:
  1089. if (Section != NULL) {
  1090. *Section = ReturnSection;
  1091. }
  1092. if (VirtualAddress != NULL) {
  1093. *VirtualAddress = ReturnSectionVirtualAddress;
  1094. }
  1095. if (SectionSizeInFile != NULL) {
  1096. *SectionSizeInFile = ReturnSectionFileSize;
  1097. }
  1098. if (SectionSizeInMemory != NULL) {
  1099. *SectionSizeInMemory = ReturnSectionMemorySize;
  1100. }
  1101. return Result;
  1102. }
  1103. KSTATUS
  1104. ImpElfLoadAllImports (
  1105. PLIST_ENTRY ListHead
  1106. )
  1107. /*++
  1108. Routine Description:
  1109. This routine loads all import libraries for all images.
  1110. Arguments:
  1111. ListHead - Supplies a pointer to the head of the list of loaded images.
  1112. Return Value:
  1113. Status code.
  1114. --*/
  1115. {
  1116. PLIST_ENTRY CurrentEntry;
  1117. PLOADED_IMAGE CurrentImage;
  1118. KSTATUS Status;
  1119. //
  1120. // Loop through the list and load imports for each image. This may cause
  1121. // additional images to get added to the end of the list, but traversal of
  1122. // the list won't get corrupted because images never disappear from the
  1123. // list this way.
  1124. //
  1125. CurrentEntry = ListHead->Next;
  1126. while (CurrentEntry != ListHead) {
  1127. CurrentImage = LIST_VALUE(CurrentEntry, LOADED_IMAGE, ListEntry);
  1128. ASSERT((CurrentImage->LoadFlags & IMAGE_LOAD_FLAG_LOAD_ONLY) == 0);
  1129. if ((CurrentImage->Flags & IMAGE_FLAG_IMPORTS_LOADED) == 0) {
  1130. Status = ImpElfLoadImportsForImage(ListHead, CurrentImage);
  1131. if (!KSUCCESS(Status)) {
  1132. goto LoadAllImportsEnd;
  1133. }
  1134. CurrentImage->Flags |= IMAGE_FLAG_IMPORTS_LOADED;
  1135. }
  1136. CurrentEntry = CurrentEntry->Next;
  1137. }
  1138. Status = STATUS_SUCCESS;
  1139. LoadAllImportsEnd:
  1140. return Status;
  1141. }
  1142. KSTATUS
  1143. ImpElfRelocateImages (
  1144. PLIST_ENTRY ListHead
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. This routine relocates all images on the given image list that have not
  1149. yet been relocated.
  1150. Arguments:
  1151. ListHead - Supplies a pointer to the head of the list to relocate.
  1152. Return Value:
  1153. Status code.
  1154. --*/
  1155. {
  1156. PLIST_ENTRY CurrentEntry;
  1157. PLOADED_IMAGE CurrentImage;
  1158. KSTATUS Status;
  1159. Status = ImpElfLoadAllImports(ListHead);
  1160. if (!KSUCCESS(Status)) {
  1161. goto RelocateImagesEnd;
  1162. }
  1163. CurrentEntry = ListHead->Previous;
  1164. while (CurrentEntry != ListHead) {
  1165. CurrentImage = LIST_VALUE(CurrentEntry, LOADED_IMAGE, ListEntry);
  1166. if ((CurrentImage->Flags & IMAGE_FLAG_RELOCATED) == 0) {
  1167. Status = ImpElfRelocateImage(ListHead, CurrentImage);
  1168. if (!KSUCCESS(Status)) {
  1169. goto RelocateImagesEnd;
  1170. }
  1171. CurrentImage->Flags |= IMAGE_FLAG_RELOCATED;
  1172. if (ImFinalizeSegments != NULL) {
  1173. Status = ImFinalizeSegments(CurrentImage->AllocatorHandle,
  1174. CurrentImage->Segments,
  1175. CurrentImage->SegmentCount);
  1176. if (!KSUCCESS(Status)) {
  1177. goto RelocateImagesEnd;
  1178. }
  1179. }
  1180. ImpElfFreeContext(CurrentImage);
  1181. }
  1182. CurrentEntry = CurrentEntry->Previous;
  1183. }
  1184. Status = STATUS_SUCCESS;
  1185. RelocateImagesEnd:
  1186. return Status;
  1187. }
  1188. VOID
  1189. ImpElfRelocateSelf (
  1190. PIMAGE_BUFFER Buffer,
  1191. PLOADED_IMAGE Image
  1192. )
  1193. /*++
  1194. Routine Description:
  1195. This routine relocates the currently running image.
  1196. Arguments:
  1197. Buffer - Supplies a pointer to the image buffer.
  1198. Image - Supplies a pointer to the zeroed but otherwise uninitialized
  1199. image buffer.
  1200. Return Value:
  1201. None.
  1202. --*/
  1203. {
  1204. LIST_ENTRY FakeList;
  1205. PSTR InterpreterPath;
  1206. ELF_LOADING_IMAGE LoadingImage;
  1207. KSTATUS Status;
  1208. //
  1209. // Create a fake image list, and a fake ELF loading image context.
  1210. //
  1211. INITIALIZE_LIST_HEAD(&FakeList);
  1212. RtlZeroMemory(&LoadingImage, sizeof(ELF_LOADING_IMAGE));
  1213. RtlCopyMemory(&(LoadingImage.Buffer), Buffer, sizeof(IMAGE_BUFFER));
  1214. //
  1215. // Set the "no static constructors" flag so that gather export information
  1216. // doesn't try to allocate a static functions structure.
  1217. //
  1218. Image->LoadFlags = IMAGE_LOAD_FLAG_PRIMARY_EXECUTABLE |
  1219. IMAGE_LOAD_FLAG_NO_STATIC_CONSTRUCTORS |
  1220. IMAGE_LOAD_FLAG_IGNORE_INTERPRETER;
  1221. Status = ImpElfGetImageSize(&FakeList, Image, Buffer, &InterpreterPath);
  1222. if (!KSUCCESS(Status)) {
  1223. goto ElfRelocateSelfEnd;
  1224. }
  1225. Image->File.Size = Image->Size;
  1226. LoadingImage.Buffer.Size = Image->Size;
  1227. LoadingImage.ElfHeader = Buffer->Data;
  1228. Image->BaseDifference = Buffer->Data - Image->PreferredLowestAddress;
  1229. Image->LoadedImageBuffer = Buffer->Data;
  1230. Image->ImageContext = &LoadingImage;
  1231. Status = ImpElfGatherExportInformation(Image, TRUE);
  1232. if (!KSUCCESS(Status)) {
  1233. goto ElfRelocateSelfEnd;
  1234. }
  1235. Status = ImpElfRelocateImage(&FakeList, Image);
  1236. ElfRelocateSelfEnd:
  1237. Image->ImageContext = NULL;
  1238. ASSERT(KSUCCESS(Status));
  1239. return;
  1240. }
  1241. KSTATUS
  1242. ImpElfGetSymbolByName (
  1243. PLOADED_IMAGE Image,
  1244. PSTR SymbolName,
  1245. PIMAGE_SYMBOL Symbol
  1246. )
  1247. /*++
  1248. Routine Description:
  1249. This routine attempts to find an exported symbol with the given name in the
  1250. given binary.
  1251. Arguments:
  1252. Image - Supplies a pointer to the image to query.
  1253. SymbolName - Supplies a pointer to the string containing the name of the
  1254. symbol to search for.
  1255. Symbol - Supplies a pointer to a structure that receives the symbol's
  1256. information on success.
  1257. Return Value:
  1258. Status code.
  1259. --*/
  1260. {
  1261. PELF_SYMBOL ElfSymbol;
  1262. ULONG Hash;
  1263. ELF_SYMBOL_TYPE SymbolType;
  1264. ELF_ADDR Value;
  1265. if ((Image->Flags & IMAGE_FLAG_GNU_HASH) != 0) {
  1266. Hash = ImpElfGnuHash(SymbolName);
  1267. } else {
  1268. Hash = ImpElfOriginalHash(SymbolName);
  1269. }
  1270. ElfSymbol = ImpElfGetSymbol(Image, Hash, SymbolName);
  1271. if ((ElfSymbol == NULL) || (ElfSymbol->SectionIndex == 0)) {
  1272. return STATUS_NOT_FOUND;
  1273. }
  1274. //
  1275. // TLS symbols are relative to their section base and are not adjusted.
  1276. //
  1277. Symbol->TlsAddress = FALSE;
  1278. SymbolType = ELF_GET_SYMBOL_TYPE(ElfSymbol->Information);
  1279. if (SymbolType == ElfSymbolTls) {
  1280. Value = ElfSymbol->Value;
  1281. Symbol->TlsAddress = TRUE;
  1282. } else if (ElfSymbol->SectionIndex >= ELF_SECTION_RESERVED_LOW) {
  1283. if (ElfSymbol->SectionIndex != ELF_SECTION_ABSOLUTE) {
  1284. return STATUS_NOT_FOUND;
  1285. }
  1286. Value = ElfSymbol->Value;
  1287. } else {
  1288. Value = ElfSymbol->Value + Image->BaseDifference;
  1289. }
  1290. Symbol->Address = (PVOID)(UINTN)Value;
  1291. Symbol->Name = Image->ExportStringTable + ElfSymbol->NameOffset;
  1292. Symbol->Image = Image;
  1293. return STATUS_SUCCESS;
  1294. }
  1295. KSTATUS
  1296. ImpElfGetSymbolByAddress (
  1297. PLOADED_IMAGE Image,
  1298. PVOID Address,
  1299. PIMAGE_SYMBOL Symbol
  1300. )
  1301. /*++
  1302. Routine Description:
  1303. This routine attempts to find the given address in the given image and
  1304. resolve it to a symbol.
  1305. Arguments:
  1306. Image - Supplies a pointer to the image to query.
  1307. Address - Supplies the address to search for.
  1308. Symbol - Supplies a pointer to a structure that receives the address's
  1309. symbol information on success.
  1310. Return Value:
  1311. Status code.
  1312. --*/
  1313. {
  1314. ELF_ADDR BaseDifference;
  1315. ELF_WORD BucketCount;
  1316. ELF_WORD BucketIndex;
  1317. PELF_SYMBOL ElfSymbol;
  1318. ELF_WORD FilterWords;
  1319. PELF_WORD HashBuckets;
  1320. PELF_WORD HashChains;
  1321. PELF_WORD HashTable;
  1322. PVOID LoadedLowestAddress;
  1323. ELF_ADDR SymbolAddress;
  1324. ELF_WORD SymbolBase;
  1325. ULONG SymbolHash;
  1326. ELF_WORD SymbolIndex;
  1327. PSTR SymbolName;
  1328. ELF_ADDR Value;
  1329. //
  1330. // If the address is not within the bounds of the image, then it should not
  1331. // be in the symbols.
  1332. //
  1333. BaseDifference = Image->BaseDifference;
  1334. LoadedLowestAddress = Image->PreferredLowestAddress + BaseDifference;
  1335. if ((Address < LoadedLowestAddress) ||
  1336. (Address >= (LoadedLowestAddress + Image->Size))) {
  1337. return STATUS_NOT_FOUND;
  1338. }
  1339. SymbolName = NULL;
  1340. SymbolAddress = 0;
  1341. //
  1342. // If there is no export symbol table for this image, then only report the
  1343. // image binary name and address without symbol information.
  1344. //
  1345. if (Image->ExportSymbolTable == NULL) {
  1346. goto GetAddressInformationEnd;
  1347. }
  1348. //
  1349. // Search for the symbol by its value, which is an address relative to the
  1350. // preferred lowest address.
  1351. //
  1352. Value = (ELF_ADDR)(UINTN)Address - BaseDifference;
  1353. //
  1354. // Handle GNU-style hashing to interate over the symbols.
  1355. //
  1356. if ((Image->Flags & IMAGE_FLAG_GNU_HASH) != 0) {
  1357. HashTable = Image->ExportHashTable;
  1358. BucketCount = *HashTable;
  1359. HashTable += 1;
  1360. SymbolBase = *HashTable;
  1361. HashTable += 1;
  1362. FilterWords = *HashTable;
  1363. HashTable += 2;
  1364. HashTable = (PELF_WORD)(HashTable + FilterWords);
  1365. for (BucketIndex = 0; BucketIndex < BucketCount; BucketIndex += 1) {
  1366. SymbolIndex = HashTable[BucketIndex];
  1367. if (SymbolIndex == 0) {
  1368. break;
  1369. }
  1370. if (SymbolIndex < SymbolBase) {
  1371. ASSERT(FALSE);
  1372. break;
  1373. }
  1374. HashChains = HashTable + BucketCount;
  1375. do {
  1376. SymbolHash = HashChains[SymbolIndex - SymbolBase];
  1377. ElfSymbol = (PELF_SYMBOL)Image->ExportSymbolTable + SymbolIndex;
  1378. if (((ElfSymbol->Size == 0) && (ElfSymbol->Value == Value)) ||
  1379. ((Value >= ElfSymbol->Value) &&
  1380. (Value < (ElfSymbol->Value + ElfSymbol->Size)))) {
  1381. SymbolName = Image->ExportStringTable +
  1382. ElfSymbol->NameOffset;
  1383. SymbolAddress = ElfSymbol->Value + BaseDifference;
  1384. goto GetAddressInformationEnd;
  1385. }
  1386. SymbolIndex += 1;
  1387. } while ((SymbolHash & 0x1) == 0);
  1388. }
  1389. //
  1390. // Handle SVR hashing's mode of storing symbols.
  1391. //
  1392. } else {
  1393. BucketCount = *((PELF_WORD)Image->ExportHashTable);
  1394. HashBuckets = (PELF_WORD)Image->ExportHashTable + 2;
  1395. HashChains = (PELF_WORD)Image->ExportHashTable + 2 + BucketCount;
  1396. for (BucketIndex = 0; BucketIndex < BucketCount; BucketIndex += 1) {
  1397. SymbolIndex = *(HashBuckets + BucketIndex);
  1398. while (SymbolIndex != 0) {
  1399. ElfSymbol = (PELF_SYMBOL)Image->ExportSymbolTable + SymbolIndex;
  1400. if (((ElfSymbol->Size == 0) && (ElfSymbol->Value == Value)) ||
  1401. ((Value >= ElfSymbol->Value) &&
  1402. (Value < (ElfSymbol->Value + ElfSymbol->Size)))) {
  1403. SymbolName = Image->ExportStringTable +
  1404. ElfSymbol->NameOffset;
  1405. SymbolAddress = ElfSymbol->Value + BaseDifference;
  1406. goto GetAddressInformationEnd;
  1407. }
  1408. //
  1409. // Get the next entry in the chain.
  1410. //
  1411. SymbolIndex = *(HashChains + SymbolIndex);
  1412. }
  1413. }
  1414. }
  1415. GetAddressInformationEnd:
  1416. Symbol->Image = Image;
  1417. Symbol->Name = SymbolName;
  1418. Symbol->Address = (PVOID)(UINTN)SymbolAddress;
  1419. Symbol->TlsAddress = FALSE;
  1420. return STATUS_SUCCESS;
  1421. }
  1422. PVOID
  1423. ImpElfResolvePltEntry (
  1424. PLIST_ENTRY ListHead,
  1425. PLOADED_IMAGE Image,
  1426. UINTN RelocationOffset
  1427. )
  1428. /*++
  1429. Routine Description:
  1430. This routine implements the slow path for a Procedure Linkable Table entry
  1431. that has not yet been resolved to its target function address. This routine
  1432. is only called once for each PLT entry, as subsequent calls jump directly
  1433. to the destination function address. It resolves the appropriate GOT
  1434. relocation and returns a pointer to the function to jump to.
  1435. Arguments:
  1436. ListHead - Supplies a pointer to the head of the list of images to use for
  1437. symbol resolution.
  1438. Image - Supplies a pointer to the loaded image whose PLT needs resolution.
  1439. This is really whatever pointer is in GOT + 4.
  1440. RelocationOffset - Supplies the byte offset from the start of the
  1441. relocation section where the relocation for this PLT entry resides, or
  1442. the PLT index, depending on the architecture.
  1443. Return Value:
  1444. Returns a pointer to the function to jump to (in addition to writing that
  1445. address in the GOT at the appropriate spot).
  1446. --*/
  1447. {
  1448. PVOID FunctionAddress;
  1449. PVOID RelocationEntry;
  1450. UINTN RelocationSize;
  1451. BOOL Result;
  1452. FunctionAddress = NULL;
  1453. //
  1454. // On ARM, what's passed in is a PLT index. Convert that to an offset based
  1455. // on the size of each PLT entry.
  1456. //
  1457. if (Image->Machine == ImageMachineTypeArm32) {
  1458. RelocationSize = sizeof(ELF32_RELOCATION_ENTRY);
  1459. if (Image->PltRelocationsAddends != FALSE) {
  1460. RelocationSize = sizeof(ELF32_RELOCATION_ADDEND_ENTRY);
  1461. }
  1462. RelocationOffset *= RelocationSize;
  1463. }
  1464. RelocationEntry = Image->PltRelocations + RelocationOffset;
  1465. Result = ImpElfApplyRelocation(ListHead,
  1466. Image,
  1467. RelocationEntry,
  1468. Image->PltRelocationsAddends,
  1469. &FunctionAddress);
  1470. ASSERT(Result != FALSE);
  1471. return FunctionAddress;
  1472. }
  1473. //
  1474. // --------------------------------------------------------- Internal Functions
  1475. //
  1476. KSTATUS
  1477. ImpElfLoadImportsForImage (
  1478. PLIST_ENTRY ListHead,
  1479. PLOADED_IMAGE Image
  1480. )
  1481. /*++
  1482. Routine Description:
  1483. This routine loads all import libraries for the given image. It does not
  1484. perform relocations or load imports of the imports.
  1485. Arguments:
  1486. ListHead - Supplies a pointer to the head of the list of loaded images.
  1487. Image - Supplies a pointer to the loaded image structure.
  1488. Return Value:
  1489. Status code.
  1490. --*/
  1491. {
  1492. PELF_DYNAMIC_ENTRY DynamicEntry;
  1493. PLOADED_IMAGE Import;
  1494. ULONG ImportCount;
  1495. ULONG ImportIndex;
  1496. PSTR ImportName;
  1497. ULONG LoadFlags;
  1498. PELF_LOADING_IMAGE LoadingImage;
  1499. KSTATUS Status;
  1500. ELF_OFF StringTableOffset;
  1501. LoadingImage = Image->ImageContext;
  1502. ASSERT(LoadingImage != NULL);
  1503. DynamicEntry = Image->DynamicSection;
  1504. Status = STATUS_SUCCESS;
  1505. if (DynamicEntry == NULL) {
  1506. goto LoadImportsForImageEnd;
  1507. }
  1508. //
  1509. // Loop over all dynamic entries once to count the number of import
  1510. // libraries needed.
  1511. //
  1512. ImportCount = 0;
  1513. while (DynamicEntry->Tag != ELF_DYNAMIC_NULL) {
  1514. //
  1515. // A "needed" entry indicates a required import library.
  1516. //
  1517. if (DynamicEntry->Tag == ELF_DYNAMIC_NEEDED) {
  1518. ImportCount += 1;
  1519. }
  1520. DynamicEntry += 1;
  1521. }
  1522. if (ImportCount == 0) {
  1523. Status = STATUS_SUCCESS;
  1524. goto LoadImportsForImageEnd;
  1525. }
  1526. //
  1527. // Allocate space to hold the imports.
  1528. //
  1529. ASSERT(Image->Imports == NULL);
  1530. Image->Imports = ImAllocateMemory(ImportCount * sizeof(PLOADED_IMAGE),
  1531. IM_ALLOCATION_TAG);
  1532. if (Image->Imports == NULL) {
  1533. Status = STATUS_INSUFFICIENT_RESOURCES;
  1534. goto LoadImportsForImageEnd;
  1535. }
  1536. RtlZeroMemory(Image->Imports, ImportCount * sizeof(PLOADED_IMAGE));
  1537. Image->ImportCount = ImportCount;
  1538. ImportIndex = 0;
  1539. DynamicEntry = Image->DynamicSection;
  1540. while (DynamicEntry->Tag != ELF_DYNAMIC_NULL) {
  1541. //
  1542. // A "needed" entry indicates a required import library.
  1543. //
  1544. if (DynamicEntry->Tag == ELF_DYNAMIC_NEEDED) {
  1545. StringTableOffset = DynamicEntry->Value;
  1546. ASSERT((Image->ExportStringTable != NULL) &&
  1547. (StringTableOffset < Image->ExportStringTableSize));
  1548. ImportName = (PSTR)Image->ExportStringTable + StringTableOffset;
  1549. //
  1550. // Load the import. Dynamic libraries shouldn't have interpreters
  1551. // specified.
  1552. //
  1553. LoadFlags = Image->LoadFlags | IMAGE_LOAD_FLAG_IGNORE_INTERPRETER;
  1554. LoadFlags &= ~IMAGE_LOAD_FLAG_PRIMARY_EXECUTABLE;
  1555. Status = ImpLoad(ListHead,
  1556. ImportName,
  1557. NULL,
  1558. NULL,
  1559. Image->SystemContext,
  1560. LoadFlags,
  1561. Image,
  1562. &Import,
  1563. NULL);
  1564. if (!KSUCCESS(Status)) {
  1565. RtlDebugPrint("%s: Failed to find import '%s'.\n",
  1566. Image->FileName,
  1567. ImportName);
  1568. goto LoadImportsForImageEnd;
  1569. }
  1570. Image->Imports[ImportIndex] = Import;
  1571. ImportIndex += 1;
  1572. }
  1573. DynamicEntry += 1;
  1574. }
  1575. LoadImportsForImageEnd:
  1576. if (!KSUCCESS(Status)) {
  1577. if (Image->Imports != NULL) {
  1578. if (ImportIndex != 0) {
  1579. ImportCount = ImportIndex - 1;
  1580. for (ImportIndex = 0;
  1581. ImportIndex < ImportCount;
  1582. ImportIndex += 1) {
  1583. ImImageReleaseReference(Image->Imports[ImportIndex]);
  1584. }
  1585. }
  1586. ImFreeMemory(Image->Imports);
  1587. Image->Imports = NULL;
  1588. Image->ImportCount = 0;
  1589. }
  1590. }
  1591. return Status;
  1592. }
  1593. KSTATUS
  1594. ImpElfGatherExportInformation (
  1595. PLOADED_IMAGE Image,
  1596. BOOL UseLoadedAddress
  1597. )
  1598. /*++
  1599. Routine Description:
  1600. This routine gathers necessary pointers from the non-loaded portion of the
  1601. image file needed to retrieve exports from the image.
  1602. Arguments:
  1603. Image - Supplies a pointer to the loaded image.
  1604. UseLoadedAddress - Supplies a boolean indicating whether to use the file
  1605. offset (FALSE) or the final virtual address (TRUE).
  1606. Return Value:
  1607. Status code.
  1608. --*/
  1609. {
  1610. PVOID Address;
  1611. ELF_ADDR BaseDifference;
  1612. PELF_DYNAMIC_ENTRY DynamicEntry;
  1613. PVOID DynamicSymbols;
  1614. PVOID DynamicSymbolStrings;
  1615. ELF_XWORD DynamicSymbolStringsSize;
  1616. PELF_ADDR Got;
  1617. PELF_WORD HashTable;
  1618. ELF_XWORD HashTag;
  1619. ELF_HALF HeaderCount;
  1620. ELF_HALF Index;
  1621. ELF_XWORD LibraryNameOffset;
  1622. PELF_LOADING_IMAGE LoadingImage;
  1623. PVOID PltRelocations;
  1624. BOOL PltRelocationsAddends;
  1625. PELF_PROGRAM_HEADER ProgramHeader;
  1626. PIMAGE_STATIC_FUNCTIONS StaticFunctions;
  1627. KSTATUS Status;
  1628. ELF_SXWORD Tag;
  1629. ELF_XWORD Value;
  1630. DynamicSymbols = NULL;
  1631. DynamicSymbolStrings = NULL;
  1632. DynamicSymbolStringsSize = 0;
  1633. HashTable = NULL;
  1634. HashTag = 0;
  1635. LibraryNameOffset = 0;
  1636. LoadingImage = Image->ImageContext;
  1637. HeaderCount = LoadingImage->ElfHeader->ProgramHeaderCount;
  1638. PltRelocations = NULL;
  1639. PltRelocationsAddends = FALSE;
  1640. ProgramHeader = NULL;
  1641. StaticFunctions = NULL;
  1642. //
  1643. // This function is not using the read buffer functions because it should
  1644. // only be called in the actual runtime address space, in which case the
  1645. // image is fully loaded.
  1646. //
  1647. ASSERT(LoadingImage->Buffer.Size == Image->File.Size);
  1648. //
  1649. // Loop through the program headers to find the dynamic section.
  1650. //
  1651. for (Index = 0; Index < HeaderCount; Index += 1) {
  1652. ProgramHeader = LoadingImage->Buffer.Data +
  1653. LoadingImage->ElfHeader->ProgramHeaderOffset +
  1654. (Index * LoadingImage->ElfHeader->ProgramHeaderSize);
  1655. if (ProgramHeader->Type == ELF_SEGMENT_TYPE_DYNAMIC) {
  1656. break;
  1657. }
  1658. }
  1659. if (Index == LoadingImage->ElfHeader->ProgramHeaderCount) {
  1660. Status = STATUS_SUCCESS;
  1661. goto GatherExportInformationEnd;
  1662. }
  1663. //
  1664. // Allocate the static functions structure if needed.
  1665. //
  1666. StaticFunctions = Image->StaticFunctions;
  1667. if ((StaticFunctions == NULL) &&
  1668. ((Image->LoadFlags & IMAGE_LOAD_FLAG_NO_STATIC_CONSTRUCTORS) == 0)) {
  1669. StaticFunctions = ImAllocateMemory(sizeof(IMAGE_STATIC_FUNCTIONS),
  1670. IM_ALLOCATION_TAG);
  1671. if (StaticFunctions == NULL) {
  1672. Status = STATUS_INSUFFICIENT_RESOURCES;
  1673. goto GatherExportInformationEnd;
  1674. }
  1675. RtlZeroMemory(StaticFunctions, sizeof(IMAGE_STATIC_FUNCTIONS));
  1676. Image->StaticFunctions = StaticFunctions;
  1677. }
  1678. BaseDifference = Image->BaseDifference;
  1679. //
  1680. // If the loaded image buffer address is the loaded address, then go ahead
  1681. // and indicate things are live.
  1682. //
  1683. if (Image->PreferredLowestAddress + BaseDifference ==
  1684. Image->LoadedImageBuffer) {
  1685. UseLoadedAddress = TRUE;
  1686. }
  1687. if (UseLoadedAddress != FALSE) {
  1688. BaseDifference = Image->BaseDifference;
  1689. DynamicEntry = (PVOID)(UINTN)(ProgramHeader->VirtualAddress +
  1690. BaseDifference);
  1691. } else {
  1692. BaseDifference = Image->LoadedImageBuffer -
  1693. Image->PreferredLowestAddress;
  1694. DynamicEntry = LoadingImage->Buffer.Data + ProgramHeader->Offset;
  1695. }
  1696. //
  1697. // Save the pointer to the dynamic section header and dynamic symbol count.
  1698. // This is used by the load import routine.
  1699. //
  1700. Image->DynamicSection = DynamicEntry;
  1701. while (DynamicEntry->Tag != ELF_DYNAMIC_NULL) {
  1702. Tag = DynamicEntry->Tag;
  1703. Value = DynamicEntry->Value;
  1704. Address = (PVOID)(UINTN)(Value + BaseDifference);
  1705. switch (Tag) {
  1706. case ELF_DYNAMIC_LIBRARY_NAME:
  1707. LibraryNameOffset = Value;
  1708. break;
  1709. //
  1710. // Remember the string table.
  1711. //
  1712. case ELF_DYNAMIC_STRING_TABLE:
  1713. DynamicSymbolStrings = Address;
  1714. break;
  1715. //
  1716. // Remember the string table size.
  1717. //
  1718. case ELF_DYNAMIC_STRING_TABLE_SIZE:
  1719. DynamicSymbolStringsSize = Value;
  1720. break;
  1721. //
  1722. // Remember the symbol table.
  1723. //
  1724. case ELF_DYNAMIC_SYMBOL_TABLE:
  1725. DynamicSymbols = Address;
  1726. break;
  1727. //
  1728. // Remember the hash table.
  1729. //
  1730. case ELF_DYNAMIC_HASH_TABLE:
  1731. case ELF_DYNAMIC_GNU_HASH_TABLE:
  1732. HashTable = Address;
  1733. HashTag = Tag;
  1734. break;
  1735. //
  1736. // Remember static constructor and destructor array boundaries, and the
  1737. // old _init and _fini functions.
  1738. //
  1739. case ELF_DYNAMIC_PREINIT_ARRAY:
  1740. if (StaticFunctions != NULL) {
  1741. StaticFunctions->PreinitArray = Address;
  1742. }
  1743. break;
  1744. case ELF_DYNAMIC_INIT_ARRAY:
  1745. if (StaticFunctions != NULL) {
  1746. StaticFunctions->InitArray = Address;
  1747. }
  1748. break;
  1749. case ELF_DYNAMIC_FINI_ARRAY:
  1750. if (StaticFunctions != NULL) {
  1751. StaticFunctions->FiniArray = Address;
  1752. }
  1753. break;
  1754. case ELF_DYNAMIC_INIT:
  1755. if (StaticFunctions != NULL) {
  1756. StaticFunctions->InitFunction = Address;
  1757. }
  1758. break;
  1759. case ELF_DYNAMIC_FINI:
  1760. if (StaticFunctions != NULL) {
  1761. StaticFunctions->FiniFunction = Address;
  1762. }
  1763. break;
  1764. case ELF_DYNAMIC_PREINIT_ARRAY_SIZE:
  1765. if (StaticFunctions != NULL) {
  1766. StaticFunctions->PreinitArraySize = Value;
  1767. }
  1768. break;
  1769. case ELF_DYNAMIC_INIT_ARRAY_SIZE:
  1770. if (StaticFunctions != NULL) {
  1771. StaticFunctions->InitArraySize = Value;
  1772. }
  1773. break;
  1774. case ELF_DYNAMIC_FINI_ARRAY_SIZE:
  1775. if (StaticFunctions != NULL) {
  1776. StaticFunctions->FiniArraySize = Value;
  1777. }
  1778. break;
  1779. case ELF_DYNAMIC_FLAGS:
  1780. if ((Value & ELF_DYNAMIC_FLAG_STATIC_TLS) != 0) {
  1781. Image->Flags |= IMAGE_FLAG_STATIC_TLS;
  1782. //
  1783. // Images with a static TLS model cannot be loaded dynamically,
  1784. // the must be loaded with the initial executable.
  1785. //
  1786. if ((Image->LoadFlags & IMAGE_LOAD_FLAG_PRIMARY_LOAD) == 0) {
  1787. Status = STATUS_TOO_LATE;
  1788. goto GatherExportInformationEnd;
  1789. }
  1790. }
  1791. break;
  1792. //
  1793. // Upon finding the GOT, save the image and the resolution address in
  1794. // the second and third entries of the GOT. Note that reaching through
  1795. // a global would be bad if trying to relocate oneself, but that
  1796. // should only ever be done by the dynamic linker, which won't have
  1797. // imports.
  1798. //
  1799. case ELF_DYNAMIC_PLT_GOT:
  1800. Got = Address;
  1801. Got[1] = (UINTN)Image;
  1802. Got[2] = (UINTN)(ImImportTable->ResolvePltEntry);
  1803. break;
  1804. //
  1805. // Remember where the Procedure Linkage Table relocations are for
  1806. // lazy binding.
  1807. //
  1808. case ELF_DYNAMIC_JUMP_RELOCATIONS:
  1809. PltRelocations = Address;
  1810. break;
  1811. case ELF_DYNAMIC_PLT_RELOCATION_TYPE:
  1812. if (DynamicEntry->Value == ELF_DYNAMIC_RELA_TABLE) {
  1813. PltRelocationsAddends = TRUE;
  1814. }
  1815. break;
  1816. case ELF_DYNAMIC_TEXT_RELOCATIONS:
  1817. Image->Flags |= IMAGE_FLAG_TEXT_RELOCATIONS;
  1818. break;
  1819. //
  1820. // Stick a pointer to the debug structure into the debug dynamic entry.
  1821. // Don't do this if loading from some alternate address space.
  1822. //
  1823. case ELF_DYNAMIC_DEBUG:
  1824. if (UseLoadedAddress != FALSE) {
  1825. DynamicEntry->Value = (ELF_SWORD)&(Image->Debug);
  1826. }
  1827. break;
  1828. case ELF_DYNAMIC_BIND_NOW:
  1829. Image->LoadFlags |= IMAGE_LOAD_FLAG_BIND_NOW;
  1830. break;
  1831. default:
  1832. break;
  1833. }
  1834. DynamicEntry += 1;
  1835. }
  1836. //
  1837. // If one of the required elements was not found, then as far as this
  1838. // library is concerned there is no export information.
  1839. //
  1840. if ((DynamicSymbols == NULL) || (DynamicSymbolStrings == NULL) ||
  1841. (DynamicSymbolStringsSize == 0) || (HashTable == NULL)) {
  1842. Status = STATUS_SUCCESS;
  1843. goto GatherExportInformationEnd;
  1844. }
  1845. Image->ExportSymbolTable = DynamicSymbols;
  1846. Image->ExportStringTable = DynamicSymbolStrings;
  1847. Image->ExportStringTableSize = DynamicSymbolStringsSize;
  1848. Image->ExportHashTable = HashTable;
  1849. Image->PltRelocations = PltRelocations;
  1850. Image->PltRelocationsAddends = PltRelocationsAddends;
  1851. if (HashTag == ELF_DYNAMIC_GNU_HASH_TABLE) {
  1852. Image->Flags |= IMAGE_FLAG_GNU_HASH;
  1853. }
  1854. //
  1855. // Set the library name if there is one.
  1856. //
  1857. if (LibraryNameOffset != 0) {
  1858. Image->LibraryName = DynamicSymbolStrings + LibraryNameOffset;
  1859. }
  1860. Status = STATUS_SUCCESS;
  1861. GatherExportInformationEnd:
  1862. return Status;
  1863. }
  1864. PELF_DYNAMIC_ENTRY
  1865. ImpElfGetDynamicEntry (
  1866. PLOADED_IMAGE Image,
  1867. ELF_SXWORD Tag
  1868. )
  1869. /*++
  1870. Routine Description:
  1871. This routine attempts to find a dynamic entry with the given tag.
  1872. Arguments:
  1873. Image - Supplies a pointer to the image.
  1874. Tag - Supplies the desired tag.
  1875. Return Value:
  1876. Returns a pointer to the requested entry on success.
  1877. NULL if the entry could not be found or there is no dynamic section.
  1878. --*/
  1879. {
  1880. PELF_DYNAMIC_ENTRY Entry;
  1881. Entry = Image->DynamicSection;
  1882. if (Entry != NULL) {
  1883. while (Entry->Tag != ELF_DYNAMIC_NULL) {
  1884. if (Entry->Tag == Tag) {
  1885. return Entry;
  1886. }
  1887. Entry += 1;
  1888. }
  1889. }
  1890. return NULL;
  1891. }
  1892. KSTATUS
  1893. ImpElfRelocateImage (
  1894. PLIST_ENTRY ListHead,
  1895. PLOADED_IMAGE Image
  1896. )
  1897. /*++
  1898. Routine Description:
  1899. This routine relocates a loaded image.
  1900. Arguments:
  1901. ListHead - Supplies a pointer to the head of the list of loaded images.
  1902. Image - Supplies a pointer to the loaded image.
  1903. Return Value:
  1904. Status code.
  1905. --*/
  1906. {
  1907. PVOID Address;
  1908. ELF_ADDR BaseDifference;
  1909. PELF_DYNAMIC_ENTRY DynamicEntry;
  1910. PELF_LOADING_IMAGE LoadingImage;
  1911. BOOL PltRelocationAddends;
  1912. PVOID PltRelocations;
  1913. ELF_XWORD PltRelocationsSize;
  1914. PVOID Relocations;
  1915. PVOID RelocationsAddends;
  1916. ELF_XWORD RelocationsAddendsSize;
  1917. ELF_XWORD RelocationsSize;
  1918. UINTN Size;
  1919. KSTATUS Status;
  1920. LoadingImage = Image->ImageContext;
  1921. ASSERT(LoadingImage != NULL);
  1922. ASSERT((Image->LoadFlags & IMAGE_LOAD_FLAG_PLACEHOLDER) == 0);
  1923. PltRelocationAddends = FALSE;
  1924. PltRelocations = NULL;
  1925. PltRelocationsSize = 0;
  1926. Relocations = NULL;
  1927. RelocationsAddends = NULL;
  1928. RelocationsSize = 0;
  1929. RelocationsAddendsSize = 0;
  1930. LoadingImage->RelocationStart = ELF_INVALID_RELOCATION;
  1931. LoadingImage->RelocationEnd = ELF_INVALID_RELOCATION;
  1932. BaseDifference = (UINTN)(Image->LoadedImageBuffer -
  1933. Image->PreferredLowestAddress);
  1934. DynamicEntry = Image->DynamicSection;
  1935. if (DynamicEntry == NULL) {
  1936. Status = STATUS_SUCCESS;
  1937. goto RelocateImageEnd;
  1938. }
  1939. while (DynamicEntry->Tag != ELF_DYNAMIC_NULL) {
  1940. Address = (PVOID)(UINTN)(DynamicEntry->Value + BaseDifference);
  1941. switch (DynamicEntry->Tag) {
  1942. case ELF_DYNAMIC_REL_TABLE:
  1943. Relocations = Address;
  1944. break;
  1945. case ELF_DYNAMIC_REL_TABLE_SIZE:
  1946. RelocationsSize = DynamicEntry->Value;
  1947. break;
  1948. case ELF_DYNAMIC_RELA_TABLE:
  1949. RelocationsAddends = Address;
  1950. break;
  1951. case ELF_DYNAMIC_RELA_TABLE_SIZE:
  1952. RelocationsAddendsSize = DynamicEntry->Value;
  1953. break;
  1954. case ELF_DYNAMIC_JUMP_RELOCATIONS:
  1955. PltRelocations = Address;
  1956. break;
  1957. case ELF_DYNAMIC_PLT_REL_SIZE:
  1958. PltRelocationsSize = DynamicEntry->Value;
  1959. break;
  1960. case ELF_DYNAMIC_PLT_RELOCATION_TYPE:
  1961. if (DynamicEntry->Value == ELF_DYNAMIC_RELA_TABLE) {
  1962. PltRelocationAddends = TRUE;
  1963. }
  1964. break;
  1965. default:
  1966. break;
  1967. }
  1968. DynamicEntry += 1;
  1969. }
  1970. if ((Relocations != NULL) && (RelocationsSize != 0)) {
  1971. Status = ImpElfProcessRelocateSection(ListHead,
  1972. Image,
  1973. Relocations,
  1974. RelocationsSize,
  1975. FALSE);
  1976. if (!KSUCCESS(Status)) {
  1977. goto RelocateImageEnd;
  1978. }
  1979. }
  1980. if ((RelocationsAddends != NULL) && (RelocationsAddendsSize != 0)) {
  1981. Status = ImpElfProcessRelocateSection(ListHead,
  1982. Image,
  1983. RelocationsAddends,
  1984. RelocationsAddendsSize,
  1985. TRUE);
  1986. if (!KSUCCESS(Status)) {
  1987. goto RelocateImageEnd;
  1988. }
  1989. }
  1990. //
  1991. // Only process the PLT relocations now if lazy binding is disabled.
  1992. // Otherwise, these relocations get patched up when they're called, but
  1993. // need to be adjusted by the base difference. This is much faster as
  1994. // symbol lookups don't need to be done.
  1995. //
  1996. if ((PltRelocations != NULL) && (PltRelocationsSize != 0)) {
  1997. if ((Image->LoadFlags & IMAGE_LOAD_FLAG_BIND_NOW) != 0) {
  1998. Status = ImpElfProcessRelocateSection(ListHead,
  1999. Image,
  2000. PltRelocations,
  2001. PltRelocationsSize,
  2002. PltRelocationAddends);
  2003. if (!KSUCCESS(Status)) {
  2004. goto RelocateImageEnd;
  2005. }
  2006. } else {
  2007. ImpElfAdjustJumpSlots(Image,
  2008. PltRelocations,
  2009. PltRelocationsSize,
  2010. PltRelocationAddends);
  2011. }
  2012. }
  2013. Status = STATUS_SUCCESS;
  2014. RelocateImageEnd:
  2015. if (LoadingImage->RelocationStart != ELF_INVALID_RELOCATION) {
  2016. ASSERT((Image->Flags & IMAGE_FLAG_TEXT_RELOCATIONS) != 0);
  2017. ASSERT(LoadingImage->RelocationEnd != ELF_INVALID_RELOCATION);
  2018. ASSERT(LoadingImage->RelocationEnd > LoadingImage->RelocationStart);
  2019. Size = LoadingImage->RelocationEnd - LoadingImage->RelocationStart;
  2020. ImInvalidateInstructionCacheRegion(LoadingImage->RelocationStart, Size);
  2021. }
  2022. return Status;
  2023. }
  2024. KSTATUS
  2025. ImpElfProcessRelocateSection (
  2026. PLIST_ENTRY ListHead,
  2027. PLOADED_IMAGE Image,
  2028. PVOID Relocations,
  2029. ELF_XWORD RelocationsSize,
  2030. BOOL Addends
  2031. )
  2032. /*++
  2033. Routine Description:
  2034. This routine processes the contents of a single relocation section.
  2035. Arguments:
  2036. ListHead - Supplies a pointer to the head of the list of loaded images.
  2037. Image - Supplies a pointer to the loaded image structure.
  2038. Relocations - Supplies a pointer to the relocations to apply.
  2039. RelocationsSize - Supplies the size of the relocation section in bytes.
  2040. Addends - Supplies a boolean indicating whether these are relocations with
  2041. explicit addends (TRUE) or implicit addends (FALSE).
  2042. Return Value:
  2043. Status code.
  2044. --*/
  2045. {
  2046. PELF_RELOCATION_ENTRY Relocation;
  2047. PELF_RELOCATION_ADDEND_ENTRY RelocationAddend;
  2048. ELF_XWORD RelocationCount;
  2049. UINTN RelocationIndex;
  2050. BOOL Result;
  2051. RelocationAddend = Relocations;
  2052. Relocation = Relocations;
  2053. if (Addends != FALSE) {
  2054. RelocationCount = RelocationsSize / sizeof(ELF_RELOCATION_ADDEND_ENTRY);
  2055. } else {
  2056. RelocationCount = RelocationsSize / sizeof(ELF_RELOCATION_ENTRY);
  2057. }
  2058. //
  2059. // Process each relocation in the table.
  2060. //
  2061. for (RelocationIndex = 0;
  2062. RelocationIndex < RelocationCount;
  2063. RelocationIndex += 1) {
  2064. if (Addends != FALSE) {
  2065. Result = ImpElfApplyRelocation(ListHead,
  2066. Image,
  2067. RelocationAddend,
  2068. TRUE,
  2069. NULL);
  2070. ASSERT(Result != FALSE);
  2071. if (Result == FALSE) {
  2072. return STATUS_INVALID_PARAMETER;
  2073. }
  2074. RelocationAddend += 1;
  2075. } else {
  2076. Result = ImpElfApplyRelocation(ListHead,
  2077. Image,
  2078. (PVOID)Relocation,
  2079. FALSE,
  2080. NULL);
  2081. ASSERT(Result != FALSE);
  2082. if (Result == FALSE) {
  2083. return STATUS_INVALID_PARAMETER;
  2084. }
  2085. Relocation += 1;
  2086. }
  2087. }
  2088. return STATUS_SUCCESS;
  2089. }
  2090. VOID
  2091. ImpElfAdjustJumpSlots (
  2092. PLOADED_IMAGE Image,
  2093. PVOID Relocations,
  2094. ELF_XWORD RelocationsSize,
  2095. BOOL Addends
  2096. )
  2097. /*++
  2098. Routine Description:
  2099. This routine iterates over all the relocations in the PLT section and adds
  2100. the base difference to them.
  2101. Arguments:
  2102. Image - Supplies a pointer to the loaded image structure.
  2103. Relocations - Supplies a pointer to the relocations to apply.
  2104. RelocationsSize - Supplies the size of the relocation section in bytes.
  2105. Addends - Supplies a boolean indicating whether these are relocations with
  2106. explicit addends (TRUE) or implicit addends (FALSE).
  2107. Return Value:
  2108. Status code.
  2109. --*/
  2110. {
  2111. ELF_ADDR BaseDifference;
  2112. ELF_XWORD Information;
  2113. ELF_ADDR Offset;
  2114. PELF_RELOCATION_ENTRY Relocation;
  2115. PELF_RELOCATION_ADDEND_ENTRY RelocationAddend;
  2116. ELF_XWORD RelocationCount;
  2117. UINTN RelocationIndex;
  2118. PELF_ADDR RelocationPlace;
  2119. ELF_WORD RelocationType;
  2120. BaseDifference = Image->BaseDifference;
  2121. if (BaseDifference == 0) {
  2122. return;
  2123. }
  2124. RelocationAddend = Relocations;
  2125. Relocation = Relocations;
  2126. if (Addends != FALSE) {
  2127. RelocationCount = RelocationsSize /
  2128. sizeof(ELF_RELOCATION_ADDEND_ENTRY);
  2129. } else {
  2130. RelocationCount = RelocationsSize / sizeof(ELF_RELOCATION_ENTRY);
  2131. }
  2132. //
  2133. // Process each relocation in the table.
  2134. //
  2135. for (RelocationIndex = 0;
  2136. RelocationIndex < RelocationCount;
  2137. RelocationIndex += 1) {
  2138. if (Addends != FALSE) {
  2139. Offset = RelocationAddend->Offset;
  2140. Information = RelocationAddend->Information;
  2141. RelocationAddend += 1;
  2142. } else {
  2143. Offset = Relocation->Offset;
  2144. Information = Relocation->Information;
  2145. Relocation += 1;
  2146. }
  2147. RelocationType = ELF_GET_RELOCATION_TYPE(Information);
  2148. //
  2149. // If this is a jump slot relocation, bump it up by the base difference.
  2150. //
  2151. if (((Image->Machine == ImageMachineTypeArm32) &&
  2152. (RelocationType == ElfArmRelocationJumpSlot)) ||
  2153. ((Image->Machine == ImageMachineTypeX86) &&
  2154. (RelocationType == Elf386RelocationJumpSlot))) {
  2155. RelocationPlace = (PELF_ADDR)((PUCHAR)Image->LoadedImageBuffer +
  2156. (Offset - (UINTN)Image->PreferredLowestAddress));
  2157. *RelocationPlace += BaseDifference;
  2158. }
  2159. }
  2160. return;
  2161. }
  2162. ELF_ADDR
  2163. ImpElfGetSymbolValue (
  2164. PLIST_ENTRY ListHead,
  2165. PLOADED_IMAGE Image,
  2166. PELF_SYMBOL Symbol,
  2167. PLOADED_IMAGE *FoundImage,
  2168. PLOADED_IMAGE SkipImage
  2169. )
  2170. /*++
  2171. Routine Description:
  2172. This routine determines the address of the given symbol.
  2173. Arguments:
  2174. ListHead - Supplies a pointer to the head of the list of loaded images.
  2175. Image - Supplies a pointer to the loaded image.
  2176. Symbol - Supplies a pointer to the symbol whose value should be computed.
  2177. FoundImage - Supplies an optional pointer where the image where the symbol
  2178. is defined will be returned on success.
  2179. SkipImage - Supplies an optional pointer to an image to ignore when
  2180. searching for a symbol definition. This is used in copy relocations
  2181. when looking for the shared object version of a symbol defined in
  2182. both the executable and a shared object.
  2183. Return Value:
  2184. Returns the symbol's value on success.
  2185. ELF_INVALID_ADDRESS on failure.
  2186. --*/
  2187. {
  2188. ELF_ADDR BaseDifference;
  2189. ELF_SYMBOL_BIND_TYPE BindType;
  2190. PLIST_ENTRY CurrentEntry;
  2191. PLOADED_IMAGE CurrentImage;
  2192. ULONG Hash;
  2193. ULONG OriginalHash;
  2194. PELF_SYMBOL Potential;
  2195. CHAR PrintSymbolName[50];
  2196. PSTR SymbolName;
  2197. ELF_SYMBOL_TYPE SymbolType;
  2198. ELF_ADDR Value;
  2199. CurrentImage = NULL;
  2200. BaseDifference = Image->BaseDifference;
  2201. BindType = ELF_GET_SYMBOL_BIND(Symbol->Information);
  2202. if (Symbol->NameOffset != 0) {
  2203. SymbolName = Image->ExportStringTable + Symbol->NameOffset;
  2204. if ((Image->Flags & IMAGE_FLAG_GNU_HASH) != 0) {
  2205. Hash = ImpElfGnuHash(SymbolName);
  2206. } else {
  2207. Hash = ImpElfOriginalHash(SymbolName);
  2208. }
  2209. OriginalHash = Hash;
  2210. CurrentEntry = ListHead->Next;
  2211. if (BindType == ElfBindLocal) {
  2212. ASSERT(SkipImage == NULL);
  2213. CurrentEntry = &(Image->ListEntry);
  2214. }
  2215. while (CurrentEntry != ListHead) {
  2216. CurrentImage = LIST_VALUE(CurrentEntry, LOADED_IMAGE, ListEntry);
  2217. if (CurrentImage == SkipImage) {
  2218. CurrentEntry = CurrentEntry->Next;
  2219. continue;
  2220. }
  2221. //
  2222. // If the two images disagree on hashing algorithms, then recompute
  2223. // the hash for the image.
  2224. //
  2225. if (((CurrentImage->Flags ^ Image->Flags) &
  2226. IMAGE_FLAG_GNU_HASH) != 0) {
  2227. if ((CurrentImage->Flags & IMAGE_FLAG_GNU_HASH) != 0) {
  2228. Hash = ImpElfGnuHash(SymbolName);
  2229. } else {
  2230. Hash = ImpElfOriginalHash(SymbolName);
  2231. }
  2232. }
  2233. Potential = ImpElfGetSymbol(CurrentImage, Hash, SymbolName);
  2234. Hash = OriginalHash;
  2235. //
  2236. // Don't match against the same undefined symbol in another image.
  2237. //
  2238. if ((Potential != NULL) && (Potential->SectionIndex != 0)) {
  2239. //
  2240. // TLS symbols are relative to their section base, and are
  2241. // not adjusted.
  2242. //
  2243. SymbolType = ELF_GET_SYMBOL_TYPE(Symbol->Information);
  2244. if (SymbolType == ElfSymbolTls) {
  2245. Value = Potential->Value;
  2246. goto ElfGetSymbolValueEnd;
  2247. } else if (Potential->SectionIndex >=
  2248. ELF_SECTION_RESERVED_LOW) {
  2249. Value = ELF_INVALID_ADDRESS;
  2250. if (Potential->SectionIndex == ELF_SECTION_ABSOLUTE) {
  2251. Value = Potential->Value;
  2252. }
  2253. goto ElfGetSymbolValueEnd;
  2254. }
  2255. Value = Potential->Value + CurrentImage->BaseDifference;
  2256. goto ElfGetSymbolValueEnd;
  2257. }
  2258. //
  2259. // Don't look in other images if it's a local symbol.
  2260. //
  2261. if (BindType == ElfBindLocal) {
  2262. break;
  2263. }
  2264. CurrentEntry = CurrentEntry->Next;
  2265. }
  2266. if (CurrentEntry == ListHead) {
  2267. CurrentImage = NULL;
  2268. }
  2269. //
  2270. // This symbol is not defined. If it's weak, that's okay. Otherwise,
  2271. // that's a problem.
  2272. //
  2273. if (BindType != ElfBindWeak) {
  2274. //
  2275. // Copy the symbol name to the stack to avoid deadly faults during
  2276. // debug print.
  2277. //
  2278. RtlStringCopy(PrintSymbolName, SymbolName, sizeof(PrintSymbolName));
  2279. RtlDebugPrint("Warning: Unresolved reference to symbol %s.\n",
  2280. PrintSymbolName);
  2281. Value = ELF_INVALID_ADDRESS;
  2282. } else {
  2283. Value = 0;
  2284. }
  2285. goto ElfGetSymbolValueEnd;
  2286. }
  2287. //
  2288. // If the section index is a reserved value, check to see if it's an
  2289. // absolute symbol. If it is, just return the symbol value. Other reserved
  2290. // values usually mean the symbol's value cannot be computed at this time.
  2291. //
  2292. if ((Symbol->SectionIndex == 0) ||
  2293. (Symbol->SectionIndex >= ELF_SECTION_RESERVED_LOW)) {
  2294. Value = ELF_INVALID_ADDRESS;
  2295. if (Symbol->SectionIndex == ELF_SECTION_ABSOLUTE) {
  2296. Value = Symbol->Value;
  2297. }
  2298. goto ElfGetSymbolValueEnd;
  2299. }
  2300. Value = Symbol->Value + BaseDifference;
  2301. ElfGetSymbolValueEnd:
  2302. if (FoundImage != NULL) {
  2303. *FoundImage = CurrentImage;
  2304. }
  2305. return Value;
  2306. }
  2307. PELF_SYMBOL
  2308. ImpElfGetSymbol (
  2309. PLOADED_IMAGE Image,
  2310. ULONG Hash,
  2311. PSTR SymbolName
  2312. )
  2313. /*++
  2314. Routine Description:
  2315. This routine attempts to find an exported symbol with the given name in the
  2316. given binary.
  2317. Arguments:
  2318. Image - Supplies a pointer to the image to query.
  2319. Hash - Supplies the hashed symbol name.
  2320. SymbolName - Supplies a pointer to the string containing the name of the
  2321. symbol to search for.
  2322. Return Value:
  2323. Returns a pointer to the symbol on success.
  2324. NULL if no such symbol was found.
  2325. --*/
  2326. {
  2327. ELF_WORD BucketCount;
  2328. ELF_WORD BucketIndex;
  2329. BOOL Equal;
  2330. PELF_WORD Filter;
  2331. ELF_WORD FilterMask;
  2332. ELF_WORD FilterWord;
  2333. ELF_WORD FilterWords;
  2334. PELF_WORD HashBuckets;
  2335. PELF_WORD HashChains;
  2336. PELF_WORD HashTable;
  2337. PELF_SYMBOL Potential;
  2338. ULONG PotentialHash;
  2339. PSTR PotentialName;
  2340. ULONG RemainingSize;
  2341. ELF_WORD Shift;
  2342. ELF_WORD SymbolBase;
  2343. ELF_WORD SymbolIndex;
  2344. ELF_WORD WordIndex;
  2345. if (Image->ExportSymbolTable == NULL) {
  2346. return NULL;
  2347. }
  2348. //
  2349. // Handle GNU-style hashing.
  2350. //
  2351. if ((Image->Flags & IMAGE_FLAG_GNU_HASH) != 0) {
  2352. HashTable = Image->ExportHashTable;
  2353. BucketCount = *HashTable;
  2354. HashTable += 1;
  2355. SymbolBase = *HashTable;
  2356. HashTable += 1;
  2357. FilterWords = *HashTable;
  2358. HashTable += 1;
  2359. Shift = *HashTable;
  2360. HashTable += 1;
  2361. BucketIndex = Hash % BucketCount;
  2362. //
  2363. // Check the Bloom filter first. The Bloom filter indicates that a
  2364. // symbol is definitely not there, or is maybe there. It basically
  2365. // represents a quick "no".
  2366. //
  2367. Filter = (PELF_WORD)HashTable;
  2368. HashTable = (PELF_WORD)(Filter + FilterWords);
  2369. WordIndex = (Hash >> ELF_WORD_SIZE_SHIFT) & (FilterWords - 1);
  2370. ASSERT(POWER_OF_2(FilterWords));
  2371. FilterWord = Filter[WordIndex];
  2372. FilterMask = (1 << (Hash & ELF_WORD_SIZE_MASK)) |
  2373. (1 << ((Hash >> Shift) & ELF_WORD_SIZE_MASK));
  2374. if ((FilterWord & FilterMask) != FilterMask) {
  2375. return NULL;
  2376. }
  2377. //
  2378. // The buckets contain the index of the first symbol with the given
  2379. // hash.
  2380. //
  2381. SymbolIndex = HashTable[BucketIndex];
  2382. if (SymbolIndex == 0) {
  2383. return NULL;
  2384. }
  2385. if (SymbolIndex < SymbolBase) {
  2386. ASSERT(FALSE);
  2387. return NULL;
  2388. }
  2389. //
  2390. // The chains then contain the hashes of each of the symbols, with the
  2391. // low bit cleared. If the low bit is set, then the chain has ended.
  2392. //
  2393. HashChains = HashTable + BucketCount;
  2394. do {
  2395. PotentialHash = HashChains[SymbolIndex - SymbolBase];
  2396. //
  2397. // If the hash matches (ignoring the low bit), then do a full
  2398. // comparison.
  2399. //
  2400. if (((PotentialHash ^ Hash) & ~0x1) == 0) {
  2401. Potential = (PELF_SYMBOL)Image->ExportSymbolTable +
  2402. SymbolIndex;
  2403. PotentialName = Image->ExportStringTable +
  2404. Potential->NameOffset;
  2405. RemainingSize = Image->ExportStringTableSize -
  2406. Potential->NameOffset;
  2407. Equal = RtlAreStringsEqual(SymbolName,
  2408. PotentialName,
  2409. RemainingSize);
  2410. if (Equal != FALSE) {
  2411. return Potential;
  2412. }
  2413. }
  2414. SymbolIndex += 1;
  2415. } while ((PotentialHash & 0x1) == 0);
  2416. //
  2417. // Handle traditional SVR hashing.
  2418. //
  2419. } else {
  2420. BucketCount = *((PELF_WORD)Image->ExportHashTable);
  2421. HashBuckets = (PELF_WORD)Image->ExportHashTable + 2;
  2422. HashChains = (PELF_WORD)Image->ExportHashTable + 2 + BucketCount;
  2423. BucketIndex = Hash % BucketCount;
  2424. SymbolIndex = *(HashBuckets + BucketIndex);
  2425. while (SymbolIndex != 0) {
  2426. Potential = (PELF_SYMBOL)Image->ExportSymbolTable + SymbolIndex;
  2427. PotentialName = Image->ExportStringTable + Potential->NameOffset;
  2428. RemainingSize = Image->ExportStringTableSize -
  2429. Potential->NameOffset;
  2430. Equal = RtlAreStringsEqual(SymbolName,
  2431. PotentialName,
  2432. RemainingSize);
  2433. if (Equal != FALSE) {
  2434. return Potential;
  2435. }
  2436. //
  2437. // Get the next entry in the chain.
  2438. //
  2439. SymbolIndex = *(HashChains + SymbolIndex);
  2440. }
  2441. }
  2442. return NULL;
  2443. }
  2444. BOOL
  2445. ImpElfApplyRelocation (
  2446. PLIST_ENTRY ListHead,
  2447. PLOADED_IMAGE Image,
  2448. PELF_RELOCATION_ADDEND_ENTRY RelocationEntry,
  2449. BOOL AddendEntry,
  2450. PVOID *FinalSymbolValue
  2451. )
  2452. /*++
  2453. Routine Description:
  2454. This routine applies a relocation entry to a loaded image.
  2455. Arguments:
  2456. ListHead - Supplies a pointer to the head of the list of loaded images.
  2457. Image - Supplies a pointer to the loaded image structure.
  2458. RelocationEntry - Supplies a pointer to the relocation entry. This should
  2459. either be of type PELF_RELOCATION_ENTRY or
  2460. PELF_RELOCATION_ADDEND_ENTRY depending on the Addends parameter.
  2461. AddendEntry - Supplies a flag indicating that the entry if of type
  2462. ELF_RELOCATION_ADDEND_ENTRY, not ELF_RELOCATION_ENTRY.
  2463. FinalSymbolValue - Supplies an optional pointer where the symbol value will
  2464. be returned on success. This is used by PLT relocations that are being
  2465. fixed up on the fly and also need to jump directly to the symbol
  2466. address.
  2467. Return Value:
  2468. TRUE on success.
  2469. FALSE on failure.
  2470. --*/
  2471. {
  2472. ELF_SXWORD Addend;
  2473. BOOL AddendNeeded;
  2474. ELF_ADDR Address;
  2475. ELF_ADDR BaseDifference;
  2476. BOOL Copy;
  2477. ELF_XWORD Information;
  2478. PELF_LOADING_IMAGE LoadingImage;
  2479. ELF_ADDR Offset;
  2480. ELF_ADDR Place;
  2481. PVOID RelocationEnd;
  2482. BOOL RelocationNeeded;
  2483. PELF_ADDR RelocationPlace;
  2484. ELF_XWORD RelocationType;
  2485. PLOADED_IMAGE SymbolImage;
  2486. ELF_XWORD SymbolIndex;
  2487. PELF_SYMBOL Symbols;
  2488. ELF_ADDR SymbolValue;
  2489. Address = 0;
  2490. LoadingImage = Image->ImageContext;
  2491. BaseDifference = Image->BaseDifference;
  2492. Offset = RelocationEntry->Offset;
  2493. Information = RelocationEntry->Information;
  2494. Addend = 0;
  2495. if (AddendEntry != FALSE) {
  2496. Addend = RelocationEntry->Addend;
  2497. }
  2498. //
  2499. // The place is the actual VA of the relocation.
  2500. //
  2501. Place = BaseDifference + Offset;
  2502. //
  2503. // The Information field contains both the symbol index to the
  2504. // relocation as well as the type of relocation to apply.
  2505. //
  2506. Symbols = Image->ExportSymbolTable;
  2507. SymbolIndex = ELF_GET_RELOCATION_SYMBOL(Information);
  2508. RelocationType = ELF_GET_RELOCATION_TYPE(Information);
  2509. //
  2510. // Compute the symbol value.
  2511. //
  2512. SymbolValue = ImpElfGetSymbolValue(ListHead,
  2513. Image,
  2514. &(Symbols[SymbolIndex]),
  2515. &SymbolImage,
  2516. NULL);
  2517. if (SymbolValue == ELF_INVALID_ADDRESS) {
  2518. SymbolValue = 0;
  2519. }
  2520. if (FinalSymbolValue != NULL) {
  2521. *FinalSymbolValue = (PVOID)(UINTN)SymbolValue;
  2522. }
  2523. //
  2524. // Based on the type of relocation, compute the relocated value.
  2525. //
  2526. Copy = FALSE;
  2527. AddendNeeded = TRUE;
  2528. RelocationNeeded = TRUE;
  2529. if (Image->Machine == ImageMachineTypeArm32) {
  2530. switch (RelocationType) {
  2531. //
  2532. // None is a no-op.
  2533. //
  2534. case ElfArmRelocationNone:
  2535. RelocationNeeded = FALSE;
  2536. break;
  2537. //
  2538. // The "copy" relocations copy data from a shared object into the
  2539. // program's BSS segment. It is used by programs that reference
  2540. // variables defined in a shared object (like stdin/out/err, environ,
  2541. // etc). Note that copy can only work if this loader has access to the
  2542. // source image address. As a clue assert that at least this image's
  2543. // final address is the same as the address this code is accessing it
  2544. // at.
  2545. //
  2546. case ElfArmRelocationCopy:
  2547. ASSERT(Image->PreferredLowestAddress + BaseDifference ==
  2548. Image->LoadedImageBuffer);
  2549. //
  2550. // Find the shared object version, not the executable version.
  2551. //
  2552. SymbolValue = ImpElfGetSymbolValue(ListHead,
  2553. Image,
  2554. &(Symbols[SymbolIndex]),
  2555. NULL,
  2556. Image);
  2557. if (SymbolValue == ELF_INVALID_ADDRESS) {
  2558. SymbolValue = 0;
  2559. }
  2560. Copy = TRUE;
  2561. AddendNeeded = FALSE;
  2562. Address = SymbolValue;
  2563. break;
  2564. //
  2565. // Absolute uses only the symbol's value.
  2566. //
  2567. case ElfArmRelocationAbsolute32:
  2568. Address = SymbolValue + Addend;
  2569. break;
  2570. //
  2571. // Global relocations just use the symbol value. Jump slots are entries
  2572. // in the Procedure Linkage Table (PLT), and also just use the symbol
  2573. // value.
  2574. //
  2575. case ElfArmRelocationGlobalData:
  2576. Address = SymbolValue;
  2577. AddendNeeded = FALSE;
  2578. break;
  2579. case ElfArmRelocationJumpSlot:
  2580. Address = SymbolValue;
  2581. AddendNeeded = FALSE;
  2582. break;
  2583. //
  2584. // Relative relocations just adjust for the new base.
  2585. //
  2586. case ElfArmRelocationRelative:
  2587. Address = BaseDifference + Addend;
  2588. break;
  2589. //
  2590. // This is the module ID.
  2591. //
  2592. case ElfArmRelocationTlsDtpMod32:
  2593. if (SymbolImage == NULL) {
  2594. SymbolImage = Image;
  2595. }
  2596. Address = SymbolImage->ModuleNumber;
  2597. ASSERT(Address != 0);
  2598. AddendNeeded = FALSE;
  2599. break;
  2600. //
  2601. // This is the offset from the start of the TLS image to the given
  2602. // symbol.
  2603. //
  2604. case ElfArmRelocationTlsDtpOff32:
  2605. Address = SymbolValue + Addend;
  2606. AddendNeeded = FALSE;
  2607. break;
  2608. //
  2609. // This is the total offset from the thread pointer to the symbol, as
  2610. // a positive value to be added to the thread pointer.
  2611. //
  2612. case ElfArmRelocationTlsTpOff32:
  2613. if (SymbolImage == NULL) {
  2614. SymbolImage = Image;
  2615. }
  2616. ASSERT((SymbolImage != NULL) &&
  2617. (SymbolImage->TlsOffset != (UINTN)-1));
  2618. //
  2619. // The TLS offset is a positive value that indicates a negative
  2620. // offset from the thread pointer, hence the subtraction here.
  2621. //
  2622. Address = SymbolValue - SymbolImage->TlsOffset + Addend;
  2623. break;
  2624. //
  2625. // Unknown relocation type.
  2626. //
  2627. default:
  2628. ASSERT(FALSE);
  2629. return FALSE;
  2630. }
  2631. //
  2632. // Handle x86 images.
  2633. //
  2634. } else if (Image->Machine == ImageMachineTypeX86) {
  2635. switch (RelocationType) {
  2636. //
  2637. // None is a no-op.
  2638. //
  2639. case Elf386RelocationNone:
  2640. RelocationNeeded = FALSE;
  2641. break;
  2642. //
  2643. // Absolute uses only the symbol's value.
  2644. //
  2645. case Elf386Relocation32:
  2646. Address = SymbolValue + Addend;
  2647. break;
  2648. //
  2649. // PC32 is Symbol + Addend - Place
  2650. //
  2651. case Elf386RelocationPc32:
  2652. Address = SymbolValue + Addend - Place;
  2653. break;
  2654. //
  2655. // The "copy" relocations copy data from a shared object into the
  2656. // program's BSS segment. It is used by programs that reference
  2657. // variables defined in a shared object (like stdin/out/err, environ,
  2658. // etc). Note that copy can only work if this loader has access to the
  2659. // source image address. As a clue assert that at least this image's
  2660. // final address is the same as the address this code is accessing it
  2661. // at.
  2662. //
  2663. case Elf386RelocationCopy:
  2664. ASSERT(Image->PreferredLowestAddress + BaseDifference ==
  2665. Image->LoadedImageBuffer);
  2666. //
  2667. // Find the shared object version, not the executable version.
  2668. //
  2669. SymbolValue = ImpElfGetSymbolValue(ListHead,
  2670. Image,
  2671. &(Symbols[SymbolIndex]),
  2672. NULL,
  2673. Image);
  2674. if (SymbolValue == ELF_INVALID_ADDRESS) {
  2675. SymbolValue = 0;
  2676. }
  2677. Copy = TRUE;
  2678. AddendNeeded = FALSE;
  2679. Address = SymbolValue;
  2680. break;
  2681. //
  2682. // Global relocations just use the symbol value. Jump slots are entries
  2683. // in the Procedure Linkage Table (PLT), and also just use the symbol
  2684. // value.
  2685. //
  2686. case Elf386RelocationGlobalData:
  2687. Address = SymbolValue;
  2688. AddendNeeded = FALSE;
  2689. break;
  2690. case Elf386RelocationJumpSlot:
  2691. Address = SymbolValue;
  2692. AddendNeeded = FALSE;
  2693. break;
  2694. //
  2695. // Relative relocations just adjust for the new base.
  2696. //
  2697. case Elf386RelocationRelative:
  2698. Address = BaseDifference + Addend;
  2699. break;
  2700. //
  2701. // This is the module ID.
  2702. //
  2703. case Elf386RelocationTlsDtpMod32:
  2704. if (SymbolImage == NULL) {
  2705. SymbolImage = Image;
  2706. }
  2707. Address = SymbolImage->ModuleNumber;
  2708. ASSERT(Address != 0);
  2709. AddendNeeded = FALSE;
  2710. break;
  2711. //
  2712. // This is the offset from the start of the TLS image to the given
  2713. // symbol.
  2714. //
  2715. case Elf386RelocationTlsDtpOff32:
  2716. Address = SymbolValue + Addend;
  2717. AddendNeeded = FALSE;
  2718. break;
  2719. //
  2720. // This is the total offset from the thread pointer to the symbol, as
  2721. // a negative value to be added to the thread pointer.
  2722. //
  2723. case Elf386RelocationTlsTpOff:
  2724. if (SymbolImage == NULL) {
  2725. SymbolImage = Image;
  2726. }
  2727. ASSERT((SymbolImage != NULL) &&
  2728. (SymbolImage->TlsOffset != (UINTN)-1));
  2729. Address = SymbolValue - SymbolImage->TlsOffset + Addend;
  2730. break;
  2731. //
  2732. // This is the total offset from the thread pointer to the symbol, as
  2733. // a positive value to be subtracted from the thread pointer.
  2734. //
  2735. case Elf386RelocationTlsTpOff32:
  2736. if (SymbolImage == NULL) {
  2737. SymbolImage = Image;
  2738. }
  2739. ASSERT((SymbolImage != NULL) &&
  2740. (SymbolImage->TlsOffset != (UINTN)-1));
  2741. Address = SymbolImage->TlsOffset - SymbolValue + Addend;
  2742. break;
  2743. //
  2744. // Unknown relocation type.
  2745. //
  2746. default:
  2747. ASSERT(FALSE);
  2748. return FALSE;
  2749. }
  2750. } else {
  2751. ASSERT(FALSE);
  2752. return FALSE;
  2753. }
  2754. //
  2755. // If a relocation is needed, apply it now.
  2756. //
  2757. if (RelocationNeeded != FALSE) {
  2758. RelocationPlace = (PELF_ADDR)((PUCHAR)Image->LoadedImageBuffer +
  2759. (Offset - (UINTN)Image->PreferredLowestAddress));
  2760. if (AddendNeeded != FALSE) {
  2761. Address += *RelocationPlace;
  2762. }
  2763. if (Copy != FALSE) {
  2764. RtlCopyMemory(RelocationPlace,
  2765. (PVOID)(UINTN)Address,
  2766. Symbols[SymbolIndex].Size);
  2767. RelocationEnd = (PVOID)RelocationPlace +
  2768. Symbols[SymbolIndex].Size;
  2769. } else {
  2770. //
  2771. // Avoid the write unless it's necessary, as unnecessary write
  2772. // faults are expensive.
  2773. //
  2774. if (*RelocationPlace != Address) {
  2775. *RelocationPlace = Address;
  2776. RelocationEnd = RelocationPlace + 1;
  2777. } else {
  2778. RelocationEnd = NULL;
  2779. }
  2780. }
  2781. if ((LoadingImage != NULL) &&
  2782. ((Image->Flags & IMAGE_FLAG_TEXT_RELOCATIONS) != 0) &&
  2783. (RelocationEnd != NULL)) {
  2784. if ((LoadingImage->RelocationStart == ELF_INVALID_RELOCATION) ||
  2785. (LoadingImage->RelocationStart > (PVOID)RelocationPlace)) {
  2786. LoadingImage->RelocationStart = RelocationPlace;
  2787. }
  2788. if ((LoadingImage->RelocationEnd == ELF_INVALID_RELOCATION) ||
  2789. (LoadingImage->RelocationEnd < RelocationEnd)) {
  2790. LoadingImage->RelocationEnd = RelocationEnd;
  2791. }
  2792. }
  2793. }
  2794. return TRUE;
  2795. }
  2796. VOID
  2797. ImpElfFreeContext (
  2798. PLOADED_IMAGE Image
  2799. )
  2800. /*++
  2801. Routine Description:
  2802. This routine frees the loading image context, and closes and unloads the
  2803. file.
  2804. Arguments:
  2805. Image - Supplies a pointer to the image that has finished loading.
  2806. Return Value:
  2807. None.
  2808. --*/
  2809. {
  2810. PELF_LOADING_IMAGE LoadingImage;
  2811. if (Image->ImageContext != NULL) {
  2812. LoadingImage = Image->ImageContext;
  2813. if (Image->File.Handle != INVALID_HANDLE) {
  2814. if (LoadingImage->Buffer.Data != NULL) {
  2815. ImUnloadBuffer(&(Image->File), &(LoadingImage->Buffer));
  2816. }
  2817. ImCloseFile(&(Image->File));
  2818. Image->File.Handle = INVALID_HANDLE;
  2819. }
  2820. LoadingImage->Buffer.Data = NULL;
  2821. LoadingImage = NULL;
  2822. ImFreeMemory(Image->ImageContext);
  2823. Image->ImageContext = NULL;
  2824. }
  2825. return;
  2826. }