summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2009-05-19 15:55:55 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2009-05-19 15:55:55 +0100
commitb15cfd5cbfa796f26e8e7ec6216cbba449aa1885 (patch)
treedb0d05d2dc69dc45039e065299caba977c5ec9fe
parenta811131e69de69b2bd57cf1f637b28b507ef1e2a (diff)
downloadpoky-b15cfd5cbfa796f26e8e7ec6216cbba449aa1885.tar.gz
ldconfig-native: Make it work for 32 bit targets from 64 bit build machines
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
-rw-r--r--meta/packages/glibc/ldconfig-native-2.5/32and64bit.patch289
-rw-r--r--meta/packages/glibc/ldconfig-native_2.5.bb5
2 files changed, 293 insertions, 1 deletions
diff --git a/meta/packages/glibc/ldconfig-native-2.5/32and64bit.patch b/meta/packages/glibc/ldconfig-native-2.5/32and64bit.patch
new file mode 100644
index 0000000000..4f8d3a39ca
--- /dev/null
+++ b/meta/packages/glibc/ldconfig-native-2.5/32and64bit.patch
@@ -0,0 +1,289 @@
1Index: ldconfig-native-2.5/readelflib.c
2===================================================================
3--- ldconfig-native-2.5.orig/readelflib.c 2009-05-19 09:40:17.000000000 +0100
4+++ ldconfig-native-2.5/readelflib.c 2009-05-19 09:56:18.000000000 +0100
5@@ -40,38 +40,190 @@
6
7 /* Returns 0 if everything is ok, != 0 in case of error. */
8 int
9-process_elf_file (const char *file_name, const char *lib, int *flag,
10+process_elf_file32 (const char *file_name, const char *lib, int *flag,
11 unsigned int *osversion, char **soname, void *file_contents,
12 size_t file_length)
13 {
14 int i;
15 unsigned int j;
16- ElfW(Addr) loadaddr;
17+ Elf32_Addr loadaddr;
18 unsigned int dynamic_addr;
19 size_t dynamic_size;
20 char *program_interpreter;
21
22- ElfW(Ehdr) *elf_header;
23- ElfW(Phdr) *elf_pheader, *segment;
24- ElfW(Dyn) *dynamic_segment, *dyn_entry;
25+ Elf32_Ehdr *elf_header;
26+ Elf32_Phdr *elf_pheader, *segment;
27+ Elf32_Dyn *dynamic_segment, *dyn_entry;
28 char *dynamic_strings;
29
30- elf_header = (ElfW(Ehdr) *) file_contents;
31+ elf_header = (Elf32_Ehdr *) file_contents;
32 *osversion = 0;
33
34- if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS))
35+ if (elf_header->e_type != ET_DYN)
36+ {
37+ error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
38+ elf_header->e_type);
39+ return 1;
40+ }
41+
42+ /* Get information from elf program header. */
43+ elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents);
44+ check_ptr (elf_pheader);
45+
46+ /* The library is an elf library, now search for soname and
47+ libc5/libc6. */
48+ *flag = FLAG_ELF;
49+
50+ loadaddr = -1;
51+ dynamic_addr = 0;
52+ dynamic_size = 0;
53+ program_interpreter = NULL;
54+ for (i = 0, segment = elf_pheader;
55+ i < elf_header->e_phnum; i++, segment++)
56 {
57- if (opt_verbose)
58+ check_ptr (segment);
59+
60+ switch (segment->p_type)
61 {
62- if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
63- error (0, 0, _("%s is a 32 bit ELF file.\n"), file_name);
64- else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
65- error (0, 0, _("%s is a 64 bit ELF file.\n"), file_name);
66- else
67- error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
68+ case PT_LOAD:
69+ if (loadaddr == (Elf32_Addr) -1)
70+ loadaddr = segment->p_vaddr - segment->p_offset;
71+ break;
72+
73+ case PT_DYNAMIC:
74+ if (dynamic_addr)
75+ error (0, 0, _("more than one dynamic segment\n"));
76+
77+ dynamic_addr = segment->p_offset;
78+ dynamic_size = segment->p_filesz;
79+ break;
80+
81+ case PT_INTERP:
82+ program_interpreter = (char *) (file_contents + segment->p_offset);
83+ check_ptr (program_interpreter);
84+
85+ /* Check if this is enough to classify the binary. */
86+ for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]);
87+ ++j)
88+ if (strcmp (program_interpreter, interpreters[j].soname) == 0)
89+ {
90+ *flag = interpreters[j].flag;
91+ break;
92+ }
93+ break;
94+
95+ case PT_NOTE:
96+ if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
97+ {
98+ Elf32_Word *abi_note = (Elf32_Word *) (file_contents
99+ + segment->p_offset);
100+ if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
101+ && memcmp (abi_note + 3, "GNU", 4) == 0)
102+ *osversion = (abi_note [4] << 24) |
103+ ((abi_note [5] & 0xff) << 16) |
104+ ((abi_note [6] & 0xff) << 8) |
105+ (abi_note [7] & 0xff);
106+ }
107+ break;
108+
109+ default:
110+ break;
111 }
112- return 1;
113+
114 }
115+ if (loadaddr == (Elf32_Addr) -1)
116+ {
117+ /* Very strange. */
118+ loadaddr = 0;
119+ }
120+
121+ /* Now we can read the dynamic sections. */
122+ if (dynamic_size == 0)
123+ return 1;
124+
125+ dynamic_segment = (Elf32_Dyn *) (file_contents + dynamic_addr);
126+ check_ptr (dynamic_segment);
127+
128+ /* Find the string table. */
129+ dynamic_strings = NULL;
130+ for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
131+ ++dyn_entry)
132+ {
133+ check_ptr (dyn_entry);
134+ if (dyn_entry->d_tag == DT_STRTAB)
135+ {
136+ dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
137+ check_ptr (dynamic_strings);
138+ break;
139+ }
140+ }
141+
142+ if (dynamic_strings == NULL)
143+ return 1;
144+
145+ /* Now read the DT_NEEDED and DT_SONAME entries. */
146+ for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
147+ ++dyn_entry)
148+ {
149+ if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
150+ {
151+ char *name = dynamic_strings + dyn_entry->d_un.d_val;
152+ check_ptr (name);
153+
154+ if (dyn_entry->d_tag == DT_NEEDED)
155+ {
156+
157+ if (*flag == FLAG_ELF)
158+ {
159+ /* Check if this is enough to classify the binary. */
160+ for (j = 0;
161+ j < sizeof (known_libs) / sizeof (known_libs [0]);
162+ ++j)
163+ if (strcmp (name, known_libs [j].soname) == 0)
164+ {
165+ *flag = known_libs [j].flag;
166+ break;
167+ }
168+ }
169+ }
170+
171+ else if (dyn_entry->d_tag == DT_SONAME)
172+ *soname = xstrdup (name);
173+
174+ /* Do we have everything we need? */
175+ if (*soname && *flag != FLAG_ELF)
176+ return 0;
177+ }
178+ }
179+
180+ /* We reach this point only if the file doesn't contain a DT_SONAME
181+ or if we can't classify the library. If it doesn't have a
182+ soname, return the name of the library. */
183+ if (*soname == NULL)
184+ *soname = xstrdup (lib);
185+
186+ return 0;
187+}
188+
189+int
190+process_elf_file64 (const char *file_name, const char *lib, int *flag,
191+ unsigned int *osversion, char **soname, void *file_contents,
192+ size_t file_length)
193+{
194+ int i;
195+ unsigned int j;
196+ Elf64_Addr loadaddr;
197+ unsigned int dynamic_addr;
198+ size_t dynamic_size;
199+ char *program_interpreter;
200+
201+ Elf64_Ehdr *elf_header;
202+ Elf64_Phdr *elf_pheader, *segment;
203+ Elf64_Dyn *dynamic_segment, *dyn_entry;
204+ char *dynamic_strings;
205+
206+ elf_header = (Elf64_Ehdr *) file_contents;
207+ *osversion = 0;
208
209 if (elf_header->e_type != ET_DYN)
210 {
211@@ -81,7 +233,7 @@
212 }
213
214 /* Get information from elf program header. */
215- elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents);
216+ elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents);
217 check_ptr (elf_pheader);
218
219 /* The library is an elf library, now search for soname and
220@@ -100,7 +252,7 @@
221 switch (segment->p_type)
222 {
223 case PT_LOAD:
224- if (loadaddr == (ElfW(Addr)) -1)
225+ if (loadaddr == (Elf64_Addr) -1)
226 loadaddr = segment->p_vaddr - segment->p_offset;
227 break;
228
229@@ -129,7 +281,7 @@
230 case PT_NOTE:
231 if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
232 {
233- ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
234+ Elf64_Word *abi_note = (Elf64_Word *) (file_contents
235 + segment->p_offset);
236 if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
237 && memcmp (abi_note + 3, "GNU", 4) == 0)
238@@ -145,7 +297,7 @@
239 }
240
241 }
242- if (loadaddr == (ElfW(Addr)) -1)
243+ if (loadaddr == (Elf64_Addr) -1)
244 {
245 /* Very strange. */
246 loadaddr = 0;
247@@ -155,7 +307,7 @@
248 if (dynamic_size == 0)
249 return 1;
250
251- dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
252+ dynamic_segment = (Elf64_Dyn *) (file_contents + dynamic_addr);
253 check_ptr (dynamic_segment);
254
255 /* Find the string table. */
256@@ -218,3 +370,33 @@
257
258 return 0;
259 }
260+/* Returns 0 if everything is ok, != 0 in case of error. */
261+int
262+process_elf_file (const char *file_name, const char *lib, int *flag,
263+ unsigned int *osversion, char **soname, void *file_contents,
264+ size_t file_length)
265+{
266+ int i;
267+ unsigned int j;
268+ ElfW(Addr) loadaddr;
269+ unsigned int dynamic_addr;
270+ size_t dynamic_size;
271+ char *program_interpreter;
272+
273+ ElfW(Ehdr) *elf_header;
274+ ElfW(Phdr) *elf_pheader, *segment;
275+ ElfW(Dyn) *dynamic_segment, *dyn_entry;
276+ char *dynamic_strings;
277+
278+ elf_header = (ElfW(Ehdr) *) file_contents;
279+ *osversion = 0;
280+
281+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
282+ return process_elf_file32(file_name, lib,flag, osversion, soname, file_contents, file_length);
283+ else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
284+ return process_elf_file64(file_name, lib,flag, osversion, soname, file_contents, file_length);
285+ error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
286+ return 1;
287+}
288+
289+
diff --git a/meta/packages/glibc/ldconfig-native_2.5.bb b/meta/packages/glibc/ldconfig-native_2.5.bb
index 1cd691e7bf..bdd41dc55f 100644
--- a/meta/packages/glibc/ldconfig-native_2.5.bb
+++ b/meta/packages/glibc/ldconfig-native_2.5.bb
@@ -1,7 +1,10 @@
1DESCRIPTION = "A standalone native ldconfig build" 1DESCRIPTION = "A standalone native ldconfig build"
2 2
3SRC_URI = "file://ldconfig-native-2.5.tar.bz2 \ 3SRC_URI = "file://ldconfig-native-2.5.tar.bz2 \
4 file://ldconfig.patch;patch=1 " 4 file://ldconfig.patch;patch=1 \
5 file://32and64bit.patch;patch=1"
6
7PR = "r1"
5 8
6inherit native 9inherit native
7 10