http://wiki.osdev.org/ELF 마지막으로 나는 그것을 금이!
아니요, GCC가 non-GOT 유형 재배치로 출력되도록 제한 할 수 없습니다.
GOT 유형 재배치를 해결하는 방법은 무엇입니까?
GOT는 재배치를위한 항목이 들어있는 동적 링커에 의해 할당 된 고정 128KB 메모리 청크 (쓰기시 복사 원칙에 따라 작동)입니다.
Dynamic Linker는 ELF 바이너리에 GOT 재배치 유형이있는 경우에만 GOT를 할당합니다.
R_386_GOTOFF(== 0 * 9)을
이 재배치 타입 심볼의 값과 전역 옵셋 테이블의 주소 사이의 차이를 계산한다. 링커가 전역 옵셋 테이블을 생성하도록 지시합니다. 그것의 계산에 전역 옵셋 테이블의 주소를 사용하는 것을 제외하고
R_386_GOTPC(== 0xa는)
이 재배치 타입은 R_386_PC32 유사하다.
어떻게 구현합니까?
참고 : 다음 코드 스 니펫은 Atom OS 소스 코드의 오픈 소스 라이센스에 의해 보호됩니다. -fPIE 또는 GOT을 해제 할 수있는 -fpie :하지만 (아톰 개발자는) 본인이 코드는 :
uint GOT = Heap.kmalloc(1024 * 128); // 128 KB
...
private static void Relocate(Elf_Header* aHeader, Elf_Shdr* aShdr, uint GOT)
{
uint BaseAddress = (uint)aHeader;
Elf32_Rel* Reloc = (Elf32_Rel*)aShdr->sh_addr;
Elf_Shdr* TargetSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + aShdr->sh_info;
uint RelocCount = aShdr->sh_size/aShdr->sh_entsize;
uint SymIdx, SymVal, RelocType;
for (int i = 0; i < RelocCount; i++, Reloc++)
{
SymVal = 0;
SymIdx = (Reloc->r_info >> 8);
RelocType = Reloc->r_info & 0xFF;
if (SymIdx != SHN_UNDEF)
{
if (RelocType == R_386_GOTPC)
SymVal = GOT;
else
SymVal = GetSymValue(aHeader, TargetSection->sh_link, SymIdx);
}
uint* add_ref = (uint*)(TargetSection->sh_addr + Reloc->r_offset);
switch(RelocType)
{
case R_386_32:
*add_ref = SymVal + *add_ref; // S + A
break;
case R_386_GOTOFF:
*add_ref = SymVal + *add_ref - GOT; // S + A - GOT
break;
case R_386_PLT32: // L + A - P
case R_386_PC32: // S + A - P
case R_386_GOTPC: // GOT + A - P
*add_ref = SymVal + *add_ref - (uint)add_ref;
break;
default:
throw new Exception("[ELF]: Unsupported Relocation type");
}
}
}
이것은 유효한 질문입니다. 그러나 자신의 동적 링커를 작성하는 경우 전체 ELF 사양을 읽고 적절한 GOT 재배치를 구현하는 것이 좋습니다. – 3442
@KemyLand 동의하지만, 지금은 제한된 시간 제약으로 제한된 구현을하고 싶습니다. – amaneureka
깔끔하고 내 장난감 OS에 꼭 필요한 것입니다. – minexew