Linux Section

简介: Linux Section

一、实例1 不同长度

1、代码

#include <stdio.h>

/* Simple shorthand for a section definition */
#ifndef __section
#define __section(s) __attribute__((__section__(#s)))
#endif

#define __packed        __attribute__((__packed__))

#define DEBUG_SECTION

#ifdef DEBUG_SECTION
#define __init __section(.init.usb.text)
#define __initdata __section(.init.usb.data)
#define __initconst __section(.init.usb.rodata)
#define __exitdata __section(.exit.usb.data)
#define __exit __section(.exit.usb.text)

#else /*!DEBUG_SECTION*/
#define __init
#define __initdata
#define __initconst
#define __exitdata
#define __exit

#endif

typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;

struct usb_desc_header {
  uint8_t bLength;
  uint8_t bDescriptorType;
} __packed;

/** USB Standard Device Descriptor defined in spec. Table 9-8 */
struct usb_device_descriptor {
  uint8_t bLength;
  uint8_t bDescriptorType;
  uint16_t bcdUSB;
  uint8_t bDeviceClass;
  uint8_t bDeviceSubClass;
  uint8_t bDeviceProtocol;
  uint8_t bMaxPacketSize0;
  uint16_t idVendor;
  uint16_t idProduct;
  uint16_t bcdDevice;
  uint8_t iManufacturer;
  uint8_t iProduct;
  uint8_t iSerialNumber;
  uint8_t bNumConfigurations;
} __packed;

/** USB Standard Configuration Descriptor defined in spec. Table 9-10 */
struct usb_cfg_descriptor {
  uint8_t bLength;
  uint8_t bDescriptorType;
  uint16_t wTotalLength;
  uint8_t bNumInterfaces;
  uint8_t bConfigurationValue;
  uint8_t iConfiguration;
  uint8_t bmAttributes;
  uint8_t bMaxPower;
} __packed;

usb_desc_header gs_1 __initdata {};
__initdata usb_device_descriptor gs_2 ;

static usb_cfg_descriptor gs_3 __initdata;
static int gs_4 __initdata;

void my_print(void) {
  static int gs_5 __initdata = 0x13;
  static int gs_6 __initdata;
}

int main() {
  my_print();
  return 0;
}

2、lds

  SECTION_DATA_PROLOGUE(usb_descriptor,,SUBALIGN(1))
  {
    __usb_descriptor_start = .;
    *(".usb.descriptor")
    KEEP(*(SORT_BY_NAME(".usb.descriptor*")))
    __usb_descriptor_end = .;
  } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

3、编译

gcc -O0 -Wall -DDEBUG_SECTION -o t_section main.cpp

4、elf

# 查看 section
readelf -a t_section | grep .init.usb.data

  [24] .init.usb.data    PROGBITS         0000000000004010  00003010
   05     .init_array .fini_array .dynamic .got .data .init.usb.data .bss


# 查看 变量
readelf -a t_section | grep gs

Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
                 FileSiz            MemSiz              Flags  Align
    12: 0000000000004038     9 OBJECT  LOCAL  DEFAULT   24 _ZL4gs_3
    13: 0000000000004044     4 OBJECT  LOCAL  DEFAULT   24 _ZL4gs_4
    14: 0000000000004048     4 OBJECT  LOCAL  DEFAULT   24 _ZZ8my_printvE4gs_5
    15: 000000000000404c     4 OBJECT  LOCAL  DEFAULT   24 _ZZ8my_printvE4gs_6
    22: 0000000000004020    18 OBJECT  GLOBAL DEFAULT   24 gs_2
    33: 0000000000004010     2 OBJECT  GLOBAL DEFAULT   24 gs_1

5、遍历下一个

static int usb_fix_descriptor(struct usb_desc_header *head)
{
  while (head->bLength != 0U) {
    /* Move to next descriptor */
    head = (struct usb_desc_header *)((uint8_t *)head + head->bLength);
  }

  if ((head + 1) != __usb_descriptor_end) {
    LOG_DBG("try to fix next descriptor at %p", head + 1);
    return usb_fix_descriptor(head + 1);
  }

  return 0;
}

二、实例2 相同类型

1、代码

/* shows in which sections varaibles are stored in.
 * globle var, static var, local var. etc...
 */

