полный сборщик мусора gcc, создающий скрипт компоновщика в linux мой gcc для архитектуры x86-64

# #c #linux #gcc #linker #x86-64

#c #линукс #gcc #линкер #x86-64

Вопрос:

это скрипт компоновщика из одного учебника, который я читал

 ENTRY(_Reset) SECTIONS {  . = 0x10000;  .startup . : { startup.o(.text) }  .text : { *(.text) }  .data : { *(.data) }  .bss : { *(.bss COMMON) }  . = ALIGN(8);  . = .   0x1000; /* 4kB of stack memory */  stack_top = .; }  

вышеописанный выход-использовать полный, т. Е. Если я перепрошиваю свою программу во флэш-память встроенного устройства, но смотрю на мой скомпилированный вывод скрипта компоновщика gcc. полный мусор ниже

Я понятия не имею, где находится начальный адрес основной функции и как узнать, где в моей программе есть функция под названием main. никаких имен функций. Поэтому мне нравится знать, могу ли я получить полезный вывод с помощью gcc для компоновщика, чтобы, по крайней мере, была напечатана моя функция и их начальные адреса плюс начальный адрес неинициализированных и инициализированных плюс начальный адрес адреса стеков функций. Это следует за абсолютным мусором, произведенным gcc. Не имеет смысла. Итак, вопрос в том, как создать полезный скрипт компоновщика с помощью gcc или любого другого инструмента, но я предпочитаю gcc, я скомпилировал код с помощью этой команды ubuntu@this:~$ gcc -static -o empty sam.c -Wl,--verbose gt;gt; ttt.txt

 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",  "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); 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 = .);  }  . = 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))   (. amp; (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) gt;= 24 ? 24 : 0, .);  .got.plt : { *(.got.plt) *(.igot.plt) }  .data :  {  *(.data .data.* .gnu.linkonce.d.*)  SORT(CONSTRUCTORS)  }  .data1 : { *(.data1) }  _edata = .; PROVIDE (edata = .);  . = .;  __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))   (. amp; (CONSTANT (MAXPAGESIZE) - 1)) :  {  *(.lrodata .lrodata.* .gnu.linkonce.lr.*)  }  .ldata ALIGN(CONSTANT (MAXPAGESIZE))   (. amp; (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_*) } }  

вышеуказанный мусор создается с помощью этой самой маленькой программы

 #include lt;stdio.hgt;  #include lt;stdint.hgt;    void hello() {  printf("hellon"); } int main() {  hello();  /*  int *i=(int[]){10000000,2,3,4,5};  uint8_t *c=(uint8_t *)(i);  printf("-%x-",*c);*/    int *i=(int[]){1,2,3,4,5};  int *x=(void *)(i 1);  printf("-%d-",*x); }  

Комментарии:

1. Похоже, вы сбрасываете ld сценарий компоновщика по умолчанию. Это сложно, независимо от того, компилируете ли вы простую программу или сложную с помощью LTO. Если вам нужны адреса функций, используйте objdump или nm в результирующем исполняемом файле ELF (вы использовали -static значение , которое переопределяет значение по -pie умолчанию -no-pie , поэтому будут реальные адреса).

2. Сценарий компоновщика не будет упоминать имена символов функций конкретно, обычно только имена разделов. Это не мусор, просто совсем не та информация, которую вы искали. Это совсем не похоже на список ассемблеров, если вы об этом думали.

3. @PeterCordes пожалуйста, скажите, какая полная команда objdump для печати этих адресов будет здорово выдать также несколько строк C в выводе

4. This is following absolute garbage gcc produced Где находится «мусор»? how to produce useful linker script with gcc Вы пишете их сами, нет никакого инструмента.

5. @KamilCuk МОЖЕТЕ ли вы, пожалуйста, рассказать, как отключить LTO в gcc