對于一般人來說,一座樓就是一座樓;但是對于一個建筑觀察者來說,任何一座建筑都可以代表更多東西。它可以是后現(xiàn)代的偉大杰作,可以是英王愛德華時代的宏偉建筑,還可以是草原風格的宅邸。它可以游走于裝飾藝術(shù)領(lǐng)域,可以從繪畫文學汲取靈感,甚至可以自己生長、拓展輻射,最終在主根系中延生出茂盛而繁復(fù)的枝蔓。在《世界建筑風格漫游:從經(jīng)典廟宇到現(xiàn)代摩天樓》中,有心的讀者會發(fā)現(xiàn)大量有價值的信息,覆蓋了從古代建筑遺跡到鄉(xiāng)村原木小屋再到稀有的摩天建筑等方方面面。它可以幫你認識建筑,總結(jié)建筑風格的關(guān)鍵詞,感受設(shè)計者的思維,梳理建筑的發(fā)展脈絡(luò)?!妒澜缃ㄖL格漫游:從經(jīng)典廟宇到現(xiàn)代摩天樓》不僅概括介紹一些著名的建筑,而且從細節(jié)處精確討論同時伴有豐富而精美的照片,并用插圖形象展現(xiàn)一些專業(yè)建筑術(shù)語,如飛檐、飛扶壁、山墻等。讀者以建筑觀察者的客觀視角,濃繪不同的風格縮影。在這《世界建筑風格漫游:從經(jīng)典廟宇到現(xiàn)代摩天樓》中游走天下,狩獵建筑,你會有頗豐的收獲,有一天,你也會成為出色的建筑觀察者。

世界建筑風格漫游造價信息

市場價 信息價 詢價
材料名稱 規(guī)格/型號 市場價
(除稅)
工程建議價
(除稅)
行情 品牌 單位 稅率 供應(yīng)商 報價日期
虛擬漫游 模擬運動測試,佩戴心率測試裝置,在進行互動時即可讀取參與人的心率及速度等,測試結(jié)果于屏幕中顯現(xiàn).屏幕隨著感應(yīng)到的體驗者腳步的移動,同步畫面內(nèi) 查看價格 查看價格

13% 上海攜筑多媒體科技有限公司
虛擬漫游 模擬運動測試,佩戴心率測試裝置,在進行互動時即可讀取參與人的心率及速度等,測試結(jié)果于屏幕中顯現(xiàn).屏幕隨著感應(yīng)到的體驗者腳步的移動,同步畫面內(nèi) 查看價格 查看價格

13% 上海樂顯電子科技有限公司
虛擬漫游 模擬運動測試,佩戴心率測試裝置,在進行互動時即可讀取參與人的心率及速度等,測試結(jié)果于屏幕中顯現(xiàn).屏幕隨著感應(yīng)到的體驗者腳步的移動,同步畫面內(nèi) 查看價格 查看價格

13% 未石互動科技股份有限公司
無線漫游專用AP 品種:無線AP;型號:IAP2315C;版本:V1.0.0;說明:單頻5GHz工業(yè)級室內(nèi)型無線AP客戶端;類別:C; 查看價格 查看價格

三旺

13% 深圳市三旺通信技術(shù)有限公司
無線漫游專用AP 品種:無線AP;型號:IAP2625C;版本:V1.0.0;說明:866Mbps單頻5GHz工業(yè)級室外型無線AP;類別:C; 查看價格 查看價格

三旺

13% 深圳市三旺通信技術(shù)有限公司
無線漫游專用AP 品種:無線AP;型號:IAP2645C;版本:V1.0.0;說明:雙5GHz工業(yè)級室外型無線AP客戶端;類別:C; 查看價格 查看價格

三旺

13% 深圳市三旺通信技術(shù)有限公司
無線漫游專用AP 品種:無線AP;型號:IAP2325C;版本:V1.0.0;說明:雙5GHz工業(yè)級室內(nèi)型無線AP客戶端;類別:C; 查看價格 查看價格

三旺

13% 深圳市三旺通信技術(shù)有限公司
無線漫游控制器 品種:無線控制器;型號:AC8505G-5GT;版本:V1.0.0;說明:5路全千兆無線漫游控制器;類別:C; 查看價格 查看價格

三旺

13% 深圳市三旺通信技術(shù)有限公司
材料名稱 規(guī)格/型號 除稅
信息價
含稅
信息價
行情 品牌 單位 稅率 地區(qū)/時間
建筑雜工 查看價格 查看價格

工日 深圳市2022年9月信息價
建筑圍擋 2厚熱鍍鋅鋼板機械沖孔,孔徑φ10,100*100*5方鋼防風斜撐,詳見《中山市建設(shè)施工裝配式圍擋圖集》 查看價格 查看價格

m 中山市2022年9月信息價
建筑雜工 查看價格 查看價格

工日 深圳市2022年4月信息價
建筑雜工 查看價格 查看價格

工日 深圳市2022年2月信息價
建筑雜工 查看價格 查看價格

