Đã làm một chút googling và thấy điều này từ here:
Chức năng call_gmon_start khởi hệ thống gmon profiling. Hệ thống này được bật khi các tệp nhị phân được biên dịch với cờ -pg, và tạo đầu ra để sử dụng với gprof (1). Trong trường hợp của kịch bản binary call_gmon_start được đặt trực tiếp tiếp tục _start chức năng. Hàm call_gmon_start tìm mục nhập cuối cùng trong Bảng bù trừ toàn cầu (còn được gọi là __gmon_start__) và, nếu không NULL, sẽ chuyển quyền kiểm soát đến địa chỉ được chỉ định. Phần tử __gmon_start__ trỏ đến hàm khởi tạo gmon, bắt đầu ghi thông tin lược tả và đăng ký chức năng dọn dẹp với atexit(). Trong trường hợp của chúng tôi tuy nhiên gmon không được sử dụng, và như vậy __gmon_start__ là NULL.
Vậy ...
- Vâng, nó có cái gì để làm với gprof
- Tôi không chắc chắn lý do tại sao biểu tượng là nhận được còn lại trong đó. Có lẽ chỉ là một người giữ chỗ cho khi nó được biên soạn cho gprof?
Cập nhật:
Được rồi, vì vậy tôi biên soạn mã của bạn có và không có -pg
. Có vẻ như __gmon_start__
được ánh xạ tới một địa chỉ trong chương trình được biên dịch. Vì vậy, với điều đó đang được nói, tôi không nghĩ rằng có một thư viện mà giải quyết biểu tượng đó, nhưng chương trình chính nó.
với -pg
:
[email protected]:~$ readelf -r hello
Relocation section '.rel.dyn' at offset 0x32c contains 1 entries:
Offset Info Type Sym.Value Sym. Name
08049fec 00000806 R_386_GLOB_DAT 08048460 __gmon_start__
Relocation section '.rel.plt' at offset 0x334 contains 6 entries:
Offset Info Type Sym.Value Sym. Name
0804a000 00000607 R_386_JUMP_SLOT 080483b0 _mcleanup
0804a004 00000107 R_386_JUMP_SLOT 00000000 __monstartup
0804a008 00000207 R_386_JUMP_SLOT 00000000 mcount
0804a00c 00000307 R_386_JUMP_SLOT 00000000 __cxa_atexit
0804a010 00000407 R_386_JUMP_SLOT 00000000 puts
0804a014 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main
objdump của __gmon_start__ mã:
[email protected]:~$ objdump -S hello | grep "460 <__gmon_start__>:" -A 20
08048460 <__gmon_start__>:
8048460: 83 ec 1c sub $0x1c,%esp
8048463: a1 20 a0 04 08 mov 0x804a020,%eax
8048468: 85 c0 test %eax,%eax
804846a: 75 2a jne 8048496 <__gmon_start__+0x36>
804846c: c7 05 20 a0 04 08 01 movl $0x1,0x804a020
8048473: 00 00 00
8048476: c7 44 24 04 36 86 04 movl $0x8048636,0x4(%esp)
804847d: 08
804847e: c7 04 24 30 84 04 08 movl $0x8048430,(%esp)
8048485: e8 36 ff ff ff call 80483c0 <[email protected]>
804848a: c7 04 24 b0 83 04 08 movl $0x80483b0,(%esp)
8048491: e8 1a 01 00 00 call 80485b0 <atexit>
8048496: 83 c4 1c add $0x1c,%esp
8048499: c3 ret
804849a: 90 nop
804849b: 90 nop
804849c: 90 nop
804849d: 90 nop
Với __gmon_start__
có mặt trong biên soạn chương trình hello
, bạn có thể thấy rằng __monstartup
được gọi vào.(monstartup man page)
mà không -pg
:
[email protected]:~$ readelf -r hello
Relocation section '.rel.dyn' at offset 0x290 contains 1 entries:
Offset Info Type Sym.Value Sym. Name
08049ff0 00000206 R_386_GLOB_DAT 00000000 __gmon_start__
Relocation section '.rel.plt' at offset 0x298 contains 3 entries:
Offset Info Type Sym.Value Sym. Name
0804a000 00000107 R_386_JUMP_SLOT 00000000 puts
0804a004 00000207 R_386_JUMP_SLOT 00000000 __gmon_start__
0804a008 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main
Bạn có thể thấy ở đây, rằng giá trị biểu tượng của __gmon_start__
được thiết lập để 00000000
.
về câu hỏi thứ ba? Tôi có nên xem mục nhập cuối cùng trong GOT là địa chỉ của __gmon_start__ không? Ngoài ra, kiểm tra các nhị phân của "hello" nó chỉ ra rằng có một mục: __gmon_start __ @ plt và một (mục PLT) __gmon_start __ @ plt-0x10> – JohnTortugo
Vậy làm thế nào để bù đắp cho 'gmon_start' được ánh xạ tới một địa chỉ vật lý ? – RouteMapper