2012-07-21 36 views
9

Tôi đang làm việc trên một vỏ kim loại trần-M3 trong C++ cho vui và lợi nhuận.Làm thế nào để gỡ lỗi quá trình liên kết - GCC/ld - STL C++

Gần đây tôi quyết định thử và sử dụng thư viện STL khi tôi cần một số vùng chứa. Tôi nghĩ rằng chỉ đơn giản là cung cấp phân bổ của tôi nó sẽ không thêm nhiều mã vào nhị phân cuối cùng , vì bạn chỉ nhận được những gì bạn sử dụng. Tôi thực sự thậm chí không mong đợi bất kỳ quá trình liên kết nào cả với STL (cấp phát của tôi), vì tôi nghĩ đó là tất cả mã mẫu.

Tôi đang biên soạn bằng -fno-exception bằng cách này.

Thật không may, khoảng 600KB trở lên được thêm vào nhị phân của tôi. Tôi nhìn lên những biểu tượng được bao gồm trong nhị phân cuối cùng với nm và nó có vẻ là một trò đùa với tôi. Danh sách dài quá Tôi sẽ không thử và vượt qua nó. Mặc dù có một số biểu tượng yếu.

Tôi cũng nhìn trong file .map tạo ra bởi mối liên kết và tôi thậm chí tìm thấy những biểu tượng scanf

.text   0x000158bc  0x30 /CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a(sscanf.o)¶ 
      0x000158bc    __sscanf¶ 
      0x000158bc    sscanf¶ 
      0x000158bc    _IO_sscanf¶ 


$ arm-none-linux-gnueabi-nm binary | grep scanf 
000158bc T _IO_sscanf 
0003e5f4 T _IO_vfscanf 
0003e5f4 T _IO_vfscanf_internal 
000164a8 T _IO_vsscanf 
00046814 T ___vfscanf 
000158bc T __sscanf 
00046814 T __vfscanf 
000164a8 W __vsscanf 
000158bc T sscanf 
00046814 W vfscanf 
000164a8 W vsscanf 

Làm thế nào tôi có thể gỡ lỗi này? Đầu tiên tôi muốn hiểu chính xác GCC đang sử dụng để liên kết (Tôi đang liên kết thông qua GCC). Tôi biết rằng nếu biểu tượng được tìm thấy trong một đoạn văn bản, thì toàn bộ phân đoạn được sử dụng, nhưng vẫn còn quá nhiều.

Bất kỳ đề xuất nào về cách giải quyết vấn đề này thực sự sẽ được đánh giá cao.

Cảm ơn, S.

Trả lời

3

Sử dụng các tùy chọn -v-Wl,-v của GCC sẽ hiển thị cho bạn các lệnh liên kết (và thông tin phiên bản của trình liên kết) đang được sử dụng.

Bạn đang sử dụng phiên bản GCC nào? Tôi đã thực hiện một số thay đổi cho GCC 4.6 (xem PR 44647PR 43863) để giảm kích thước mã để giúp các hệ thống nhúng. Vẫn còn một yêu cầu nâng cao nổi bật (PR 43852) để cho phép vô hiệu hóa các biểu tượng IO mà bạn nhìn thấy - một số trong số đó đến từ trình xử lý chấm dứt chi tiết, sẽ in thông báo khi quá trình chấm dứt với một ngoại lệ hoạt động. Nếu bạn không sử dụng execptions thì một số mã đó là vô dụng đối với bạn.

+0

Tôi đang sử dụng phiên bản gcc 4.6.3 từ Mã Sourcery. Tùy chọn -Wl, -v rất hữu ích. Dọc theo các lá cờ tôi đã chuyển đến liên kết, nó cũng bao gồm sau -lstdC++ -lm --start-group -lgcc -lgcc_eh -lc --end-group bây giờ tôi phải hiểu tại sao và cách xóa chúng. Đặc biệt là gcc_eh mà tôi giả sử là viết tắt của xử lý ngoại lệ. Bất kỳ đề xuất hoặc đọc về điều này? – emitrax

+0

Nếu bạn liên kết với 'gcc' thay vì' g ++' thì nó sẽ không chuyển '-lstdC++' vào trình liên kết, và điều đó cũng có thể loại bỏ sự cần thiết của '-lgcc -lgcc_eh' (tôi không nhớ, tôi 'd phải kiểm tra) nhưng nếu bạn không sử dụng bất kỳ mã nào từ những libs đó thì không nên tăng kích thước thực thi - trình xử lý chấm dứt chi tiết trong libstdC++ có lẽ là những gì kéo vào mã không mong muốn –

+0

Nếu tôi sử dụng gcc nó đã thắng Không tìm thấy _List_node_base :: _ M_hook symbol.Passing -lstdC++ bao gồm mọi thứ khác. Để thu hẹp sự cố, tôi đã thử liên kết trực tiếp với ld thêm từng cờ một. Nó thiếu __aeabi_unwind_cpp_pr0 trong libstdC++ a (list.o): (..._ List_node_base7_M_hookE) mà sau đó liên kết đến libc (memcpy và khác), sau đó liên kết mọi thứ khác. Đó là một chuỗi lớn và một PITA. Tôi chỉ muốn một cái hộp. :-) Tôi cũng nghĩ rằng, vì tôi có một đối tượng toàn cầu, nó cần __static_initialization_and_destruction_0 mà tôi không mong đợi. Cảm ơn bạn đã giúp đỡ. – emitrax

2

Vấn đề không phải là về STL, đó là về thư viện chuẩn.

Các STL chính nó là tinh khiết (trong một chiều), nhưng bộ thư viện chuẩn cũng bao gồm tất cả những gói suối và có vẻ như là bạn cũng được quản lý để kéo trong libc cũng ...

Vấn đề là Thư viện chuẩn chưa bao giờ được chọn để tách ra, vì vậy có thể không có nhiều lo ngại về việc sử dụng lại nội dung từ Thư viện chuẩn C ...

Trước tiên, bạn nên cố gắng xác định tệp nào được lấy vào khi bạn biên dịch (sử dụng stracefor example), theo cách này bạn có thể xác minh rằng bạn chỉ sử dụng chỉ tiêu đề tệp.

Sau đó, bạn có thể thử và xóa liên kết xảy ra. Có các tùy chọn để chuyển tới gcc để chính xác rằng bạn muốn xây dựng thư viện chuẩn miễn phí, chẳng hạn như --nostdlib chẳng hạn, tuy nhiên tôi không đủ thông thạo để chỉ dẫn bạn chính xác ở đây.

+0

Tôi đã chuyển -nostdlib cho trình biên dịch, cùng với -fno-exception, nhưng có vẻ như không hoạt động. – emitrax

Các vấn đề liên quan