锘??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲欧美成人久久综合中文网,久久精品国产WWW456C0M,久久久久久精品免费看SSShttp://m.shnenglu.com/JonsenElizee/category/13505.htmlSoftware Developing Blog <BR> <BR> "An idea is fragile . It can be killed by a scornful smile or a yawn .It can be mound down by irony and scared to death by a cold look." <BR> "Most cultures throughout human history have not liked creative individuals .They ignore them or kill them.It is a very efficient way of stopping creativity." <BR> <BR> ------Advertising boss Charles Browe and Howard Gardner ,professor at Harvard zh-cnSat, 22 Jan 2011 10:04:48 GMTSat, 22 Jan 2011 10:04:48 GMT60High Memory In The Linux Kernelhttp://m.shnenglu.com/JonsenElizee/archive/2011/01/22/139105.htmlJonsenElizeeJonsenElizeeSat, 22 Jan 2011 02:44:00 GMThttp://m.shnenglu.com/JonsenElizee/archive/2011/01/22/139105.htmlhttp://m.shnenglu.com/JonsenElizee/comments/139105.htmlhttp://m.shnenglu.com/JonsenElizee/archive/2011/01/22/139105.html#Feedback0http://m.shnenglu.com/JonsenElizee/comments/commentRss/139105.htmlhttp://m.shnenglu.com/JonsenElizee/services/trackbacks/139105.htmlFeature: High Memory In The Linux Kernel
Submitted by Amit Shah
on February 21, 2004 - 6:02am

As RAM increasingly becomes a commodity, the prices drop and computer users are able to buy more. 32-bit archictectures face certain limitations in regards to accessing these growing amounts of RAM. To better understand the problem and the various solutions, we begin with an overview of Linux memory management. Understanding how basic memory management works, we are better able to define the problem, and finally to review the various solutions.

This article was written by examining the Linux 2.6 kernel source code for the x86 architecture types.


Overview of Linux memory management

32-bit architectures can reference 4 GB of physical memory (2^32). Processors that have an MMU (Memory Management Unit) support the concept of virtual memory: page tables are set up by the kernel which map "virtual addresses" to "physical addresses"; this basically means that each process can access 4 GB of memory, thinking it's the only process running on the machine (much like multi-tasking, in which each process is made to think that it's the only process executing on a CPU).

The virtual address to physical address mappings are done by the kernel. When a new process is "fork()"ed, the kernel creates a new set of page tables for the process. The addresses referenced within a process in user-space are virtual addresses. They do not necessarily map directly to the same physical address. The virtual address is passed to the MMU (Memory Management Unit of the processor) which converts it to the proper physical address based on the tables set up by the kernel. Hence, two processes can refer to memory address 0x08329, but they would refer to two different locations in memory.

The Linux kernel splits the 4 GB virtual address space of a process in two parts: 3 GB and 1 GB. The lower 3 GB of the process virtual address space is accessible as the user-space virtual addresses and the upper 1 GB space is reserved for the kernel virtual addresses. This is true for all processes.

							      
+----------+ 4 GB
| |
| |
| |
| Kernel |
| | +----------+
| Virtual | | |
| | | |
| Space | | High |
| | | |
| (1 GB) | | Memory |
| | | |
| | | (unused) |
+----------+ 3 GB +----------+ 1 GB
| | | |
| | | |
| | | |
| | | Kernel |
| | | |
| | | Physical |
| | | |
|User-space| | Space |
| | | |
| Virtual | | |
| | | |
| Space | | |
| | | |
| (3 GB) | +----------+ 0 GB
| |
| | Physical
| | Memory
| |
| |
| |
| |
| |
+----------+ 0 GB

Virtual
Memory

The kernel virtual area (3 - 4 GB address space) maps to the first 1 GB of physical RAM. The 3 GB addressable RAM available to each process is mapped to the available physical RAM.

The Problem

So, the basic problem here is, the kernel can just address 1 GB of virtual addresses, which can translate to a maximum of 1 GB of physical memory. This is because the kernel directly maps all available kernel virtual space addresses to the available physical memory.

Solutions

