Minimal Linux IA-32 ví dụ minh họa sử dụng của nó
main.S:
.section .text
.global _start
_start:
/* Dummy access so that after will be referenced and kept. */
mov after, %eax
/*mov keep, %eax*/
/* Exit system call. */
mov $1, %eax
/* Take the exit status 4 bytes after before. */
mov $4, %ebx
mov before(%ebx), %ebx
int $0x80
.section .before
before: .long 0
/* TODO why is the `"a"` required? */
.section .keep, "a"
keep: .long 1
.section .after
after: .long 2
liên kết.ld:
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text :
{
*(.text)
*(.before)
KEEP(*(.keep));
*(.keep)
*(.after)
}
}
Biên dịch và chạy:
as --32 -o main.o main.S
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o
./main.out
echo $?
Output:
1
Nếu chúng ta nhận xét ra dòng KEEP
đầu ra là:
2
Nếu một trong hai chúng tôi:
- thêm một giả
mov keep, %eax
- loại bỏ
--gc-sections
Sản lượng đi trở lại 1
.
Thử nghiệm trên Ubuntu 14.04, Binutils 2.25.
Giải thích:
Không có tham chiếu đến các biểu tượng keep
, và do đó có chứa nó phần .keep
.
Do đó, nếu thu thập rác được bật và chúng tôi không sử dụng KEEP
để tạo ngoại lệ, phần đó sẽ không được đưa vào tệp thực thi.
Vì chúng tôi đang thêm 4 vào địa chỉ before
, nếu không có phần keep
thì trạng thái thoát sẽ là 2
, xuất hiện ở phần .after
tiếp theo.
TODO: không có gì xảy ra nếu chúng tôi xóa "a"
từ .keep
, điều này làm cho nó có thể phân bổ. Tôi không hiểu tại sao lại như vậy: phần đó sẽ được đặt bên trong phân đoạn .text
, vì đó là tên ma thuật sẽ được phân bổ.
Nguồn
2015-10-08 10:44:42
KEEP được ghi lại trong phiên bản [this] (https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep) của hướng dẫn sử dụng. – alexei