精品欧美一区二区三区在线观看 _久久久久国色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∨高清免费观看| 中文字幕欧美激情| 亚州国产精品久久久| 色婷婷免费视频| 日韩欧美一区二区三区在线观看 | 亚洲精品自拍视频在线观看| 99精品女人在线观看免费视频| 亚洲一区二区在线免费看| 欧美日韩视频在线一区二区观看视频| 一级黄色大片免费| 国产综合自拍| 久久青草欧美一区二区三区| 国产精品国产福利国产秒拍| 18岁成人毛片| 国产探花一区在线观看| 欧美一级免费大片| 粉嫩虎白女毛片人体| 老司机午夜在线视频| 97国产一区二区| 成人信息集中地欧美| 四虎成人永久免费视频| 欧美在线影院| 日韩中文字幕第一页| aaaaaav| 日本免费一区二区三区视频| 欧美午夜寂寞影院| 男女高潮又爽又黄又无遮挡| 成人在线网址| 国产精品毛片无遮挡高清| 久久99精品久久久久久秒播放器| 91美女精品网站| 视频一区视频二区中文字幕| 久久久久亚洲精品成人网小说| 美女av免费看| 欧洲杯半决赛直播| 亚洲美女性视频| 日本护士做爰视频| 一区二区三区国产好| 欧美日韩激情一区二区| 日本激情视频在线| 在线观看爽视频| 激情久久av一区av二区av三区| 日韩在线视频在线| 26uuu亚洲电影在线观看| 国产精品萝li| 亚洲欧洲久久| 求av网址在线观看| 久久麻豆一区二区| 欧美日韩一区二区三区免费| 青青草视频在线免费观看| 99re这里只有精品首页| 国产亚洲欧美另类一区二区三区| 精品欧美在线观看| 国产高清不卡一区| 91九色极品视频| 亚洲国产精品久久久久久久| 国产一区二区在线视频| 亚洲自拍偷拍网址| 午夜精品久久久久久久爽 | 国产美女精品免费电影| 波多野结衣高清在线| 日日夜夜精品视频天天综合网| 日本亚洲欧洲色α| 在线永久看片免费的视频| 日韩福利视频网| 国产精品夜色7777狼人| 国产人妖在线播放| 国产成人在线看| 国产一区在线观| 国模精品一区二区| 国产精品国产三级国产普通话99 | 日韩电影毛片| 色激情天天射综合网| 五月婷婷深爱五月| 91麻豆精品国产综合久久久 | 国产黄色一区二区三区| 日韩亚洲精品在线观看| 亚洲激情在线观看| 亚洲第一视频区| 911精品美国片911久久久| 欧美激情久久久久久| 日韩欧美一级视频| 蜜桃91丨九色丨蝌蚪91桃色| 91系列在线播放| 天堂在线视频免费观看| 久久久精品黄色| 椎名由奈jux491在线播放 | 7777精品伊久久久大香线蕉语言 | 久热精品视频在线观看| 日韩免费视频网站| 麻豆精品国产传媒mv男同| 5566av亚洲| 国产免费av高清在线| 亚洲欧美区自拍先锋| 欧美日本视频在线观看| 精品国产美女a久久9999| 日韩一级高清毛片| 中文字幕 自拍| 中文字幕日韩欧美精品高清在线| 午夜精品免费视频| 91成人国产综合久久精品| 成人激情校园春色| 亚洲图片都市激情| 阿v视频在线观看| 欧美日韩1234| 成人片黄网站色大片免费毛片| 婷婷亚洲最大| 国产91免费观看| 丰满少妇在线观看bd| 国产精品视频你懂的| 成人中文字幕在线播放| 视频一区国产| 日韩在线小视频| 中文字幕国产在线观看| 成人自拍视频在线| 资源网第一页久久久| 忘忧草在线www成人影院| 精品少妇一区二区| 久久av红桃一区二区禁漫| 蜜桃av综合| 精品午夜一区二区三区| 伊人影院在线视频| 欧美私人免费视频| 最近中文字幕免费| 一本一本久久| 国产一区二区精品免费| 影音先锋在线视频| 91精品国产综合久久久久久漫画 | 国产91在线播放| 老牛影视av牛牛影视av| 亚洲激情成人在线| 日韩成人av免费| 日本一区二区免费高清| 国产91在线播放| 色就是色亚洲色图| 欧美视频一区二区三区…| 成年女人免费视频| 国产精品激情| 国产精品久久久久免费| 日本资源在线| 日韩欧美国产午夜精品| 欧美黄色aaa| 国产成人免费在线| 国内自拍中文字幕| 136福利精品导航| 欧美福利小视频| 亚洲第一天堂在线观看| 亚洲影视在线播放| 精品久久久久一区二区| 亚洲黄页一区| 久久综合婷婷综合| 成人性生交大片免费观看网站| 亚洲激情视频在线播放| 国产精品第5页| 久久精品人人做| www.99在线| 婷婷激情图片久久| 99影视tv| 少妇视频在线观看| 亚洲欧美日韩综合| 中文字字幕在线中文乱码| 国产精品三级久久久久三级| 手机版av在线| 中文在线日韩| 久久99精品久久久久久青青日本| 亚洲妇女成熟| 在线电影中文日韩| 国产乱码精品一区二区| 亚洲午夜三级在线| 亚洲天堂网一区二区| 日韩av在线发布| 美国av在线播放| 1313精品午夜理伦电影| 欧美孕妇性xx| 毛片免费不卡| 亚洲高清在线观看| 国产真人无遮挡作爱免费视频| 日本一区免费视频| 日本黄色www| 国产精品美女| 伊人av成人| 成人搞黄视频| 国产精品无av码在线观看| av毛片在线播放| 亚洲精品99999| 欧美激情一区二区三区免费观看 | 99r精品视频| 一道本在线免费视频| 国语精品一区| 相泽南亚洲一区二区在线播放 | 欧美日韩在线视频免费播放| a亚洲天堂av| 日韩欧美国产片| 99av国产精品欲麻豆| 欧美日本一区二区三区| 日韩欧美国产二区| 96sao精品免费视频观看| 久久久久亚洲精品成人网小说| 国模吧精品人体gogo| 日韩一级完整毛片| 日本黄色中文字幕| 亚洲综合清纯丝袜自拍| 中国毛片在线观看| 国产精品一区二区不卡| 欧美激情国产精品日韩| 欧美激情91| 无遮挡亚洲一区| 蜜桃一区av| 91亚洲精品久久久| gogo亚洲高清大胆美女人体| 欧美极品少妇xxxxⅹ免费视频| 高清性色生活片在线观看| 精品美女一区二区| 中国一级特黄视频| 欧美日韩激情网| 国产黄色小视频网站| 久久久精品人体av艺术| www.555国产精品免费| 美女视频一区在线观看| 黄色影院一级片| 国产精品vip| 黄色免费高清视频| 日韩精品dvd| 日韩国产精品一区二区| 人人精品亚洲| 国产精品自拍首页| 亚洲啊v在线免费视频| 国产精品视频永久免费播放| 亚洲福利影院| 51精品在线观看| h片在线观看| 久久久久久久久久亚洲| a毛片在线看免费观看| 久久精品国产一区| 日本不卡不卡| 日韩天堂在线视频| 日本免费在线视频| 中文字幕精品一区二区精品| 免费黄色片在线观看| 日韩精品免费观看| 五月天激情婷婷| 日韩精品极品视频免费观看| 午夜视频免费看| 日韩精品视频免费在线观看| 丰满人妻av一区二区三区| 欧美成人性战久久| 成人午夜福利视频| 亚洲精品在线免费播放| 蜜桃视频久久一区免费观看入口| 日韩精品在线看片z| 国产极品久久久| 欧美成人a视频| 色欲av伊人久久大香线蕉影院| 欧美大片在线观看一区二区| 亚洲第一黄色片| 亚洲国产精品99| 午夜国产在线观看| 日韩精品在线第一页| 三级毛片在线免费看| 亚洲另类激情图| 国产黄色在线播放| 色老头一区二区三区在线观看| 波多野结衣在线影院| www日韩中文字幕在线看| 成人日批视频| 欧美激情一区二区三级高清视频| ririsao久久精品一区| 69精品小视频| 69堂精品视频在线播放| 成人黄色大片在线免费观看| 国产999精品在线观看| 俄罗斯精品一区二区三区| 久久亚州av| 亚洲7777| 午夜久久久久| 日韩中文字幕三区| 欧美bbbbb| 性一交一黄一片| 久久亚洲捆绑美女| 黄色录像一级片| 亚洲福利一二三区| 日韩不卡高清视频| 日韩美女一区二区三区四区| 欧美黄色小说| 久久av在线播放| 在线免费av资源| 91在线中文字幕| 日韩在线麻豆| 欧美日韩在线免费观看视频| 亚洲激情不卡| 欧美在线aaa| 成人性生交大片免费看中文网站| 精品国产av无码| 一区二区欧美国产| av首页在线观看| 精品99999| 日本美女高清在线观看免费| 午夜精品在线观看| 日本黄色成人| 免费一区二区三区在在线视频| 亚洲草久电影| 99草草国产熟女视频在线| 国产精品一区二区不卡| 欧美日韩高清丝袜| 一区二区三区四区av| 天堂av免费在线观看| 精品国产乱码久久久久久老虎| avtt亚洲| 欧美一级bbbbb性bbbb喷潮片| 成人永久在线| 色综合影院在线观看| 亚洲三级影院| 四虎1515hh.com| 国产香蕉久久精品综合网| 久久精品视频日本| 欧美丰满高潮xxxx喷水动漫| 男人天堂亚洲二区| 久久久久久久久网站| 玖玖精品一区| 一本一本a久久| 日韩精品91亚洲二区在线观看| 无码人妻丰满熟妇区毛片蜜桃精品| 亚洲人成精品久久久| 国产亚洲精品一区二555| 先锋成人av| 国产专区精品视频| 国产剧情一区| 成人在线免费播放视频| 99久久综合国产精品| 久久午夜无码鲁丝片午夜精品| 在线播放国产精品二区一二区四区| 毛片网站在线| 欧美一区视频在线| 亚洲精品合集| 春日野结衣av| 久久综合色综合88| 综合激情网五月| 亚洲精品理论电影| 国产传媒在线| 久久国产精品久久| 国产精品一级| 在线观看国产网站| 欧美日韩国产色视频| 国精产品一品二品国精品69xx | 日韩欧美国产高清| caopen在线视频| 7777精品久久久大香线蕉小说| 艳女tv在线观看国产一区| 亚洲最大天堂网| 亚洲色图在线播放| 国内精品国产成人国产三级| 色在人av网站天堂精品| 波多野结衣在线一区二区| 男女猛烈激情xx00免费视频| 成人三级在线视频| 国产成人无码精品| 亚洲男人天堂网站| 欧美国产日韩电影| 伊人狠狠色丁香综合尤物| 国产乱人伦偷精品视频免下载 | www.亚洲.com| 国产综合福利在线| 欧美精品一卡| 精品一区二区视频在线观看| 日韩不卡在线| 97久久天天综合色天天综合色hd| 欧美96在线丨欧| 少妇一级淫免费观看| 欧美性极品xxxx娇小| 国产精品秘入口| 成人欧美在线视频| 精品成人免费| 蜜乳av中文字幕| 91精品国产一区二区人妖| 女人天堂av在线播放| 久久精品ww人人做人人爽| 日韩精品91亚洲二区在线观看| 美女网站视频色| 欧美成人精品1314www| 亚洲精品福利电影| 免费看啪啪网站| av中文一区二区三区| 无码一区二区三区| 萌白酱国产一区二区| 偷拍一区二区| 欧美视频国产视频| 亚洲高清视频的网址| 97电影在线看视频| 成人h视频在线观看| 日韩电影在线看| 久久久全国免费视频| 亚洲天堂网在线观看| 欧美大片91| 成人精品视频一区二区| 亚洲乱码精品一二三四区日韩在线| 天天色棕合合合合合合合| 国产精品视频男人的天堂| 亚洲精品欧洲| 丰满少妇被猛烈进入一区二区| 亚洲精品小视频在线观看|