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
官方网站:点击访问青云互联活动官网优惠码:终身88折扣优惠码:WN789-2021香港测试IP:154.196.254美国测试IP:243.164.1活动方案:用户购买任意全区域云服务器月付以上享受免费更换IP服务;限美国区域云服务器凡是购买均可以提交工单定制天机防火墙高防御保护端口以及保护模式;香港区域购买季度、半年付、年付周期均可免费申请额外1IP;使用优惠码购买后续费周期终身同活动价,价格不...
百纵科技湖南百纵科技有限公司是一家具有ISP ICP 电信增值许可证的正规公司,多年不断转型探索现已颇具规模,公司成立于2009年 通过多年经营积累目前已独具一格,公司主要经营香港服务器,香港站群服务器,美国高防服务器,美国站群服务器,云服务器,母机租用托管!美国CN2云服务器,美国VPS,美国高防云主机,美国独立服务器,美国站群服务器,美国母机。美国原生IP支持大批量订货 合作 适用电商 亚马逊...
gcorelabs提供美国阿什本数据中心的GPU服务器(显卡服务器),默认给8路RTX2080Ti,服务器网卡支持2*10Gbps(ANX),CPU为双路Silver-4214(24核48线程),256G内存,1Gbps独享带宽仅需150欧元、10bps带宽仅需600欧元,不限流量随便跑吧。 官方网站 :https://gcorelabs.com/hosting/dedicated/gpu/ ...
android5.1为你推荐
模块ios8支持ipad支持ipad支持ios尺寸(mm)操作區域手控127.0.0.1传奇服务器非法网关连接: 127.0.0.1联通版iphone4s怎样看苹果4S是联通版还是电信版win7如何关闭445端口如何关闭445端口,禁用smb协议迅雷下载速度迅雷下载速度与什么有关?bitchina怎么下载电影?
域名注册查询 四川虚拟主机 游戏服务器租用 新秒杀 diahosting 国外php主机 韩国空间 精品网 iisphpmysql ixwebhosting css样式大全 国外空间 福建天翼加速 阿里校园 qq云端 爱奇艺vip免费领取 服务器监测 多线空间 ca187 创建邮箱 更多