精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux從源碼分析ldconfig命令對可執行文件緩存信息的讀取原理(緩存文件的讀)

系統 Linux
本文主要通過解讀Linux的ldconfig命令的關鍵代碼,分析了ldconfig命令是如何實現讀取緩存文件 /etc/ld.so.cache 的內容的。

今日問題:Linux的ldconfig -p命令可打印出系統緩存已記錄的所有動態庫的信息。那么這個功能是如何實現的?

本文主要通過解讀Linux的ldconfig命令的關鍵代碼,分析了ldconfig命令是如何實現讀取緩存文件 /etc/ld.so.cache 的內容的。本文涉及到的ldconfig的cache.c 代碼文件網址[1],在參考資料里。

ldconfig 使用的 /etc/ld.so.cache 文件,曾出現過兩個版本:

1.老版本的緩存文件格式 老版本指libc5 格式的動態庫,在glibc 2.0/2.1版本時采用的格式。緩存文件內容由cache_file類型的數據結構填充,其定義為

struct cache_file
{
  char magic[sizeof CACHEMAGIC - 1];
  unsigned int nlibs; /* 記錄的條數*/
  struct file_entry libs[0];
};

2.新版本的的緩存文件格式 新版本指glibc 2.2及之后版本的。緩存文件內容由cache_file_new數據結構填充。定義為:

struct cache_file_new
{
  char magic[sizeof CACHEMAGIC_NEW - 1];
  char version[sizeof CACHE_VERSION - 1];
  uint32_t nlibs;  /* 記錄的條數 */
  uint32_t len_strings;  /* Size of string table. */

  /* flags & cache_file_new_flags_endian_mask is one of the values
     cache_file_new_flags_endian_unset, cache_file_new_flags_endian_invalid,
     cache_file_new_flags_endian_little, cache_file_new_flags_endian_big.

     The remaining bits are unused and should be generated as zero and
     ignored by readers.  */
  uint8_t flags;

  uint8_t padding_unsed[3]; /* Not used, for future extensions.  */

  /* File offset of the extension directory.  See struct
     cache_extension below.  Must be a multiple of four.  */
  uint32_t extension_offset;

  uint32_t unused[3];  /* Leave space for future extensions
       and align to 8 byte boundary.  */
  struct file_entry_new libs[0]; /* Entries describing libraries.  */
  /* After this the string table of size len_strings is found. */
};

glibc-ld.so.cache1.1??? 以上輸出信息確實以glibc-ld.so.cache開始,所以我用的Ubuntu22.04系統的ldconfig的緩存文件內容是新格式的。

ldconfig代碼的cache.c 文件里是這樣根據magic的不同用if(){} else{}處理的:

if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1)) {///當屬于老版本時,按這里的方式處理 /* This can only be the new format without the old one. */ cache_new = (struct cache_file_new *) cache;

if (memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)

在glibc-2.35的代碼中已用英文說明了,glibc2.2格式的,能兼容glibc2.2之前的緩存文件內容。這里說的兼容,是依賴于代碼檢測實現的:由于兩種結構體都以magic作為第一個項目,來識別緩存文件類型。再根據magic值的不同,對后續數據段采用不同的處理方式。老magic的定義為#define CACHEMAGIC "ld.so-1.7.0",新magic的定義為#define CACHEMAGIC_NEW "glibc-ld.so.cache"。也就是老版本 cache_file 的文件頭部以字符串ld.so-1.7.0開始,新版本cache_file_new 的文件頭部以字符串glibc-ld.so.cache開始。這點我們可以用head -c 命令查看下/etc/ld.so.cache文件的頭部30個字符串舊可以驗證了:

# head -c 30  /etc/ld.so.cache
glibc-ld.so.cache1.1???

以上輸出信息確實以glibc-ld.so.cache開始,所以我用的Ubuntu22.04系統的ldconfig的緩存文件內容是新格式的。

ldconfig代碼的cache.c 文件里是這樣根據magic的不同用if(){} else{}處理的:

if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
    {///當屬于老版本時,按這里的方式處理
      /* This can only be the new format without the old one.  */
      cache_new = (struct cache_file_new *) cache;

      if (memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)
   || memcmp (cache_new->version, CACHE_VERSION,
        sizeof CACHE_VERSION - 1))
 error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
      check_new_cache (cache_new);
      format = 1;
      /* This is where the strings start.  */
      cache_data = (const char *) cache_new;
    }
  else
    {//當屬于新版本緩存文件的時候,按下面內容處理
      ……省略
    }

