Toolchain glibc library의 dynamic link 경로 문제

lux1075의 이미지

안녕하세요.

툴체인을 직접 구성하여 타겟보드에 올리려 하고 있습니다.

툴체인 구성은 아래와 같습니다.
binutils-2.20.1
glibc-2.11.3
gcc-4.4.3
kernel-2.6.35
busybox-1.15.0

각 소스코드를 컴파일하여 툴체인을 /opt/arm-none-linux-gnueabi 하위 디렉토리에 구성하였습니다.
/opt/arm-none-linux-gnueabi/lib, /opt/arm-none-linux-gnueabi/bin 등등 을 통하여 rootfs를 구성했고
타겟보드에 업데이트 하였습니다.

그리고나서 타겟보드 부팅시 아래와 같은 에러메시지가 발생합니다.
==================================================================================================
/sbin/init: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x18/0x1c)
r7:c7c16bc0 r6:c7c16bc0 r5:be92aa08 r4:c02d7de0
[] (dump_stack+0x0/0x1c) from [] (panic+0x60/0xe0)
[] (panic+0x0/0xe0) from [] (do_exit+0x74/0x5e8)
r3:c02bba2c r2:00000000 r1:c7c19e2c r0:c0273c90
[] (do_exit+0x0/0x5e8) from [] (do_group_exit+0x94/0xc8)
[] (do_group_exit+0x0/0xc8) from [] (sys_exit_group+0x18/0x24)
r5:be92aa08 r4:40024000
[] (sys_exit_group+0x0/0x24) from [] (ret_fast_syscall+0x0/0x2c)
==================================================================================================

busybox를 실행하는데 libc.so.6을 찾지 못하고 있습니다. rootfs의 lib폴더에 libc.so.6 있는것을 확인했는데도 말이죠. 링크도 모두 이상이 없습니다.

/opt/arm-none-linux-gnueabi/lib$ ll libc.so.6
lrwxrwxrwx 1 root root 14 2월 23 18:13 libc.so.6 -> libc-2.11.3.so*

그런데, readelf로 libc-2.11.3.so 파일을 확인해보면 program interpreter 의 경로가 문제가 있어 보입니다.
==================================================================================================
/opt/arm-none-linux-gnueabi/lib$ arm-none-linux-gnueabi-readelf -l libc-2.11.3.so

Elf file type is DYN (Shared object file)
Entry point 0x1564c
There are 10 program headers, starting at offset 52

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x119e6c 0x00119e6c 0x00119e6c 0x011e0 0x011e0 R 0x4
PHDR 0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4
INTERP 0x11948c 0x0011948c 0x0011948c 0x00030 0x00030 R 0x4
[Requesting program interpreter: /opt/arm-none-linux-gnueabi/lib/ld-linux.so.3]
LOAD 0x000000 0x00000000 0x00000000 0x11e1b4 0x11e1b4 R E 0x8000
LOAD 0x11e6e4 0x001266e4 0x001266e4 0x02268 0x04de8 RW 0x8000
DYNAMIC 0x11ff18 0x00127f18 0x00127f18 0x000e8 0x000e8 RW 0x4
NOTE 0x000174 0x00000174 0x00000174 0x00020 0x00020 R 0x4
TLS 0x11e6e4 0x001266e4 0x001266e4 0x00008 0x00040 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
GNU_RELRO 0x11e6e4 0x001266e4 0x001266e4 0x0191c 0x0191c R 0x1

Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01
02 .interp
03 .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt .text __libc_freeres_fn __libc_thread_freeres_fn .rodata .interp .ARM.extab .ARM.exidx .eh_frame .hash
04 .tdata .fini_array .ctors .dtors __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got .data .bss
05 .dynamic
06 .note.ABI-tag
07 .tdata .tbss
08
09 .tdata .fini_array .ctors .dtors __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic
==================================================================================================

program interpreter 경로가 /lib/ld-linux.so.3으로 되어야 할거 같은데, /opt/arm-none-linux-gnueabi/lib로 되어 있습니다.

제 생각인데, 저거땜시 busybox가 /lib/libc.so.6를 동작시킬때 잘못된 경로때문에 찾지를 못하고 있는것 같은데.... 맞는건가요?