工日 深圳市2022年1月信息價
建筑雜工 查看價格 查看價格

工日 深圳市2021年12月信息價
建筑圍擋 2厚熱鍍鋅鋼板機械沖孔,孔徑φ10,100*100*5方鋼防風斜撐,詳見《中山市建設(shè)施工裝配式圍擋圖集》 查看價格 查看價格

m 中山市2021年12月信息價
建筑雜工 查看價格 查看價格

工日 深圳市2021年11月信息價
材料名稱 規(guī)格/需求量 報價數(shù) 最新報價
(元)
供應(yīng)商 報價地區(qū) 最新報價時間
虛擬漫游 模擬運動測試,佩戴心率測試裝置,在進行互動時即可讀取參與人的心率及速度等,測試結(jié)果于屏幕中顯現(xiàn).屏幕隨著感應(yīng)到的體驗者腳步的移動,同步畫面內(nèi)容,讓人仿佛漫步在云層中|1套 3 查看價格 上海樂顯電子科技有限公司 全國   2021-07-30
風格吊頂 型號:300×300mm 規(guī)格:0.5厚|8799片 1 查看價格 現(xiàn)代冠軍 北京  北京市 2015-06-04
皮膚風格 1.基礎(chǔ)空間基礎(chǔ)空間是由版式布局、皮膚風格、應(yīng)用組件等功能構(gòu)成,供不同角色進行空間基本模塊管理的平臺載體.2.皮膚風格展示空間為用戶提供多種皮膚風格樣式,用戶可根據(jù)自己的喜好自定義切換展示空間皮膚,皮膚樣式包含banner圖片,鏈接顏色,圖標樣式等.|11 1 查看價格 廣東天智實業(yè)有限公司 全國   2021-07-23
風格吊頂 型號:300×300mm 規(guī)格:0.5厚|4618片 1 查看價格 現(xiàn)代冠軍 北京  北京市 2015-06-26
科室簡介 中文立體字:8mm 亞克力烤漆 英文立體字:5mm 亞克力烤漆 鋁型材磁吸畫框+高精度寫真+透明PVC面板1.底板采用2mm金屬鋁板激光切割焊接成型,左右彎弧2.表面汽車烤漆3.圖文絲網(wǎng)印刷4.鋁型材抽插盒,表面粘貼2mm透明亞克力|1套 3 查看價格 廣東恒創(chuàng)標識廣告有限公司 廣東   2022-09-14
人物簡介 1.內(nèi)容:方形人物簡介2.方形尺寸與個數(shù):360×180mm×10個3.底板材質(zhì):10mm厚亞克力板雕刻成型4.表面加工:噴漆后UV噴印,上光油5.黏結(jié)方式:玻璃膠粘貼6.安裝方式:機具、人工、制作安裝|10個 2 查看價格 四川甲骨文標識制作有限責任公司 四川   2019-12-18
單元簡介 1200×1000|1塊 1 查看價格 西安江興不銹鋼裝飾有限公司 全國   2018-04-13
海底世界 無|1個 3 查看價格 廣州市番禺區(qū)沙灣育才游樂玩具廠 全國   2019-03-26

第一章古典建筑的遺產(chǎn)002

古典風格/003

古典柱式/005

多立克柱式/006

愛奧尼克柱式/007

科林斯柱式/008

希臘神廟/009

羅馬風格/011

羅馬拱/013

穹頂和筒形拱/014

神廟以及劇院/015

第二章拜占庭和羅馬風的建筑018

拜占庭建筑/019

羅馬風/021

諾曼風格/023

后羅馬風建筑/025

第三章伊斯蘭建筑028

倭馬亞和阿巴斯/029

非洲的伊斯蘭教/031

摩爾式建筑風格/033

奧斯曼風格/035

波斯建筑/037

莫臥兒建筑/039

第四章傳統(tǒng)的亞洲風格 042

中國傳統(tǒng)建筑/043

日本傳統(tǒng)建筑/045

廟宇建筑/047

亞洲地區(qū)建筑風格/049

第五章哥特式以及中世紀建筑052

中世紀的奠基/053

中世紀的防御工事/055

成長為哥特式/057

法式哥特/059

英式哥特/061

意大利和德國的哥特建筑/063

歐洲中部和北部的哥特建筑/065

第六章文藝復(fù)興及巴洛克建筑 068

文藝復(fù)興/069

文藝復(fù)興盛期/071

風格主義/073

都鐸王朝和詹姆斯一世時期/075

巴洛克/077

英式巴洛克/079

洛可可/081

阿爾卑斯和波西米亞/083

西班牙巴洛克風格/085

地中海風格/087

低地國家/089

俄羅斯巴洛克/091

第七章新大陸094

前哥倫布時期/095

印第安人村莊/土磚/097

西班牙人的構(gòu)想/099

英國殖民地建筑/101

鹽盒式建筑/103

美國德裔賓州人建筑/105

震教徒建筑/107