There are some solutions which address this problem:

  1. 2G / 2G, 1G / 3G split
  2. HIGHMEM solution for using up to 4 GB of memory
  3. HIGHMEM solution for using up to 64 GB of memory

1. 2G / 2G, 1G / 3G split

Instead of splitting the virtual address space the traditional way of 3G / 1G (3 GB for user-space, 1 GB for kernel space), third-party patches exist to split the virtual address space 2G / 2G or 1G / 3G. The 1G / 3G split is a bit extreme in that you can map up to 3 GB of physical memory, but user-space applications cannot grow beyond 1 GB. It could work for simple applications; but if one has more than 3 GB of physical RAM, he / she won't run simple applications on it, right?

The 2G / 2G split seems to be a balanced approach to using RAM more than 1 GB without using the HIGHMEM patches. However, server applications like databases always want as much virtual addressing space as possible; so this approach may not work in those scenarios.

There's a patch for 2.4.23 that includes a config-time option of selecting the user / kernel split values by Andrea Arcangeli. It is available at his kernel page. It's a simple patch and making it work on 2.6 should not be too difficult.

Before looking at solutions 2 & 3, let's take a look at some more Linux Memory Management issues.

Zones

In Linux, the memory available from all banks is classified into "nodes". These nodes indicate how much memory each bank has. This classification is mainly useful for NUMA architectures, but it's also used for UMA architectures, where the number of nodes is just 1.

Memory in each node is divided into "zones". The zones currently defined are ZONE_DMA, ZONE_NORMAL and ZONE_HIGHMEM.

ZONE_DMA is used by some devices for data transfer and is mapped in the lower physical memory range (up to 16 MB).

Memory in the ZONE_NORMAL region is mapped by the kernel in the upper region of the linear address space. Most operations can only take place in ZONE_NORMAL; so this is the most performance critical zone. ZONE_NORMAL goes from 16 MB to 896 MB.

To address memory from 1 GB onwards, the kernel has to map pages from high memory into ZONE_NORMAL.

Some area of memory is reserved for storing several kernel data structures that store information about the memory map and page tables. This on x86 is 128 MB. Hence, of the 1 GB physical memory the kernel can access, 128MB is reserved. This means that the kernel virtual address in this 128 MB is not mapped to physical memory. This leaves a maximum of 896 MB for ZONE_NORMAL. So, even if one has 1 GB of physical RAM, just 896 MB will be actually available.

Back to the solutions:

2. HIGHMEM solution for using up to 4 GB of memory

Since Linux can't access memory which hasn't been directly mapped into its address space, to use memory > 1 GB, the physical pages have to be mapped in the kernel virtual address space first. This means that the pages in ZONE_HIGHMEM have to be mapped in ZONE_NORMAL before they can be accessed.

The reserved space which we talked about earlier (in case of x86, 128 MB) has an area in which pages from high memory are mapped into the kernel address space.

To create a permanent mapping, the "kmap" function is used. Since this function may sleep, it may not be used in interrupt context. Since the number of permanent mappings is limited (if not, we could've directly mapped all the high memory in the address space), pages mapped this way should be "kunmap"ped when no longer needed.

Temporary mappings can be created via "kmap_atomic". This function doesn't block, so it can be used in interrupt context. "kunmap_atomic" un-maps the mapped high memory page. A temporary mapping is only available as long as the next temporary mapping. However, since the mapping and un-mapping functions also disable / enable preemption, it's a bug to not kunmap_atomic a page mapped via kmap_atomic.

3. HIGHMEM solution for using 64 GB of memory

This is enabled via the PAE (Physical Address Extension) extension of the PentiumPro processors. PAE addresses the 4 GB physical memory limitation and is seen as Intel's answer to AMD 64-bit and AMD x86-64. PAE allows processors to access physical memory up to 64 GB (36 bits of address bus). However, since the virtual address space is just 32 bits wide, each process can't grow beyond 4 GB. The mechanism used to access memory from 4 GB to 64 GB is essentially the same as that of accessing the 1 GB - 4 GB RAM via the HIGHMEM solution discussed above.

Should I enable CONFIG_HIGHMEM for my 1 GB RAM system?

It is advised to not enable CONFIG_HIGHMEM in the kernel to utilize the extra 128 MB you get for your 1 GB RAM system. I/O Devices cannot directly address high memory from PCI space, so bounce buffers have to be used. Plus the virtual memory management and paging costs come with extra mappings. For details on bounce buffers, refer to Mel Gorman's documentation (link below).

For more information, see



JonsenElizee 2011-01-22 10:44 鍙戣〃璇勮
]]>
Linux libhttp://m.shnenglu.com/JonsenElizee/archive/2010/10/01/128163.htmlJonsenElizeeJonsenElizeeThu, 30 Sep 2010 18:10:00 GMThttp://m.shnenglu.com/JonsenElizee/archive/2010/10/01/128163.htmlhttp://m.shnenglu.com/JonsenElizee/comments/128163.htmlhttp://m.shnenglu.com/JonsenElizee/archive/2010/10/01/128163.html#Feedback0http://m.shnenglu.com/JonsenElizee/comments/commentRss/128163.htmlhttp://m.shnenglu.com/JonsenElizee/services/trackbacks/128163.htmlHow does linux lib work?


