AndroidDynamicLinker-MarshmallowWANGZhenhua,i@jackwish.
netAbstractDynamiclinker,linkssharedlibrariestogethertobeabletorun,hasbeenafundamentalmechanisminmodernoperatingsystemandrichsoftwareecosystemoverthepastdecades.
Dynamiclinkerisalwayshighlyplatform-customizedsinceit'scoupledwithbinaryformatofasystem.
ThisarticleintroducesthebasicconceptionofdynamiclinkerandtakesAndroid(Marshmallow)dynamiclinkerasexampletodiscusstheimplementation.
IntroductionDynamicLinkOpenanyprogramminglanguagebook,"HelloWorld"isusuallytherstcodeexample.
TheCexamplebelowwhichwearefamiliarwithisrelatedwithdynamiclink.
ThelifecycleofthiscodeisasFigure1(memoryrelatedpartisinbluewhilesymbolrelatedisinpurple).
#includeintmain(){printf("HelloWorld!
\n");return0;}Asweknow,functionsneedtobedeclaredanddenedbeforeuse.
Forthe"HelloWorld"example,printf()isdeclaredinstdio.
handtheimplementationisinsharedlibrarylibc.
so.
Theprocedureoflocatingthedeclarationiscompiling(pre-processmoreprecisely)whilelocatingtheimplementationislinking.
Therearetwocategoriesoflinking-staticlinkinganddynamiclinking-ofwhichthedierenceisthetimethelinkingprocedureisperformed,asFigure1demonstrated.
Staticlinkingisperformedbycompilertool-chain,gccexample.
c-staticonLinuxisanexample.
Astaticlinkedbinaryrunswithouttheneedtorelocate1symbol-printfisasitsself-denedfunction.
Whenthebinaryhello.
elfisexecuted,operatingsystemonlyneedstoloaditintomemory.
Dynamiclinkingisperformedatruntimebydynamiclinker.
Atcompiletime,compilertool-chaingeneratesdynamiclinkedbinaryhello.
elfwhichcontainstheinformationthatitdependsonlibc.
sofortheimplementationofprintf.
Atruntime,dynamiclinkerloadshello.
elf,readsthedependentdata,loadslibc.
sointomemory,andllstheaddressofprintfintohello.
elf.
Inthisway,themainfunctioncancorrectlycallsprintf.
Figure1:printfExampleofLinkWiththeabilityofdynamiclinking,developerscouldcreateandsharelibraries.
Libraryauthorcouldupdateinternalimplementationwithoutneedtoinformusers,whilelibraryusersdon'tneedtore-deploytheirapplicationsunlesslibraryinterfaceshavechange.
ThisistheinfrastructureofAPI(ApplicationProgramInterface)!
LibraryDependencyDiverseprogramsrunningonmoderncomputersystemareconstructedbylibrariestodiminishdevelopmenteortandmemoryandstorageconsumption.
2Dynamiclinkerisresponsibleforlocatinglibrariesfromstorage,loadingthemintomemoryandlinkingthereferenceofthem.
Developerscreateprogramorlibrarybasedondierentlibraries.
OnetypicaldependencyoflibraryisasFigure2(libcutils.
soofAndroid,libdl.
soisignored).
Alibraryauthorknowswhichlibrariesisdependeduponbyhislibrary,andrecordsthedependencyinthelibrary(DT_NEEDEDtableforELFformatlibrary).
Atruntime,dynamiclinkerre-buildsthedependencyofanexecutableorsharedlibraryandlinksthebinaryagainstitsdependency.
Figure2:Dependencyoflibcutils.
soThedependencyismostlyaDAG(DirectedAcyclicGraph).
Fordynamicsystemsupportingrecursivedependent,thedependencycouldbeaDCG(DirectedCyclicGraph).
Nomatterwhatkindthegraphis,dynamiclinkercansimplyvisitallnodesinthegraph,locate,loadandlinkthem.
Inadependencygraph,thereisoneandonlyonenodewhichhasnoentryedge,calledroot.
There-buildingprocedureofadependencyistraversingthegraphinDFS(DepthFirstSearch)orBFS(BreadthFirstSearch)orderstartingwithroot.
Figure2isaBFSexample.
Inthisarticle,ourdiscussionisbasedontheBFSdependency.
DocumentStructureWetakethedynamiclinkerofAndroidastheimplementationexample.
Itispartofbionic,thestandardClibrarydevelopedbyGoogleforitsAndroidoperatingsystem.
AndroidisbasedonLinuxofwhichthesharedlibraryformatisELF.
DynamiclinkerprovideslinkingserviceforAndroidsystemandapplicationsdeployedwithJNIcapability.
WerstlyintroducethebasicmechanismofdynamiclinkerofAndroid.
Thentalkabouthowspecialfeaturesisimplemented.
Afterthat,thebootstrapofdynamiclinkerisdiscussed.
And,atlast,comingtothetrickypartoflibrarydependency.
3DynamicLinkingMechanismInAndroid,dynamiclinkerisinvokedwhenSystem.
loadLibrary()isexecutedinJavaordlopen()isexecutedinnativecode.
ForJavacode,Dalvik/Android-runtimecallsintodynamiclinkerjustlikedlopen()eventually.
StartingwithLollipopMR1(OurdiscussionisbasedonMarshmallow),Androiddynamiclinkingistwo-phase:libraryloadingandlibraryrelocation.
AsFigure3shows,thelefthalfisloadingwhiletherighthalfislinking.
Duringthelibraryloadingprocedure,dynamiclinkerre-buildsthelibraryde-pendency,loadsalllibrariesofitintomemory.
Thelibraryrelocationprocedurelinksthedependency.
WetalkabouttheimportantdatastructureofAndroiddynamiclinkerrstly.
Figure3:WorkowofAndroidDynamicLinkerDataStructurePersistentDataStructureDynamiclinkerofAndroidhastwopersistentdatastructureduringthelifetimeofanapplication/program-LSPath(LibrarySearchPaths)andALList(Already-loadedLibraryList).
4LSPatharethedirectorieswherelibrariesarestored.
Dynamiclinkertraversesthesepathstohuntforalibrary.
Thesepathsarecriticaltothelibrarylocatingandaresequencedinpriority.
ALListisalistofsoinfowhichisusedtomaintainmetadataofloadedlibraries(ELFdataandmemorylayoutforexample).
DynamiclinkerobtainsdatafromALListacrossdierentlibraryloadingandlinking.
ALListgrowsandshortenswhenlibraryisloadingandunloadingrespectively.
PersistentdatastructuresareatthetopsideofFigure3.
"Storage"inFigure3meansLSPathsomehow.
TemporaryDataStructureNaturally,manytemporarydatastructuresareusedduringloadinglibrary.
Amongthem,themostimportanttwoareload_tasksandlocal_group.
Bothofthempresentthelibrarydependency.
load_tasksisaqueuecontainingthelibrariestobeloaded-asubsetlibrariesoflibrarydependencywhichhaveNOTbeenloadedintomemoryyet.
load_tasksdequeueswhenlinkerbeginstosearchalibraryandenqueuesthedependentlibrariesjustparsed(fromDT_NEEDEDtableofanELFformatlibrary).
Afterallthetreehasbeenloaded(load_tasksisemptyatthistime),local_groupisconstructedandusedforrelocation.
local_groupisaqueueofsoinfoandrepresentslibrarydependencyinBFSorder.
(Anothersimilardatastructurecalledglobal_groupwillbediscussedin"SpecialFeatures"section.
)TemporarydatastructuresarelistedatthebottomsideofFigure3.
LibraryLoadingProcedureAtthebeginning,thelibraryrequestedbyoperatingsystem-root-isaddedtoload_tasks,asFigure3.
Duringtheprocedureoflibraryloading,dynamiclinkercontinuallyloadsalllibrariesinload_tasksandupdatesitifnecessary,asthelefthalfpartofFigure3.
Alllibrariesinthelibrarydependencywillbeloadedwhenthisprocedureisnished.
LibraryLocatingDynamiclinkerextractsonename/pathfromload_tasks,andopensdirectlyifit'sabsolutepathortraversesLSPathtohuntforthelibraryotherwise.
Whenthelibraryislocatedandopened,itcouldbeasystemlibraryoraapplibrary.
systemlibraryarelibrariesloadedfromsystemlibrarypaths5like/system/lib;applibraryareloadedfromapplicationlibrarypathslike/data/data/com.
example.
app/lib.
BeforeapplicationisforkedfromZygote,dynamiclinkeronlysearchesforlibraryundersystemlibrarypaths.
Afterapplicationisforkedandlibrarypathsareset,dynamiclinkersearchesunderapplicationpathsrstly,thensystemlibrarypaths.
LibraryLoadingAfterlibraryisopenedfromstorage,andbeforeloadsthelibraryintomemory,linkerwantstoverifywhetherthelejustopenedisavalidsharedlibrary.
ItperformscheckbasedonELFdata:magicnumber,32/64bit,little/bigendian,machinetypeandsoon.
Ifanythingwrong,thislibraryandthelibrarydependencywillbeunloaded.
Ifvalidationpasses,dynamiclinkerreadsthelibraryheaderandloadsallloadablesegmentsintomemory.
ItcalculatestheneededmemorysizeofthelibrarybycheckingPT_LOADtablesofprogramheader.
Thememoryallocationissimplyviammap.
(InandbeforeJellyBean,thelibrarymemoryismanagedbyabuddymemoryallocationsystemsystem)LibraryPre-link"Pre-link"intendstobuildonemoreleveloflibrarydependencybyreadingthedependency(dynamicDT_NEEDEDsection)ofalibrary.
AlllibrarynamesrecordedinDT_NEEDEDtableareaddedtoload_tasksandtobeloaded.
It'seasilytoseethatsamelibrary(name)maybeaddedtoload_tasksmanytimeswhenloadsalibrary.
DynamiclinkertraversesALListtocheckifthelibraryhasalreadybeloadedintomemorybynameandi-node,beforeandafteropenthatlibrary.
Iffound,dynamiclinkerdropsthatload_tasksnodeandfetchesnext.
SotherearenoduplicateloadedlibrariesinALList.
TheoccurrencetimeofreadingdependencyofalibraryhaschangedacrossthedevelopmentofAndroid.
BeforeLollipop-MR1,librarylinkingisDFSwhichloadsandlinksthelibrarydependencyrecursively.
BeginningwithLollipop-MR1,librarylinkingchangestoBFS.
Thischangemakesthelibrarylinkingatwo-stageprocedure,alllibrariesinalibrarydependencyhasbeenloadedintomemorybeforeanyofthemhasbeenrelocated.
LibraryRelocationProcedureAfterlibraryloadingprocedure,thedependentrelationshipoflibariesarerecordedinsoinfo.
Dynamiclinkerreadssoinfobeginningwithroottobuild6local_group.
Relocationisperformedonlocal_group.
Mainloopofrelocationdequeuesalibraryfromlocal_groupandrelocatesit.
local_groupisBFSbuilt,sotherelocationisBFStoo.
Whenresolvingasymbolofalibrary,dynamiclinkerwalkstheRelocationSection,atableofallthingsneededtoberelocated(DT_RELorDT_RELAofELF),ofasharedlibrary.
Foreachrelocationentry,linkerreadsthesymbolindexandconvertsittosymbolname.
Withthename,linkersearchesthedenitionofitinthedependencytree-beginwiththelibraryitself,thenglobal_group(see"ExtensionofDynamicLinker")andlocal_group.
Whensearchesasymboldenitioninalibrary,dynamiclinkerchecksthesymboltable(DT_SYMTABofELF)ofit.
Thereisaccelerationmethodsforthetablelookup,DT_HASHofELFisahashlistwhichcontainsallthe"exported"or"imported"symbolofalibrary.
Thelibraryrelocationprocedureisintuitive.
Whenit'sdone,dynamiclinkercallsalllibraryconstructorsinthedependency.
Afterconstructorsarenished,thelibraryisloaded,dynamiclinkerreturnsahandlerofthislibrarytouser.
ExtensionofDynamicLinkerDynamiclinkinghassomeextensionstosupportvariousscenarios,andAndroidhasextendeddynamiclinkingfunctionsforspecicpurpose.
GenericDynamicLinkGlobalLibraryWhenalibraryisdeclaredasa"globallibrary",loadedwiththeagRTLD_GLOBAL,thedenitionofthesymbolofthelibraryhasthehighestpriorityforalllibrariesloadedafterit.
Androiddynamiclinkerbuildstheglobal_groupeverytimeatthebeginningwhenloadalibrary.
Whenrelocatingasymbol,theglobal_groupisrstlylookedup-"globallibrary"canoverlaysthesymboldenitionofthelibrariestobeloadedafterwards.
PreloadLibraryWhenabinaryexecutedwithagLD_PRELOAD.
Theselibrarieswillbeloadedbeforethebinaryisreallyexecuted.
Androiddynamiclinkerpreloadstheselibrarieswhenitinitializes.
TheselibrarieswillcarrytheagRTLD_GLOBAL.
Afterthat,"preloadlibrary"isjustlike"globallibrary".
LD_PRELOADonlytakeseectforpurenativeprograms.
7AndroidExtendedDynamicLinkAndroidsystemextendsdynamiclinkingtoimproveexperiencewhenloadslibrariesfrombothJavaandnative.
TheAPIisandroid_dlopen_ext().
TillM,featuresofthisextensionisasbelow,mostofthemareprettyeasytounderstand.
Justcopyfromthesourcele.
.
.
.
Thedatastructureofthisextensionislikethis:typedefstruct{uint64_tflags;void*reserved_addr;size_treserved_size;intrelro_fd;intlibrary_fd;off64_tlibrary_fd_offset;}android_dlextinfo;LibraryMemoryRelatedANDROID_DLEXT_RESERVED_ADDRESS:Whenset,thereserved_addrandreserved_sizeeldsmustpointtoanalready-reservedregionofaddressspacewhichwillbeusedtoloadthelibraryifitts.
Ifthereservedregionisnotlargeenough,theloadwillfail.
ANDROID_DLEXT_RESERVED_ADDRESS_HINT:AsDLEXT_RESERVED_ADDRESS,butifthereservedregionisnotlargeenough,thelinkerwillchooseanavailableaddressinstead.
LibraryOpeningRelatedANDROID_DLEXT_USE_LIBRARY_FD:Instructdlopentouselibrary_fdinsteadofopeninglebyname.
Thelenameparameterisstillusedtoidentifythelibrary.
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET:Ifopeningalibraryusinglibrary_fdreaditstartingatlibrary_fd_offset.
ThisagisonlyvalidwhenANDROID_DLEXT_USE_LIBRARY_FDisset.
ANDROID_DLEXT_FORCE_LOAD:Whenset,donotcheckifthelibraryhasalreadybeenloadedbylestat(2)s.
ThisagallowsforcedloadingofthelibraryinthecasewhenforsomereasonmultipleELFlessharethesamelename(becausethealready-loadedlibraryhasbeenremovedandoverwritten,forexample).
Notethatifthelibraryhasthesamedt_sonameasanoldoneandsomeotherlibraryhasthesonameinDT_NEEDEDlist,therstonewillbeusedtoresolveanydependencies.
8LibraryRelocationRelatedANDROID_DLEXT_WRITE_RELRO:Whenset,writetheGNURELROsectionofthemappedlibrarytorelro_fdafterrelocationhasbeenperformed,toallowittobereusedbyanotherprocessloadingthesamelibraryatthesameaddress.
ThisimpliesANDROID_DLEXT_USE_RELRO.
ANDROID_DLEXT_USE_RELRO:Whenset,comparetheGNURELROsectionofthemappedlibrarytorelro_fdafterrelocationhasbeenperformed,andreplaceanyrelocatedpagesthatareidenticalwithaversionmappedfromthele.
BootstrapofDynamicLinkerDynamiclinkerisdesignedto"link"allrelocatablebinaries,andmustmakeitselflookslikelibdl.
sotorelocatables-thelibdl.
sobinaryisjustadummylibrarywhichmakesldofcompilertool-chainhappy.
Dynamiclinkerisstaticallylinkedatcompiletimeanddoesn'tdependonanyotherresourcesexceptsystemcall.
Theself-relocatingandfakinglibdl.
soisBootstrap.
ThebootstrapofAndroiddynamiclinkerisdividedintotwosteps:1.
Initialize:hardcodedtorelocatelinkeritself.
2.
Post-initialize:prepare"linkerruntime"forlibraryloading.
InitializeDuringthisstage,allexecutedcodeisstaticallyrelocated.
Noexternvariable,externfunction,orGOTaccess.
Calledfrombegin.
SandwillcallPost-initializefunctionsafterwards.
Primaryoperationsarerelocatinglinkeritselfandcreatingthedummylibdl.
sosoinfo.
Relocatinglinkeritselfisasadstory,everythingishand-obtained.
Afterthesoinfoiswell-setuped(memoryrelatedmostly),therealrelocationisconducted.
Thenconstructorsoflinkerarecalledtoinitializelinker'sglobalvariables.
Creatingdummylibdl.
sosoinfoismainlysetandupdatethereferenceofthesoinfotohard-codedarray,symboltableforexample.
Thissoinfonodeoflibdl.
soisalwaystherstnodeofALList.
Withtheseworkdone,linkerisrelocated.
9Post-initializeAfterself-relocated,dynamiclinkerrelocatessomain-themainprocess-Zygote.
BeforerelocatesZygote,linkerasksforruntimevariablefromsystemlikeLD_LIBRARY_PATHandLD_PRELOAD.
Andthen,itrelocatesZygote.
WithZygoterelocated,loadalllibrariesdeclaredinLD_PRELOAD.
Witheverythingdone,linkernishesBootstrapandjumpstoZygote.
LibraryDependencyAsdiscussedinthebeginning,onetaskofdynamiclinkeristore-buildlibrarydependency.
There-buildingprocedureissensitivetoruntimeenvironmentinsomecornerscenario.
Figure4:TrickyLibraryDepdendencyGenerationofAndroidConsiderthattherearetwosetsoflibraries-set1andset2.
Somelibrariesinthesetwosetssharesamenamebuthavedierentdenitions.
Atthebeginning,onlyset1canbeloaded,andthenbothset1andset2canbeloaded.
Thetrickis,inanydependency,thelibraryloadedinphase1couldonlydependsonlibraryinset1,asFigure4.
Thisisbecausewheneverlibraryinset1isneeded,dynamiclinkersimplyreusesthesoinfoofit.
LD_PRELOADintraditionalLinuxandlibrariesloadedbeforeZygoteforksinAndroidaresuchscenarios.
Thisisneformostdevelopers,butcouldimpactsomeemulationsystem.
10SummaryDynamiclinkerre-buildsthedependencyofexecutables,locates,loadsandlinksit.
It'sfundamentalinfrastructureofmodernoperatingsystemandsensitivetorunningenvironment.
Dynamiclinkingisusuallyhighplatformcustomizedandrequiresbootstrap.
AndroidNincludesnamespacechangestopreventloadingofnon-publicAPIs.
ThisfeatureheavilyimpactstheecosystemofAndroid.
Intheory,namespaceenables"virtualization"indynamiclinking.
Thedynamiclinkingwediscussedinthisdocumentin"processinternal",whilenamespacecanbuildseveralvirtualspace-namespace-fordynamiclinkinginoneprocess,makingthedynamiclink"namespaceinternal".
Wewillrefertonamespaceinthefuture.
11
tmhhost放出了2021年的端午佳节+618年中大促的优惠活动:日本软银、洛杉矶200G高防cn2 gia、洛杉矶三网cn2 gia、香港200M直连BGP、韩国cn2,全都是高端优化线路,所有这些VPS直接8折,部分已经做了季付8折然后再在此基础上继续8折(也就是6.4折)。 官方网站:https://www.tmhhost.com 香港BGP线路VPS ,200M带宽 200M带...
官方网站:点击访问特网云官网活动方案:===========================香港云限时购==============================支持Linux和Windows操作系统,配置都是可以自选的,非常的灵活,宽带充足新老客户活动期间新购活动款产品都可以享受续费折扣(只限在活动期间购买活动款产品才可享受续费折扣 优惠码:AADE01),购买折扣与续费折扣不叠加,都是在原价...
iWebFusion(iWFHosting)在部落分享过很多次了,这是成立于2001年的老牌国外主机商H4Y旗下站点,提供的产品包括虚拟主机、VPS和独立服务器租用等等,其中VPS主机基于KVM架构,数据中心可选美国洛杉矶、北卡、本德、蒙蒂塞洛等。商家独立服务器可选5个不同机房,最低每月57美元起,而大流量10Gbps带宽服务器也仅149美元起。首先我们分享几款常规服务器配置信息,以下机器可选择5...
android5.1为你推荐
TableBasicAbnormallyStoppedServicesituneshttp://www.huajinsc.cn/步骤ios请仔细阅读在本报告尾部的重要法律声明ipad连不上wifiiPad mini WiFi开关成灰色无法连接,怎么办iphone连不上wifi苹果手机“无法加入网络”怎么办win7telnetWin7系统中的telnet命令如何应用?win7telnetwindows7的TELNET服务在哪里开启啊x-router思科路由器有线端无法上网,而无线段却可以,用的是PPPOE拨号上网,一开始两种方法都不可以,检查宽googleadsencegoogle adsense打不开怎么办
pccw 美国仿牌空间 外国域名 42u标准机柜尺寸 evssl lighttpd 轻量 圣诞节促销 cpanel空间 tna官网 免费美国空间 微软服务器操作系统 免费mysql数据库 smtp虚拟服务器 广州虚拟主机 789电视剧网 winserver2008 美国代理服务器 什么是dns web是什么意思 更多