libc.so 파일을 확인해 봐도 경로가 이상합니다.
/opt/arm-none-linux-gnueabi/lib$ more libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
GROUP ( /opt/arm-none-linux-gnueabi/lib/libc.so.6 /opt/arm-none-linux-gnueabi/lib/libc_nonshared.a AS_NEEDED ( /opt/arm-none-linux-gnueabi/lib/ld-linux.so.3 ) )

이 부분을 해결하지 못해 2주동안 계속 제자리 걸음 입니다. 제발 도와주세요.

김정균의 이미지

/sbin/init: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

에서 lib.so.6 은 파일 이름이 아니라 SONAME 입니다.

/opt/arm-none-linux-gnueabi/lib$ ll libc.so.6
lrwxrwxrwx 1 root root 14 223 18:13 libc.so.6 -> libc-2.11.3.so*

라고 하셨으니,

readelf -d libc-2.11.3.so | grep SONAME

명령으로 SONAME 이 맞는지 확인해 보십시오. 파일 이름을 libc.so.6 으로 하는 것은 효과가 없습니다. SONAME을 맞추기 위해서는 rebuild 가 필요 합니다. 현 상황에서는 busybox를 변경 하든지 glibc를 변경 하든지 해야 할 듯 싶네요.

lux1075의 이미지

안녕하세요 답변 정말 감사합니다.

정말 감사히도 많은 분들이 포스팅 해놓으신 자료를 보고 하나하나 알아가고 있습니다.
이런 소중한 기회를 삼아서 제대로 이해하고 싶은 심정입니다.

