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
易探云怎么样?易探云(yitanyun.com)是一家知名云计算品牌,2017年成立,从业4年之久,目前主要从事出售香港VPS、香港独立服务器、香港站群服务器等,在售VPS线路有三网CN2、CN2 GIA,该公司旗下产品均采用KVM虚拟化架构。目前,易探云推出免备案香港物理机服务器性价比很高,E3-1230 8 核*1/16G DDR3/SATA 1TB/香港BGP线路/20Mbps/不限流量,仅...
ZJI又上新了!商家是原Wordpress圈知名主机商:维翔主机,成立于2011年,2018年9月启用新域名ZJI,提供中国香港、台湾、日本、美国独立服务器(自营/数据中心直营)租用及VDS、虚拟主机空间、域名注册等业务。本次商家新上韩国BGP+CN2线路服务器,国内三网访问速度优秀,适用8折优惠码,优惠后韩国服务器最低每月440元起。韩国一型CPU:Intel 2×E5-2620 十二核二十四线...
六一云互联六一云互联为西安六一网络科技有限公司的旗下产品。是一个正规持有IDC/ISP/CDN的国内公司,成立于2018年,主要销售海外高防高速大带宽云服务器/CDN,并以高质量.稳定性.售后相应快.支持退款等特点受很多用户的支持!近期公司也推出了很多给力的抽奖和折扣活动如:新用户免费抽奖,最大可获得500元,湖北新购六折续费八折折上折,全场八折等等最新活动:1.湖北100G高防:新购六折续费八折...
android5.1为你推荐
投标迅雷Couriercss伺服器win7photoshop技术ps几大关键技术?ipad连不上wifi苹果ipad突然连不上网了,是怎么回事?网络是好的,手机能上网。itunes备份itunes备份是什么ipad上网新买的ipad怎么用。什么装程序 怎么上网联通版iphone4s怎么区分iphone4s电信版和联通版联通版iphone4s怎么知道到苹果4s是联通版,还是移动版win7如何关闭445端口如何关闭445端口,禁用smb协议
免费cn域名注册 广东服务器租用 香港bgp机房 softbank官网 贵州电信宽带测速 NetSpeeder tightvnc 河南服务器 河南m值兑换 美国在线代理服务器 服务器合租 512mb 服务器是干什么用的 lick cxz 东莞主机托管 广州虚拟主机 ledlamp 带宽测试 七牛云存储 更多