鐢?Linux 榪涜鍔ㄦ佸姞杞?/a>

Linux 騫朵笉浼氳嚜鍔ㄤ負緇欏畾紼嬪簭鍔犺澆鍜岄摼鎺ュ簱錛岃屾槸涓庡簲鐢ㄧ▼搴忔湰韜叡浜鎺у埗鏉冦傝繖涓繃紼嬪氨縐頒負鍔ㄦ佸姞杞?/em>銆備嬌鐢ㄥ姩鎬佸姞杞斤紝搴旂敤紼嬪簭鑳藉鍏堟寚瀹氳鍔犺澆鐨勫簱錛岀劧鍚庡皢璇ュ簱浣滀負涓涓彲鎵ц鏂囦歡鏉ヤ嬌鐢紙鍗寵皟鐢ㄥ叾涓殑鍑芥暟錛夈備絾鏄濡傛偍鍦ㄥ墠闈㈡墍浜嗚В鍒扮殑錛岀敤浜庡姩鎬佸姞杞界殑鍏變韓搴撲笌鏍囧噯鍏變韓搴擄紙ELF 鍏變韓瀵硅薄錛夋棤寮傘備簨瀹炰笂錛?code>ld-linux 鍔ㄦ侀摼鎺ュ櫒浣滀負 ELF 鍔犺澆鍣ㄥ拰瑙i噴鍣紝浠嶇劧浼氬弬涓庡埌榪欎釜榪囩▼涓?/p>

鍔ㄦ佸姞杞斤紙Dynamic Loading錛孌L錛堿PI 灝辨槸涓轟簡鍔ㄦ佸姞杞借屽瓨鍦ㄧ殑錛屽畠鍏佽鍏變韓搴撳鐢ㄦ埛絀洪棿紼嬪簭鍙敤銆傚敖綆¢潪甯稿皬錛屼絾鏄繖涓?API 鎻愪緵浜嗘墍鏈夐渶瑕佺殑涓滆タ錛岃屼笖寰堝鍥伴毦鐨勫伐浣滄槸鍦ㄥ悗鍙板畬鎴愮殑銆傝〃 1 灞曠ず浜嗚繖涓畬鏁寸殑 API銆?/p>
琛?1. Dl API
鍑芥暟 鎻忚堪
dlopen 浣垮璞℃枃浠跺彲琚▼搴忚闂?/td>
dlsym 鑾峰彇鎵ц浜?dlopen 鍑芥暟鐨勫璞℃枃浠朵腑鐨勭鍙風殑鍦板潃
dlerror 榪斿洖涓婁竴嬈″嚭鐜伴敊璇殑瀛楃涓查敊璇?/td>
dlclose 鍏抽棴鐩爣鏂囦歡