在知道了 緩存文件類型(magic標記)后,就可以開始根據格式標準,逐條讀/寫每條記錄了,這是ldconfig的重頭戲。

先看對cache文件的讀取效果,以 ldconfig -p命令打印出緩存文件的所有記錄的結果為例:

# ldconfig -p
1525 libs found in cache `/etc/ld.so.cache
……
  libGLESv1_CM.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libGLESv1_CM.so
  libGL.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libGL.so.1
  libGL.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libGL.so
……

這里每條都是一個動態庫的名稱、格式(libc6等格式)、CPU架構、所在路徑的記錄。

緩存文件中的這么一條記錄,對應的結構體,舊版本的為file_entry,新版本的為file_entry_new。它們的定義分別為:

struct file_entry
{
  int32_t flags;  /* This is 1 for an ELF library.  */
  uint32_t key, value;  /* String table indices.  */
};

以及新版本的 file_entry格式:

struct file_entry_new ///文件記錄的新格式,增加了OS版本、硬件信息
{
  union
  {
    /* Fields shared with struct file_entry.  */
    struct file_entry entry;
    /* Also expose these fields directly.  */
    struct
    {
      int32_t flags;  /* This is 1 for an ELF library.  */
      uint32_t key, value; /* String table indices.  */
    };
  };
  uint32_t osversion;  /* Required OS version.  */
  uint64_t hwcap;  /* Hwcap entry.  */
};

繼續分析【讀緩存文件】的簡要流程:

使用了 mmap() 函數,將 /etc/ld.so.cache 緩存文件整體讀入內存:

struct cache_file *cache
    = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

這是通過mmap()函數,將打開的緩存文件(open(/etc/ld.so.cache)的句柄fd)的數據映射到內存,由于文件數據就是按struct cache_file_new結構體格式填充的,所以mmap()后,就可以按這個結構體去解析各個條目。2. 判斷magic,新老magic分流處理。3. 如果是新的magic,則按struct cache_file_new數據結構解析。4. 對于新格式,遍歷讀取數據、打印:

……
else{
      struct cache_extension_all_loaded ext;
      if (……)錯誤處理;

      /* Print everything.  */
      for (unsigned int i = 0; i < cache_new->nlibs; i++)
 {
   const char *hwcaps_string
     = glibc_hwcaps_string (&ext, cache, cache_size,
       &cache_new->libs[i]);
    
   print_entry (cache_data + cache_new->libs[i].key,
         cache_new->libs[i].flags,
         cache_new->libs[i].osversion,
         cache_new->libs[i].hwcap, hwcaps_string,
         cache_data + cache_new->libs[i].value);
 }
      print_extensions (&ext);
}

這里關鍵內容是:

  • cache_data,代表了mmap()讀取到的緩存文件內容;以cache_data的地址為初始地址,按偏移量cache_new->libs[i].key 相加后,可得到每條file_entry_new的入口,然后分別打印出記錄內容,就實現了 ldconfig -p 的代碼功能。
  • 動態庫的條數,等于 cache_new->nlibs 這個變量的值。作為for循環遍歷時的條件。
  • cache_new->libs[i].key 這里的key,在struct file_entry_new中的定義是:
uint32_t key, value;  /* String table indices.  */

key相當于第i條動態庫記錄的目錄索引。通過索引可以查到value。在實現時,key和value都是數字,這個數字代表字符串相對于cache_data這個首地址的字節偏移量,例如key->value 即 cache_new->libs[i].key, cache_new->libs[i].value 43256 -> 43234

總之,通過對結構體的合理使用,將緩存文件內容解析后,可打印出緩存文件中記錄的所有已知動態庫文件的信息。

void print_cache (const char *cache_name) 的函數代碼結束之前,還做了一下內存回收工作:

  /* Cleanup.  */
  munmap (cache, cache_size);
  close (fd);

首先使用munmap()函數,將之前已映射內存數據做一下清除;然后關閉打開的cache緩存文件描述符。

本文主要通過解讀Linux的ldconfig命令的關鍵代碼,分析了ldconfig命令是如何實現讀取緩存文件 /etc/ld.so.cache 的內容的。本文涉及到的ldconfig的cache.c 代碼文件網址[1],在參考資料里。

參考資料

[1]ldconfig的cache.c 代碼文件網址: https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/cache.c;h=8149f889bab9f9cb32a50e349991ba821e4db0dd;hb=HEAD

責任編輯:趙寧寧 來源: 深入理解Linux
相關推薦

2009-06-20 09:21:37

UNIXLINUX

2012-01-05 10:37:40

Java

2021-01-06 05:29:57

虛擬內存文件

2023-03-31 23:31:06

.go文本文件

2023-12-27 08:27:03

Linuxldconfig命令

2015-02-02 11:03:12

2010-02-22 18:04:27

CentOS mpla

2017-02-07 10:22:53

2024-08-12 16:42:50

二進制工具系統

2021-01-12 10:10:41

shell腳本Linux命令

2021-01-08 08:06:19

腳本Shell文件

2011-08-09 10:24:19

可執行文件病毒病毒

2022-05-11 14:50:34

Python解包執行文件

2024-05-21 12:01:39

.NET 6開發

2009-04-16 10:37:17

Javaexejar

2024-05-06 00:00:00

Go文件瘦身代碼

2021-01-14 22:17:09

PythonLinux工具

2022-05-20 08:55:02

py文件exepython

2023-12-18 09:21:22

開發靜態編譯Linux

2023-09-04 07:14:36

點贊
收藏

51CTO技術棧公眾號

日韩欧美字幕| 日本另类视频| 成人国产亚洲欧美成人综合网| 久久久久久久久久国产| 黄色录像a级片| 一级毛片久久久| 国产精品视频一二三| 亚洲综合国产精品| 69成人免费视频| 日韩黄色大片| 亚洲精品一区二区三区蜜桃下载 | 亚洲色图欧美偷拍| 国产精品污www一区二区三区| 天天干,天天干| 亚洲国产成人精品女人| 日韩电视剧在线观看免费网站| 日韩大片一区二区| 久色国产在线| 国产精品乱码久久久久久| 国产精品视频免费观看| 在线观看亚洲国产| 精品成人一区| www.日韩视频| 成人片黄网站色大片免费毛片| 99综合久久| 日本精品一区二区三区四区的功能| 日本特级黄色大片| 久久久久久久影视| 成人精品国产一区二区4080| 国产在线a不卡| 国产又大又黄又粗| 99久久99久久精品国产片桃花| 日韩电影中文字幕在线观看| 99九九99九九九99九他书对| 欧美freesex| 亚洲一区二区三区爽爽爽爽爽 | 国产精品videosex性欧美| 亚洲精品丝袜日韩| 中文字幕a在线观看| 99精品美女视频在线观看热舞| 91黄视频在线观看| 日韩一区二区高清视频| 免费在线看黄| 亚洲国产精品传媒在线观看| 久久综合毛片| 四虎永久在线精品免费网址| 国产福利精品一区| 国产精品日韩精品| 懂色av中文字幕| 亚洲主播在线| 热久久这里只有| 在线观看免费国产视频| 亚洲国产99| 欧美黑人国产人伦爽爽爽| 91麻豆精品成人一区二区| 99精品一区| 俺去亚洲欧洲欧美日韩| 性爱在线免费视频| 欧美独立站高清久久| 最近2019年中文视频免费在线观看 | 日韩在线小视频| 精品少妇一区二区三区免费观| 欧美高清hd| 欧美一区二区国产| 91精产国品一二三| 风间由美性色一区二区三区四区| 日韩久久免费av| 国产精品日日摸夜夜爽| aaa国产精品视频| 亚洲第一视频在线观看| 国产a级黄色片| 精品视频自拍| 亚洲美女在线看| japanese中文字幕| 91欧美在线| 欧美高清在线视频观看不卡| 国产精品suv一区二区69| 日韩天堂av| 国产成人亚洲综合| 一级片免费观看视频| 国产麻豆精品在线观看| av一区二区在线看| 欧美日韩激情视频一区二区三区| 日本一区二区免费在线 | 国产三级视频在线| 中文字幕欧美三区| 中国一级黄色录像| 538视频在线| 色噜噜夜夜夜综合网| 粉色视频免费看| 五月亚洲婷婷| 亚洲美女www午夜| 免费黄色激情视频| 激情综合在线| 国产精品爱久久久久久久| 一卡二卡在线视频| 国产jizzjizz一区二区| 日韩理论片在线观看| 福利在线视频网站| 欧美视频国产精品| 特黄视频免费观看| 秋霞蜜臀av久久电影网免费| 色狠狠av一区二区三区香蕉蜜桃| 国产亚洲精品码| 视频一区视频二区中文字幕| 亚洲自拍在线观看| 韩国中文免费在线视频| 亚洲综合自拍偷拍| 国内自拍视频网| 香蕉免费一区二区三区在线观看| 亚洲欧美日韩视频一区| 久操免费在线视频| 蜜桃视频一区二区三区 | 欧美人与牛zoz0性行为| 久久成人精品一区二区三区| 黄色一级视频免费看| 国产成人av福利| 天堂一区二区三区| 欧美裸体视频| 欧美白人最猛性xxxxx69交| 国产毛片欧美毛片久久久| 亚洲麻豆av| 91精品在线观| avtt亚洲| 欧美视频在线免费看| 女同性αv亚洲女同志| 色喇叭免费久久综合| 欧美在线视频免费| 高h震动喷水双性1v1| 亚洲人成人一区二区在线观看| 男人舔女人下面高潮视频| 国产精品白丝一区二区三区| 久久视频免费在线播放| 中文字幕福利视频| 久久影院电视剧免费观看| 国产欧美精品aaaaaa片| www.久久草.com| 尤物yw午夜国产精品视频明星| 成年人免费看毛片| 成人h动漫精品一区二| 久久亚洲a v| 免费欧美网站| 超在线视频97| 91久久精品国产91性色69 | 久久国产精品精品国产色婷婷| av在线app| 欧美一区三区四区| www深夜成人a√在线| 美女视频网站久久| 亚洲国产欧美一区二区三区不卡| 中文字幕21页在线看| 亚洲激情视频在线| 日本学生初尝黑人巨免费视频| 国产成人精品综合在线观看| 国产又粗又猛又爽又黄的网站| 国产免费区一区二区三视频免费| 精品国产欧美一区二区五十路| 中文字幕在线观看欧美| 国产精品久久久一本精品| jizzzz日本| 国产精品99久久| 成人性生交大片免费看小说| 91蜜桃在线视频| 欧美成人艳星乳罩| 日韩成人高清视频| 99免费精品视频| 能在线观看的av| 免费欧美一区| 国产欧美日韩精品在线观看 | 国产网站一区二区三区| 欧美一级黄色影院| 国产欧美一区二区三区精品观看| 国产精品第2页| 97电影在线| 欧美一区二区免费观在线| 久久激情免费视频| 91视视频在线观看入口直接观看www | 男的插女的下面视频| 国产精品白丝av嫩草影院| 久久久久久久一区二区三区| 性猛交xxxx| 欧美日韩在线播放三区| 日韩高清dvd碟片| 成人精品一区二区三区四区 | 日韩欧美一二区| 日韩av电影网址| 国产网红主播福利一区二区| 国产一区二区在线观看免费视频| 国内精品久久久久久久影视蜜臀 | 久久久久五月天| 黄色在线免费观看大全| 欧美精品一级二级| 日本系列第一页| 国产精品欧美久久久久无广告| 色综合久久久无码中文字幕波多| 国产午夜精品一区二区三区欧美 | 中文精品久久| 久久婷婷开心| av成人在线网站| 国内精品小视频在线观看| jzzjzzjzz亚洲成熟少妇| 日韩欧美电影一区| 成年人视频免费| 亚洲国产三级在线| 永久免费av无码网站性色av| 成人激情综合网站| 亚洲一区日韩精品| 国产精品日本| 米仓穗香在线观看| 欧美日韩国产传媒| 国产一区二区无遮挡| 黑人一区二区三区| 欧美一级视频免费在线观看| 亚洲精品一线| 中文字幕日韩欧美在线视频| 欧美一级视频免费| 欧美丰满高潮xxxx喷水动漫| 三级视频在线观看| 亚洲成人免费视频| 日韩激情综合网| 国产欧美日本一区二区三区| 国产黑丝一区二区| 国产传媒欧美日韩成人| 国产视频1区2区3区| 午夜亚洲福利在线老司机| 91精品国产吴梦梦| 99久久国产综合精品成人影院| 欧美福利精品| 欧美挤奶吃奶水xxxxx| 91成人免费在线观看| 亚洲精品伊人| 国产精品毛片a∨一区二区三区|国| 国产高清中文字幕在线| 久久成人免费视频| 成人av黄色| 久久精品91久久香蕉加勒比| 成年人在线观看网站| 亚洲欧洲xxxx| 蜜芽tv福利在线视频| 日韩电影免费观看在线观看| 成人乱码一区二区三区| 91精品国产乱码| 国产伦理一区二区| 91麻豆精品国产91| 亚洲一级在线播放| 欧美另类久久久品| 91丨九色丨蝌蚪丨对白| 欧美日韩成人激情| 一级黄色短视频| 欧美日韩不卡在线| 国产伦子伦对白视频| 日韩欧美在线网站| 亚洲黄色小说网址| 亚洲成成品网站| 午夜18视频在线观看| 精品一区二区三区四区| 欧美日韩伦理片| 伊是香蕉大人久久| 免费超碰在线| 久久亚洲国产精品| 亚洲丝袜一区| 国产美女一区| 日本黄网免费一区二区精品| 精品一区亚洲| 亚洲精品高清国产一线久久| 欧美aaaa视频| 神马午夜伦理影院| 在线观看视频日韩| 国内外成人免费激情视频| 久久久人人人| 99sesese| 国产成人自拍网| 日韩精品视频一区二区| 91免费看`日韩一区二区| www.99热| 亚洲精品免费在线播放| 国产精品第108页| 欧美香蕉大胸在线视频观看| 中文字幕无线码一区| 欧美一卡2卡3卡4卡| 色婷婷视频在线| 亚洲图片制服诱惑| 久久日韩视频| 国内伊人久久久久久网站视频 | 国产91亚洲精品| 国精品产品一区| ts人妖另类在线| 一本久久青青| 男女啪啪的视频| 亚洲色诱最新| 亚洲免费黄色录像| 成人精品视频一区二区三区尤物| 久久精品无码一区| 亚洲欧美一区二区三区极速播放| 男人的天堂一区| 欧美日韩一本到| 韩国av免费在线| 爽爽爽爽爽爽爽成人免费观看| 日本在线视频www鲁啊鲁| 国产成人精品久久二区二区91| 国产一区二区久久久久| 免费av在线一区二区| 亚洲国产一成人久久精品| 97成人在线观看视频| 国产美女av一区二区三区| 性色av蜜臀av色欲av| 日韩一区日韩二区| 日本视频在线观看免费| 日韩视频123| 91美女视频在线| 77777少妇光屁股久久一区| 亚洲欧洲二区| 欧洲亚洲一区二区| 欧美日一区二区在线观看| 五月天激情视频在线观看| 99久久精品免费看| 国产极品国产极品| 欧美三级日韩三级| 男女网站在线观看| 久久琪琪电影院| 91麻豆精品国产综合久久久 | 青青青草网站免费视频在线观看| 久久伊人免费视频| 成人国产精品入口免费视频| 久久久婷婷一区二区三区不卡| 国产一区激情| 最新av免费在线观看| 亚洲国产岛国毛片在线| 无码人妻黑人中文字幕| 亚洲激情免费观看| aa视频在线观看| 电影午夜精品一区二区三区 | 北条麻妃一区二区三区中文字幕| 裤袜国产欧美精品一区| 国产一区二区三区免费不卡| 欧美激情无毛| 性久久久久久久久久久久久久| 中文字幕欧美国产| 中文字幕免费观看| 日韩毛片在线看| 亚洲涩涩在线| 精品一区二区三区视频日产| 亚洲韩日在线| 国产一卡二卡三卡四卡| 亚洲精品免费一二三区| 99热这里精品| 久久综合久久八八| 91麻豆精品| 狠狠精品干练久久久无码中文字幕 | 日韩av在线免费| 美女精品导航| 国产二区不卡| 亚洲国内欧美| 无遮挡aaaaa大片免费看| 福利视频一区二区| 外国精品视频在线观看| 欧美一级片一区| 一本色道久久综合亚洲精品酒店| 久久久一本二本三本| 91一区二区在线| 51国产偷自视频区视频| 亚洲欧美在线播放| 欧美日韩不卡| 亚洲乱码一区二区三区| 九一九一国产精品| 黄页网站免费观看| 亚洲第一精品夜夜躁人人躁| h片在线观看视频免费| 久久精品magnetxturnbtih| 久久一综合视频| 国产成人在线网址| 欧美一区二区福利视频| 高清电影在线观看免费| 久久婷婷开心| 麻豆成人久久精品二区三区红 | 欧美丰满日韩| 日本xxxx免费| 精品国产电影一区| 在线日本视频| 古典武侠综合av第一页| 久久av一区| 欧美爱爱免费视频| 亚洲成人黄色网| 黄色欧美视频| 国产av熟女一区二区三区| 久久综合国产精品| 97超碰人人模人人人爽人人爱| 久久久久www| 久久精品国产亚洲5555| 免费涩涩18网站入口| 一区二区三区欧美在线观看| 三级在线视频| 成人性生交大片免费观看嘿嘿视频| 尤物网精品视频| 国产美女免费网站| 日韩网站在线看片你懂的| 欧美日韩电影免费看| 99re6这里有精品热视频| 国产色产综合色产在线视频| 精品人妻少妇AV无码专区 |