#include <stdio.h>

/*shorthand for attribute section*/
/*
#ifndef __section
#define __seciton(s) __attribute__((__section__(#s)))
#endif
 */

/* Simple shorthand for a section definition */
#ifndef __section
#define __section(s) __attribute__((__section__(#s)))
#endif

#define __packed __attribute__((__packed__))

#define DEBUG_SECTION

#ifdef DEBUG_SECTION
#define __init __section(.init.usb.text)
#define __initdata __section(.init.usb.data)
#define __initconst __section(.init.usb.rodata)
#define __exitdata __section(.exit.usb.data)
#define __exit __section(.exit.usb.text)

#else /*!DEBUG_SECTION*/
#define __init
#define __initdata
#define __initconst
#define __exitdata
#define __exit

#endif

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;

struct usb_desc_header {
  uint8_t bLength;
  uint8_t bDescriptorType;
} __packed;

/** USB Standard Device Descriptor defined in spec. Table 9-8 */
struct usb_device_descriptor {
  uint8_t bLength;
  uint8_t bDescriptorType;
  uint16_t bcdUSB;
  uint8_t bDeviceClass;
  uint8_t bDeviceSubClass;
  uint8_t bDeviceProtocol;
  uint8_t bMaxPacketSize0;
  uint16_t idVendor;
  uint16_t idProduct;
  uint16_t bcdDevice;
  uint8_t iManufacturer;
  uint8_t iProduct;
  uint8_t iSerialNumber;
  uint8_t bNumConfigurations;
} __packed;

/** USB Standard Configuration Descriptor defined in spec. Table 9-10 */
struct usb_cfg_descriptor {
  uint8_t bLength;
  uint8_t bDescriptorType;
  uint16_t wTotalLength;
  uint8_t bNumInterfaces;
  uint8_t bConfigurationValue;
  uint8_t iConfiguration;
  uint8_t bmAttributes;
  uint8_t bMaxPower;
} __packed;

usb_desc_header gs_1 __initdata{};
__initdata usb_desc_header gs_2;

static usb_desc_header gs_3 __initdata;
static usb_desc_header gs_4 __initdata;

extern usb_desc_header __init_usb_data_start[];
extern usb_desc_header __init_usb_data_end[];

void my_print(void) {
  static usb_desc_header gs_5 __initdata;
  static usb_desc_header gs_6 __initdata;
  int cnt = 0;
  for (auto p = __init_usb_data_start; p < __init_usb_data_end; p++) {
    cnt++;
  }
  printf("cnt:%d\n", cnt);
}

int main() {
  my_print();
  return 0;
}

2、lds

t.lds

SECTIONS
{
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id  : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
      *(.rela.ifunc)
    }
  .rela.plt       :
    {
      *(.rela.plt)
      PROVIDE_HIDDEN (__rela_iplt_start = .);
      *(.rela.iplt)
      PROVIDE_HIDDEN (__rela_iplt_end = .);
    }
  .relr.dyn : { *(.relr.dyn) }
  . = ALIGN(CONSTANT (MAXPAGESIZE));
  .init           :
  {
    KEEP (*(SORT_NONE(.init)))
  }
  .plt            : { *(.plt) *(.iplt) }
