2013-01-10 20 views
5

Ví dụ khi tôi có:Sự khác nhau giữa phần .rodata và .rodata.str1.4 trong đầu ra đã biên dịch cho chuỗi ký tự là gì?

const char mesg [] = "Hello World"; 

nó được đưa trực tiếp vào .rodata nhưng khi tôi có:

const char* mesg = "Hello World"; 

nó được đưa trực tiếp vào .rodata.str1.4

sự khác biệt giữa chúng là gì và tại sao chúng ta sử dụng .rodata.str1.4 khi chúng ta sử dụng con trỏ?

+0

Trình biên dịch, phiên bản và lệnh biên dịch nào? –

+0

clang 3.5 đặt cả hai vào '.rodata.str1.1' cho các chuỗi ký tự địa phương,' .data' cho hình cầu, vì vậy tôi không tái tạo hoàn toàn. –

Trả lời

3

tôi đã làm một vài thí nghiệm, có vẻ như trình biên dịch đặt chuỗi trong phần đặc biệt trong các tập tin đối tượng. Điều thú vị xảy ra khi nhị phân được biên dịch, các chuỗi kết thúc bằng .rodata như mong đợi. Các thí nghiệm khác cho thấy rằng điều xảy ra là nếu bạn có cùng một chuỗi trong các đối tượng khác nhau, chúng được hợp nhất thành cùng một chuỗi trong kết quả nhị phân. Vì vậy, tôi nghi ngờ rằng lý do cho điều này là trình biên dịch muốn cung cấp cho người liên kết một số thông tin về dữ liệu chỉ đọc khác với "nó chỉ đọc", để liên kết cuối cùng có thể đưa ra quyết định thông minh hơn về làm thế nào để xử lý nó, bao gồm cả pc.

$ cat foo.c 
const char * 
fun(int i) 
{ 
     const char *foo = "foofoo foo foo foo"; 
    const char *bar = "barbar bar bar bar"; 
    return i ? foo : bar; 
} 
$ cat bar.c 
#include <stdio.h> 
extern const char *fun(int); 

int 
main(int argc, char **argv) 
{ 
    const char *foo = "foofoo foo foo foo"; 

    printf("%s%s\n", foo, fun(1)); 
    return 0; 
} 
$ cc -c -O2 foo.c 
$ cc -c -O2 bar.c 
$ objdump -s foo.o 
[...] 
Contents of section .rodata.str1.1: 
0000 62617262 61722062 61722062 61722062 barbar bar bar b 
0010 61720066 6f6f666f 6f20666f 6f20666f ar.foofoo foo fo 
0020 6f20666f 6f00      o foo. 
[...] 
$ objdump -s bar.o 
[...] 
Contents of section .rodata.str1.1: 
0000 666f6f66 6f6f2066 6f6f2066 6f6f2066 foofoo foo foo f 
0010 6f6f0025 7325730a 00     oo.%s%s.. 
[...] 
$ cc -o foobar foo.o bar.o 
$ objdump -s foobar 
[...] 
Contents of section .rodata: 
400608 01000200 00000000 00000000 00000000 ................ 
400618 62617262 61722062 61722062 61722062 barbar bar bar b 
400628 61720066 6f6f666f 6f20666f 6f20666f ar.foofoo foo fo 
400638 6f20666f 6f002573 25730a00   o foo.%s%s.. 
[...] 
+0

Cảm ơn câu trả lời của bạn, tôi chỉ có một câu hỏi nhỏ hơn. Bạn có thể cho tôi biết làm thế nào tôi có thể xem thứ tự của các phần của tập tin ELF? – mehmetozer

+0

Tôi không biết nếu objdump cung cấp cho bạn chúng theo thứ tự hoặc sắp xếp chúng bằng cách nào đó. Cùng một điều với chính mình. Nếu bạn muốn thực sự chắc chắn, hãy phân tích cú pháp các tiêu đề ELF, nó không thực sự khó. Các tiêu đề là tất cả trong '/ usr/include/elf.h' trên hệ thống của tôi và phải là một cái gì đó tương tự ở khắp mọi nơi. Có hướng dẫn trên mạng về cách đọc và phân tích ELF. Tại sao bạn muốn biết rằng mặc dù? – Art

+0

Cảm ơn rất nhiều. Tôi chỉ muốn học thứ tự của họ. Không phải là nó .text, .rodata, .data, .bss, .heap và .stack? – mehmetozer

2

trình biên dịch khác nhau có thể sử dụng các phần khác nhau cho dữ liệu chỉ đọc, tùy thuộc vào loại, tờ khai, vv

.rodata, theo quy ước, có thể được sử dụng cho bất cứ điều gì mà sẽ cần phải được đặt trong một Read- chỉ một phần bộ nhớ của bộ nạp.
Vì vậy, bạn có thể đặt ký tự const * ở đó.

Nhưng thông thường, trình biên dịch cũng tạo ra các phần, bắt đầu bằng .rodata, để phân loại dữ liệu chỉ đọc.
Nó có thể bị bỏ qua bởi bộ tải và xử lý chính xác như phần .rodata (tôi nghĩ nó thường là trường hợp), nhưng nó có thể cho phép một số sắp xếp cụ thể trong bộ nhớ, nếu cần.

Đây là lý do tại sao các kịch bản mối liên kết thường chỉ định .rodata và .rodata *

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