法國殖民地:阿卡迪亞教區(qū)/109

荷蘭殖民建筑/111

法國殖民地:克里奧爾及其

南部/113

非洲人的影響/115

西部本地建筑/117

西班牙殖民地/119

原木房屋/121

加勒比地區(qū)建筑風格/123

第八章古典復(fù)興建筑126

帕拉迪奧式建筑/127

法國新古典主義/129

德國新古典主義/131

喬治亞時代的藝術(shù)風格/133

聯(lián)邦制/亞當式/135

杰弗遜式/137

希臘復(fù)興式/139

英國攝政時期/141

第九章維多利亞風格144

哥特式建筑復(fù)興/145

維多利亞哥特式/147

古羅馬建筑復(fù)興/149

文藝復(fù)興時期的建筑復(fù)興/151

意大利風格建筑/153

木匠哥特式建筑/155

美洲木結(jié)構(gòu)建筑/157

安妮女王式建筑/159

木瓦風格建筑/161

理查森羅馬式/163

異國風情的復(fù)興/165

美術(shù)派風格/167

城堡風格/169

第二帝國風格/171

汽船哥特式/173

城市公寓/175

都鐸王朝風格的復(fù)興/177

“鐵器時代”唯物主義/179

英國工藝美術(shù)運動/181

第十章早期現(xiàn)代建筑184

美國的文藝復(fù)興/185

凱爾特復(fù)興/187

芝加哥學派/189

摩天大樓/191

草原風格/193

鄉(xiāng)村風格/195

涼臺平房/197

手工藝風格/西班牙傳教會式

建筑風格/199

新藝術(shù)/201

分離派/青年風格/203

加泰羅尼亞的現(xiàn)代主義/205

構(gòu)成主義/207

藝術(shù)裝飾派:爵士時代/209

藝術(shù)裝飾派:流線型/211

功能主義/213

美國風/215

包豪斯/217

國際風格/219

有機建筑(賴特)/221

第十一章戰(zhàn)后現(xiàn)代建筑224

戰(zhàn)后國際風格/225

賴特:成熟期/227

現(xiàn)代主義/229

粗野主義/野獸派/231

未來主義/233

表現(xiàn)主義/235

結(jié)構(gòu)表現(xiàn)主義/237

當代的現(xiàn)代主義/239

后現(xiàn)代主義/241

解構(gòu)主義/243

弗蘭克·蓋里/245

流體建筑/247

有機建筑/249

當代建筑趨勢/2512100433B

世界建筑風格漫游內(nèi)容簡介常見問題

  • 中外建筑史的內(nèi)容簡介

    本書共分20講,敘述了中外建筑的起源與發(fā)展概況,對中國古建筑發(fā)展、古建筑特征、各建筑類型、近現(xiàn)代建筑和國外各歷史階段最具代表性的建筑風格、建筑流派、代表人物與代表作品進行了詳細的闡述和分析。《中外建筑...

  • 建筑識圖與構(gòu)造的內(nèi)容簡介

    本書是根據(jù)目前高職高專院校工程造價等專業(yè)的教學基本要求編寫而成。本書共13章,包括建筑概述,建筑制圖與識圖的基本知識,基礎(chǔ),墻體,樓板層與地面,樓梯,屋頂,門與窗,變形縫,工業(yè)建筑構(gòu)造,建筑施工圖的識...

  • 羅馬建筑風格的建筑簡介

    古羅馬建筑是古羅馬人沿習亞平寧半島上伊特魯里亞人的建筑技術(shù),繼承古希臘建筑成就,在建筑形制、技術(shù)和藝術(shù)方面廣泛創(chuàng)新 的一種建筑風格。古羅馬建筑在公元一~三世紀為極盛時期,達到西方古代建筑的高峰。古羅馬...

世界建筑風格漫游內(nèi)容簡介文獻

6.2建筑風格——心儀的建筑風格 6.2建筑風格——心儀的建筑風格

格式:pdf

大小:4.4MB

頁數(shù): 37頁

評分: 4.4

6.2建筑風格——心儀的建筑風格

立即下載
歐式建筑風格VS美式建筑風格 歐式建筑風格VS美式建筑風格

格式:pdf

大?。?span id="kb7kb2e" class="single-tag-height">4.4MB

頁數(shù): 11頁

評分: 4.5

