]> code.ossystems Code Review - openembedded-core.git/commitdiff
ldconfig-native: Make it work for 32 bit targets from 64 bit build machines
authorRichard Purdie <rpurdie@linux.intel.com>
Tue, 19 May 2009 14:55:55 +0000 (15:55 +0100)
committerRichard Purdie <rpurdie@linux.intel.com>
Tue, 19 May 2009 14:55:55 +0000 (15:55 +0100)
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
meta/packages/glibc/ldconfig-native-2.5/32and64bit.patch [new file with mode: 0644]
meta/packages/glibc/ldconfig-native_2.5.bb

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 (file)
index 0000000..4f8d3a3
--- /dev/null
@@ -0,0 +1,289 @@
+Index: ldconfig-native-2.5/readelflib.c
+===================================================================
+--- ldconfig-native-2.5.orig/readelflib.c      2009-05-19 09:40:17.000000000 +0100
++++ ldconfig-native-2.5/readelflib.c   2009-05-19 09:56:18.000000000 +0100
+@@ -40,38 +40,190 @@
+ /* Returns 0 if everything is ok, != 0 in case of error.  */
+ int
+-process_elf_file (const char *file_name, const char *lib, int *flag,
++process_elf_file32 (const char *file_name, const char *lib, int *flag,
+                 unsigned int *osversion, char **soname, void *file_contents,
+                 size_t file_length)
+ {
+   int i;
+   unsigned int j;
+-  ElfW(Addr) loadaddr;
++  Elf32_Addr loadaddr;
+   unsigned int dynamic_addr;
+   size_t dynamic_size;
+   char *program_interpreter;
+-  ElfW(Ehdr) *elf_header;
+-  ElfW(Phdr) *elf_pheader, *segment;
+-  ElfW(Dyn) *dynamic_segment, *dyn_entry;
++  Elf32_Ehdr *elf_header;
++  Elf32_Phdr *elf_pheader, *segment;
++  Elf32_Dyn *dynamic_segment, *dyn_entry;
+   char *dynamic_strings;
+-  elf_header = (ElfW(Ehdr) *) file_contents;
++  elf_header = (Elf32_Ehdr *) file_contents;
+   *osversion = 0;
+-  if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS))
++  if (elf_header->e_type != ET_DYN)
++    {
++      error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
++           elf_header->e_type);
++      return 1;
++    }
++
++  /* Get information from elf program header.  */
++  elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents);
++  check_ptr (elf_pheader);
++
++  /* The library is an elf library, now search for soname and
++     libc5/libc6.  */
++  *flag = FLAG_ELF;
++
++  loadaddr = -1;
++  dynamic_addr = 0;
++  dynamic_size = 0;
++  program_interpreter = NULL;
++  for (i = 0, segment = elf_pheader;
++       i < elf_header->e_phnum; i++, segment++)
+     {
+-      if (opt_verbose)
++      check_ptr (segment);
++
++      switch (segment->p_type)
+       {
+-        if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+-          error (0, 0, _("%s is a 32 bit ELF file.\n"), file_name);
+-        else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
+-          error (0, 0, _("%s is a 64 bit ELF file.\n"), file_name);
+-        else
+-          error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
++      case PT_LOAD:
++        if (loadaddr == (Elf32_Addr) -1)
++          loadaddr = segment->p_vaddr - segment->p_offset;
++        break;
++
++      case PT_DYNAMIC:
++        if (dynamic_addr)
++          error (0, 0, _("more than one dynamic segment\n"));
++
++        dynamic_addr = segment->p_offset;
++        dynamic_size = segment->p_filesz;
++        break;
++
++      case PT_INTERP:
++        program_interpreter = (char *) (file_contents + segment->p_offset);
++        check_ptr (program_interpreter);
++
++        /* Check if this is enough to classify the binary.  */
++        for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]);
++             ++j)
++          if (strcmp (program_interpreter, interpreters[j].soname) == 0)
++            {
++              *flag = interpreters[j].flag;
++              break;
++            }
++        break;
++
++      case PT_NOTE:
++        if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
++          {
++            Elf32_Word *abi_note = (Elf32_Word *) (file_contents
++                                                   + segment->p_offset);
++            if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
++                && memcmp (abi_note + 3, "GNU", 4) == 0)
++              *osversion = (abi_note [4] << 24) |
++                           ((abi_note [5] & 0xff) << 16) |
++                           ((abi_note [6] & 0xff) << 8) |
++                           (abi_note [7] & 0xff);
++          }
++        break;
++
++      default:
++        break;
+       }
+-      return 1;
++
+     }
++  if (loadaddr == (Elf32_Addr) -1)
++    {
++      /* Very strange. */
++      loadaddr = 0;
++    }
++
++  /* Now we can read the dynamic sections.  */
++  if (dynamic_size == 0)
++    return 1;
++
++  dynamic_segment = (Elf32_Dyn *) (file_contents + dynamic_addr);
++  check_ptr (dynamic_segment);
++
++  /* Find the string table.  */
++  dynamic_strings = NULL;
++  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++       ++dyn_entry)
++    {
++      check_ptr (dyn_entry);
++      if (dyn_entry->d_tag == DT_STRTAB)
++      {
++        dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
++        check_ptr (dynamic_strings);
++        break;
++      }
++    }
++
++  if (dynamic_strings == NULL)
++    return 1;
++
++  /* Now read the DT_NEEDED and DT_SONAME entries.  */
++  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++       ++dyn_entry)
++    {
++      if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
++      {
++        char *name = dynamic_strings + dyn_entry->d_un.d_val;
++        check_ptr (name);
++
++        if (dyn_entry->d_tag == DT_NEEDED)
++          {
++
++            if (*flag == FLAG_ELF)
++              {
++                /* Check if this is enough to classify the binary.  */
++                for (j = 0;
++                     j < sizeof (known_libs) / sizeof (known_libs [0]);
++                     ++j)
++                  if (strcmp (name, known_libs [j].soname) == 0)
++                    {
++                      *flag = known_libs [j].flag;
++                      break;
++                    }
++              }
++          }
++
++        else if (dyn_entry->d_tag == DT_SONAME)
++          *soname = xstrdup (name);
++
++        /* Do we have everything we need?  */
++        if (*soname && *flag != FLAG_ELF)
++          return 0;
++      }
++    }
++
++  /* We reach this point only if the file doesn't contain a DT_SONAME
++     or if we can't classify the library.  If it doesn't have a
++     soname, return the name of the library.  */
++  if (*soname == NULL)
++    *soname = xstrdup (lib);
++
++  return 0;
++}
++
++int
++process_elf_file64 (const char *file_name, const char *lib, int *flag,
++                unsigned int *osversion, char **soname, void *file_contents,
++                size_t file_length)
++{
++  int i;
++  unsigned int j;
++  Elf64_Addr loadaddr;
++  unsigned int dynamic_addr;
++  size_t dynamic_size;
++  char *program_interpreter;
++
++  Elf64_Ehdr *elf_header;
++  Elf64_Phdr *elf_pheader, *segment;
++  Elf64_Dyn *dynamic_segment, *dyn_entry;
++  char *dynamic_strings;
++
++  elf_header = (Elf64_Ehdr *) file_contents;
++  *osversion = 0;
+   if (elf_header->e_type != ET_DYN)
+     {
+@@ -81,7 +233,7 @@
+     }
+   /* Get information from elf program header.  */
+-  elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents);
++  elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents);
+   check_ptr (elf_pheader);
+   /* The library is an elf library, now search for soname and
+@@ -100,7 +252,7 @@
+       switch (segment->p_type)
+       {
+       case PT_LOAD:
+-        if (loadaddr == (ElfW(Addr)) -1)
++        if (loadaddr == (Elf64_Addr) -1)
+           loadaddr = segment->p_vaddr - segment->p_offset;
+         break;
+@@ -129,7 +281,7 @@
+       case PT_NOTE:
+         if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
+           {
+-            ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
++            Elf64_Word *abi_note = (Elf64_Word *) (file_contents
+                                                    + segment->p_offset);
+             if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
+                 && memcmp (abi_note + 3, "GNU", 4) == 0)
+@@ -145,7 +297,7 @@
+       }
+     }
+-  if (loadaddr == (ElfW(Addr)) -1)
++  if (loadaddr == (Elf64_Addr) -1)
+     {
+       /* Very strange. */
+       loadaddr = 0;
+@@ -155,7 +307,7 @@
+   if (dynamic_size == 0)
+     return 1;
+-  dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
++  dynamic_segment = (Elf64_Dyn *) (file_contents + dynamic_addr);
+   check_ptr (dynamic_segment);
+   /* Find the string table.  */
+@@ -218,3 +370,33 @@
+   return 0;
+ }
++/* Returns 0 if everything is ok, != 0 in case of error.  */
++int
++process_elf_file (const char *file_name, const char *lib, int *flag,
++                unsigned int *osversion, char **soname, void *file_contents,
++                size_t file_length)
++{
++  int i;
++  unsigned int j;
++  ElfW(Addr) loadaddr;
++  unsigned int dynamic_addr;
++  size_t dynamic_size;
++  char *program_interpreter;
++
++  ElfW(Ehdr) *elf_header;
++  ElfW(Phdr) *elf_pheader, *segment;
++  ElfW(Dyn) *dynamic_segment, *dyn_entry;
++  char *dynamic_strings;
++
++  elf_header = (ElfW(Ehdr) *) file_contents;
++  *osversion = 0;
++
++  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
++    return process_elf_file32(file_name, lib,flag, osversion, soname, file_contents, file_length);
++  else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
++    return process_elf_file64(file_name, lib,flag, osversion, soname, file_contents, file_length);
++  error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
++  return 1;
++}
++
++
index 1cd691e7bf928ee9b2f5be10c30e9d3ab38eaad7..bdd41dc55fb37b350ca4a2488f3465598c7abe87 100644 (file)
@@ -1,7 +1,10 @@
 DESCRIPTION = "A standalone native ldconfig build"
 
 SRC_URI = "file://ldconfig-native-2.5.tar.bz2 \
-           file://ldconfig.patch;patch=1 "
+           file://ldconfig.patch;patch=1 \
+           file://32and64bit.patch;patch=1"
+
+PR = "r1"
 
 inherit native