Что означает «COM» в столбце Ndx раздела .symtab? - PullRequest
6 голосов
/ 09 ноября 2010

add2.c:

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 --symbols 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?Я понимаю, что "counter" и "a" определены в разделе # 3 (т.е. .bss) и что "add" определен в разделе # 1 (т.е. .text), но я ожидал "b" и«c» также будет определено в разделе .bss, и поэтому получите «3» в столбце Ndx.

Спасибо

Ответы [ 3 ]

5 голосов
/ 09 ноября 2010

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.)

2 голосов
/ 09 ноября 2010

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

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

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

0 голосов
/ 09 ноября 2010

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

Правка: Хмм, Пол Бейкер побил меня этим, со ссылками не меньше.используйте его ответ:)

...