2015-07-05 7 views
5

próbowałem tego, ale nie zawahał się z odpowiedzią poniżej pytania gdzie hello_world-1.c jestwielkość i objdump zgłaszać różne rozmiary dla segmentu tekstu

#include<stdio.h> 
int main(void) 
{ 
    printf("Hello world\n"); 
    return 0; 
} 

Dokonane komendy:

[[email protected] ~]$ gcc -Wall -Wextra -c hello_world-1.c 
[[email protected] ~]$ gcc -o hello_world-1 hello_world-1.o 
[[email protected] ~]$ size hello_world-1 hello_world-1.o 

    text data bss  dec hex filename 
    1222  280  4 1506 5e2 hello_world-1 
    139  0  0  139  8b hello_world-1.o 

[[email protected] ~]$ objdump -h hello_world-1.o 

    hello_world-1.o:  file format elf32-i386 

    Sections: 
    Idx Name   Size  VMA  LMA  File off Algn 
     0 .text   0000003b 00000000 00000000 00000034 2**0 
         CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 
     1 .data   00000000 00000000 00000000 0000006f 2**0 
         CONTENTS, ALLOC, LOAD, DATA 
     2 .bss   00000000 00000000 00000000 0000006f 2**0 
         ALLOC 
     3 .rodata  0000000c 00000000 00000000 0000006f 2**0 
         CONTENTS, ALLOC, LOAD, READONLY, DATA 
     4 .comment  0000002d 00000000 00000000 0000007b 2**0 
         CONTENTS, READONLY 
     5 .note.GNU-stack 00000000 00000000 00000000 000000a8 2**0 
         CONTENTS, READONLY 
     6 .eh_frame  00000044 00000000 00000000 000000a8 2**2 
         CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 

Może ktoś proszę pomóż mi dowiedzieć się, jakie mogą być przyczyny poniższych pytań?

  1. Komenda size nie listy segment stosu lub sterty dla hello_world lub hello_world.o. Jaki może być tego powód? (dla powyższego pytania odpowiedź brzmi, ponieważ nie nazwałem żadnej funkcji, a także nie użyto żadnego segmentu sterty, dlatego nie pojawiły się tutaj.) Czy mam rację?)
  2. Istnieją brak zmiennych globalnych w hello_world-1.c. Dlaczego size doniesienia, że ​​danei BSS segmenty mają zerowej długości dla pliku obiektu ale niezerowej długości dla wykonywalnego?
  3. size i objdump zgłosić różne rozmiary dla segmentu tekstu. Czy możesz doradzić, skąd pochodzą rozbieżności?

Próbowałem, ale nie udało mi się wyciągnąć wniosków na temat powyżej 3 pytań. Doceń swoją pomoc w tej sprawie.

+0

Nie masz globalnych * zmiennych *, ale masz dane globalne: tablicę 13 znaków 'char's odpowiadających twojemu literałowi. Plus wszystko, co może być zadeklarowane w 'stdio.h'. –

+0

Dla nr 3: czy "rozmiar -A hello_world-1.o" wyświetla rozmiar segmentu tekstu bliżej tego, co wyświetla "objdump"? –

Odpowiedz

10

1) Heap i stos są tworzone przez system operacyjny w czasie wykonywania; oznacza to, że po wczytaniu pliku wykonywalnego do pamięci wirtualnej. Dlatego nie są częścią pliku wykonywalnego.

2) Ponieważ plik wykonywalny zawiera również dane - i kod, proszę pamiętać - z biblioteki stdio, która została połączona z plikiem obiektu przez linker.

3) Ponieważ size, wywołany w ten sposób (bez żadnych parametrów) wyświetla rozmiary zgodnie z konwencją Berkeley. Zgodnie z tym scenariuszem, wpis text donosi połączone rozmiary trzech różnych segmentach:

.text

.rodata

.eh_frame

Z drugiej strony, objdump informuje o wielkości tylko .text. Możesz zobaczyć rozmiary .text, .rodata i .eh_frame oddzielnie z size, jeśli wywołasz je zgodnie z konwencją SysV, na przykład: size -A hello_world-1.c. Następnie zobaczysz dokładnie te same informacje, które widzisz z objdump.

Mam nadzieję, że to pomoże.

3

Dla pytania nr 2. Wynika to z faktu, że zdefiniowano kilka domyślnych zmiennych globalnych, gdy łączenie jest wykonywane w celu utworzenia pliku wykonywalnego. Poniżej polecenia można wyświetlić tabelę symboli. Dwie zmienne po 4 bajty to __data_start i __bss_start.

objdump -x hello_world-1

0000000000601030 g .data 0000000000000000 __data_start

0000000000601034 g .bss 0000000000000000 __bss_start

Na pytania nr 1 stosu i sterty nie zostaną wymienione w pliku wykonywalnym, ponieważ są dynamicznie przydzielane przez system operacyjny. Plik binarny dostarcza tylko sekcje, które mają charakter statyczny. Podobnie jak zawartość i rozmiary danych, segmenty bss tekstu są ustalane w czasie kompilacji.

Dla pytania nr 3 Sprawdź źródło rozmiaru na stronie https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/size.c;h=dcfd9547b25cdd58db890f9fe0dc9a3ba9228d89;hb=HEAD#l449.

Wyświetla dodanie wszystkich sekcji ReadOnly/Code jako tekst. ja.e

446 static void 
447 berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, 
448    void *ignore ATTRIBUTE_UNUSED) 
449 { 
450 flagword flags; 
451 bfd_size_type size; 
452 
453 flags = bfd_get_section_flags (abfd, sec); 
454 if ((flags & SEC_ALLOC) == 0) 
455  return; 
456 
457 size = bfd_get_section_size (sec); 
458 if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0) 
459  textsize += size; 
460 else if ((flags & SEC_HAS_CONTENTS) != 0) 
461  datasize += size; 
462 else 
463  bsssize += size; 
464 } 

Więc jeśli wziąć wyjście objdump i dodać wszystkie odcinki tylko do odczytu/code to będziesz miał wartość 1222

Powiązane problemy