璇ヨ繃紼嬮鍏堟槸璋冪敤 dlopen錛屾彁渚涜璁塊棶鐨勬枃浠跺璞″拰妯″紡銆傝皟鐢?dlopen 鐨勭粨鏋滄槸紼嶅欒浣跨敤鐨勫璞$殑鍙ユ焺銆?code>mode 鍙傛暟閫氱煡鍔ㄦ侀摼鎺ュ櫒浣曟椂鎵ц鍐嶅畾浣嶃傛湁涓や釜鍙兘鐨勫箋傜涓涓槸 RTLD_NOW錛屽畠琛ㄦ槑鍔ㄦ侀摼鎺ュ櫒灝嗕細鍦ㄨ皟鐢?dlopen 鏃跺畬鎴愭墍鏈夊繀瑕佺殑鍐嶅畾浣嶃傜浜屼釜鍙夌殑妯″紡鏄?RTLD_LAZY錛屽畠鍙湪闇瑕佹椂鎵ц鍐嶅畾浣嶃傝繖鏄氳繃鍦ㄥ唴閮ㄤ嬌鐢ㄥ姩鎬侀摼鎺ュ櫒閲嶅畾鍚戞墍鏈夊皻鏈啀瀹氫綅鐨勮姹傛潵瀹屾垚鐨勩傝繖鏍鳳紝鍔ㄦ侀摼鎺ュ櫒灝辮兘澶熷湪璇鋒眰鏃剁煡鏅撲綍鏃跺彂鐢熶簡鏂扮殑寮曠敤錛岃屼笖鍐嶅畾浣嶅彲浠ユ甯歌繘琛屻傚悗闈㈢殑璋冪敤鏃犻渶閲嶅鍐嶅畾浣嶈繃紼嬨?/p>

榪樺彲浠ラ夋嫨鍙﹀涓ょ妯″紡錛屽畠浠彲浠ユ寜浣?OR 鍒?mode 鍙傛暟涓?code>RTLD_LOCAL 琛ㄦ槑鍏朵粬浠諱綍瀵硅薄閮芥棤娉曚嬌鍔犺澆鐨勫叡浜璞$殑絎﹀彿鐢ㄤ簬鍐嶅畾浣嶈繃紼嬨傚鏋滆繖姝f槸鎮ㄦ兂瑕佺殑鐨勮瘽錛堜緥濡傦紝涓轟簡璁╁叡浜殑瀵硅薄鑳藉璋冪敤鍘熷榪涚▼鏄犲儚涓殑絎﹀彿錛夛紝閭e氨浣跨敤 RTLD_GLOBAL 鍚с?/p>

dlopen 鍑芥暟榪樹細鑷姩瑙f瀽鍏變韓搴撲腑鐨勪緷璧栭」銆傝繖鏍鳳紝濡傛灉鎮ㄦ墦寮浜嗕竴涓緷璧栦簬鍏朵粬鍏變韓搴撶殑瀵硅薄錛屽畠灝變細鑷姩鍔犺澆瀹冧滑銆傚嚱鏁拌繑鍥炰竴涓彞鏌勶紝璇ュ彞鏌勭敤浜庡悗緇殑 API 璋冪敤銆?code>dlopen 鐨勫師鍨嬩負錛?/p>
#include <dlfcn.h>

void *dlopen( const char *file, int mode );

鏈変簡 ELF 瀵硅薄鐨勫彞鏌勶紝灝卞彲浠ラ氳繃璋冪敤 dlsym 鏉ヨ瘑鍒繖涓璞″唴鐨勭鍙風殑鍦板潃浜嗐傝鍑芥暟閲囩敤涓涓鍙峰悕縐幫紝濡傚璞″唴鐨勪竴涓嚱鏁扮殑鍚嶇О銆傝繑鍥炲間負瀵硅薄絎﹀彿鐨勮В鏋愬湴鍧錛?/p>
void *dlsym( void *restrict handle, const char *restrict name );

濡傛灉璋冪敤璇?API 鏃跺彂鐢熶簡閿欒錛屽彲浠ヤ嬌鐢?dlerror 鍑芥暟榪斿洖涓涓〃紺烘閿欒鐨勪漢綾誨彲璇葷殑瀛楃涓層傝鍑芥暟娌℃湁鍙傛暟錛屽畠浼氬湪鍙戠敓鍓嶉潰鐨勯敊璇椂榪斿洖涓涓瓧絎︿覆錛屽湪娌℃湁閿欒鍙戠敓鏃惰繑鍥?NULL錛?/p>
char *dlerror();

