ELF 文件操作手冊

目錄

一、ELF 文件結構概述

二、查看 ELF 文件頭信息

1、命令選項

2、示例輸出

3、內核數據結構

三、ELF 程序頭表

1、命令選項

2、示例輸出

3、關鍵說明

4、內核數據結構

四、ELF 節頭表詳解

查看節頭表信息

1、命令選項

2、示例輸出

3、標志說明

4、重要節說明

5、內核數據結構

五、查看節內容

1、反匯編節內容

2、查看目標文件節內容

關鍵說明


一、ELF 文件結構概述

????????ELF (Executable and Linkable Format) 是 Unix/Linux 系統中可執行文件、目標文件和共享庫的標準文件格式。


二、查看 ELF 文件頭信息

1、命令選項

-h?或?--file-header:顯示 ELF 文件的文件頭信息。文件頭包含了 ELF 文件的基本信息,包括:

  • 文件類型

  • 機器類型

  • 版本信息

  • 入口點地址

  • 程序頭表和節頭表的位置和大小等

2、示例輸出

$ readelf -h mainELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              EXEC (Executable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x400640Start of program headers:          64 (bytes into file)Start of section headers:          7048 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         9Size of section headers:           64 (bytes)Number of section headers:         31Section header string table index: 30

3、內核數據結構

Linux 內核中 ELF 頭部的相關定義(位于?/linux/include/elf.h):

/* 32位 ELF 頭 */
typedef struct elf32_hdr {unsigned char e_ident[EI_NIDENT];Elf32_Half e_type;Elf32_Half e_machine;Elf32_Word e_version;Elf32_Addr e_entry;   /* 入口點 */Elf32_Off e_phoff;    /* 程序頭表偏移 */Elf32_Off e_shoff;    /* 節頭表偏移 */Elf32_Word e_flags;Elf32_Half e_ehsize;Elf32_Half e_phentsize;Elf32_Half e_phnum;Elf32_Half e_shentsize;Elf32_Half e_shnum;Elf32_Half e_shstrndx;
} Elf32_Ehdr;/* 64位 ELF 頭 */
typedef struct elf64_hdr {unsigned char e_ident[EI_NIDENT]; /* ELF 魔數 */Elf64_Half e_type;Elf64_Half e_machine;Elf64_Word e_version;Elf64_Addr e_entry;   /* 入口點虛擬地址 */Elf64_Off e_phoff;    /* 程序頭表文件偏移 */Elf64_Off e_shoff;    /* 節頭表文件偏移 */Elf64_Word e_flags;Elf64_Half e_ehsize;Elf64_Half e_phentsize;Elf64_Half e_phnum;Elf64_Half e_shentsize;Elf64_Half e_shnum;Elf64_Half e_shstrndx;
} Elf64_Ehdr;

三、ELF 程序頭表

1、命令選項

? ? -l?或?--program-headers:顯示 ELF 文件的程序頭部(段頭)信息。這些信息對于理解可執行文件在內存中的布局和加載過程非常重要。

2、示例輸出

$ readelf -l mainElf file type is EXEC (Executable file)
Entry point 0x400640
There are 9 program headers, starting at offset 64Program Headers:Type           Offset             VirtAddr           PhysAddrFileSiz            MemSiz              Flags  AlignPHDR           0x0000000000000040 0x0000000000400040 0x00000000004000400x00000000000001f8 0x00000000000001f8  R E    8INTERP         0x0000000000000238 0x0000000000400238 0x00000000004002380x000000000000001c 0x000000000000001c  R      1[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]LOAD           0x0000000000000000 0x0000000000400000 0x00000000004000000x0000000000000d24 0x0000000000000d24  R E    200000LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e100x0000000000000254 0x0000000000000258  RW     200000DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e280x00000000000001d0 0x00000000000001d0  RW     8NOTE           0x0000000000000254 0x0000000000400254 0x00000000004002540x0000000000000044 0x0000000000000044  R      4GNU_EH_FRAME   0x0000000000000b34 0x0000000000400b34 0x0000000000400b340x000000000000005c 0x000000000000005c  R      4GNU_STACK      0x0000000000000000 0x0000000000000000 0x00000000000000000x0000000000000000 0x0000000000000000  RW     10GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e100x00000000000001f0 0x00000000000001f0  R      1Section to Segment mapping:Segment Sections...00     01     .interp 02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 04     .dynamic 05     .note.ABI-tag .note.gnu.build-id 06     .eh_frame_hdr 07     08     .init_array .fini_array .jcr .dynamic .got

3、關鍵說明

  1. PhysAddr:在現代操作系統中,物理地址字段通常可以忽略

  2. LOAD:并非所有的節(section)都需要加載到內存,只有標記為 LOAD 的段(segment)才會被加載

4、內核數據結構

/* 32位程序頭 */
typedef struct elf32_phdr {Elf32_Word p_type;Elf32_Off p_offset;Elf32_Addr p_vaddr;Elf32_Addr p_paddr;Elf32_Word p_filesz;Elf32_Word p_memsz;Elf32_Word p_flags;Elf32_Word p_align;
} Elf32_Phdr;/* 64位程序頭 */
typedef struct elf64_phdr {Elf64_Word p_type;Elf64_Word p_flags;Elf64_Off p_offset;   /* 段在文件中的偏移 */Elf64_Addr p_vaddr;   /* 段虛擬地址 */Elf64_Addr p_paddr;   /* 段物理地址 */Elf64_Xword p_filesz; /* 段在文件中的大小 */Elf64_Xword p_memsz;  /* 段在內存中的大小 */Elf64_Xword p_align;  /* 段對齊方式 */
} Elf64_Phdr;

四、ELF 節頭表詳解

查看節頭表信息

1、命令選項

? ? -S?或?--section-headers:顯示 ELF 文件的節頭信息,包括各節的起始地址、大小、標志等重要屬性。

2、示例輸出

$ readelf -S mainThere are 31 section headers, starting at offset 0x1b88:Section Headers:[Nr] Name              Type            Address          OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL            0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .interp           PROGBITS        0000000000400238  00000238000000000000001c  0000000000000000   A       0     0     1[ 2] .note.ABI-tag     NOTE            0000000000400254  000002540000000000000020  0000000000000000   A       0     0     4[ 3] .note.gnu.build-i NOTE            0000000000400274  000002740000000000000024  0000000000000000   A       0     0     4[ 4] .gnu.hash         GNU_HASH        0000000000400298  00000298000000000000001c  0000000000000000   A       5     0     8[ 5] .dynsym           DYNSYM          00000000004002b8  000002b80000000000000108  0000000000000018   A       6     1     8[ 6] .dynstr           STRTAB          00000000004003c0  000003c00000000000000076  0000000000000000   A       0     0     1[ 7] .gnu.version      VERSYM          0000000000400436  000004360000000000000016  0000000000000002   A       5     0     2[ 8] .gnu.version_r    VERNEED         0000000000400450  000004500000000000000030  0000000000000000   A       6     1     8[ 9] .rela.dyn         RELA            0000000000400480  000004800000000000000018  0000000000000018   A       5     0     8[10] .rela.plt         RELA            0000000000400498  0000049800000000000000d8  0000000000000018  AI       5    24     8[11] .init             PROGBITS        0000000000400570  00000570000000000000001a  0000000000000000  AX       0     0     4[12] .plt              PROGBITS        0000000000400590  0000059000000000000000a0  0000000000000010  AX       0     0     16[13] .plt.got          PROGBITS        0000000000400630  000006300000000000000008  0000000000000000  AX       0     0     8[14] .text             PROGBITS        0000000000400640  0000064000000000000004b2  0000000000000000  AX       0     0     16[15] .fini             PROGBITS        0000000000400af4  00000af40000000000000009  0000000000000000  AX       0     0     4[16] .rodata           PROGBITS        0000000000400b00  00000b000000000000000032  0000000000000000   A       0     0     8[17] .eh_frame_hdr     PROGBITS        0000000000400b34  00000b34000000000000005c  0000000000000000   A       0     0     4[18] .eh_frame         PROGBITS        0000000000400b90  00000b900000000000000194  0000000000000000   A       0     0     8[19] .init_array       INIT_ARRAY      0000000000600e10  00000e100000000000000008  0000000000000008  WA       0     0     8[20] .fini_array       FINI_ARRAY      0000000000600e18  00000e180000000000000008  0000000000000008  WA       0     0     8[21] .jcr              PROGBITS        0000000000600e20  00000e200000000000000008  0000000000000000  WA       0     0     8[22] .dynamic          DYNAMIC         0000000000600e28  00000e2800000000000001d0  0000000000000010  WA       6     0     8[23] .got              PROGBITS        0000000000600ff8  00000ff80000000000000008  0000000000000008  WA       0     0     8[24] .got.plt          PROGBITS        0000000000601000  000010000000000000000060  0000000000000008  WA       0     0     8[25] .data             PROGBITS        0000000000601060  000010600000000000000004  0000000000000000  WA       0     0     1[26] .bss              NOBITS          0000000000601064  000010640000000000000004  0000000000000000  WA       0     0     1[27] .comment          PROGBITS        0000000000000000  00001064000000000000002d  0000000000000001  MS       0     0     1[28] .symtab           SYMTAB          0000000000000000  000010980000000000000750  0000000000000018          29    49     8[29] .strtab           STRTAB          0000000000000000  000017e80000000000000291  0000000000000000           0     0     1[30] .shstrtab         STRTAB          0000000000000000  00001a79000000000000010c  0000000000000000           0     0     1

3、標志說明

  • W (write)??? - 可寫
  • A (alloc)??? - 運行時分配內存
  • X (execute)? - 可執行
  • M (merge)??? - 可合并
  • S (strings)? - 包含字符串
  • I (info)???? - 額外信息
  • L (link order) - 保留鏈接順序
  • O (extra OS processing required) - 需要特殊處理
  • G (group)??? - 組成員
  • T (TLS)????? - 線程局部存儲
  • C (compressed) - 壓縮數據
  • x (unknown)? - 未知
  • o (OS specific) - 操作系統特定
  • E (exclude)? - 排除
  • l (large)??? - 大型節
  • p (processor specific) - 處理器特定

4、重要節說明

  • .got:全局偏移表(Global Offset Table),用于動態鏈接

  • .plt:過程鏈接表(Procedure Linkage Table),支持延遲綁定

  • .text:包含程序的可執行指令

  • .data:包含初始化的全局變量

  • .bss:包含未初始化的全局變量

5、內核數據結構

/* 32位節頭 */
typedef struct {Elf32_Word sh_name;      /* 節名稱索引 */Elf32_Word sh_type;      /* 節類型 */Elf32_Word sh_flags;     /* 節標志 */Elf32_Addr sh_addr;      /* 節虛擬地址 */Elf32_Off  sh_offset;    /* 節文件偏移 */Elf32_Word sh_size;      /* 節大小 */Elf32_Word sh_link;      /* 相關節索引 */Elf32_Word sh_info;      /* 附加信息 */Elf32_Word sh_addralign; /* 節對齊要求 */Elf32_Word sh_entsize;   /* 表項大小(如有) */
} Elf32_Shdr;/* 64位節頭 */
typedef struct elf64_shdr {Elf64_Word  sh_name;      /* 節名稱索引 */Elf64_Word  sh_type;      /* 節類型 */Elf64_Xword sh_flags;     /* 節標志 */Elf64_Addr  sh_addr;      /* 節虛擬地址 */Elf64_Off   sh_offset;    /* 節文件偏移 */Elf64_Xword sh_size;      /* 節大小 */Elf64_Word  sh_link;      /* 相關節索引 */Elf64_Word  sh_info;      /* 附加信息 */Elf64_Xword sh_addralign; /* 節對齊要求 */Elf64_Xword sh_entsize;   /* 表項大小(如有) */
} Elf64_Shdr;

五、查看節內容

1、反匯編節內容

$ objdump -S mainmain:     file format elf64-x86-64Disassembly of section .init:0000000000400570 <_init>:400570:       48 83 ec 08             sub    $0x8,%rsp400574:       48 8b 05 7d 0a 20 00    mov    0x200a7d(%rip),%rax        # 600ff8 <__gmon_start__>40057b:       48 85 c0                test   %rax,%rax40057e:       74 05                   je     400585 <_init+0x15>400580:       e8 ab 00 00 00          callq  400630 <.plt.got>400585:       48 83 c4 08             add    $0x8,%rsp400589:       c3                      retqDisassembly of section .plt:0000000000400590 <.plt>:400590:       ff 35 72 0a 20 00       pushq  0x200a72(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>400596:       ff 25 74 0a 20 00       jmpq   *0x200a74(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>40059c:       0f 1f 40 00             nopl   0x0(%rax)00000000004005a0 <write@plt>:4005a0:       ff 25 72 0a 20 00       jmpq   *0x200a72(%rip)        # 601018 <write@GLIBC_2.2.5>4005a6:       68 00 00 00 00          pushq  $0x04005ab:       e9 e0 ff ff ff          jmpq   400590 <.plt>00000000004005b0 <printf@plt>:4005b0:       ff 25 6a 0a 20 00       jmpq   *0x200a6a(%rip)        # 601020 <printf@GLIBC_2.2.5>4005b6:       68 01 00 00 00          pushq  $0x14005bb:       e9 d0 ff ff ff          jmpq   400590 <.plt>00000000004005c0 <close@plt>:4005c0:       ff 25 62 0a 20 00       jmpq   *0x200a62(%rip)        # 601028 <close@GLIBC_2.2.5>4005c6:       68 02 00 00 00          pushq  $0x24005cb:       e9 c0 ff ff ff          jmpq   400590 <.plt>00000000004005d0 <__libc_start_main@plt>:4005d0:       ff 25 5a 0a 20 00       jmpq   *0x200a5a(%rip)        # 601030 <__libc_start_main@GLIBC_2.2.5>4005d6:       68 03 00 00 00          pushq  $0x34005db:       e9 b0 ff ff ff          jmpq   400590 <.plt>

2、查看目標文件節內容

$ objdump -d hello.ohello.o:     file format elf64-x86-64Disassembly of section .text:0000000000000000 <main>:0:   55                      push   %rbp1:   48 89 e5                mov    %rsp,%rbp4:   bf 00 00 00 00          mov    $0x0,%edi9:   e8 00 00 00 00          callq  e <main+0xe>e:   b8 00 00 00 00          mov    $0x0,%eax13:   e8 00 00 00 00          callq  18 <main+0x18>18:   b8 00 00 00 00          mov    $0x0,%eax1d:   5d                      pop    %rbp1e:   c3                      retq

關鍵說明

  1. .init:程序初始化代碼

  2. .plt:動態鏈接跳轉表

  3. .text:主程序代碼

  4. 目標文件中的地址在鏈接前為0,鏈接后會填充實際地址

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89906.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89906.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89906.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入淺出Python函數:參數傳遞、作用域與案例詳解

&#x1f64b;?♀? 博主介紹&#xff1a;顏顏yan_ ? 本期精彩&#xff1a;深入淺出Python函數&#xff1a;參數傳遞、作用域與案例詳解 &#x1f3c6; 熱門專欄&#xff1a;零基礎玩轉Python爬蟲&#xff1a;手把手教你成為數據獵人 &#x1f680; 專欄亮點&#xff1a;零基…

ps aux 和 ps -ef

在 Linux/Unix 系統中&#xff0c;ps aux 和 ps -ef 都是用于查看進程信息的命令&#xff0c;結合 grep node 可以篩選出與 Node.js 相關的進程。它們的核心功能相似&#xff0c;但在輸出格式和選項含義上有區別&#xff1a;1. 命令對比命令含義主要區別ps auxBSD 風格語法列更…

Spark ML 之 LSH

src/test/scala/org/apache/spark/ml/feature/BucketedRandomProjectionLSHSuite.scala test("approxSimilarityJoin for self join") {val data = {for (i <- 0 until 24) yield Vectors

關鍵成功因素法(CSF)深度解析:從戰略目標到數據字典

關鍵成功因素法由John Rockart提出&#xff0c;用于信息系統規劃&#xff0c;幫助企業識別影響系統成功的關鍵因素&#xff0c;從而確定信息需求&#xff0c;指導信息技術管理。該方法通過識別關鍵成功因素&#xff0c;找出關鍵信息集合&#xff0c;確定系統開發優先級&#xf…

Django母嬰商城項目實踐(六)- Models模型之ORM操作

6、Models模型操作 1 ORM概述 介紹 Django對數據進行增刪改操作是借助內置的ORM框架(Object Relational Mapping,對象關系映射)所提供的API方法實現的,允許你使用類和對象對數據庫進行操作,從而避免通過SQL語句操作數據庫。 簡單來說,ORM框架的數據操作API是在 QuerySet…

【PTA數據結構 | C語言版】哥尼斯堡的“七橋問題”

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 哥尼斯堡是位于普累格河上的一座城市&#xff0c;它包含兩個島嶼及連接它們的七座橋&#xff0c;如下圖所示。 可否走過這樣的七座橋&#xff0c;而且每橋只走過一次&#xff1f;瑞士數學家歐拉(Leo…

Redis 詳解:從入門到進階

文章目錄前言一、什么是 Redis&#xff1f;二、Redis 使用場景1. 緩存熱點數據2. 消息隊列3. 分布式鎖4. 限流與防刷5. 計數器、排行榜三、緩存三大問題&#xff1a;雪崩 / 穿透 / 擊穿1. ?? 緩存雪崩&#xff08;Cache Avalanche&#xff09;2. &#x1f50d; 緩存穿透&…

QCustomPlot 使用教程

下載網址&#xff1a;官方網站&#xff1a;http://www.qcustomplot.com/我的環境是 window10 qt5.9.9 下載后&#xff0c;官網提供了很多例子。可以作為參考直接運行自己如何使用&#xff1a;第一步&#xff1a;使用QCustomPlot非常簡單&#xff0c;只需要把qcustomplot.cpp和…

基于springboot+mysql的作業管理系統(源碼+論文)

一、開發環境 1 Spring Boot框架簡介 描述&#xff1a; 簡化開發&#xff1a;Spring Boot旨在簡化新Spring應用的初始搭建和開發過程。配置方式&#xff1a;采用特定的配置方式&#xff0c;減少樣板化配置&#xff0c;使開發人員無需定義繁瑣的配置。開發工具&#xff1a;可…

LVS 集群技術基礎

LVS(linux virual server)LVS集群技術---NAT模式一.準備四臺虛擬機1.client(eth0ip:172.254.100)2.lvs(eth0ip:172.254.200;eth1ip:192.168.0.200)3.rs1(eht0ip:192.168.0.10)4.rs2(eth0ip:192.168.0.20)二&#xff1a;在rs1和rs2安裝httpd功能dnf/yum install htppd -y三&…

Oracle RU19.28補丁發布,一鍵升級穩

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中國DBA聯盟(ACDU)成員&#xff0c;15年DBA工作經驗 Oracle、PostgreSQL ACE CSDN博客專家及B站知名UP主&#xff0c;全網粉絲15萬 擅長主流Oracle、MySQL、PG、高斯及…

lvs 集群技術

LVS概念LVS&#xff1a;Linux Virtual Server&#xff0c;負載調度器&#xff0c;是一種基于Linux操作系統內核的高性能、高可用網絡服務負載均衡解決方案。LVS工作原理基于網絡層&#xff08;四層&#xff0c;傳輸層&#xff09;的負載均衡技術&#xff0c;它通過內核級別的IP…

AR巡檢和傳統巡檢的區別

隨著工業4.0時代的到來&#xff0c;數字化轉型逐漸成為各行各業提升效率、保障安全和降低成本的關鍵。而在這一轉型過程中&#xff0c;巡檢工作作為確保設備穩定運行的重要環節&#xff0c;逐步從傳統方式走向智能化、數字化。尤其是增強現實&#xff08;AR&#xff09;技術的引…

Axure設計設備外殼 - AxureMost 落葵網

在UI設計中&#xff0c;設備外殼&#xff08;硬件外殼與界面中的“虛擬外殼”&#xff09;和背景是構成視覺體驗的核心元素&#xff0c;它們不僅影響美觀&#xff0c;更直接關聯用戶對功能的理解和操作效率。以下從設計角度詳細解析其作用與使用邏輯&#xff1a; 一、設備外殼&…

基于深度學習的電信號分類識別與混淆矩陣分析

基于深度學習的電信號分類識別與混淆矩陣分析 1. 引言 1.1 研究背景與意義 電信號分類識別是信號處理領域的重要研究方向,在醫療診斷、工業檢測、通信系統等多個領域有著廣泛的應用。傳統的電信號分類方法主要依賴于手工提取特征和淺層機器學習模型,但這些方法往往難以捕捉…

Git 和Gitee遠程連接 上傳和克隆

第一步創建遠程庫第二步初始化本地庫創建鏈接刪掉.idea 和target(這兩個沒用運行就自動生成了)右鍵空白處選擇Git Bash Here 初始化本地庫git init建立遠程連接建立連接這里是我的地址&#xff0c;后面拼接你的地址git remote add origin https://gitee.com/liu-qing_liang/git…

零基礎100天CNN實戰計劃:用Python從入門到圖像識別高手

一、為什么你需要這份100天CNN學習計劃&#xff1f; 在人工智能領域&#xff0c;卷積神經網絡&#xff08;CNN&#xff09; 是計算機視覺的基石技術。無論是人臉識別、醫學影像分析還是自動駕駛&#xff0c;CNN都扮演著核心角色。但對于初學者來說&#xff0c;面對復雜的數學公…

Python Matplotlib中的fontdict參數說明

文章目錄 1 fontdict 參數的常用屬性 1.1 使用示例 1.2 其他注意事項 1.3 結合其他參數 各位老板好, 在 Python 的 Matplotlib 庫中,fontdict 參數用于定義文本屬性的字典。這些屬性包括字體大小、顏色、樣式等,主要用于控制標題、標簽和其他文本元素的顯示效果。通過將 font…

25數據庫三級備考自整理筆記

備考策略&#xff1a;博主是邊做題邊學習知識點的&#xff0c;從每個章節->每套真題的流程&#xff0c;知識點清晰詳細&#xff0c;喜歡的請點個關注和收藏&#xff0c;祝大家考試順利&#xff0c;必過必過必過&#xff01;一、數據庫應用系統開發方法1.數據庫的三級模式&am…

文娛投資的逆勢突破:博派資本的文化旅游綜合體戰略

在多數資本因“變現難、政策風險、退出緩慢”等問題紛紛撤離文娛賽道時&#xff0c;博派資本創始人鄭蘭卻選擇逆勢而上&#xff0c;聚焦線下文化消費&#xff0c;并推出了全新的文化旅游綜合體戰略。鄭蘭深刻認為&#xff0c;2025年將成為區域經濟和文化產業復蘇的關鍵節點。她…