0x3 1 so載入流程

2021-10-01 07:30:53 字數 2274 閱讀 1909

system.loadlibrary()

dvmloadnativecode()

dlopen

do_dlopen() //在linker.cpp中

set_soinfo_pool_protection(prot_read);

}//執行

void soinfo::callconstructors()

void soinfo::callarray(const char* array_name unused, linker_function_t* functions, size_t count, bool reverse) …}

//載入

findlibrary(const char* name)

find_library_internal(soname)

// load_library函式是整個so載入過程的重中之重!它建立了動態鏈結庫的控制代碼

load_library(name)

soinfo* si = soinfo_alloc(bname ? bname + 1 : name);

if (si == null)

//讀取efl的檔案頭

si->base = elf_reader.load_start();

si->size = elf_reader.load_size();

si->load_bias = elf_reader.load_bias();

si->flags = 0;

si->entry = 0; //入口函式設為null

si->dynamic = null;

si->phnum = elf_reader.phdr_count();

si->phdr = elf_reader.loaded_phdr();

return si;

//主要函式

bool elfreader::load()

bool elfreader::readprogramheader()

/*返回elf檔案程式頭部表中所指定的所有可載入segments(這些segments可能是非連續的)的區間大小,如果沒有可載入的segments,就返回0

如果out_min_vaddr 或 out_max_vadd是非空的,它們就會被設定成將被儲存的頁的最小/大位址(如果沒有可載入segments的話,就設為0) */

size_t phdr_table_get_load_size(const elfw(phdr)* phdr_table, size_t phdr_count,

elfw(addr)* out_min_vaddr,

elfw(addr)* out_max_vaddr)

found_pt_load = true;

if (phdr->p_vaddr < min_vaddr)

if (phdr->p_vaddr + phdr->p_memsz > max_vaddr)

}if (!found_pt_load)

min_vaddr = page_start(min_vaddr);

max_vaddr = page_end(max_vaddr);

if (out_min_vaddr != null)

if (out_max_vaddr != null)

return max_vaddr - min_vaddr;}

通俗點講,此函式就是返回elf檔案中包含的可載入segments總共需要占用的空間大小,並設定其最小虛擬位址的值(是頁對齊的)。值得注意的是,原函式有4個引數,但是在reserveaddressspace中呼叫該函式時卻只傳遞了3個引數,忽略了out_max_vaddr。在我個人看來是因為已知了out_min_vaddr及兩者的差值load_size

,所以可以通過out_min_vaddr + load_size來求得out_max_vaddr。

現在回到reserveaddressspace函式。求得load_size之後,就需要為這些segments分配足夠的記憶體空間。這裡需要注意的是mmap的第乙個引數並非為null,而是addr。這就表示將對映區間的開始位址放在程序的addr位址處(一般不會成功,而是由系統自動分配,所以可以看作是null),mmap返回實際對映後的記憶體開始位址start。顯然load_bias_ = start – addr就是實際對映記憶體位址同linker期望的對映位址的誤差值。後面的操作中,linker就可以通過p_vaddr + load_bias_來獲取某一segments在記憶體中的開始位址了。

bool elfreader::loadsegments()

rt thread版本3 1 X串列埠初始化流程

rt hw usart init中呼叫rt device register將dev flag設定為rt device flag rdwr rt device flag int rx 如果開啟了dma,則rt device flag rdwr rt device flag int rx rt devi...

java筆記0x003 控制執行流程

boolean issuccess true if issuccess if issuccess else system.out.println failure if issuccess else if issuccess elsewhile issuccess 以上 將永遠執行下去,所以我們需要手...

BIOS載入MBR到記憶體位址0x7C00的由來

2012 11 27 14 03 48 對於很多人來講0x7c00這個位址是很神秘的,不知道這是幹什麼的。但是對於了解過x86平台下bios啟動過程的人,對這個位址再熟悉不過了。bios就是將mbr讀入0x7c00位址,然後進行後續的引導的。作業系統或是bootloader開發者必須假設 他們的彙編...