鏈鍚庯紝濡傛灉鏃犻渶鍐嶈皟鐢ㄥ叡浜璞$殑璇濓紝搴旂敤紼嬪簭鍙互璋冪敤 dlclose 鏉ラ氱煡鎿嶄綔緋葷粺涓嶅啀闇瑕佸彞鏌勫拰瀵硅薄寮曠敤浜嗐傚畠瀹屽叏鏄寜寮曠敤鏉ヨ鏁扮殑錛屾墍浠ュ悓涓涓叡浜璞$殑澶氫釜鐢ㄦ埛鐩鎬簰闂翠笉浼氬彂鐢熷啿紿侊紙鍙榪樻湁涓涓敤鎴峰湪浣跨敤瀹冿紝瀹冨氨浼氬緟鍦ㄥ唴瀛樹腑錛夈備換浣曢氳繃宸插叧闂殑瀵硅薄鐨?dlsym 瑙f瀽鐨勭鍙烽兘灝嗕笉鍐嶅彲鐢ㄣ?/p>
char *dlclose( void *handle );





鍥為〉棣?/strong>


鍔ㄦ佸姞杞界ず渚?/a>

浜? 瑙d簡 API 涔嬪悗錛屼笅闈㈣鎴戜滑鏉ョ湅涓鐪?DL API 鐨勪緥瀛愩傚湪榪欎釜搴旂敤紼嬪簭涓紝鎮ㄤ富瑕佸疄鐜頒簡涓涓? shell錛屽畠鍏佽鎿嶄綔鍛樻潵鎸囧畾搴撱佸嚱鏁板拰鍙傛暟銆傛崲鍙ヨ瘽璇達紝涔熷氨鏄敤鎴瘋兘澶熸寚瀹氫竴涓簱騫惰皟鐢ㄨ搴擄紙鍏堝墠鏈摼鎺ヤ簬璇ュ簲鐢ㄧ▼搴忕殑錛夊唴鐨勪換鎰忎竴涓嚱鏁般傞鍏堜嬌鐢? DL API 鏉ヨВ鏋愯搴撲腑鐨勫嚱鏁幫紝鐒跺悗浣跨敤鐢ㄦ埛瀹氫箟鐨勫弬鏁幫紙鐢ㄦ潵鍙戦佺粨鏋滐級鏉ヨ皟鐢ㄥ畠銆傛竻鍗?2 灞曠ず浜嗗畬鏁寸殑搴旂敤紼嬪簭銆?/p>
娓呭崟 2. 浣跨敤 DL API 鐨?Shell
	
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>

#define MAX_STRING 80


void invoke_method( char *lib, char *method, float argument )
{
void *dl_handle;
float (*func)(float);
char *error;

/* Open the shared object */
dl_handle = dlopen( lib, RTLD_LAZY );
if (!dl_handle) {
printf( "!!! %s\n", dlerror() );
return;
}

/* Resolve the symbol (method) from the object */
func = dlsym( dl_handle, method );
error = dlerror();
if (error != NULL) {
printf( "!!! %s\n", error );
return;
}

/* Call the resolved method and print the result */
printf(" %f\n", (*func)(argument) );

/* Close the object */
dlclose( dl_handle );

return;
}


int main( int argc, char *argv[] )
{
char line[MAX_STRING+1];
char lib[MAX_STRING+1];
char method[MAX_STRING+1];
float argument;

while (1) {

printf("> ");

line[0]=0;
fgets( line, MAX_STRING, stdin);

if (!strncmp(line, "bye", 3)) break;

sscanf( line, "%s %s %f", lib, method, &argument);

invoke_method( lib, method, argument );

}

}

