2010-11-09 21 views
6

add2.c:"COM" có nghĩa là gì trong cột Ndx của phần .symtab?

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

biên soạn: gcc -c add2.c -o add2.o

đọc bảng biểu tượng: --symbols 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" có nghĩa là gì trong cột Ndx? Tôi hiểu rằng "counter" và "a" được định nghĩa trong phần # 3 (ví dụ, .bss) và "add" được định nghĩa trong phần # 1 (ví dụ, .text), nhưng tôi đã mong đợi "b" và "c" để được định nghĩa trong phần .bss, và vì vậy có được một "3" trong cột Ndx.

Cảm ơn bạn

Trả lời

5

gcc xử lý các hình cầu chưa được khởi tạo mà không được khai báo rõ ràng extern là các ký hiệu "phổ biến" (do đó "COM").

Nhiều định nghĩa của cùng một biểu tượng chung (trên nhiều tệp đối tượng) được liên kết với nhau bởi trình liên kết khi tạo tệp thực thi cuối cùng, để tất cả đều tham chiếu đến cùng một bộ nhớ. Một trong các tệp đối tượng có thể khởi tạo nó thành một giá trị cụ thể (trong trường hợp đó nó sẽ kết thúc trong phần dữ liệu); nếu không có tập tin đối tượng khởi tạo nó, sẽ kết thúc trong BSS; nếu nhiều hơn một đối tượng khởi tạo nó, bạn sẽ nhận được một lỗi liên kết.

Nói tóm lại, nếu bạn có, nói, hai định nghĩa về int a:

  • int a; trong một đối tượng và int a; trong đối tượng khác là OK: cả hai đều chỉ cùng a, khởi tạo 0
  • int a; trong một đối tượng và int a = 42; trong một đối tượng khác là OK: cả hai đều tham chiếu đến cùng một số a, được khởi tạo thành 42
  • int a = 23; trong một đối tượng và int a= 42; trong một đối tượng khác wi sẽ đưa ra lỗi liên kết.

Lưu ý rằng việc sử dụng nhiều định nghĩa của cùng một biểu tượng trên hai đối tượng không được phép theo tiêu chuẩn C; nhưng nó được hỗ trợ bởi nhiều trình biên dịch, bao gồm gcc, dưới dạng phần mở rộng. (Nó được liệt kê trong phần "Các phần mở rộng chung" - không có ý định chơi chữ - trong thông số C99.)

+0

Ok! Tôi hiểu rằng chúng ta không thể bây giờ mà một biểu tượng "COMMON" sẽ kết thúc bằng cách tìm kiếm một tệp đối tượng có thể định vị lại. Điều này được quyết định bởi trình liên kết, tại thời gian liên kết, trong chức năng của các tệp đối tượng có thể định vị lại khác thực hiện với biểu tượng này. Đúng không ? – user368507

+0

Vâng, đúng vậy. –

2

Từ this PDF, bảng 7-11:

SHN_COMMON
Biểu tượng de fi ned so với phần này là biểu tượng phổ biến, chẳng hạn như FORTRAN CHUNG hoặc chưa phân bổ C biến bên ngoài. Các ký hiệu này là đôi khi được gọi là dự kiến.

Ngoài ra, hãy xem this page.

+0

Liên kết tới PDF hiện đã chết. –

+0

@PiotrZierhoffer: Đã sửa liên kết. – user200783

0

Chúng là các biến toàn cục chưa được khởi tạo do trình liên kết phân bổ. Đôi khi được gọi là biến xã.

Chỉnh sửa: Hrmm, Paul Baker đánh tôi với nó, với các liên kết không kém. sử dụng câu trả lời của mình :)