libc의 서로 다른 기호가 서로 다른 바인딩 선언을 사용하는 이유는 무엇입니까?
1510 0x0003d200 0xf7d55200 WEAK FUNC 55 system
454 0x00067b40 0xf7d7fb40 WEAK FUNC 474 puts
147 0x000303d0 0xf7d483d0 GLOBAL FUNC 33 exit
에서 readelf -s /lib/i386-linux-gnu/libc-2.27.so
,
1510: 0003d200 55 FUNC WEAK DEFAULT 13 system@@GLIBC_2.0
454: 00067b40 474 FUNC WEAK DEFAULT 13 puts@@GLIBC_2.0
147: 000303d0 33 FUNC GLOBAL DEFAULT 13 exit@@GLIBC_2.0
이 질문에서, 작성자의 libc에 LOCAL
종료가 있는 것 같습니다.
다양한 libc 바인딩 수준 뒤에 숨은 운율이나 이유는 무엇입니까?
답변1
glibc의 약한 기호는 정적 링크에서도 재정의를 허용합니다.
글로벌 엑시트(Global Exit)는 강력한 상징입니다. 추가 정의는 해결되지 않으며 링크 오류가 발생합니다.
따라서 자신만의 를 제공할 수 있으며 puts
, 두 번째 정의가 puts
강력 하지 않으면 puts
메모리 공간(크기)이 가장 큰 정의가 선택됩니다.
왜 최대 크기입니까? 글쎄요, GCC에는 몇 가지 판별자가 필요하며 대부분의 glibc는 공개 기호가 거의 보편적으로 비공개 기호에 별칭이 지정되도록 구조화되어 있습니다. 이는 크기가 매우 작다는 것을 의미합니다(점프). 즉 puts
, 자체 구현을 제공하는 경우 정확히 동일한 방식으로 별칭으로 구성하지 않으면 구현이 실패할 가능성이 더 높습니다. puts
별칭 포인팅 의 경우 __IO_puts
.
이는 표준 라이브러리가 표준 라이브러리 호출 구현을 제공하는 메커니즘입니다.그리고이를 재정의할 수 있습니다.
답변2
대답무엇기술적인 관점에서 무슨 일이 일어나고 있는지는Edwin이 언급한 이유로 구현 세부 사항(기호 별칭). 그러나 더 중요한 것은 부수적이고 패치에 적합하기 때문에 존재한다는 것입니다.
15:14 <azanella> EvanCarroll, 이는 구현 세부 사항이며
exit
내부적으로 사용되지 않으므로 별칭 [...]을 사용하여 내부 기호를 정의할 필요가 없으며system
둘puts
다 별칭 [...]을 사용하여 서로 다른 기호로 구현됩니다. 이것은 좋은 질문입니다.exit
이 경우 glibc는 실제로 정적 링크에 초점을 맞추지 않았으며 정적 링크에서 이를 재정의하려는 질문을 한 사람이 아무도 없다고 생각합니다.
2018년 10월 31일 irc.freenode.net의 #glibc에서