瑕佹瀯寤鴻繖涓簲鐢ㄧ▼搴忥紝闇瑕侀氳繃 GNU Compiler Collection錛圙CC錛変嬌鐢ㄥ涓嬬殑緙栬瘧琛屻傞夐」 -rdynamic 鐢ㄦ潵閫氱煡閾炬帴鍣ㄥ皢鎵鏈夌鍙鋒坊鍔犲埌鍔ㄦ佺鍙瘋〃涓紙鐩殑鏄兘澶熼氳繃浣跨敤 dlopen 鏉ュ疄鐜板悜鍚庤窡韙級銆?code>-ldl 琛ㄦ槑涓瀹氳灝?dllib 閾炬帴浜庤紼嬪簭銆?/p>
gcc -rdynamic -o dl dl.c -ldl

鍐嶅洖鍒?娓呭崟 2錛?code>main 鍑芥暟浠呭厖褰撹В閲婂櫒錛岃В鏋愭潵鑷緭鍏ヨ鐨勪笁涓弬鏁幫紙搴撳悕銆佸嚱鏁板悕鍜屾誕鐐瑰弬鏁幫級銆傚鏋滃嚭鐜?bye 鐨勮瘽錛屽簲鐢ㄧ▼搴忓氨浼氶鍑恒傚惁鍒欑殑璇濓紝榪欎笁涓弬鏁板氨浼氫紶閫掔粰浣跨敤 DL API 鐨?invoke_method 鍑芥暟銆?/p>

棣栧厛璋冪敤 dlopen 鏉ヨ闂洰鏍囨枃浠躲傚鏋滆繑鍥?NULL 鍙ユ焺錛岃〃紺烘棤娉曟壘鍒板璞★紝榪囩▼緇撴潫銆傚惁鍒欑殑璇濓紝灝嗕細寰楀埌瀵硅薄鐨勪竴涓彞鏌勶紝鍙互榪涗竴姝ヨ闂璞°傜劧鍚庝嬌鐢?dlsym API 鍑芥暟錛屽皾璇曡В鏋愭柊鎵撳紑鐨勫璞℃枃浠朵腑鐨勭鍙楓傛偍灝嗕細寰楀埌涓涓湁鏁堢殑鎸囧悜璇ョ鍙風殑鎸囬拡錛屾垨鑰呮槸寰楀埌涓涓?NULL 騫惰繑鍥炰竴涓敊璇?/p>

鍦? ELF 瀵硅薄涓В鏋愪簡絎﹀彿鍚庯紝涓嬩竴姝ュ氨鍙渶瑕佽皟鐢ㄥ嚱鏁般傝娉ㄦ剰涓涓嬭繖涓唬鐮佸拰鍓嶉潰璁ㄨ鐨勫姩鎬侀摼鎺ョ殑宸埆銆傚湪榪欎釜渚嬪瓙涓紝鎮ㄥ己琛屽皢鐩爣鏂囦歡涓殑絎﹀彿鍦板潃鐢ㄤ綔鍑芥暟鎸? 閽堬紝鐒跺悗璋冪敤瀹冦傝屽湪鍓嶉潰鐨勪緥瀛愭槸灝嗗璞″悕浣滀負鍑芥暟錛岀敱鍔ㄦ侀摼鎺ュ櫒鏉ョ‘淇濈鍙鋒寚鍚戞紜殑浣嶇疆銆傝櫧鐒跺姩鎬侀摼鎺ュ櫒鑳藉涓烘偍鍋氭墍鏈夐夯鐑︾殑宸ヤ綔錛屼絾榪欎釜鏂規硶浼氳鎮? 鏋勫緩鍑烘瀬鍏跺姩鎬佺殑搴旂敤紼嬪簭錛屽畠浠彲浠ュ啀榪愯鏃惰鎵╁睍銆?/p>

璋冪敤 ELF 瀵硅薄涓殑鐩爣鍑芥暟鍚庯紝閫氳繃璋冪敤 dlclose 鏉ュ叧闂瀹冪殑璁塊棶銆?/p>

