2016-06-13 16 views
6

Mỗi mã máy về phần văn bản trong tệp đối tượng có địa chỉ, nó sẽ từ 0 đến một số.di chuyển tĩnh về c

Khi trình liên kết liên kết tất cả các tệp đối tượng, địa chỉ về hướng dẫn sẽ thay đổi.

Tôi không thể biết liệu trình liên kết sẽ đọc hướng dẫn về từng phần văn bản để thay đổi mọi địa chỉ hướng dẫn hay không.

Disassembly of section .text: 

00000000 <_start>: 

    0: bf 00 00 00 00   mov $0x0,%edi 
    5: 8b 04 bd 00 00 00 00 mov 0x0(,%edi,4),%eax 
    c: 89 c3     mov %eax,%ebx 

bởi liên kết

08048074 <_start>: 

    8048074: bf 00 00 00 00   mov $0x0,%edi 
    8048079: 8b 04 bd a0 90 04 08 mov 0x80490a0(,%edi,4),%eax 
    8048080: 89 c3     mov %eax,%ebx 

chỉ thích 0 → 8.048.074 và vân vân.

+0

Không chắc đây có phải là thứ bạn đang tìm hay không, nhưng quá trình được mô tả trong '- phần liên quan đến fpic' trong ['man gcc'] (http://linux.die.net/man/1/gcc). – CristiFati

+8

Câu hỏi thực tế là gì? – Art

+0

Không tồn tại mã máy cho đến khi trình liên kết tạo ra nó, vì vậy tôi không hiểu ý bạn là gì. "đọc hướng dẫn về từng phần văn bản" từ đâu? – Lundin

Trả lời

2

Được rồi vì vậy tôi giả sử bạn đang sử dụng một số hệ thống dựa trên Unix vì điều này có vẻ như đầu ra của lệnh objdump, nhưng tôi biết điều này có liên quan đến cả tệp ELF và PE.

vì vậy hãy bắt đầu, trước hết khi bạn sử dụng c, bạn biên dịch một số mô hình thành các tệp đối tượng và cuối cùng liên kết chúng với nhau, như đã thấy trước đó. ví dụ:

  • m1.c ->m1.o
  • m2.c ->m2.o
  • main.c + m2.o + m1.o ->main.exe

chúng tôi có một số chương trình c gọi m1.c/m2.c định nghĩa một số chức năng, được gọi bởi main.c, cuối cùng tất cả được liên kết và biên dịch với nhau thành main.exe wh ich hoàn toàn có thể thực thi được.

bây giờ, hãy đi sâu vào và xem điều gì đã xảy ra dưới mui xe. trước tiên tôi muốn bắt đầu với một khởi đầu rất quan trọng, trong thực thi cuối cùng, trong ví dụ của chúng tôi (main.exe) tất cả các địa chỉ là CÁC ĐỊA CHỈ VÔ TUYẾN HOÀN TOÀN HOÀN TOÀN (điều này không nhất thiết đúng vì một số khái niệm được gọi là PIE/PIC nhưng bây giờ chúng ta không tham gia vào nó)

do đó trong phạm vi bạn có thể thực thi, chức năng foo trong phạm vi m1.o sẽ có một số địa chỉ được giải quyết (ví dụ 0x400100), trong main.exe khi foo được gọi là bạn sẽ thấy trong phần tháo gỡ như

call 0x400100 

bây giờ, đây là những gì khái niệm xảy ra, bây giờ hãy vào những gì thực sự xảy ra. khi tìm nạp hướng dẫn, ví dụ: jmp hoặc call hướng dẫn một số địa chỉ được cung cấp dưới dạng toán hạng và sau đó thanh ghi hướng dẫn của bộ vi xử lý được thay đổi thành địa chỉ được đặt làm toán hạng, do đó câu hỏi của bạn là thông minh. cần phải được thay đổi và thay đổi nó? NO, mối liên kết đơn giản là không làm điều đó, nó thông minh hơn nhiều.

trước tiên, khi biên dịch, trình biên dịch tạo ra các bước nhảy và cuộc gọi đến các mô-đun bên trong (ví dụ jmp đến một số địa chỉ đã thuộc về m1.o trong ví dụ của chúng tôi) liên quan đến thực thi lệnh hiện tại. điều đó nghĩa là gì? giả sử chúng ta có một số câu lệnh if, sẽ được biên dịch để nhảy tới một số địa chỉ, trình biên dịch đủ thông minh để sử dụng toán tử nhảy tương đối và đặt độ lệch giữa các lệnh, do đó khi liên kết mối liên kết thậm chí không phải thay đổi , nó không liên quan đến địa chỉ mã được nạp như các cuộc gọi liên quan đến hướng dẫn hiện tại và bù đắp giữa các lệnh của một số tập tin đối tượng vẫn tĩnh thông qua các giai đoạn liên kết.

bây giờ đây là nơi mà mọi thứ có được một chút phức tạp hơn, chúng tôi đã thảo luận cách linker tránh các địa chỉ thay đổi trong phạm vi m1.o, bây giờ những gì nếu m2.o cuộc gọi chức năng quy định tại m1.o cả hai đều thực thi và không có cách nào trên trái đất mà trình biên dịch có thể giả định sự bù đắp giữa chúng vì cả hai đều không có ý tưởng về việc có bao nhiêu mô hình khác chúng sẽ được liên kết, cách này được giải quyết như thế nào? Các bảng biểu tượng và tái định cư được giới thiệu.

  • Symbol Bảng - Một bảng chứa tất cả những biểu tượng trong mô hình của bạn - một biểu tượng là điều mà các mô hình khác có thể cần phải nhận theo tên, như chức năng và các biến toàn cầu.
  • Bảng di dời - Bảng chứa tất cả "lần xuất hiện" của các ký hiệu trong một số kiểu máy.

Bạn có thể nghe nói về những điều này trước đây, nhưng bây giờ tôi sẽ giải thích cho bạn về những điều này. trước khi đi vào nó, tôi cần cảnh báo rằng tôi quen thuộc hơn với các tệp định dạng ELF nhưng nhiều như tôi biết là các tệp PE khái niệm hoạt động theo cùng một cách. nhìn

let tại mã ví dụ này

#include <stdio.h> 
/** file: m1.c **/ 

extern void goo(); 

void foo() 
{ 
    printf("I am foo()!\n"); 
    goo(); 
} 

#include <stdio.h> 
/** file: m2.c **/ 

void goo() 
{ 
    printf("I am goo()!\n"); 
} 

khi biên dịch m1.o trong tập tin đối tượng, sẽ có một số bảng nói điều gì đó như thế này

BIỂU TƯỢNG: foo - > tại offset X trong hồ sơ, goo -> UNDEFINED RELOCATION: goo -> tại offset Y trong tệp,

bây giờ điều này có nghĩa là trình biên dịch tạo ra một bảng thu thập tất cả các chức năng mà mô hình sử dụng và xác định xem chúng có được định nghĩa hay không. đã nộp và nếu không được xác định, nó sẽ nêu rõ,

cũng sẽ nêu rõ rằng trong mô hình này, goo đang được gọi là bù đắp X và cần phải được di dời (Chúng tôi sẽ giải quyết vấn đề của mình) câu hỏi của bạn!)