歐式建筑風格 VS 美式建筑風格 一、兩大風格之間的歷史背景對比 1、歐式風格的發(fā)展 歐洲建筑在大的概念上應(yīng)歸屬于西方建筑,從古希臘時代起到 20世紀三四 十年代,歐洲一直是西方建筑文明的中心, 第二次世界大戰(zhàn)結(jié)束后, 這個中心逐 漸偏移到了北美, 雖然有更為早期的歐洲原始建筑, 但是歐洲建筑真正的源頭是 古希臘文明,公元前 5世紀到公元前 4世紀,古希臘的建筑藝術(shù)達到鼎盛, 以雅 典衛(wèi)城及其神廟為代表的一個個建筑杰作橫空出世,它們簡單而純凈和諧而完 美,具有驚人的藝術(shù)創(chuàng)造力。 公元前 1世紀,古希臘人的 “光榮”被古羅馬人的 “偉大”所取代,后者興建的宮殿、 凱旋門、競技場、劇場和大浴場雄偉壯觀富麗堂皇, 他們和古希臘建筑一道被視 為垂范千古的經(jīng)典成為西方建筑文化最深刻的根源。 在接下來中世紀的 1000余年中,歐洲建筑具有兩大特點:一是基督教堂和 修道院始終是歐洲建筑的主體; 二是伴隨

立即下載

來源:MRRiddler ,

blog.mrriddler.com/2017/02/10/計算機體系-編譯體系漫游/

要想讓代碼乖乖運行,自然代碼要先經(jīng)過編譯,這篇文章就來聊聊編譯體系。

代碼的編譯過程分為四個階段,預(yù)處理、編譯、匯編、鏈接。而編譯階段是整個過程中最復(fù)雜的階段,編譯階段還可以分為詞法分析、語法分析、語義分析。

在一頭扎進這四個階段之間,先聊一下語法、語義。人類之所以能在進化的歷史長河中,成為動物中的佼佼者,進化出的復(fù)雜的溝通機制—語言功不可沒。假如,我說出這句話:你個產(chǎn)品狗還在改需求!那么語法是啥呢?簡單說就是構(gòu)成這句話的順序,假如順序錯亂意思就不同了。那么語義是啥呢?就是語境,根據(jù)我說這句話的情景,才能解釋出你指的是誰。語法在編程語言中,表現(xiàn)出來的就是語法結(jié)構(gòu)和結(jié)合律。語義表現(xiàn)出來的就是上下文(context)。

預(yù)處理(Preprocess):處理預(yù)處理符(#),包括宏展開、頭文件引入。 詞法分析(Lexical Analysis、Tokenizer):寫出的代碼實際上就是字符串,此階段需要對字符串進行掃描(Scanner),將字符串掃描出分析的最基本單位(token),并在掃描過程中將它們分類,此階段是沒有任何語義的。也可以理解成將代碼掃描出基本表達式。 語法分析(Syntactic analysis、Parser):生成AST抽象語法樹,檢查語法結(jié)構(gòu),此階段是上下文無關(guān)的。也可以理解成將基本表達式按語法結(jié)構(gòu)組合成復(fù)合表達式。 語義分析(Semantic Analysis):語義檢查(比如檢查浮點數(shù)乘以指針,雖然語法結(jié)構(gòu)正確但是語義檢查不合格),將程序與上下文結(jié)合,進行靜態(tài)類型分析,確定AST每個節(jié)點的類型。也可以理解將復(fù)合表達式結(jié)合環(huán)境(Environment),并且確定基本表達式、復(fù)合表達式的類型。 中間碼(Intermediate Representation):與語言無關(guān)、平臺無關(guān)的中間碼。如果編譯器面向多語言,對于任意語言編譯階段后可以生成通用的中間碼,這樣編譯器就有多語言的高拓展性了。生成中間碼后再交給匯編階段,再生成與平臺相關(guān)的匯編,這樣使編譯器將平臺相關(guān)性盡量往后推移。中間碼除了做為“橋接“,對中間碼的優(yōu)化也是整個編譯過程中的關(guān)鍵優(yōu)化。 匯編(Assemble):對中間碼生成平臺具體的匯編,在這個階段添加對多個平臺的支持,編譯器就可以跨平臺了。最后生成機器碼。 鏈接(Link):將每個機器碼編譯單位中引用的其他編譯單位中的變量、函數(shù)符號修正(fix)成真實地址。

編譯歷史

編譯的歷史基本就是計算機的進化史,是很有趣的一段故事。Long time ago… 程序員寫程序都是用紙帶,那時候還在寫0、1機器碼。紙帶上打孔就是0,不打孔就是1。然后計算機讀取紙帶就是讀取指令。但是就像互聯(lián)網(wǎng)本質(zhì)就是提高效率一樣,這樣寫程序的效率怎能接受?并且,寫程序如果犯了錯誤怎么辦?重新從頭到尾再用新紙帶搞一遍?程序員們機智的開始想辦法了,先是這樣搞:

將指帶有誤的地方,用黑黑的小貼紙?zhí)钌先ィ@樣將0改成1了。這也是Patch名字的由來。但是這樣寫指令效率還是太低,程序員們再機智的想辦法。后來將指令進行符號化(Symbol),抽象出指令集,這時就出現(xiàn)了匯編,程序員的效率上了一個檔次。但是新的問題又出現(xiàn)了。在寫過程調(diào)用的時候,要寫jmp 具體的函數(shù)地址。如果后來要在被調(diào)用的函數(shù)前面添加指令,那么函數(shù)地址也要跟著改。這樣牽一發(fā)動全身的感覺可不好,為了讓影響(impact)縮減到最小,不如將函數(shù)地址也符號化。凡是寫過程調(diào)用先寫成jmp func,等到程序生成機器碼的時候,再將func換成真正的函數(shù)地址,這一步也就是將程序員手動修正交由匯編器修正。

