2012-12-25 15 views
7

Tôi crosscompiling C++ trong Gentoo cho một ARM Cortex M3 (Maple Mini), nhưng dường như đã trúng một mái nhà với các nguồn tài nguyên bộ nhớ khi liên kết các elf-fileGiảm kích thước của .rodata

/usr/libexec/gcc/arm-none-eabi/ld: build/maple_mini.elf section `.rodata' will not fit in region `rom' 
/usr/libexec/gcc/arm-none-eabi/ld: region `rom' overflowed by 1508 bytes 

Bài đăng này là câu hỏi về cách giảm kích thước nội dung của .rodata, để có thể hoàn thành việc liên kết tệp elf.

Tôi đã loại bỏ mã được bao gồm và đang biên dịch với các tùy chọn có liên quan sau.

CXXFLAGS = -fno-rtti -fno-exceptions -Os -fdata-sections -ffunction-sections -Wl,-gc-sections ... 
LDFLAGS = -Wl,-gc-sections -fno-exceptions -fno-rtti ... 

Tuy nhiên, .rodata trong tệp bản đồ (mà tôi khá lạ) chứa thông tin loại nào đó cho từng lớp trong chương trình. Một số đồ-file trích đoạn (lưu ý. MPU6050 là một SuperSensor <> mà là một cảm biến <>, trong một cảm giác C++)

0x000000000801d6c0  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d6c0 _ZTVN5syrup6SensorILi6EEE 
.rodata._ZTVN5syrup11SuperSensorILi6EEE 0x000000000801d6e8  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d6e8    _ZTVN5syrup11SuperSensorILi6EEE 
.rodata._ZTVN5syrup7MPU6050E 0x000000000801d710  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d710    _ZTVN5syrup7MPU6050E 
.rodata._ZTVN5syrup6SensorILi1EEE 
    0x000000000801d738     0x28 .../libsyrup.a(MS5611.o) 
    0x000000000801d738    _ZTVN5syrup6SensorILi1EEE 
.rodata._ZTVN5syrup11SuperSensorILi1EEE 
      0x000000000801d760   0x28 .../libsyrup.a(MS5611.o) 
      0x000000000801d760    _ZTVN5syrup11SuperSensorILi1EEE 
... 
      0x000000000801ee24   0x6f3 .../libstdc++.a(cp-demangle.o) 
             0x730 (size before relaxing) 
*fill*   0x000000000801f517  0x1 
.rodata  0x000000000801f518  0x14 .../libgcc.a(unwind-arm.o) 
.rodata  0x000000000801f52c  0x23c .../libc.a(lib_a-strerror.o) 
.rodata.str1.4 0x000000000801f768 0x635 .../libc.a(lib_a-strerror.o) 
             0x63c (size before relaxing) 

Vì vậy, lib_a-strerror.o và cp-demangle.o dường như là những gì chiếm hầu hết không gian, mặc dù tôi đoán đây là những điều khá quan trọng.

Vì vậy, câu hỏi của tôi là, tôi có thể thực hiện thêm các bước nào để giảm (hoặc cấu trúc lại mã) phần .rodata và chính xác những gì được lưu trữ ở đó? Bất kỳ đề xuất được hoan nghênh! Tôi khá mới mẻ với các hoạt động biên dịch và liên kết sâu hơn, nhưng học tập.

+0

Đây là các chuỗi thông báo lỗi được liên kết từ thư viện thời gian chạy C và C++. Họ cho người dùng biết lý do chương trình của bạn bị lỗi. Loại bỏ chúng sẽ yêu cầu viết lại các thư viện thời gian chạy, không chính xác thực tế nhưng nó đã được thực hiện. –

Trả lời

7

Tôi nghĩ rằng vấn đề của bạn có thể không nhất thiết phải nằm trong phần rodata như vậy - nó chỉ là anh chàng không ngồi xuống trong thời gian tại sự kiện ghế muscal. Nói cách khác, rodata trong chính nó không phải là những gì quá lớn, nhưng hình ảnh WHOLE là quá lớn để phù hợp. Giải pháp sẽ là xem xét toàn bộ mã, dữ liệu và dữ liệu trong hệ thống của bạn và xem có bất kỳ mã nào nổi bật hay không.

Xóa mã (hoặc chuỗi) không cần thiết nói chung sẽ là điểm mấu chốt ở đây. Nếu không có gì có thể được gỡ bỏ, thì bạn sẽ phải tìm một cách khác để giải quyết vấn đề. Một cách có thể là để nén mã và dữ liệu, và giải nén nó vào RAM (giả sử có RAM nhiều hơn đáng kể so với ROM trên hệ thống đích). Đây không phải là một vấn đề chưa từng xảy ra, nhưng nó không bao giờ thực sự dễ dàng sửa chữa - trừ khi ai đó đã thực hiện một số mã hóa thực sự xấu và thêm vào hàng trăm kilobyte mã. Nếu bạn có một hệ thống điều khiển phiên bản và bạn biết một phiên bản phù hợp, có thể là một điều tốt để kiểm tra chính xác có bao nhiêu không gian trống - nếu nó đột nhiên phát triển rất nhiều, hãy kiểm tra xem có ai đó đã thêm một số dữ liệu tĩnh lớn không hoặc một số cấu trúc như vậy.

+1

Cảm ơn, Trong việc dọn dẹp tiếp theo, tôi đã tìm thấy một xác nhận sai lệch đi lạc bao gồm đó dường như là một thư mục chính bao gồm các phần của thư viện chuẩn đã làm lộn xộn bản thân.Điểm chính ở đây có vẻ là giảm sự phụ thuộc vào stdlib (bao gồm cả toán tử mới và xóa) ở mức tối thiểu. – templar

6

Vấn đề cơ bản không phải là phần .rodata quá lớn, nhất thiết - bạn chỉ cần hết dung lượng ROM nói chung. (Các mối liên kết chỉ xảy ra được đánh giới hạn trong khi nó đang liên kết trong phần đó.)

Loại bỏ bất kỳ cuộc gọi đến các chức năng như perror, strerror, và công ty nên kết thúc giảm sự phụ thuộc vào strerror.o, mà nên giúp bạn tiết kiệm kilobyte và một nửa bạn đã qua. Có thể có những cách khác, dễ dàng hơn bạn có thể thực hiện những khoản tiết kiệm tương tự, mặc dù - tất cả phụ thuộc vào ứng dụng của bạn.