말씀해주신 SONAME에 대해서 알아보니..(https://wiki.kldp.org/HOWTO/html/Program-Library/Program-Library-HOWTO-3.html)

모든 공유 라이브러리는 "soname"이라 불리는 특별한 이름을 가지고 있다. "soname"은 접두어 "lib", 라이브러리 이름, ".so"라는 문구, 그 다음 마침표와 인터페이스 변경시 증가되는 버전 넘버로 구성된다. ( 예외로 가장 저수준의 C라이브러리들은 "lib"로 시작되지 않는다) 완전한 공식적 "soname"에는 라이 브러리가 속한 디렉토리명이 앞부분에 들어간다. 운용중인 시스템에서는 완전 한 공식적 "soname" 이란 공유라이브러리의 실제 이름("real name")에 대한 심볼릭 링크(실제 코드를 담고있는 파일이 아닌)가 될 것이다.

"libc.so.6 → libc-2.11.3.so*" 의 경우, libc.so.6이 SONAME, libc-2.11.3.so 가 REAL-NAME 이라는 걸로 이해했습니다.

또한 libc-2.11.3.so 파일의 dynamic section에 대해 확인해 봤습니다.

/opt/arm-none-linux-gnueabi$ arm-none-linux-gnueabi-readelf -d lib/libc-2.11.3.so | grep SONAME
 0x0000000e (SONAME)                     Library soname: [libc.so.6]

위 결과로 봐서 SONAME은 libc.so.6 으로 맞게 설정된것 같습니다.

그 다음,

"SONAME을 맞추기 위해서는 rebuild 가 필요 합니다. 현 상황에서는 busybox를 변경 하든지 glibc를 변경 하든지 해야 할 듯 싶네요."

라고 하셨는데, 이 부분은 잘 이해가 가질 않았습니다. "SONAME을 맞추기 위해서는..." 이란 말씀은 libc-2.11.3.so의 SONAME이 잘못된 것이니, 바로 맞춰야 합니다... 라는 의미로 이해가 됩니다만,

그렇다면 readelf의 SONAME 결과가 잘못된 것인가요?? (잘못된 것이라면) 어떤 SONAME이 올바른 것인지요??
readelf의 SONAME 이 올바른 것이라면 이 다음부터 어떤 부분으로 확인을 거쳐야 하는지 알고 싶습니다.

김정균의 이미지

libc-2.11.3.so 의 SONAME이 libc.so.6 이 맞다면 rebuild issue는 생각하지 않아도 됩니다. 다를 경우 SONAME을 맞추기 위해 rebuild를 해야 한다는 것이고요.

그렇다면 이 경우는, 기본으로 읽어들이는 library path가 문제라는 얘기 같은데요.

실제로 빌드를 해서 실행을 했을 경우, /opt/arm-none-linux-gnueabi 경로가 / 가 되는 것이 맞는지요? SONAME이 동일하다면 결국에는 library path의 위치가 틀렸다는 걸로 보이네요.

embeded 는 제가 해 본 적이 없어 더 이상 조언이 힘드네요 :(

bushi의 이미지

추정하지 말고 직접 확인해보세요.

busybox 를 static link 빌드해서 집어넣어 타겟 보드를 부팅시켜 놓고,
dynamic link 로 빌드된 다른 실험용 실행파일을 가지고 뭐가 잘못됐는지 알아보세요.

gcc specs 에서 바꿀 수 있습니다.
예전엔 외부 파일에 기록해서 참조시키는게 default 였는데, 지금은 built-in 이 default 가 되도록 바뀌었나보네요...
default dynamic linker(loader) 가 잘못 기록된다면, 툴체인을 잘 못 만들었다는 뜻입니다. prefix 와 install path 는 다른 개념인데 이 둘을 같은 것으로 착각하시고 뭔가를 하신 것 같네요.

[schoi0@SEL-SCHOI0-D2 vm]$ gcc -o v vm_test.c
[schoi0@SEL-SCHOI0-D2 vm]$ readelf -l v | grep interpreter
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
[schoi0@SEL-SCHOI0-D2 vm]$ 
[schoi0@SEL-SCHOI0-D2 vm]$ gcc -o v vm_test.c -Wl,-dynamic-linker=/some/where/blah
[schoi0@SEL-SCHOI0-D2 vm]$ readelf -l v | grep interpreter
      [Requesting program interpreter: /some/where/blah]
[schoi0@SEL-SCHOI0-D2 vm]$ ./v
bash: ./v: /some/where/blah: bad ELF interpreter: 그런 파일이나 디렉터리가 없습니다

[schoi0@SEL-SCHOI0-D2 vm]$ gcc -v 2>&1| grep specs
Using built-in specs.
 
[schoi0@SEL-SCHOI0-D2 vm]$ gcc -dumpspecs | grep ld-linux
%{!r:--build-id} --no-add-needed %{!static:--eh-frame-hdr} --hash-style=gnu %{!mandroid|tno-android-ld:%{m16|m32|mx32:;:-m elf_x86_64}                    %{m16|m32:-m elf_i386}                    %{mx32:-m elf32_x86_64}   %{shared:-shared}   %{!shared:     %{!static:       %{rdynamic:-export-dynamic}       %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-i386.so.1;:/lib/ld-linux.so.2}}}}       %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:%{mmusl:/lib/ld-musl-x86_64.so.1;:/lib64/ld-linux-x86-64.so.2}}}}       %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:%{mmusl:/lib/ld-musl-x32.so.1;:/libx32/ld-linux-x32.so.2}}}}}     %{static:-static}};:%{m16|m32|mx32:;:-m elf_x86_64}                    %{m16|m32:-m elf_i386}                    %{mx32:-m elf32_x86_64}   %{shared:-shared}   %{!shared:     %{!static:       %{rdynamic:-export-dynamic}       %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-i386.so.1;:/lib/ld-linux.so.2}}}}       %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:%{mmusl:/lib/ld-musl-x86_64.so.1;:/lib64/ld-linux-x86-64.so.2}}}}       %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:%{mmusl:/lib/ld-musl-x32.so.1;:/libx32/ld-linux-x32.so.2}}}}}     %{static:-static}} %{shared: -Bsymbolic}}
[schoi0@SEL-SCHOI0-D2 vm]$ 
[schoi0@SEL-SCHOI0-D2 vm]$ gcc -o v vm_test.c -mbionic
[schoi0@SEL-SCHOI0-D2 vm]$ readelf -l v | grep interpreter
      [Requesting program interpreter: /system/bin/linker64]
[schoi0@SEL-SCHOI0-D2 vm]$ 
[schoi0@SEL-SCHOI0-D2 vm]$ ./v
bash: ./v: /system/bin/linker64: bad ELF interpreter: 그런 파일이나 디렉터리가 없습니다

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.