娓? 鍗?3 灞曠ず浜嗕竴涓浣曚嬌鐢ㄨ繖涓祴璇曠▼搴忕殑渚嬪瓙銆傚湪榪欎釜渚嬪瓙涓紝棣栧厛緙栬瘧紼嬪簭鑰屽悗鎵ц瀹冦傛帴鐫璋冪敤浜?math 搴擄紙libm.so錛変腑鐨勫嚑涓嚱鏁般傚畬鎴愭紨紺哄悗錛岀▼搴忕幇鍦ㄨ兘澶熺敤鍔ㄦ佸姞杞芥潵璋冪敤鍏變韓瀵硅薄錛堝簱錛変腑鐨勪換鎰忓嚱鏁頒簡銆傝繖鏄竴涓緢寮哄ぇ鐨勫姛鑳斤紝閫氳繃瀹冭繕鑳藉緇欑▼搴? 鎵╁厖鏂扮殑鍔熻兘銆?/p>
娓呭崟 3. 浣跨敤綆鍗曠殑紼嬪簭鏉ヨ皟鐢ㄥ簱鍑芥暟
	
mtj@camus:~/dl$ gcc -rdynamic -o dl dl.c -ldl
mtj@camus:~/dl$ ./dl
> libm.so cosf 0.0
1.000000
> libm.so sinf 0.0
0.000000
> libm.so tanf 1.0
1.557408
> bye
mtj@camus:~/dl$





鍥為〉棣?/strong>


宸ュ叿

Linux 鎻愪緵浜嗗緢澶氱鏌ョ湅鍜岃В鏋?ELF 瀵硅薄錛堝寘鎷叡浜簱錛夌殑宸ュ叿銆傚叾涓渶鏈夌敤鐨勪竴涓綋灞?ldd 鍛戒護錛屾偍鍙互浣跨敤瀹冩潵鍙戦佸叡浜簱渚濊禆欏廣備緥濡傦紝鍦?dl 搴旂敤紼嬪簭涓婁嬌鐢?ldd 鍛戒護浼氭樉紺哄涓嬪唴瀹癸細

mtj@camus:~/dl$ ldd dl
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7fdb000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eac000)
/lib/ld-linux.so.2 (0xb7fe7000)
mtj@camus:~/dl$

ldd 鎵鍛婅瘔鎮ㄧ殑鏄細璇?ELF 鏄犲儚渚濊禆浜?linux-gate.so錛堜竴涓壒孌婄殑鍏變韓瀵硅薄錛屽畠澶勭悊緋葷粺璋冪敤錛屽畠鍦ㄦ枃浠剁郴緇熶腑鏃犲叧鑱旀枃浠訛級銆乴ibdl.so錛圖L API錛夈丟NU C 搴擄紙libc.so錛変互鍙?Linux 鍔ㄦ佸姞杞藉櫒錛堝洜涓哄畠閲岄潰鏈夊叡浜簱渚濊禆欏癸級銆?/p>

readelf 鍛戒護鏄竴涓湁寰堝鐗規х殑瀹炵敤紼嬪簭錛屽畠璁╂偍鑳藉瑙f瀽鍜岃鍙?ELF 瀵硅薄銆?code>readelf 鏈変竴涓湁瓚g殑鐢ㄩ旓紝灝辨槸鐢ㄦ潵璇嗗埆瀵硅薄鍐呭彲鍐嶅畾浣嶇殑欏廣傚浜庢垜浠繖涓畝鍗曠殑紼嬪簭鏉ヨ錛?a >娓呭崟 2 灞曠ず鐨勭▼搴忥級錛屾偍鍙互鐪嬪埌闇瑕佸啀瀹氫綅鐨勭鍙蜂負錛?/p>
mtj@camus:~/dl$ readelf -r dl

Relocation section '.rel.dyn' at offset 0x520 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
08049a3c 00001806 R_386_GLOB_DAT 00000000 __gmon_start__
08049a78 00001405 R_386_COPY 08049a78 stdin