隨著生產(chǎn)力的提升,程序的規(guī)模越來越大,新的問題出現(xiàn)了,程序膨脹到難以維護和閱讀了。程序員們就將程序模塊化、層次化。這樣也使編譯的單位更小粒度化。編譯的時候,不同編譯單位之間的細節(jié)是互相隔離的。比如,對于C語言系,一個.h和一個.m就構(gòu)成了一個編譯單位。.m匯編時,是不知道其他.m的全局變量、函數(shù)地址的,而調(diào)用的時候就只能用符號進行調(diào)用,等到最后所有.m都生成機器碼后再進行統(tǒng)一的修正。而負責這一步的就是鏈接器(Linker),這一步也叫重定位(Relocation)。

目標文件

經(jīng)過匯編這一階段后,就會生成目標文件。目標文件和可執(zhí)行文件已經(jīng)非常相近了,只是有些符號還未修正,結(jié)構(gòu)上會進行調(diào)整。Windows平臺下為PE(Portable Executable),Linux平臺下為ELF(Executable Linkable Format),Mac平臺下為Mach-O。雖然不同平臺都有自己的格式,但是它們實際上都大同小異。下面大體聊一下文件的實際字段,這些知識會為后面我們搞一些符號重綁定做鋪墊。

section

首先,文件分段(section)。不同的Section放置不同的信息,文件還有一個section header table放置控制信息。實際上,就類似圖片格式和mutipart的HTTP報文。以下是一個ELF目標文件的常見section:

—— —— —— —— —— —— ——

|header | -----> 文件頭

|—— —— —— —— —— —— ——|

|.text | -----> 代碼段

|—— —— —— —— —— —— ——|

|.data | -----> 已初始化全局變量、靜態(tài)變量

|—— —— —— —— —— —— ——|

|.bss | -----> 未初始化全局變量、靜態(tài)變量

|—— —— —— —— —— —— ——|

|other sections... |

|—— —— —— —— —— —— ——|

|section header table| -----> section控制信息表

|—— —— —— —— —— —— ——|

|.strtab | -----> 字符串表

|—— —— —— —— —— —— ——|

|.symtab | -----> 符號表

|—— —— —— —— —— —— ——|

|..... |

—— —— —— —— —— —— —— —

.text放置代碼,.data放置已初始化的全局變量和靜態(tài)變量,.bss放置未初始化的全局變量和靜態(tài)變量。為什么代碼和全局變量、靜態(tài)變量要分開放?實際上,這就是個等同性問題。代碼段就是可讀的數(shù)據(jù),而全局變量、靜態(tài)變量是可讀可寫的數(shù)據(jù)。如果有多個進程進行同一份代碼,這些代碼都是等同的,不需要各自復(fù)制一份。而全局變量、靜態(tài)變量是不等同的,需要各自復(fù)制一份。而分什么又要分已初始化、未初始化呢?目標文件未初始化的全局、靜態(tài)變量只需要放置一個占位符,代表其在.bss。而.bss在鏈接階段,變量不占空間,在裝載時由操作系統(tǒng)再分配空間。可以看到,既然是文件格式,不管怎么設(shè)計,主要的目的就是占更少的空間。

header有很多文件控制信息,就不一一表述了,其中最重要的就是記錄了section header table的起始地址。而section header table記錄了所有section的名字、類型、長度、在文件中的偏移量(offset)等。如果想要尋址到任意section都要通過這個header table。section header table實際上是由struct構(gòu)成的數(shù)組。

.strtab放置section名、變量名,包括符號名的字符串。由于在整個結(jié)構(gòu)中,字符串的長度是不定的,一般將這些字符串統(tǒng)一放置在一個table中,然后存儲table中的offset,最后尋址到字符串。比如,在下表中,我想找到girlfriend一詞,我只要拿到.strtab的base地址,加上girlfriend的offset 9就可以找到這個字符串。

0 1 2 3 4 5 6 7 8

i 0 w a n t 0 a 0

g i r l f r i e n

d

.symtab就是大名鼎鼎的符號表。每個目標文件都有自己的符號表,符號表記錄符號的映射,符號可以這樣分:文件外符號和文件內(nèi)符號,文件外符號就是使用在其他文件定義的符號,文件內(nèi)符號除了在文件內(nèi)定義給其他文件使用的符號,還包括每個section符號,在文件內(nèi)定義光是文件內(nèi)使用的符號。光文件內(nèi)使用的符號,對鏈接沒有幫助,主要為了崩潰后分析而存在。符號表也是一個由struct構(gòu)成的數(shù)組。ELF的32位符號sturct:

