LinuxDev 板


LINE

※ 引述《mshockwave (夏克维夫)》之铭言: : ※ 引述《gigigigi (gigigigi)》之铭言: : : 何谓Binding : : Def: 决定程式执行的起始位址。 : : 即:程式要在内存的哪个地方开始执行。 好奇问一下, 这个定义是哪来的? 就如 mshockwave 所说, 一般讲 binding 是指 name binding. 而 binding time 就是指什麽时候决定 "name" 与他 "所指之事" 算是较 high-level 的事情, 偏软体的问题, 虽然是跟位址有关, 但其实位址本身不是重点, 和 OS 也比较没有直接关系, 这里的定义不太正确, 所以後面的讨论好像整个歪掉 orz : : 可能的Binding时期有三个: : : 1. Compiling Time : : 2. Loading Time : : 3. Execution Time : : 3-1 : Dynamic Binding : : 3-2 : Dynamic Loading : : 链接器( Linker )是把不同部分的代码和数据,收集、组合成为一个可加载、可执行的文 : : 件。 : : 加载器( Loader )把可执行文件从外存装入内存并进行执行 补充一下, 平常讲 loader, 一般应该是指 dynamic linker, 在 load time 时 resolve symbol 与 address 的东西. 相对於 static 的 linker, 是 link-time 时 resovle symble 你这边讲的 loader 是指把 executable 从 file system 放到 memory 的东西, 并不会做 symbol resolving, 功能比较单纯. 一般 loader 不是指这个. loader (dynamic linker) 在 GNU/linux 是 ld.so 或 ld-linux.so linker 像是 GNU binutils 里的 ld 或 gold (gold linker) 你提到的 loader 会是想 linux kernel 的 binfmt_elf 之类的东西, http://lxr.free-electrons.com/source/fs/binfmt_elf.c 还有像 binfmt_script 是 linux 用来 load shell script 执行的东西 : : MMU : 分段 + 分页 : : 分段 - 逻辑位址 -> 线性位址 : : 分页 - 线性位址 -> 实体位址 : : _________________________________________________________________________________ : : 我被上面情况给搞的有点乱 , 有下面几点疑惑 : : 1. : : Binging 三个时期程式位址都算是虚拟位址? : 是的 除非你玩的是没MMU的处理器 : : Compiling Time 位址是由编译器计算出来? : 不算是 其实是由连结器那边设定的 : : Loading Time 是由 加载器 计算出位址? : : Execution Time : 位址是 Local Address + Base Register ? 承前面所说, binding 并不是在指位址上的问题 拿这一小段 C code 来说 static int foo (int a, int b) { return a + b; } int bar () { return foo (1, 2); } int qux () { return bar (); } 当讲 xxx-time 做 binding, 也就是说在 xxx-time 後, 这个 binding 就不能再改变 但是可以通过重新 xxx 改变 binding. "通常" 越早 binding 的话, 效率越好, overhead 越低, optimization 越容易介入 * compile-time bar call foo, 静态就能决定是上面那个 static int foo 例如这个阶段可以做 inline optimization. 但若如果 foo 的内容改了, 那就只有重新编译一途, 不然 bar 会和 foo 不一致 * link-time, 现在程式通常会分档编译, 如果不在同一个档有定义, 那可能在 link-time 从其他的 .o 或 .a 系结 * load-time 可以想成从程式 load 到 memory, 到他真的能开始跑前的时间. 例如, 程式中有用到 libc.so (standard C library) 的东西 (printf, etc), 那就是 load-time 才会决定要 call 哪个版本. 这时才决定的东西, 可以透过重新执行来改变 binding, 例如 printf 有 bug, 可以更新 libc.so 再重新执行, 或是可以透过 LD_PRELOAD 来影响 ld.so (loader) 要使用哪个 shard object 来的定义. 另外, qux call bar, 与 bar 之间的 binding, 在现在 GNU/Linux toolchain 的情况下, 若是 position indepedent code (PIC) 的 shared object 会是 load-time, 而不是 link-time. * execution-time, 又指 run-time 是指程式正在 run 到时才能知道决定的, 不同语言的状况很不一样, 例如像 C++ 的 virtual function. load-time 和 run-time 有时况状很像, 但还是有差异. 很多 script 类的 language 可以直接呼叫 foo function, foo funtion 根本就不存在 (例如 typo 的 bug), 但 run 到时才会跟你 抱怨找不到 foo. 若是 load-time 做 binding, 就会在一开始执行时就 说无法 resolving foo 而一般 C/C++ 的 PIC code 通常会经过 GOT/PLT 查表来执行, 但 run-time 查 vtable 的状况 (overhead) 类似. 但能 optimize 的策略方法不同, load-time 在程式一开始就决定了不会改变, 若用基本的 JIT 就可以避开这个 overhead. 但 run-time 的 overhead 可能就要再透过 run-time profile 和 inline-cache 等方式 : 小弟不才 可能不完全正确 但其实元PO问的事情没那麽复杂 : 用一句话回答的话就是:把一切交给虚拟位址就对了! : 基本上会考虑到实体位址的就只有一位:核心 : 包括编译器连结器在内 都是用虚拟位址在思考 : 而我刚刚讲的 编译完的位址 其实是由叫做linker script的东西设定的 : 这些script是ld在编译的链结时期读取的 : (script路径可由 ld --verbose | grep SEARCH_DIR 得知) : 决定的事情包括最重要也最基本的:执行档的开头要载到哪一个位址(虚拟位址) : 也多亏了虚拟位址 每一个执行档 档案里写的开始执行位址都可以一样 : 反正实际在记忆体中的位址是由核心分配的嘛 : linker script其实常常用在一些很hack的地方 : 例如linux kernel 会把某些符号在链结时期改成另外一个名字 : Mozilla B2G (Firfox OS)也利用linker script : 把一些重要的libc符号 映射到他们自己实作的版本 说可以避免concurrency(? 以上好像有点复杂化这个问题XD : : 2. : : 目前Linux 是用MMU 段式 + 页式 ? : 这个问题蛮好玩的 因为x86大力鼓吹段式(segment) 但Linux为了跨平台着想 : 因为很多RISC家族根本没有segment的概念 所以是采用页式(page) segment 还留着只是因为相容的问题, 现在算是没在用了, 在 8086 16-bit 的年代, 利用 segment 是一个简单有效存取超过 64K 位址的一个方法 --- address = segment + offset 但现在直接都有 32/64-bit 的 (offset) register, 所以 segment 都直接 设成 0 (例如 code/data segment). 其他 segment 也拿去做别的特殊用途, 例如拿 FS (还是GS?) 当做 thread pointer 用来加速存取 thead-local-storage : : Linux 跟 Binding三个时期有关系嘛? : : Binding三个时期技术是早期的技术嘛? 目前有机会使用到嘛? : 其实我不太知道你这边的Binding是什麽意思 : 因为小弟是搞编译器的 第一个就想到Name Binding XDD 自我介绍一下, 小弟我之前是搞 assembler, linker, debugger 和一点点 loader 因为要写能 run linux user space program 的 emulator, 所以对 linux 怎麽 load/mapping executable 那边有花些时间研究, 最近几年也是在搞 compiler XD : : 3. : : 链接器( Linker )是把不同部分的代码和数据,收集、组合成为一个可加载、可执行的文 : : 件。 : : 我认知编译出执行文件使用 objdump -d 就可以看到虚拟位址 , 就位址是ld Linker : : 计算出来的嘛? 如果是它是属於哪个Binding? : : gcc -g test.c : : 使用 objdump -d ./a.out : : 08048414 <main>: : : 8048414: 55 push %ebp : : 8048415: 89 e5 mov %esp,%ebp : : 8048417: 6a 03 push $0x3 : : 8048419: 6a 02 push $0x2 : : 804841b: e8 e1 ff ff ff call 8048401 <foo> : : 8048420: 83 c4 08 add $0x8,%esp : : 8048423: b8 00 00 00 00 mov $0x0,%eax : : 8048428: c9 leave : : 8048429: c3 ret : : 804842a: 66 90 xchg %ax,%ax : : 804842c: 66 90 xchg %ax,%ax : : 804842e: 66 90 xchg %ax,%ax : : 加载器( Loader )把可执行文件从外存装入内存并进行执行 <-- 这过程有经过虚拟位址 : : 映射实体位址转换嘛? : 虚拟位址的映射(到实体位址)完全是执行的时候做的事喔 : : Linux 系统的加载器( Loader ) 这是位於 linux kernel 里面? : 是的 加载执行档一定是作业系统的事 : ld.so的角色呢(不是编译时期的ld)?他是负责解析动态函式库(.so)的相关事情 : 例如帮忙resolve现在执行需要的so并加以载入 : 那那个so载入的位址呢?前面讲过 每个执行档编译出来 开始的虚拟位址可以一样 : 但so的虚拟位址并不是写死的 : 其中的技术就是PIC(Position independent code) 也就是编译so时下的 -fPIC : 就如字面上讲的 他并不是绝对位址 而是相对位址 : 因此ld.so就可以把他载到执行位址空间的任何一个地方 : 详细的技术比较复杂一点 这边写不下 推荐原PO去读 程式设计师的自我修养 : 那本书真的很珍贵 因为我竟然发现 这麽重要的技术 竟然很少原文书 那本书的内容很针对特定环境的实作, 建议还是要多 trace/survey 现在不同平台的实作, 才不会被局限住.. 另外推荐两本书, 都是 Morgan Kaufmann 出版 想往 linker/loader 看的话, 有一本 Linkers and Loaders 作者看已的网页有 draft 可以抓 要往 language 看的话, 可以看 Programming Language Pragmatics : 上述回答可能有误 请各位大大多多指教了<(_ _)> : : 谢谢 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.110.214.155
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/LinuxDev/M.1436627615.A.07B.html
1F:推 cobrasgo: 搞compiler的,我要跪着看文章了… 07/16 21:59







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP