Isn't the value of the function pointer A function address?

Source: Internet
Author: User

Initially released in: http://user.qzone.qq.com/31731705/blog/1302859584

Before writingBefore Running mainIt was a strange problem.

int initBreak(){DebugBreak();return 0;}typedef int (*pInit)();pInit start3 = initBreak;

Initbreak is the function name,Start3Yes, they have different values.

When you start to learn the C language, you will know that the function name represents the function address and can be assigned to the function pointer to facilitate subsequent calls. Why is the value different here?

Still run inBefore main (2) Code example: continue to use windbg for analysis.

0: 000> G
Fri Apr 15 17:03:10. 492 2011 (UTC +): breakpoint 0 hit
Eax = 00000000 EBX = 7ffdf000 ECx = 0041956c edX = 00130000 ESI = 00000000 EDI = 00000000
EIP = 0f9186a6 ESP = 0012ff30 EBP = 0012ff34 iopl = 0 NV up ei pl Zr na PE NC
Cs = 001b Ss = 0023 DS = 0023 es = 0023 FS = 003b GS = 0000 EFL = 00000246
Msvcr100d! _ Initterm_e + 0x6:
0f9186a6 c745fc00000000 mov dword ptr [ebp-4], 0 SS: 0023: 0012ff30 = {testc! _ Native_startup_lock (0041956c )}
0: 000> kpl
Childebp retaddr
0012ff34 00400002b msvcr100d! _ Initterm_e (
<Function> ** pfbegin = 0x0041641c,
<Function> ** pfend = 0x00416a40) + 0x6

0012ff80 0041263f testc! _ Tmaincrtstartup (void) + 0xdb
0012ff88 77773c45 testc! Maincrtstartup (void) + 0xf
0012ff94 77ce37f5 Kernel32! Basethreadinitthunk + 0xe
0012ffd4 77ce37c8 NTDLL! _ Rtluserthreadstart + 0x70
0012 ffec 00000000 NTDLL! _ Rtluserthreadstart + 0x1b
0: 000> dd start L4
00416728 00411186 00411023 0041118b 00000000
0: 000> dd start2 L4
00416208 00411186 00411023 0041118b 00000000
0: 000> dd start3 L4
004166240041118b00000000 00000000 00000000
0: 000> dd start4 L4
004168380041118b00000000 00000000 00000000
0: 000> ln 41118b
(0041118b)Testc! ILT more than 390(_ Initbreak) | (00411190) testc! ILT + 395 (_ controlfp_s)
Exact matches:
0: 000> ln start3
(00416624) testc! Start3 | (00416728) testc! Start
Exact matches:
Testc! Start3 = 0x0041118b

0: 000> ln start4
(00416838) testc! Start4 | (0041693c) testc! Pinit
Exact matches:
Testc! Start4 = 0x0041118b
0: 000> ln initbreak
D: \ project \ mine \ vs.net \ testc. C (47)
(004120f0) testc! Initbreak| (00412150) testc! Main
Exact matches:
Testc! Initbreak (void)

We can see that start3 and start4 are both 0x0041118b, while the functionsInitbreakThe value is 004120f0, and their values are different. Why?

Just move forward and there will be an answer,

0: 000> U 41118b-8
Testc! ILT + 380 (_ rtc_initialize) + 0x2:
00411183 25.0e985 and eax, 85e90000h
00411188 0e push CS
00411189 0000 add byte PTR [eax], Al
Testc! ILT + 390 (_ initbreak ):
0041118b e9600f0000 JMP testc! Initbreak (004120f0)

Testc! ILT + 395 (_ controlfp_s ):
00411190 e987300000 JMP testc! Controlfp_s (0041421c)
Testc! ILT + 400 (_ stackoverflow ):
00411195 e9d6040000 JMP testc! _ Stackoverflow (00411670)
Testc! ILT + 405 (_ getsystemtimeasfiletime:
0041119a e90d310000 JMP testc! Getsystemtimeasfiletime (004142ac)
Testc! ILT + 410 (_ F1 ):
0041119f e96c0d0000 JMP testc! F1 (00411f10)

The truth is as simple as a 5-byte JMP command.

The other question comes with it. Why does the compiler do so, instead of reducing efficiency. Google:

What is incremental link table?

Assume that a program has two consecutive Foo and bar (the so-called continuity means that the function body is stored continuously after the compilation and connection). The Foo entry is located at 0x0400 and the length is 0 x bytes, the bar entry should be 0x0600 = 0x0400 + 0x0200. During development, programmers often modify code and build code. If the programmer adds some content to Foo, the foo function occupies 0 x bytes, the bar entry has to move 0x100 back to 0x0700, so there is a problem. If foo is called N times in the program, so linker has to modify the N function call points. Although linker is not too tired, it takes a long time to link and programmers will feel uncomfortable. So msvc build in the debug version won't make every function body so compact, and every function body has padding (all assembly code INT 3 is used to cause interruption, in this way, exceptions may occur when the padding part is not running due to odd reasons.) with these padding, the above mentioned problems can be mitigated to a certain extent, but when the function adds more content than padding, the problem persists. What should I do? Msvc uses incremental Link Table in debug build. ILT is actually a string of JMP statements. Each JMP statement corresponds to a function. The JMP destination is the function entry point, the difference with the absence of ILT is that the call to a function is not a direct call to the function entry point, but a call to the corresponding location in the ILT, and nothing is done at this location, directly add JMP to the function. The advantage is that when the address of a function entry changes, you only need to modify the corresponding value in the ILT and do not need to modify each call location, it is worthwhile to use a redundant ITL to reduce the time complexity from O (n) to O (1). Of course, the binary files of the debug version will be slightly larger and slower, and the release version will not use ILT.

Therefore, to get the correct result, disable incremental linking. The cost is that the link time is longer and there is no perfect solution for both worlds.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.