Mercurial > hg > CbC > CbC_gcc
diff gcc/lto/lto-elf.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children |
line wrap: on
line diff
--- a/gcc/lto/lto-elf.c Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/lto/lto-elf.c Mon May 24 12:47:05 2010 +0900 @@ -1,5 +1,5 @@ /* LTO routines for ELF object files. - Copyright 2009 Free Software Foundation, Inc. + Copyright 2009, 2010 Free Software Foundation, Inc. Contributed by CodeSourcery, Inc. This file is part of GCC. @@ -29,6 +29,22 @@ #include "ggc.h" #include "lto-streamer.h" +/* Cater to hosts with half-backed <elf.h> file like HP-UX. */ +#ifndef EM_SPARC +# define EM_SPARC 2 +#endif + +#ifndef EM_SPARC32PLUS +# define EM_SPARC32PLUS 18 +#endif + + +/* Handle opening elf files on hosts, such as Windows, that may use + text file handling that will break binary access. */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif + /* Initialize FILE, an LTO file object for FILENAME. */ static void @@ -163,7 +179,7 @@ the start and size of each section in the .o file. */ htab_t -lto_elf_build_section_table (lto_file *lto_file) +lto_obj_build_section_table (lto_file *lto_file) { lto_elf_file *elf_file = (lto_elf_file *)lto_file; htab_t section_hash_table; @@ -306,7 +322,7 @@ /* Begin a new ELF section named NAME in the current output file. */ void -lto_elf_begin_section (const char *name) +lto_obj_begin_section (const char *name) { lto_elf_begin_section_with_type (name, SHT_PROGBITS); } @@ -317,7 +333,7 @@ been written. */ void -lto_elf_append_data (const void *data, size_t len, void *block) +lto_obj_append_data (const void *data, size_t len, void *block) { lto_elf_file *file; Elf_Data *elf_data; @@ -354,7 +370,7 @@ and sets the current output file's scn member to NULL. */ void -lto_elf_end_section (void) +lto_obj_end_section (void) { lto_elf_file *file; @@ -367,6 +383,41 @@ } +/* Return true if ELF_MACHINE is compatible with the cached value of the + architecture and possibly update the latter. Return false otherwise. + + Note: if you want to add more EM_* cases, you'll need to provide the + corresponding definitions at the beginning of the file. */ + +static bool +is_compatible_architecture (Elf64_Half elf_machine) +{ + if (cached_file_attrs.elf_machine == elf_machine) + return true; + + switch (cached_file_attrs.elf_machine) + { + case EM_SPARC: + if (elf_machine == EM_SPARC32PLUS) + { + cached_file_attrs.elf_machine = elf_machine; + return true; + } + break; + + case EM_SPARC32PLUS: + if (elf_machine == EM_SPARC) + return true; + break; + + default: + break; + } + + return false; +} + + /* Validate's ELF_FILE's executable header and, if cached_file_attrs is uninitialized, caches the architecture. */ @@ -391,8 +442,7 @@ \ if (!cached_file_attrs.initialized) \ cached_file_attrs.elf_machine = elf_header->e_machine; \ - \ - if (cached_file_attrs.elf_machine != elf_header->e_machine) \ + else if (!is_compatible_architecture (elf_header->e_machine)) \ { \ error ("inconsistent file architecture detected"); \ return false; \ @@ -405,6 +455,22 @@ DEFINE_VALIDATE_EHDR (64) +#ifndef HAVE_ELF_GETSHDRSTRNDX +/* elf_getshdrstrndx replacement for systems that lack it, but provide + either the gABI conformant or Solaris 2 variant of elf_getshstrndx + instead. */ + +static int +elf_getshdrstrndx (Elf *elf, size_t *dst) +{ +#ifdef HAVE_ELF_GETSHSTRNDX_GABI + return elf_getshstrndx (elf, dst); +#else + return elf_getshstrndx (elf, dst) ? 0 : -1; +#endif +} +#endif + /* Validate's ELF_FILE's executable header and, if cached_file_attrs is uninitialized, caches the results. Also records the section header string table's section index. Returns true on success or false on failure. */ @@ -538,34 +604,38 @@ Returns the opened file. */ lto_file * -lto_elf_file_open (const char *filename, bool writable) +lto_obj_file_open (const char *filename, bool writable) { lto_elf_file *elf_file; lto_file *result = NULL; off_t offset; + long loffset; off_t header_offset; const char *offset_p; char *fname; + int consumed; - offset_p = strchr (filename, '@'); - if (!offset_p) + offset_p = strrchr (filename, '@'); + if (offset_p + && offset_p != filename + && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1 + && strlen (offset_p) == (unsigned int)consumed) + { + fname = (char *) xmalloc (offset_p - filename + 1); + memcpy (fname, filename, offset_p - filename); + fname[offset_p - filename] = '\0'; + offset = (off_t)loffset; + /* elf_rand expects the offset to point to the ar header, not the + object itself. Subtract the size of the ar header (60 bytes). + We don't uses sizeof (struct ar_hd) to avoid including ar.h */ + header_offset = offset - 60; + } + else { fname = xstrdup (filename); offset = 0; header_offset = 0; } - else - { - fname = (char *) xmalloc (offset_p - filename + 1); - memcpy (fname, filename, offset_p - filename); - fname[offset_p - filename] = '\0'; - offset_p += 3; /* skip the @0x */ - offset = lto_parse_hex (offset_p); - /* elf_rand expects the offset to point to the ar header, not the - object itself. Subtract the size of the ar header (60 bytes). - We don't uses sizeof (struct ar_hd) to avoid including ar.h */ - header_offset = offset - 60; - } /* Set up. */ elf_file = XCNEW (lto_elf_file); @@ -574,7 +644,8 @@ elf_file->fd = -1; /* Open the file. */ - elf_file->fd = open (fname, writable ? O_WRONLY|O_CREAT : O_RDONLY, 0666); + elf_file->fd = open (fname, writable ? O_WRONLY|O_CREAT|O_BINARY + : O_RDONLY|O_BINARY, 0666); if (elf_file->fd == -1) { error ("could not open file %s", fname); @@ -633,7 +704,7 @@ fail: if (result) - lto_elf_file_close (result); + lto_obj_file_close (result); return NULL; } @@ -643,7 +714,7 @@ any cached data buffers are freed. */ void -lto_elf_file_close (lto_file *file) +lto_obj_file_close (lto_file *file) { lto_elf_file *elf_file = (lto_elf_file *) file; struct lto_char_ptr_base *cur, *tmp; @@ -679,7 +750,7 @@ if (gelf_update_ehdr (elf_file->elf, ehdr_p) == 0) fatal_error ("gelf_update_ehdr() failed: %s", elf_errmsg (-1)); lto_write_stream (elf_file->shstrtab_stream); - lto_elf_end_section (); + lto_obj_end_section (); lto_set_current_out_file (old_file); free (elf_file->shstrtab_stream);