Что означает "com" означает в столбце NDX по части.раздел symtab?


Add2.с:

int counter=0;
int a=0;
int b;
int c;
int add(int a, int b) {
    return a+b;
}

Компиляция: gcc-c add2.c-o add2.o

Чтение таблицы символов: readelf -- символы add2.o

Symbol table '.symtab' contains 12 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS add2.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1 
     3: 00000000     0 SECTION LOCAL  DEFAULT    2 
     4: 00000000     0 SECTION LOCAL  DEFAULT    3 
     5: 00000000     0 SECTION LOCAL  DEFAULT    5 
     6: 00000000     0 SECTION LOCAL  DEFAULT    4 
     7: 00000000     4 OBJECT  GLOBAL DEFAULT    3 counter
     8: 00000004     4 OBJECT  GLOBAL DEFAULT    3 a
     9: 00000004     4 OBJECT  GLOBAL DEFAULT  COM b
    10: 00000004     4 OBJECT  GLOBAL DEFAULT  COM c
    11: 00000000    14 FUNC    GLOBAL DEFAULT    1 add

Что означает " COM " в столбце Ndx ? Я понимаю, что "счетчик" и "А" определены в разделе № 3 (т. е.bss) и что "добавить" определено в разделе №1 (т. е.текст), но я ожидал, что "в" и "С" будут определены в тексте .раздел bss тоже, и поэтому получите "3" в столбце Ndx.

Спасибо

3 6
gcc

3 ответа:

Gcc рассматривает неинициализированные глобалы, которые явно не объявлены extern как "общие" символы (следовательно, "COM").

Несколько определений одного и того же общего символа (в нескольких объектных файлах) объединяются компоновщиком при создании конечного исполняемого файла, так что все они ссылаются на одно и то же хранилище. Один из объектных файлов может инициализировать его до определенного значения (в этом случае он будет находиться в разделе данных); если ни один объектный файл не инициализирует его, он будет находиться в BSS; если его инициализирует несколько объектов,вы получите ошибку компоновщика.

В общем, если у вас есть, скажем, два определения int a:
  • int a; в одном объекте и int a; в другом объекте в порядке: оба относятся к одному и тому же a, инициализированному до 0
  • int a; в одном объекте и int a = 42; в другом объекте нормально: оба относятся к одному и тому же a, инициализированному до 42
  • int a = 23; в одном объекте и int a= 42; в другом объекте дадут ошибку связи.

Обратите внимание, что использование нескольких определений одного и того же символа в двух объектах технически не допускается стандартом C; но оно поддерживается многими компиляторами, включая gcc, в качестве расширения. (Он указан в разделе" Общие расширения " - без каламбура - в спецификации C99.)

Из этого PDF, таблица 7-11:

SHN_COMMON
Символы, определенные относительно в этом разделе представлены общие символы, такие как как Fortran общего или нераспределенные с внешняя переменная. Эти символы являются иногда его называют пробным.

Также смотрите эту страницу.

Это неинициализированные глобальные переменные, которые выделяются компоновщиком. Иногда их называют общими переменными.

Edit: МММ, пол Бейкер опередил меня, со ссылками не меньше. используйте его ответ :)