diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/lto/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/lto/lto-elf.c | 10 | ||||
-rw-r--r-- | gcc/lto/lto.c | 33 | ||||
-rw-r--r-- | gcc/lto/lto.h | 1 |
4 files changed, 37 insertions, 15 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 54dabf2cc8a..6792d183a51 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,11 @@ +2009-11-19 Rafael Avila de Espindola <espindola@google.com> + + PR bootstrap/42096 + * lto-elf.c (lto_elf_file_open): Use lto_parse_hex. + * lto.c (lto_parse_hex): New. + (lto_resolution_read): Use lto_parse_hex. + * lto.h (lto_parse_hex): New. + 2009-11-17 Rafael Avila de Espindola <espindola@google.com> * lto-elf.c (lto_file_init): Add offset argument. diff --git a/gcc/lto/lto-elf.c b/gcc/lto/lto-elf.c index 368d8d4d75f..7c5453a41bf 100644 --- a/gcc/lto/lto-elf.c +++ b/gcc/lto/lto-elf.c @@ -559,14 +559,8 @@ lto_elf_file_open (const char *filename, bool writable) fname = (char *) xmalloc (offset_p - filename + 1); memcpy (fname, filename, offset_p - filename); fname[offset_p - filename] = '\0'; - offset_p++; - errno = 0; - offset = strtoll (offset_p, NULL, 10); - if (errno != 0) - { - error ("could not parse offset %s", offset_p); - goto fail; - } + 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 */ diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9cb7d65a60b..4d7c3079b49 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -249,6 +249,28 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data, lto_data_in_delete (data_in); } +/* strtoll is not portable. */ +int64_t +lto_parse_hex (const char *p) { + uint64_t ret = 0; + for (; *p != '\0'; ++p) + { + char c = *p; + unsigned char part; + ret <<= 4; + if (c >= '0' && c <= '9') + part = c - '0'; + else if (c >= 'a' && c <= 'f') + part = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + part = c - 'A' + 10; + else + internal_error ("could not parse hex number"); + ret |= part; + } + return ret; +} + /* Read resolution for file named FILE_NAME. The resolution is read from RESOLUTION. An array with the symbol resolution is returned. The array size is written to SIZE. */ @@ -280,15 +302,12 @@ lto_resolution_read (FILE *resolution, lto_file *file) if (file->offset != 0) { int t; - char offset_p[21]; - long long offset; - t = fscanf (resolution, "@%20s", offset_p); + char offset_p[17]; + int64_t offset; + t = fscanf (resolution, "@0x%16s", offset_p); if (t != 1) internal_error ("could not parse file offset"); - errno = 0; - offset = strtoll(offset_p, NULL, 10); - if (errno != 0) - internal_error ("could not parse file offset"); + offset = lto_parse_hex (offset_p); if (offset != file->offset) internal_error ("unexpected offset"); } diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 3b92b41e9a3..0c4305a1731 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -57,5 +57,6 @@ struct lto_section_slot size_t len; }; +int64_t lto_parse_hex (const char *p); #endif /* LTO_H */ |