lazy_load는 파일의 해당 부분이 불러와질 때 frame과 연결되고, 물리 메모리에 할당된다.
do_iret 직후에는 해당 파일의 main의 주소로 이동한다.
하지만 코드를 진행하면서 읽으려는 코드가 들어있는 가상주소에 해당 코드가 로드가 안 되어 있을 수 있다.
그런데 그 접근하는 순서가 ‘순차적이 아니다’. 중간에 함수 호출, 조건 분기 등으로 page를 넘어서 코드를 건너 뛸 수 있다.
예시에서는 2번째 lazy load를 하는데, 해당 코드가 0x605248에 있다.
이 때 file_seek 를 하지 않고 file_read를 하면, read는 마지막 file_read의 최근 offset(0x400c7f+PAGE_SIZE)부터 시작하고, 가상주소 0x605248에 들어갔어야 할 파일 내용이 아닌 최근 offset의 파일이 로드되어 예상외의 동작을 하게 된다.
file_seek()만 넣어줬을 때도 문제가 생길 수 있다.
예시에서 0x605248 페이지 실행을 무사히 마치고 다시 0x401076자리로 돌아간다.
이 때 offset 이동 코드를 쓰지 않았다면, file의 offset은 마지막으로 file_read를 끝마친 offset( 0x604d20+PAGESIZE )을 가리키고, 가상주소 0x401076에 로드되어야 하는 파일의 내용에는 해당 offset의 내용이 로드되어서 이후에 예상하지 못한 방식으로 동작하게 된다.
미해결 의문
#include "tests/lib.h"
int
main (int argc, char *argv[])
{
int i;
test_name = "args";
if (((unsigned long long) argv & 7) != 0)
msg ("argv and stack must be word-aligned, actually %p", argv);
msg ("begin"); //msg함수 코드의 위치 0x605248?
msg ("argc = %d", argc); // 다시 0x40176?
for (i = 0; i <= argc; i++)
if (argv[i] != NULL)
msg ("argv[%d] = '%s'", i, argv[i]);
else
msg ("argv[%d] = null", i);
msg ("end");
return 0;
}
args-one 테스트를 돌리면 실제로 돌아가는 args.c 에서, 어디에서 점프를 뛰는지 알고 싶은데, msg가 유력한 후보인 것 같다.
msg실행 이후 다시 main 함수로 돌아와서 msg(”argc =%d”,argc) 를 실행하는 코드 (어셈블리어) 가 들어가 있는 부분이 0x40176 에 들어있는 것으로 추측된다.