함수 호출을 재정의하는 가장 직접적인 방법은 VxWorks의로드 시간 연결을 사용하는 것입니다.
file1.c에서 :
#include <stdio.h>
int function1 (void);
int function1()
{
printf ("function1 called\n");
return 1;
}
와 file2.c :
#include <stdio.h>
int function2 (void);
int function2()
{
printf ("function2 called\n");
return 2;
}
file3.c :
int function1 (void);
int function2 (void);
int function3 (void);
int function3()
{
function1();
function2();
return 0;
}
mock.c :
#include <stdio.h>
int function1 (void);
int function2 (void);
int function1()
{
printf ("mock function1 called\n");
return 1;
}
int function2()
{
printf ("mock function2 called\n");
return 2;
}
다음 소스를 고려
개체를로드하면 그 기능이 전역 기호 테이블에 추가됩니다.
-> ld < file1.o
value = 273740816 = 0x1050f410
-> lkup "function"
function1 0x108b0000 text (file1.o)
value = 0 = 0x0
->
는 심볼 테이블에 이미 기능을 사용하는 개체를로드 , 각 호출은 즉시 테이블의 심볼과 관련된 마지막 주소로 해결 될 것입니다. l()
가 유용하게 기능 명을 표시
-> ld < file2.o
value = 292535232 = 0x116fbbc0
-> ld < file3.o
value = 292537592 = 0x116fc4f8
-> lkup "function"
function1 0x108b0000 text (file1.o)
function2 0x108d0000 text (file2.o)
function3 0x108f0000 text (file3.o)
value = 0 = 0x0
-> l function3
function3:
0x108f0000 55 PUSH EBP
0x108f0001 89 e5 MOV EBP, ESP
0x108f0003 56 PUSH ESI
0x108f0004 57 PUSH EDI
0x108f0005 e8 f6 ff fb ff CALL function1
0x108f000a e8 f1 ff fd ff CALL function2
0x108f000f 31 c0 XOR EAX, EAX
0x108f0011 5f POP EDI
0x108f0012 5e POP ESI
0x108f0013 89 ec MOV ESP, EBP
value = 0 = 0x0
-> function3
function1 called
function2 called
value = 0 = 0x0
->
있지만, 어떤 심볼은 실제로 개체 메모리에로드되지 않는다. 대신, 함수와 관련된 마지막 주소에 대한 호출이로드됩니다. 따라서 이전에로드 된 함수는 동일한 이름의 다른 함수를로드하여 재정의 할 수 있습니다.
-> unld "file3.o"
value = 0 = 0x0
-> ld < mock.o
value = 292537592 = 0x116fc4f8
-> ld < file3.o
value = 292539496 = 0x116fcc68
-> lkup "function"
function1 0x108f0000 text (mock.o)
function1 0x108b0000 text (file1.o)
function2 0x108f0020 text (mock.o)
function2 0x108d0000 text (file2.o)
function3 0x10910000 text (file3.o)
value = 0 = 0x0
-> l function3
function3:
0x10910000 55 PUSH EBP
0x10910001 89 e5 MOV EBP, ESP
0x10910003 56 PUSH ESI
0x10910004 57 PUSH EDI
0x10910005 e8 f6 ff fd ff CALL function1
0x1091000a e8 11 00 fe ff CALL function2
0x1091000f 31 c0 XOR EAX, EAX
0x10910011 5f POP EDI
0x10910012 5e POP ESI
0x10910013 89 ec MOV ESP, EBP
value = 0 = 0x0
-> function3
mock function1 called
mock function2 called
value = 0 = 0x0
->
이 방법을 사용하려면 호출 된 함수와 호출하는 함수를 같은 개체로 컴파일 할 수 없습니다. 호출 할 주소가 기호 표의 주소와 일치하지 않을 수도 있습니다. 이것은 VxSim에서 위의 실행 결과입니다. VxSim 로더는 실제로 기본 운영 체제의 로더를 호출합니다.따라서이 주소는 기호 테이블의 주소와 일치하지 않으며 어셈블리는 WorkBench가 실행중인 기본 Pentium 아키텍처를 반영합니다.
메모리에서 호출 할 주소를 직접 조작하여 함수 호출을 재정의 할 수도 있습니다. 이 메서드는 구현에 의존합니다. 아래에서는 gcc -mlongcall 옵션을 사용하여 PPC 용으로 컴파일 된 소스에 대해 설명합니다. 이것은 VxSim이 아닌 실제 대상에서 실행되었습니다.
-> ld < file1.o
value = 33538216 = 0x1ffc0a8 = function1 + 0x498
-> ld < file2.o
value = 33548336 = 0x1ffe830 = function2 + 0x80
-> ld < mock.o
value = 33549600 = 0x1ffed20 = function2 + 0x570
-> ld < file3.o
value = 33550744 = 0x1fff198 = function2 + 0x9e8
->
-> lkup "function"
function1 0x01ffbef8 text (mock.o)
function1 0x01ffbc10 text (file1.o)
function2 0x01ffbf58 text (mock.o)
function2 0x01ffe7b0 text (file2.o)
function3 0x01ffe558 text (file3.o)
value = 0 = 0x0
->
-> function3
mock function1 called
mock function2 called
value = 0 = 0x0
->
-> l function3
function3:
0x1ffe558 9421ffe8 stwu r1,-24(r1)
0x1ffe55c 7c0802a6 mfspr r0,LR
0x1ffe560 93a1000c stw r29,12(r1)
0x1ffe564 93c10010 stw r30,16(r1)
0x1ffe568 93e10014 stw r31,20(r1)
0x1ffe56c 9001001c stw r0,28(r1)
0x1ffe570 7c3f0b78 or r31,r1,r1
0x1ffe574 3d200200 lis r9,512
0x1ffe578 3ba9bef8 addi r29,r9,-16648
0x1ffe57c 7fa803a6 mtspr LR,r29
value = 33547648 = 0x1ffe580 = function3 + 0x28
->
-> *0x1ffe578
function3 + 0x20 = 0x1ffe578: value = 1000980216 = 0x3ba9bef8
-> *0x1ffe578 = 0x3ba9bc10
function3 + 0x20 = 0x1ffe578: value = 1000979472 = 0x3ba9bc10
-> *0x1ffe578
function3 + 0x20 = 0x1ffe578: value = 1000979472 = 0x3ba9bc10
->
-> function3
function1 called
mock function2 called
value = 0 = 0x0
->
분명히 메모리에서 포인터를 직접 조작하는 작업은 빠르게 지루해집니다. 또한 메모리 보호 기능을 사용하면 VxSim에로드 된 RTP 또는 개체를 변경할 수 없습니다. (따라서, 실제 하드웨어에서이 코드를 실행 한 이유는 무엇입니까?) 가능성을 언급합니다. 주로 질문의 내용과 가장 잘 어울리는 것 같습니다.
마지막으로, 평범하지 않은 단위 테스트의 경우 작업을 위해 특별히 설계된 도구를 고려할 수 있습니다. "vxworks 유닛 테스트 프레임 워크"에 대한 검색을 시도하십시오. 나는 특정 도구에 대해 깊은 경험이 없다. (그리고 스팸을 만나고 싶지도 않다.) 아마도 여기 다른 사람이 좋은 제안을 할 수 있습니다.