typedef struct {

int32_t st_name;

uint32_t st_value;

int32_t st_size;

unsigned char st_info;

unsigned char st_other;

uint16_t st_shndx;

} ELF32_Sym;

st_name字段就是符號的名字,表示為在.strtab中的字符串offset。st_info表示是局部符號、全局符號還是弱符號。符號也可以分為強符號(Strong Symbol)、弱符號(Weak Symbol),顧名思義,強符號有唯一性,弱符號沒有唯一性,一個強符號可以和多個弱符號共存,多個重復(fù)的強符號不可以共存,鏈接器會報出duplicate dymbol,可以用attribute((weak))指明弱符號。相對的,符號也有強引用(Strong Reference)、弱引用(Weak Reference),在鏈接進行符號修正的時候,強引用必須修正,而弱引用可以不修正,可以用attribute((weakref))指明符號弱引用。

st_shndx字段指明了符號是文件外符號,還是文件內(nèi)符號。如果是文件外符號就為SHN_UNDEF。如果是文件內(nèi)符號包括給其他文件使用的、光自己使用的、section符號,就為所在section的索引號,而st_value表示所在section的offset。等到鏈接過后,不管是文件外符號還是文件內(nèi)符號,st_value指明實際地址。

符號修飾(Symbol-Decoration)與函數(shù)簽名(Function-Signature)

機智的同學已經(jīng)發(fā)現(xiàn)了,如果光按上面聊的方式進行符號鏈接是有問題的,假如目標文件有個func符號又引用了其他文件同名的func符號,那符號不就出現(xiàn)沖突了?這里就需要引入函數(shù)簽名,函數(shù)簽名是一個函數(shù)的名字、參數(shù)類型、所在類名組成的字符串,不同語言、不同編譯器對同一個函數(shù)生成的函數(shù)簽名是不一樣的,比如OC中函數(shù)簽名還要加上返回變量類型,C++中還要加上NameSpace。在鏈接的時候,過程調(diào)用符號不光是函數(shù)名,是對函數(shù)簽名處理后的結(jié)果,全局變量符號也是經(jīng)過類似用函數(shù)簽名處理后的結(jié)果。這一處理過程就是符號修飾。

fishhook

fishhook是facebook開源的重綁定Mach-O符號的庫,最常用來hook C語言函數(shù),而且實際上只能重新綁定C符號,因為符號修飾這一步只去掉了”_”,相當于只針對C語言做了符號修飾。在了解了目標文件后,重綁定就不是那么困難了。最基本的思路就是先拿到header,然后通過header拿到section header table,再找到.hash,.hash是一個用于加快訪問.symtab的哈希結(jié)構(gòu),再索引到.symtab,詳見這里,通過name去.strtab比對符號名,如果匹配就置換value。

https://docs.oracle.com/cd/E2382401/html/819-0690/chapter6-48031.html

fishhook大體實現(xiàn)原理就是這樣,只不過對Mach-O平臺特性改進一下方案就行。在Mach-O中類似于section header table的段叫做load commands。并且Mach-O中使用二級命名空間,先分segment,就相當于上文中的section,然后再在同一segment中區(qū)分section。

先拿到header,通過header中的ncmds(segment的個數(shù))和cmdsize(segment的大小)字段就可以找到所有的segment。然后找到.strtab、.symtab、indirect symbol table。這個indirect symbol table是一個uint32_t的數(shù)組。它就是nl_symbol_ptr(non-lazy)和la_symbol_ptr(lazy )對應(yīng)的.symtab struct數(shù)組的索引。nl_symbol_ptr和la_symbol_ptr section section中的reserved1字段指明對應(yīng)的indirect symbol table起始offset。只要從這兩個section對應(yīng)的indirect symbol table起始表項再跳到.symtab去匹配、置換就可以了。

下面是32位下.symtab的struct,可以看到和上段文章講的幾乎一致:

struct nlist {

union {

char *n_name; /* for use when in-core */

uint32_t n_strx; /* index into the string table */

} n_un;

uint8_t n_type; /* type flag, see below */

uint8_t n_sect; /* section number or NO_SECT */

int16_t n_desc; /* see <mach-o/stab.h> */

uint32_t n_value; /* value of this symbol (or stab offset) */

};

上文提到的Mach-O格式如下:

—— —— —— —— —— —— ——

|header |

|—— —— —— —— —— —— ——|

|load commands |

|—— —— —— —— —— —— ——|

|__Text |

|—— —— —— —— —— —— ——| —— __nl_symbol_ptr

|__Data | -----> |

|—— —— —— —— —— —— ——| —— __la_symbol_ptr

|other sections... |

|—— —— —— —— —— —— ——|

|.strtab |

|—— —— —— —— —— —— ——|

|.dynsym | -----> indirect symbol table

|—— —— —— —— —— —— ——|

|..... |

—— —— —— —— —— —— —— —

更加詳細的格式,推薦這篇文章。

http://turingh.github.io/2016/03/07/mach-o文件格式分析/

鏈接