.plt.got        : { *(.plt.got) }
.plt.sec        : { *(.plt.sec) }
  .text           :
  {
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(SORT(.text.sorted.*))
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf.em.  */
    *(.gnu.warning)
  }
  .fini           :
  {
    KEEP (*(SORT_NONE(.fini)))
  }
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  . = ALIGN(CONSTANT (MAXPAGESIZE));
  /* Adjust the address for the rodata segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
  /* Thread Local Storage sections  */
  .tdata          :
   {
     PROVIDE_HIDDEN (__tdata_start = .);
     *(.tdata .tdata.* .gnu.linkonce.td.*)
   }
  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array    :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array    :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array    :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
  .got.plt        : { *(.got.plt) *(.igot.plt) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  _edata = .; PROVIDE (edata = .);
  . = .;

    __init_usb_data_start = .;
  .init.usb.data           : { *(.init.usb.data) } 
  __init_usb_data_end = .;

  __bss_start = .;
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we do not
      pad the .data section.  */
   . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  .lbss   :
  {
    *(.dynlbss)
    *(.lbss .lbss.* .gnu.linkonce.lb.*)
    *(LARGE_COMMON)
  }
  . = ALIGN(64 / 8);
  . = SEGMENT_START("ldata-segment", .);
  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
  }
  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.ldata .ldata.* .gnu.linkonce.l.*)
    . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  . = ALIGN(64 / 8);
  _end = .; PROVIDE (end = .);
  . = DATA_SEGMENT_END (.);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1.  */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions.  */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2.  */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2.  */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions.  */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3.  */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  /* DWARF 5.  */
  .debug_addr     0 : { *(.debug_addr) }
  .debug_line_str 0 : { *(.debug_line_str) }
  .debug_loclists 0 : { *(.debug_loclists) }
  .debug_macro    0 : { *(.debug_macro) }
  .debug_names    0 : { *(.debug_names) }
  .debug_rnglists 0 : { *(.debug_rnglists) }
  .debug_str_offsets 0 : { *(.debug_str_offsets) }
  .debug_sup      0 : { *(.debug_sup) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

3、编译

gcc -Tt.lds -o t_section main.cpp

cmake

cmake_minimum_required(VERSION 3.11.0)
project(t2 VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${CMAKE_SOURCE_DIR}/t.lds")

include(CTest)
enable_testing()

add_executable(t2 main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

如何在 CMake 中使用特定的链接脚本(*.lds)

4、elf

# 查看 .init.usb.data
readelf -a t_section | grep .init.usb.data

  [27] .init.usb.data    PROGBITS         0000000000404030  00003030
   05     .init_array .fini_array .dynamic .got .got.plt .data .init.usb.data .bss
    34: 000000000040403c     0 NOTYPE  GLOBAL DEFAULT   27 __init_usb_data_end
    38: 0000000000404030     0 NOTYPE  GLOBAL DEFAULT   27 __init_usb_data_start


# 查看 gs
readelf -a t_section | grep gs

Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
                 FileSiz            MemSiz              Flags  Align
    12: 0000000000404034     2 OBJECT  LOCAL  DEFAULT   27 _ZL4gs_3
    13: 0000000000404036     2 OBJECT  LOCAL  DEFAULT   27 _ZL4gs_4
    14: 0000000000404038     2 OBJECT  LOCAL  DEFAULT   27 _ZZ8my_printvE4gs_5
    15: 000000000040403a     2 OBJECT  LOCAL  DEFAULT   27 _ZZ8my_printvE4gs_6
    22: 0000000000404032     2 OBJECT  GLOBAL DEFAULT   27 gs_2
    35: 0000000000404030     2 OBJECT  GLOBAL DEFAULT   27 gs_1

5、遍历下一个

  int cnt = 0;
  for (auto p = __init_usb_data_start; p < __init_usb_data_end; p++) {
    cnt++;
  }
  printf("cnt:%d\n", cnt);

目录
相关文章
|
21天前
|
Linux 网络安全 Python
linux后台运行命令screen的使用
linux后台运行命令screen的使用
54 2
linux后台运行命令screen的使用
|
21天前
|
Ubuntu Linux
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
138 3
|
16天前
|
机器学习/深度学习 安全 网络协议
Linux防火墙iptables命令管理入门
本文介绍了关于Linux防火墙iptables命令管理入门的教程,涵盖了iptables的基本概念、语法格式、常用参数、基础查询操作以及链和规则管理等内容。
176 73
|
9天前
|
Linux Shell
Linux 中 Tail 命令的 9 个实用示例
Linux 中 Tail 命令的 9 个实用示例
37 6
Linux 中 Tail 命令的 9 个实用示例
|
15天前
|
Linux 应用服务中间件 nginx
|
1天前
|
机器学习/深度学习 存储 Linux
linux中强大且常用命令:find、xargs、grep
linux中强大且常用命令:find、xargs、grep
23 9
|
1天前
|
SQL 移动开发 Linux
linux下find、grep命令详解
linux下find、grep命令详解
24 8
|
8天前
|
存储 Linux 编译器
linux中vim介绍以及常用命令大全
linux中vim介绍以及常用命令大全
30 8