Relocation section '.rel.plt' at offset 0x530 contains 8 entries:
Offset Info Type Sym.Value Sym. Name
08049a4c 00000207 R_386_JUMP_SLOT 00000000 dlsym
08049a50 00000607 R_386_JUMP_SLOT 00000000 fgets
08049a54 00000b07 R_386_JUMP_SLOT 00000000 dlerror
08049a58 00000c07 R_386_JUMP_SLOT 00000000 __libc_start_main
08049a5c 00000e07 R_386_JUMP_SLOT 00000000 printf
08049a60 00001007 R_386_JUMP_SLOT 00000000 dlclose
08049a64 00001107 R_386_JUMP_SLOT 00000000 sscanf
08049a68 00001907 R_386_JUMP_SLOT 00000000 dlopen
mtj@camus:~/dl$

浠庤繖涓垪琛ㄤ腑錛屾偍鍙互鐪嬪埌鍚勭鍚勬牱鐨勯渶瑕佸啀瀹氫綅錛堝埌 libc.so錛夌殑 C 搴撹皟鐢紝鍖呮嫭瀵?DL API錛坙ibdl.so錛夌殑璋冪敤銆傚嚱鏁? __libc_start_main 鏄竴涓? C 搴撳嚱鏁幫紝瀹冧紭鍏堜簬紼嬪簭鐨? main 鍑芥暟錛堜竴涓彁渚涘繀瑕佸垵濮嬪寲鐨?shell錛夎岃璋冪敤銆?/p>

鍏朵粬鎿嶄綔瀵硅薄鏂囦歡鐨勫疄鐢ㄧ▼搴忓寘鎷細objdump錛屽畠灞曠ず浜嗗叧浜庡璞℃枃浠剁殑淇℃伅錛?code>nm錛屽畠鍒楀嚭鏉ヨ嚜瀵硅薄鏂囦歡錛堝寘鎷皟璇曚俊鎭級鐨勭鍙楓傝繕鍙互灝?EFL 紼嬪簭浣滀負鍙傛暟錛岀洿鎺ヨ皟鐢?Linux 鍔ㄦ侀摼鎺ュ櫒錛屼粠鑰屾墜鍔ㄥ惎鍔ㄦ槧鍍忥細

mtj@camus:~/dl$ /lib/ld-linux.so.2 ./dl
> libm.so expf 0.0
1.000000
>

鍙﹀錛屽彲浠ヤ嬌鐢?ld-linux.so 鐨?--list 閫夐」鏉ョ綏鍒?ELF 鏄犲儚鐨勪緷璧栭」錛?code>ldd 鍛戒護涔熷姝わ級銆傚垏璁幫紝瀹冧粎浠呮槸涓涓敤鎴風┖闂寸▼搴忥紝鏄敱鍐呮牳鍦ㄩ渶瑕佹椂寮曞鐨勩?/p>


]]>
久久九九久精品国产免费直播| 无码人妻久久一区二区三区蜜桃 | 狠狠综合久久综合88亚洲| 久久亚洲国产最新网站| 精品久久久久久久久午夜福利| 久久国产精品99精品国产987| 久久99精品久久久久久齐齐 | 久久综合给合久久狠狠狠97色| 国产成年无码久久久久毛片| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久精品国产亚洲AV不卡| 97久久天天综合色天天综合色hd| 国产成人99久久亚洲综合精品| 精品熟女少妇AV免费久久| 青青草原综合久久| 亚洲va久久久噜噜噜久久狠狠| 99热都是精品久久久久久| 无码国产69精品久久久久网站| 久久久久久一区国产精品| 99久久久国产精品免费无卡顿| 蜜臀久久99精品久久久久久| 2021久久精品国产99国产精品| 热RE99久久精品国产66热| 99久久精品无码一区二区毛片| 人妻无码αv中文字幕久久 | 欧美大战日韩91综合一区婷婷久久青草| 久久久久波多野结衣高潮| 久久国产乱子伦精品免费午夜| 国产精品一久久香蕉国产线看观看 | 亚洲人成网站999久久久综合| 亚洲嫩草影院久久精品| 国产亚洲精久久久久久无码| 熟妇人妻久久中文字幕| 少妇久久久久久久久久| 亚洲欧美日韩久久精品第一区| 亚洲午夜精品久久久久久浪潮| 久久99精品久久久久久不卡| 精品多毛少妇人妻AV免费久久| 99久久国产综合精品网成人影院| 久久成人国产精品二三区| 久久久久久免费一区二区三区|