khi liên kết thành tệp thực thi, trình liên kết lấy tất cả các ký hiệu của tất cả các tệp đối tượng, giải quyết một số địa chỉ bên trong chúng, sau đó đi qua từng bảng biểu tượng của từng tệp đối tượng, xem và xác định ký hiệu nào chưa được xác định. đi qua bảng di chuyển và xem các cuộc gọi nào được thực hiện cho các ký hiệu không xác định, đi đến vị trí đó trong tệp và chỉ cần viết lại địa chỉ được gọi đến địa chỉ đã được giải quyết, vì vậy nếu trước đó chúng tôi có thứ gì đó như thế này m1.o

call 0x000000 ;undefined goo address 

sau biểu tượng giải quyết, mối liên kết có lẽ sẽ có một số entry trên bàn di dời nói rằng bạn cần chuyển nơi ở địa chỉ goo trên dòng X và chúng tôi sẽ dẫn đến

call 0x400100 ;actual goo address 

FYI, khi có một lỗi tham khảo mối liên kết không xác định nó có nghĩa là bạn có một số biểu tượng không xác định trong bảng biểu tượng của bạn và mối liên kết không thể giải quyết một định nghĩa chức năng phù hợp cho nó ... cũng nếu tôi không tự làm rõ, điều này hoạt động giống nhau đối với biến toàn cầu và tĩnh, chúng cũng được coi là biểu tượng

+0

Điều này là hoàn hảo, bạn xứng đáng nhận được huy chương! Cảm ơn. – Pyjong

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