上面聊了這么多 ,那靜態(tài)鏈接到底是如何將多個目標文件鏈接成一個可執(zhí)行文件的呢?

靜態(tài)鏈接分為兩階段(Two-pass Linking),第一階段先掃描所有目標文件,調(diào)整結(jié)構(gòu)。將所有目標文件相同section合并,包括.symtab合并成全局.symtab,然后為每個section分配虛擬地址,再將全局.symtab中的符號進行置換成虛擬地址。

這里如何將全局.symtab中的符號置換成虛擬地址呢?實際上,在分配section虛擬地址后,符號的虛擬地址按所在section虛擬地址加offset就可以計算出了。

第二階段將所有符號進行修正。通過重定位表找到所有section中需要被修正的符號位置,然后從全局.symtab查詢出虛擬地址置換。

每個section都會對應(yīng)一個重定位段,這些重定位段組成一個重定位表。每個重定位表項叫做重定位入口(Relocation Entry),它記錄了所需重定向符號所在段的offset。

靜態(tài)鏈接庫

靜態(tài)鏈接庫就是一組目標文件,經(jīng)過壓縮、索引而成的一個文件形式。當我們平時在使用靜態(tài)鏈接庫的時候,實際上鏈接器會根據(jù)所需的符號,在庫中搜索到相應(yīng)的目標文件,并將其鏈接入最終可執(zhí)行文件。

動態(tài)鏈接

隨著靜態(tài)鏈接慢慢發(fā)展起來,靜態(tài)鏈接也暴露出了問題。靜態(tài)鏈接將鏈接與被鏈接的目標文件結(jié)合的太緊密了,導(dǎo)致如果多個目標文件要鏈接同一個目標文件,那這個被鏈接的目標文件相當于要被復(fù)制多份,每個可執(zhí)行文件都要包含這個被鏈接的目標文件的內(nèi)容,這樣會占太多冗余空間。那怎么辦?將鏈接與被鏈接的目標文件先隔離開,將鏈接的時機往后推移,等到裝載的時候再進行鏈接。這樣,讓被鏈接的目標文件只占一份空間就好。

既然動態(tài)鏈接隔離開了鏈接、被鏈接目標文件,鏈接目標文件需動態(tài)鏈接的符號,就需要先做個動態(tài)鏈接占位符。這也就是說,在目標文件鏈接成可執(zhí)行文件時,即使是用作動態(tài)鏈接的目標文件也要作為動態(tài)鏈接庫輸入到鏈接階段,以供目標文件識別哪些符號是動態(tài)符號。

動態(tài)鏈接重定位

上面已經(jīng)聊完了在鏈接階段對靜態(tài)鏈接進行重定位,根據(jù)符號所在section的虛擬地址和所在section的offset。而動態(tài)鏈接可以這樣重定位嗎?不行,這時動態(tài)鏈接庫的地址還沒有確定,必須等到裝載以后操作系統(tǒng)分配。那可以等到裝載以后,確定地址后再直接進行重定位嗎?不行,假如動態(tài)鏈接庫被多個進程引用,裝載時動態(tài)鏈接庫進行重定位,動態(tài)鏈接庫映射到每個進程中的虛擬地址都不一樣,動態(tài)鏈接庫只能對一個進程重定位,那么動態(tài)鏈接庫就不是共享的了。那怎么搞?

通過.got(global offset table),.got就是一個指針數(shù)組,.got存儲引用符號的實際地址。而代碼段引用符號直接更改為引用.got項的位移,這在鏈接階段以后就不會再改變了。然后將.got分配在.data section,裝載時每個進程復(fù)制一份并修正。實際上,動態(tài)鏈接重定位指的就是在裝載的時候,根據(jù)全局符號表修正.got表項。動態(tài)鏈接庫使用全局變量、靜態(tài)變量、引用文件外過程調(diào)用都要經(jīng)過.got。.got就像indirection table一樣,解決多進程共享動態(tài)鏈接庫。

這樣,動態(tài)鏈接庫雖然在不同進程中有不同的映射虛擬空間,但物理空間上共享。.got在不同進程中,虛擬空間和物理空間都不共享。如下圖所示:

virtual address -> physical address

—— —— —— —— —— —— ——

|processA |

|—— —— —— —— —— —— ——|

|..... |

|—— —— —— —— —— —— ——|

|dynamic libiraries |----------

|—— —— —— —— —— —— ——| |

|..... | | |..... |

|—— —— —— —— —— —— ——| | |—— —— —— —— —— —— ——|

|.got |---------|---------->|.got |

|—— —— —— —— —— —— ——| | |—— —— —— —— —— —— ——|

|..... | | |..... |

|—— —— —— —— —— —— ——| | |—— —— —— —— —— —— ——|

----------->|dynamic libiraries |

—— —— —— —— —— —— —— | |—— —— —— —— —— —— ——|

|processB | | |..... |

|—— —— —— —— —— —— ——| | |—— —— —— —— —— —— ——|

|..... | | ------>|.got |

