1Upstream-Status: Inappropriate [embedded specific] 2 3Do data input/output handling according to endien-ness of the library file. That 4enables use of ldconfig in the cross fashion for any architecture. 5 62011/04/04 7Richard Purdie <richard.purdie@linuxfoundation.org> 8Nitin Kamble <nitin.a.kamble@intel.com> 9 10Index: ldconfig-native-2.12.1/readelflib.c 11=================================================================== 12--- ldconfig-native-2.12.1.orig/readelflib.c 13+++ ldconfig-native-2.12.1/readelflib.c 14@@ -38,6 +38,28 @@ do \ 15 } \ 16 while (0); 17 18+int be; 19+static uint16_t read16(uint16_t x, int be) 20+{ 21+ if (be) 22+ return be16toh(x); 23+ return le16toh(x); 24+} 25+ 26+static uint32_t read32(uint32_t x, int be) 27+{ 28+ if (be) 29+ return be32toh(x); 30+ return le32toh(x); 31+} 32+ 33+static uint64_t read64(uint64_t x, int be) 34+{ 35+ if (be) 36+ return be64toh(x); 37+ return le64toh(x); 38+} 39+ 40 /* Returns 0 if everything is ok, != 0 in case of error. */ 41 int 42 process_elf_file32 (const char *file_name, const char *lib, int *flag, 43@@ -59,15 +81,17 @@ process_elf_file32 (const char *file_nam 44 elf_header = (Elf32_Ehdr *) file_contents; 45 *osversion = 0; 46 47- if (elf_header->e_type != ET_DYN) 48+ be = (elf_header->e_ident[EI_DATA] == ELFDATA2MSB); 49+ 50+ if (read16(elf_header->e_type, be) != ET_DYN) 51 { 52 error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name, 53- elf_header->e_type); 54+ read16(elf_header->e_type, be)); 55 return 1; 56 } 57 58 /* Get information from elf program header. */ 59- elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents); 60+ elf_pheader = (Elf32_Phdr *) (read32(elf_header->e_phoff, be) + file_contents); 61 check_ptr (elf_pheader); 62 63 /* The library is an elf library, now search for soname and 64@@ -79,27 +103,27 @@ process_elf_file32 (const char *file_nam 65 dynamic_size = 0; 66 program_interpreter = NULL; 67 for (i = 0, segment = elf_pheader; 68- i < elf_header->e_phnum; i++, segment++) 69+ i < read16(elf_header->e_phnum, be); i++, segment++) 70 { 71 check_ptr (segment); 72 73- switch (segment->p_type) 74+ switch (read32(segment->p_type, be)) 75 { 76 case PT_LOAD: 77 if (loadaddr == (Elf32_Addr) -1) 78- loadaddr = segment->p_vaddr - segment->p_offset; 79+ loadaddr = read32(segment->p_vaddr, be) - read32(segment->p_offset, be); 80 break; 81 82 case PT_DYNAMIC: 83 if (dynamic_addr) 84 error (0, 0, _("more than one dynamic segment\n")); 85 86- dynamic_addr = segment->p_offset; 87- dynamic_size = segment->p_filesz; 88+ dynamic_addr = read32(segment->p_offset, be); 89+ dynamic_size = read32(segment->p_filesz, be); 90 break; 91 92 case PT_INTERP: 93- program_interpreter = (char *) (file_contents + segment->p_offset); 94+ program_interpreter = (char *) (file_contents + read32(segment->p_offset, be)); 95 check_ptr (program_interpreter); 96 97 /* Check if this is enough to classify the binary. */ 98@@ -113,20 +137,20 @@ process_elf_file32 (const char *file_nam 99 break; 100 101 case PT_NOTE: 102- if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4) 103+ if (!*osversion && read32(segment->p_filesz, be) >= 32 && segment->p_align >= 4) 104 { 105 Elf32_Word *abi_note = (Elf32_Word *) (file_contents 106- + segment->p_offset); 107- Elf32_Addr size = segment->p_filesz; 108+ + read32(segment->p_offset, be)); 109+ Elf32_Addr size = read32(segment->p_filesz, be); 110 111- while (abi_note [0] != 4 || abi_note [1] != 16 112- || abi_note [2] != 1 113+ while (read32(abi_note [0], be) != 4 || read32(abi_note [1], be) != 16 114+ || read32(abi_note [2], be) != 1 115 || memcmp (abi_note + 3, "GNU", 4) != 0) 116 { 117-#define ROUND(len) (((len) + sizeof (Elf32_Word)) - 1) & -sizeof (Elf32_Word))) 118- Elf32_Addr) note_size = 3 * sizeof (Elf32_Word)) 119- + ROUND (abi_note[0]) 120- + ROUND (abi_note[1]); 121+#define ROUND(len) (((len) + sizeof (Elf32_Word) - 1) & -sizeof (Elf32_Word)) 122+ Elf32_Addr note_size = 3 * sizeof (Elf32_Word) 123+ + ROUND (read32(abi_note[0], be)) 124+ + ROUND (read32(abi_note[1], be)); 125 126 if (size - 32 < note_size || note_size == 0) 127 { 128@@ -140,10 +164,10 @@ process_elf_file32 (const char *file_nam 129 if (size == 0) 130 break; 131 132- *osversion = (abi_note [4] << 24) | 133- ((abi_note [5] & 0xff) << 16) | 134- ((abi_note [6] & 0xff) << 8) | 135- (abi_note [7] & 0xff); 136+ *osversion = (read32(abi_note [4], be) << 24) | 137+ ((read32(abi_note [5], be) & 0xff) << 16) | 138+ ((read32(abi_note [6], be) & 0xff) << 8) | 139+ (read32(abi_note [7], be) & 0xff); 140 } 141 break; 142 143@@ -167,13 +191,13 @@ process_elf_file32 (const char *file_nam 144 145 /* Find the string table. */ 146 dynamic_strings = NULL; 147- for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 148+ for (dyn_entry = dynamic_segment; read32(dyn_entry->d_tag, be) != DT_NULL; 149 ++dyn_entry) 150 { 151 check_ptr (dyn_entry); 152- if (dyn_entry->d_tag == DT_STRTAB) 153+ if (read32(dyn_entry->d_tag, be) == DT_STRTAB) 154 { 155- dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); 156+ dynamic_strings = (char *) (file_contents + read32(dyn_entry->d_un.d_val, be) - loadaddr); 157 check_ptr (dynamic_strings); 158 break; 159 } 160@@ -183,15 +207,15 @@ process_elf_file32 (const char *file_nam 161 return 1; 162 163 /* Now read the DT_NEEDED and DT_SONAME entries. */ 164- for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 165+ for (dyn_entry = dynamic_segment; read32(dyn_entry->d_tag, be) != DT_NULL; 166 ++dyn_entry) 167 { 168- if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME) 169+ if (read32(dyn_entry->d_tag, be) == DT_NEEDED || read32(dyn_entry->d_tag, be) == DT_SONAME) 170 { 171- char *name = dynamic_strings + dyn_entry->d_un.d_val; 172+ char *name = dynamic_strings + read32(dyn_entry->d_un.d_val, be); 173 check_ptr (name); 174 175- if (dyn_entry->d_tag == DT_NEEDED) 176+ if (read32(dyn_entry->d_tag, be) == DT_NEEDED) 177 { 178 179 if (*flag == FLAG_ELF) 180@@ -208,7 +232,7 @@ process_elf_file32 (const char *file_nam 181 } 182 } 183 184- else if (dyn_entry->d_tag == DT_SONAME) 185+ else if (read32(dyn_entry->d_tag, be) == DT_SONAME) 186 *soname = xstrdup (name); 187 188 /* Do we have everything we need? */ 189@@ -246,15 +270,17 @@ process_elf_file64 (const char *file_nam 190 elf_header = (Elf64_Ehdr *) file_contents; 191 *osversion = 0; 192 193- if (elf_header->e_type != ET_DYN) 194+ be = (elf_header->e_ident[EI_DATA] == ELFDATA2MSB); 195+ 196+ if (read16(elf_header->e_type, be) != ET_DYN) 197 { 198 error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name, 199- elf_header->e_type); 200+ read16(elf_header->e_type, be)); 201 return 1; 202 } 203 204 /* Get information from elf program header. */ 205- elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents); 206+ elf_pheader = (Elf64_Phdr *) (read64(elf_header->e_phoff, be) + file_contents); 207 check_ptr (elf_pheader); 208 209 /* The library is an elf library, now search for soname and 210@@ -266,27 +292,27 @@ process_elf_file64 (const char *file_nam 211 dynamic_size = 0; 212 program_interpreter = NULL; 213 for (i = 0, segment = elf_pheader; 214- i < elf_header->e_phnum; i++, segment++) 215+ i < read16(elf_header->e_phnum, be); i++, segment++) 216 { 217 check_ptr (segment); 218 219- switch (segment->p_type) 220+ switch (read32(segment->p_type, be)) 221 { 222 case PT_LOAD: 223 if (loadaddr == (Elf64_Addr) -1) 224- loadaddr = segment->p_vaddr - segment->p_offset; 225+ loadaddr = read64(segment->p_vaddr, be) - read64(segment->p_offset, be); 226 break; 227 228 case PT_DYNAMIC: 229 if (dynamic_addr) 230 error (0, 0, _("more than one dynamic segment\n")); 231 232- dynamic_addr = segment->p_offset; 233- dynamic_size = segment->p_filesz; 234+ dynamic_addr = read64(segment->p_offset, be); 235+ dynamic_size = read32(segment->p_filesz, be); 236 break; 237 238 case PT_INTERP: 239- program_interpreter = (char *) (file_contents + segment->p_offset); 240+ program_interpreter = (char *) (file_contents + read64(segment->p_offset, be)); 241 check_ptr (program_interpreter); 242 243 /* Check if this is enough to classify the binary. */ 244@@ -300,20 +326,21 @@ process_elf_file64 (const char *file_nam 245 break; 246 247 case PT_NOTE: 248- if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4) 249+ if (!*osversion && read32(segment->p_filesz, be) >= 32 && read32(segment->p_align, be) >= 4) 250 { 251 Elf64_Word *abi_note = (Elf64_Word *) (file_contents 252- + segment->p_offset); 253- Elf64_Addr size = segment->p_filesz; 254+ + read64(segment->p_offset, be)); 255+ Elf64_Addr size = read32(segment->p_filesz, be); 256 257- while (abi_note [0] != 4 || abi_note [1] != 16 258- || abi_note [2] != 1 259+ while (read32(abi_note [0], be) != 4 || read32(abi_note [1], be) != 16 260+ || read32(abi_note [2], be) != 1 261 || memcmp (abi_note + 3, "GNU", 4) != 0) 262 { 263+#undef ROUND 264 #define ROUND(len) (((len) + sizeof (Elf64_Word) - 1) & -sizeof (Elf64_Word)) 265 Elf64_Addr note_size = 3 * sizeof (Elf64_Word) 266- + ROUND (abi_note[0]) 267- + ROUND (abi_note[1]); 268+ + ROUND (read32(abi_note[0], be)) 269+ + ROUND (read32(abi_note[1], be)); 270 271 if (size - 32 < note_size || note_size == 0) 272 { 273@@ -327,10 +354,10 @@ process_elf_file64 (const char *file_nam 274 if (size == 0) 275 break; 276 277- *osversion = (abi_note [4] << 24) | 278- ((abi_note [5] & 0xff) << 16) | 279- ((abi_note [6] & 0xff) << 8) | 280- (abi_note [7] & 0xff); 281+ *osversion = (read32(abi_note [4], be) << 24) | 282+ ((read32(abi_note [5], be) & 0xff) << 16) | 283+ ((read32(abi_note [6], be) & 0xff) << 8) | 284+ (read32(abi_note [7], be) & 0xff); 285 } 286 break; 287 288@@ -354,13 +381,13 @@ process_elf_file64 (const char *file_nam 289 290 /* Find the string table. */ 291 dynamic_strings = NULL; 292- for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 293+ for (dyn_entry = dynamic_segment; read64(dyn_entry->d_tag, be) != DT_NULL; 294 ++dyn_entry) 295 { 296 check_ptr (dyn_entry); 297- if (dyn_entry->d_tag == DT_STRTAB) 298+ if (read64(dyn_entry->d_tag, be) == DT_STRTAB) 299 { 300- dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); 301+ dynamic_strings = (char *) (file_contents + read64(dyn_entry->d_un.d_val, be) - loadaddr); 302 check_ptr (dynamic_strings); 303 break; 304 } 305@@ -370,15 +397,15 @@ process_elf_file64 (const char *file_nam 306 return 1; 307 308 /* Now read the DT_NEEDED and DT_SONAME entries. */ 309- for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; 310+ for (dyn_entry = dynamic_segment; read64(dyn_entry->d_tag, be) != DT_NULL; 311 ++dyn_entry) 312 { 313- if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME) 314+ if (read64(dyn_entry->d_tag, be) == DT_NEEDED || read64(dyn_entry->d_tag, be) == DT_SONAME) 315 { 316- char *name = dynamic_strings + dyn_entry->d_un.d_val; 317+ char *name = dynamic_strings + read64(dyn_entry->d_un.d_val, be); 318 check_ptr (name); 319 320- if (dyn_entry->d_tag == DT_NEEDED) 321+ if (read64(dyn_entry->d_tag, be) == DT_NEEDED) 322 { 323 324 if (*flag == FLAG_ELF) 325@@ -395,7 +422,7 @@ process_elf_file64 (const char *file_nam 326 } 327 } 328 329- else if (dyn_entry->d_tag == DT_SONAME) 330+ else if (read64(dyn_entry->d_tag, be) == DT_SONAME) 331 *soname = xstrdup (name); 332 333 /* Do we have everything we need? */ 334Index: ldconfig-native-2.12.1/readlib.c 335=================================================================== 336--- ldconfig-native-2.12.1.orig/readlib.c 337+++ ldconfig-native-2.12.1/readlib.c 338@@ -169,7 +169,8 @@ process_file (const char *real_file_name 339 ret = 1; 340 } 341 /* Libraries have to be shared object files. */ 342- else if (elf_header->e_type != ET_DYN) 343+ else if ((elf_header->e_ident[EI_DATA] == ELFDATA2MSB && be16toh(elf_header->e_type) != ET_DYN) || 344+ (elf_header->e_ident[EI_DATA] == ELFDATA2LSB && le16toh(elf_header->e_type) != ET_DYN)) 345 ret = 1; 346 else if (process_elf_file (file_name, lib, flag, osversion, soname, 347 file_contents, statbuf.st_size)) 348Index: ldconfig-native-2.12.1/cache.c 349=================================================================== 350--- ldconfig-native-2.12.1.orig/cache.c 351+++ ldconfig-native-2.12.1/cache.c 352@@ -39,6 +39,29 @@ 353 # define N_(msgid) msgid 354 #define _(msg) msg 355 356+extern int be; 357+ 358+static uint16_t write16(uint16_t x, int be) 359+{ 360+ if (be) 361+ return htobe16(x); 362+ return htole16(x); 363+} 364+ 365+static uint32_t write32(uint32_t x, int be) 366+{ 367+ if (be) 368+ return htobe32(x); 369+ return htole32(x); 370+} 371+ 372+static uint64_t write64(uint64_t x, int be) 373+{ 374+ if (be) 375+ return htobe64(x); 376+ return htole64(x); 377+} 378+ 379 struct cache_entry 380 { 381 char *lib; /* Library name. */ 382@@ -279,7 +302,12 @@ save_cache (const char *cache_name) 383 /* Number of normal cache entries. */ 384 int cache_entry_old_count = 0; 385 386- for (entry = entries; entry != NULL; entry = entry->next) 387+ if (be) 388+ printf("saving cache in big endian encoding\n"); 389+ else 390+ printf("saving cache in little endian encoding\n"); 391+ 392+ for (entry = entries; entry != NULL; entry = entry->next) 393 { 394 /* Account the final NULs. */ 395 total_strlen += strlen (entry->lib) + strlen (entry->path) + 2; 396@@ -310,7 +338,7 @@ save_cache (const char *cache_name) 397 memset (file_entries, '\0', sizeof (struct cache_file)); 398 memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1); 399 400- file_entries->nlibs = cache_entry_old_count; 401+ file_entries->nlibs = write32(cache_entry_old_count, be); 402 } 403 404 struct cache_file_new *file_entries_new = NULL; 405@@ -330,8 +358,8 @@ save_cache (const char *cache_name) 406 memcpy (file_entries_new->version, CACHE_VERSION, 407 sizeof CACHE_VERSION - 1); 408 409- file_entries_new->nlibs = cache_entry_count; 410- file_entries_new->len_strings = total_strlen; 411+ file_entries_new->nlibs = write32(cache_entry_count, be); 412+ file_entries_new->len_strings = write32(total_strlen, be); 413 } 414 415 /* Pad for alignment of cache_file_new. */ 416@@ -358,9 +386,9 @@ save_cache (const char *cache_name) 417 /* First the library. */ 418 if (opt_format != 2 && entry->hwcap == 0) 419 { 420- file_entries->libs[idx_old].flags = entry->flags; 421+ file_entries->libs[idx_old].flags = write32(entry->flags, be); 422 /* XXX: Actually we can optimize here and remove duplicates. */ 423- file_entries->libs[idx_old].key = str_offset + pad; 424+ file_entries->libs[idx_old].key = write32(str_offset + pad, be); 425 } 426 if (opt_format != 0) 427 { 428@@ -368,10 +396,10 @@ save_cache (const char *cache_name) 429 not doing so makes the code easier, the string table 430 always begins at the beginning of the the new cache 431 struct. */ 432- file_entries_new->libs[idx_new].flags = entry->flags; 433- file_entries_new->libs[idx_new].osversion = entry->osversion; 434- file_entries_new->libs[idx_new].hwcap = entry->hwcap; 435- file_entries_new->libs[idx_new].key = str_offset; 436+ file_entries_new->libs[idx_new].flags = write32(entry->flags, be); 437+ file_entries_new->libs[idx_new].osversion = write32(entry->osversion, be); 438+ file_entries_new->libs[idx_new].hwcap = write64(entry->hwcap, be); 439+ file_entries_new->libs[idx_new].key = write32(str_offset, be); 440 } 441 442 size_t len = strlen (entry->lib) + 1; 443@@ -379,9 +407,9 @@ save_cache (const char *cache_name) 444 str_offset += len; 445 /* Then the path. */ 446 if (opt_format != 2 && entry->hwcap == 0) 447- file_entries->libs[idx_old].value = str_offset + pad; 448+ file_entries->libs[idx_old].value = write32(str_offset + pad, be); 449 if (opt_format != 0) 450- file_entries_new->libs[idx_new].value = str_offset; 451+ file_entries_new->libs[idx_new].value = write32(str_offset, be); 452 len = strlen (entry->path) + 1; 453 str = mempcpy (str, entry->path, len); 454 str_offset += len; 455