1Upstream-Status: Inappropriate [embedded specific] 2 3We run the ldconfig in the cross fashion. make the code bitsize aware so that 4we can cross build ldconfig cache for various architectures. 5 6Richard Purdie <richard.purdie@linuxfoundation.org> 2009/05/19 7Nitin A Kamble <nitin.a.kamble@intel.com> 2009/03/29 8 9Index: ldconfig-native-2.12.1/readelflib.c 10=================================================================== 11--- ldconfig-native-2.12.1.orig/readelflib.c 12+++ ldconfig-native-2.12.1/readelflib.c 13@@ -40,39 +40,212 @@ do \ 14 15 /* Returns 0 if everything is ok, != 0 in case of error. */ 16 int 17-process_elf_file (const char *file_name, const char *lib, int *flag, 18+process_elf_file32 (const char *file_name, const char *lib, int *flag, 19 unsigned int *osversion, char **soname, void *file_contents, 20 size_t file_length) 21 { 22 int i; 23 unsigned int j; 24- ElfW(Addr) loadaddr; 25+ Elf32_Addr loadaddr; 26 unsigned int dynamic_addr; 27 size_t dynamic_size; 28 char *program_interpreter; 29 30- ElfW(Ehdr) *elf_header; 31- ElfW(Phdr) *elf_pheader, *segment; 32- ElfW(Dyn) *dynamic_segment, *dyn_entry; 33+ Elf32_Ehdr *elf_header; 34+ Elf32_Phdr *elf_pheader, *segment; 35+ Elf32_Dyn *dynamic_segment, *dyn_entry; 36 char *dynamic_strings; 37 38- elf_header = (ElfW(Ehdr) *) file_contents; 39+ elf_header = (Elf32_Ehdr *) file_contents; 40 *osversion = 0; 41 42- if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS)) 43+ if (elf_header->e_type != ET_DYN) 44 { 45- if (opt_verbose) 46+ error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name, 47+ elf_header->e_type); 48+ return 1; 49+ } 50+ 51+ /* Get information from elf program header. */ 52+ elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents); 53+ check_ptr (elf_pheader); 54+ 55+ /* The library is an elf library, now search for soname and 56+ libc5/libc6. */ 57+ *flag = FLAG_ELF; 58+ 59+ loadaddr = -1; 60+ dynamic_addr = 0; 61+ dynamic_size = 0; 62+ program_interpreter = NULL; 63+ for (i = 0, segment = elf_pheader; 64+ i < elf_header->e_phnum; i++, segment++) 65+ { 66+ check_ptr (segment); 67+ 68+ switch (segment->p_type) 69 { 70- if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) 71- error (0, 0, _("%s is a 32 bit ELF file.\n"), file_name); 72- else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64) 73- error (0, 0, _("%s is a 64 bit ELF file.\n"), file_name); 74- else 75- error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name); 76+ case PT_LOAD: 77+ if (loadaddr == (Elf32_Addr) -1) 78+ loadaddr = segment->p_vaddr - segment->p_offset; 79+ break; 80+ 81+ case PT_DYNAMIC: 82+ if (dynamic_addr) 83+ error (0, 0, _("more than one dynamic segment\n")); 84+ 85+ dynamic_addr = segment->p_offset; 86+ dynamic_size = segment->p_filesz; 87+ break; 88+ 89+ case PT_INTERP: 90+ program_interpreter = (char *) (file_contents + segment->p_offset); 91+ check_ptr (program_interpreter); 92+ 93+ /* Check if this is enough to classify the binary. */ 94+ for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]); 95+ ++j) 96+ if (strcmp (program_interpreter, interpreters[j].soname) == 0) 97+ { 98+ *flag = interpreters[j].flag; 99+ break; 100+ } 101+ break; 102+ 103+ case PT_NOTE: 104+ if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4) 105+ { 106+ Elf32_Word *abi_note = (Elf32_Word *) (file_contents 107+ + segment->p_offset); 108+ Elf32_Addr size = segment->p_filesz; 109+ 110+ while (abi_note [0] != 4 || abi_note [1] != 16 111+ || abi_note [2] != 1 112+ || memcmp (abi_note + 3, "GNU", 4) != 0) 113+ { 114+#define ROUND(len) (((len) + sizeof (Elf32_Word)) - 1) & -sizeof (Elf32_Word))) 115+ Elf32_Addr) note_size = 3 * sizeof (Elf32_Word)) 116+ + ROUND (abi_note[0]) 117+ + ROUND (abi_note[1]); 118+ 119+ if (size - 32 < note_size || note_size == 0) 120+ { 121+ size = 0; 122+ break; 123+ } 124+ size -= note_size; 125+ abi_note = (void *) abi_note + note_size; 126+ } 127+ 128+ if (size == 0) 129+ break; 130+ 131+ *osversion = (abi_note [4] << 24) | 132+ ((abi_note [5] & 0xff) << 16) | 133+ ((abi_note [6] & 0xff) << 8) | 134+ (abi_note [7] & 0xff); 135+ } 136+ break; 137+ 138+ default: 139+ break; 140+ } 141+ 142+ } 143+ if (loadaddr == (Elf32_Addr) -1) 144+ { 145+ /* Very strange. */ 146+ loadaddr = 0; 147+ } 148+ 149+ /* Now we can read the dynamic sections. */ 150+ if (dynamic_size == 0) 151+ return 1; 152+ 153+ dynamic_segment = (Elf32_Dyn *) (file_contents + dynamic_addr); 154+ check_ptr (dynamic_segment); 155+ 156+ /* Find the string table. */ 157+ dynamic_strings = NULL; 158+ for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 159+ ++dyn_entry) 160+ { 161+ check_ptr (dyn_entry); 162+ if (dyn_entry->d_tag == DT_STRTAB) 163+ { 164+ dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); 165+ check_ptr (dynamic_strings); 166+ break; 167 } 168- return 1; 169 } 170 171+ if (dynamic_strings == NULL) 172+ return 1; 173+ 174+ /* Now read the DT_NEEDED and DT_SONAME entries. */ 175+ for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 176+ ++dyn_entry) 177+ { 178+ if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME) 179+ { 180+ char *name = dynamic_strings + dyn_entry->d_un.d_val; 181+ check_ptr (name); 182+ 183+ if (dyn_entry->d_tag == DT_NEEDED) 184+ { 185+ 186+ if (*flag == FLAG_ELF) 187+ { 188+ /* Check if this is enough to classify the binary. */ 189+ for (j = 0; 190+ j < sizeof (known_libs) / sizeof (known_libs [0]); 191+ ++j) 192+ if (strcmp (name, known_libs [j].soname) == 0) 193+ { 194+ *flag = known_libs [j].flag; 195+ break; 196+ } 197+ } 198+ } 199+ 200+ else if (dyn_entry->d_tag == DT_SONAME) 201+ *soname = xstrdup (name); 202+ 203+ /* Do we have everything we need? */ 204+ if (*soname && *flag != FLAG_ELF) 205+ return 0; 206+ } 207+ } 208+ 209+ /* We reach this point only if the file doesn't contain a DT_SONAME 210+ or if we can't classify the library. If it doesn't have a 211+ soname, return the name of the library. */ 212+ if (*soname == NULL) 213+ *soname = xstrdup (lib); 214+ 215+ return 0; 216+} 217+ 218+int 219+process_elf_file64 (const char *file_name, const char *lib, int *flag, 220+ unsigned int *osversion, char **soname, void *file_contents, 221+ size_t file_length) 222+{ 223+ int i; 224+ unsigned int j; 225+ Elf64_Addr loadaddr; 226+ unsigned int dynamic_addr; 227+ size_t dynamic_size; 228+ char *program_interpreter; 229+ 230+ Elf64_Ehdr *elf_header; 231+ Elf64_Phdr *elf_pheader, *segment; 232+ Elf64_Dyn *dynamic_segment, *dyn_entry; 233+ char *dynamic_strings; 234+ 235+ elf_header = (Elf64_Ehdr *) file_contents; 236+ *osversion = 0; 237+ 238 if (elf_header->e_type != ET_DYN) 239 { 240 error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name, 241@@ -81,7 +254,7 @@ process_elf_file (const char *file_name, 242 } 243 244 /* Get information from elf program header. */ 245- elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents); 246+ elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents); 247 check_ptr (elf_pheader); 248 249 /* The library is an elf library, now search for soname and 250@@ -100,7 +273,7 @@ process_elf_file (const char *file_name, 251 switch (segment->p_type) 252 { 253 case PT_LOAD: 254- if (loadaddr == (ElfW(Addr)) -1) 255+ if (loadaddr == (Elf64_Addr) -1) 256 loadaddr = segment->p_vaddr - segment->p_offset; 257 break; 258 259@@ -129,16 +302,16 @@ process_elf_file (const char *file_name, 260 case PT_NOTE: 261 if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4) 262 { 263- ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents 264+ Elf64_Word *abi_note = (Elf64_Word *) (file_contents 265 + segment->p_offset); 266- ElfW(Addr) size = segment->p_filesz; 267+ Elf64_Addr size = segment->p_filesz; 268 269 while (abi_note [0] != 4 || abi_note [1] != 16 270 || abi_note [2] != 1 271 || memcmp (abi_note + 3, "GNU", 4) != 0) 272 { 273-#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) 274- ElfW(Addr) note_size = 3 * sizeof (ElfW(Word)) 275+#define ROUND(len) (((len) + sizeof (Elf64_Word) - 1) & -sizeof (Elf64_Word)) 276+ Elf64_Addr note_size = 3 * sizeof (Elf64_Word) 277 + ROUND (abi_note[0]) 278 + ROUND (abi_note[1]); 279 280@@ -166,7 +339,7 @@ process_elf_file (const char *file_name, 281 } 282 283 } 284- if (loadaddr == (ElfW(Addr)) -1) 285+ if (loadaddr == (Elf64_Addr) -1) 286 { 287 /* Very strange. */ 288 loadaddr = 0; 289@@ -176,7 +349,7 @@ process_elf_file (const char *file_name, 290 if (dynamic_size == 0) 291 return 1; 292 293- dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr); 294+ dynamic_segment = (Elf64_Dyn *) (file_contents + dynamic_addr); 295 check_ptr (dynamic_segment); 296 297 /* Find the string table. */ 298@@ -233,3 +406,33 @@ process_elf_file (const char *file_name, 299 300 return 0; 301 } 302+/* Returns 0 if everything is ok, != 0 in case of error. */ 303+int 304+process_elf_file (const char *file_name, const char *lib, int *flag, 305+ unsigned int *osversion, char **soname, void *file_contents, 306+ size_t file_length) 307+{ 308+ int i; 309+ unsigned int j; 310+ ElfW(Addr) loadaddr; 311+ unsigned int dynamic_addr; 312+ size_t dynamic_size; 313+ char *program_interpreter; 314+ 315+ ElfW(Ehdr) *elf_header; 316+ ElfW(Phdr) *elf_pheader, *segment; 317+ ElfW(Dyn) *dynamic_segment, *dyn_entry; 318+ char *dynamic_strings; 319+ 320+ elf_header = (ElfW(Ehdr) *) file_contents; 321+ *osversion = 0; 322+ 323+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) 324+ return process_elf_file32(file_name, lib,flag, osversion, soname, file_contents, file_length); 325+ else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64) 326+ return process_elf_file64(file_name, lib,flag, osversion, soname, file_contents, file_length); 327+ error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name); 328+ return 1; 329+} 330+ 331+ 332