|—— —— —— —— —— —— ——| | | |—— —— —— —— —— —— ——|

|dynamic libiraries |---------- | |..... |

|—— —— —— —— —— —— ——| |

|..... | |

|—— —— —— —— —— —— ——| |

|.got |---------------

|—— —— —— —— —— —— ——|

|..... |

|—— —— —— —— —— —— ——|

動態(tài)鏈接庫文件外符號重定位用.got就搞定了,那動態(tài)鏈接庫文件內(nèi)符號呢?靜態(tài)鏈接同樣是在鏈接階段重定位就搞定了。動態(tài)鏈接將絕對尋址指令更換成相對尋址指令,只要指令的offset不變,相對尋址指令就可根據(jù)當前地址和offset得到正確的地址,這樣文件內(nèi)符號根本不需要重定位了?;谝陨蟽牲c的處理,代碼段在鏈接后就不需要更改了,這樣的代碼段也叫做地址無關(guān)碼(PIC),也就是說代碼段和裝載后的地址無關(guān)。

延遲綁定(PLT)

由于要跳過.got引用動態(tài)鏈接庫的符號,動態(tài)鏈接庫比靜態(tài)鏈接庫慢5%左右,但相比于節(jié)省的大量空間還是很劃算的。除此之外,動態(tài)鏈接還會有其他的問題,裝載時需要進行重定位,會導(dǎo)致性能下降。不如,直接延遲綁定,等到過程調(diào)用符號運行時被用到再進行重定位。

整個過程強烈推薦這篇文章,要想理解動態(tài)鏈接重定位,沒有比追匯編更好的方法了。動態(tài)鏈接和延遲綁定整個過程都是由動態(tài)鏈接器幫我們完成的。當引用符號(callq)時,先jmpq去plt結(jié)構(gòu),使用了PLT,引用符號就要先jmpq去plt結(jié)構(gòu)。如果沒找到相應(yīng)的地址,然后再jmpq去.got.plt或.got中。再把符號相應(yīng).rela.plt表中的索引和.got.plt相應(yīng)的表項,pushq入棧,rela.plt中有符號的類型和名字。再jmp到動態(tài)鏈接庫中(_dl_fixup),去全局符號表中找到符號相應(yīng)的地址。再將地址reloc到.got.plt或.got相應(yīng)表項。然后就完成了延遲綁定,下次引用同樣的符號就可以jmpq去plt結(jié)構(gòu)找到地址。

http://sysfork.com/post/linux-dynamic-lib-lazy-load/

引用

程序員的自我修養(yǎng)—鏈接、裝載與庫

關(guān)注「ImportNew」,看技術(shù)干貨

《計算機建筑漫游實例(附光盤)》共九章。內(nèi)容有:建筑漫游動畫基礎(chǔ)知識、Premiere軟件學習、室內(nèi)一樓建模、室內(nèi)二樓建模、住宅小區(qū)室外建模、住宅小區(qū)游覽等。

當您出差在外地時,您可以在任何一臺有互聯(lián)網(wǎng)連接的電腦上,登陸到自己的傳真服務(wù)器上,實現(xiàn)您漫游查看傳真的功能。2100433B

世界建筑風格漫游相關(guān)推薦
  • 相關(guān)百科
  • 相關(guān)知識
  • 相關(guān)專欄

最新詞條

安徽省政采項目管理咨詢有限公司 數(shù)字景楓科技發(fā)展(南京)有限公司 懷化市人民政府電子政務(wù)管理辦公室 河北省高速公路京德臨時籌建處 中石化華東石油工程有限公司工程技術(shù)分公司 手持無線POS機 廣東合正采購招標有限公司 上海城建信息科技有限公司 甘肅鑫禾國際招標有限公司 燒結(jié)金屬材料 齒輪計量泵 廣州采陽招標代理有限公司河源分公司 高鋁碳化硅磚 博洛尼智能科技(青島)有限公司 燒結(jié)剛玉磚 深圳市東海國際招標有限公司 搭建香蕉育苗大棚 SF計量單位 福建省中億通招標咨詢有限公司 泛海三江 威海鼠尾草 Excel 數(shù)據(jù)處理與分析應(yīng)用大全 廣東國咨招標有限公司 甘肅中泰博瑞工程項目管理咨詢有限公司 山東創(chuàng)盈項目管理有限公司 當代建筑大師 拆邊機 廣西北纜電纜有限公司 大山檳榔 上海地鐵維護保障有限公司通號分公司 甘肅中維國際招標有限公司 舌花雛菊 華潤燃氣(上海)有限公司 湖北鑫宇陽光工程咨詢有限公司 GB8163標準無縫鋼管 中國石油煉化工程建設(shè)項目部 韶關(guān)市優(yōu)采招標代理有限公司 莎草目 建設(shè)部關(guān)于開展城市規(guī)劃動態(tài)監(jiān)測工作的通知 電梯平層準確度 廣州利好來電氣有限公司 四川中澤盛世招標代理有限公司