#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
+#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(S) (((S) & 0xff) == 0)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+#endif
#include <libiberty.h>
#include <hashtab.h>
#include "../gcc/lto/common.h"
#include "simple-object.h"
#include "plugin-api.h"
+/* We need to use I64 instead of ll width-specifier on native Windows.
+ The reason for this is that older MS-runtimes don't support the ll. */
+#ifdef __MINGW32__
+#define PRI_LL "I64"
+#else
+#define PRI_LL "ll"
+#endif
+
/* Handle opening elf files on hosts, such as Windows, that may use
text file handling that will break binary access. */
#ifndef O_BINARY
/* The part of the symbol table the plugin has to keep track of. Note that we
must keep SYMS until all_symbols_read is called to give the linker time to
- copy the symbol information. */
+ copy the symbol information.
+ The id must be 64bit to minimze collisions. */
struct sym_aux
{
uint32_t slot;
- unsigned id;
+ unsigned long long id;
unsigned next_conflict;
};
int nsyms;
struct sym_aux *aux;
struct ld_plugin_symbol *syms;
- unsigned id;
+ unsigned long long id;
};
/* Encapsulates object file data during symbol scan. */
static char *arguments_file_name;
static ld_plugin_register_claim_file register_claim_file;
static ld_plugin_register_all_symbols_read register_all_symbols_read;
-static ld_plugin_get_symbols get_symbols;
+static ld_plugin_get_symbols get_symbols, get_symbols_v2;
static ld_plugin_register_cleanup register_cleanup;
static ld_plugin_add_input_file add_input_file;
static ld_plugin_add_input_library add_input_library;
static char nop;
static char *resolution_file = NULL;
-/* Set by default from configure.ac, but can be overridden at runtime
+/* The version of gold being used, or -1 if not gold. The number is
+ MAJOR * 100 + MINOR. */
+static int gold_version = -1;
+
+/* Not used by default, but can be overridden at runtime
by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
(in fact, only first letter of style arg is checked.) */
-static enum symbol_style sym_style = SYM_STYLE;
+static enum symbol_style sym_style = ss_none;
static void
check_1 (int gate, enum ld_plugin_level level, const char *text)
entry->visibility = translate_visibility[t];
p++;
- entry->size = *(uint64_t *) p;
+ memcpy (&entry->size, p, sizeof (uint64_t));
p += 8;
- aux->slot = *(uint32_t *) p;
+ memcpy (&aux->slot, p, sizeof (uint32_t));
p += 4;
entry->resolution = LDPR_UNKNOWN;
{
struct ld_plugin_symbol *s = &symtab->syms[j];
free (s->name);
- if (s->comdat_key)
- free (s->comdat_key);
+ free (s->comdat_key);
}
free (symtab->syms);
symtab->syms = NULL;
claimed_files = NULL;
num_claimed_files = 0;
- if (arguments_file_name)
- free (arguments_file_name);
+ free (arguments_file_name);
arguments_file_name = NULL;
}
assert (resolution != LDPR_UNKNOWN);
- fprintf (f, "%u %x %s %s\n", (unsigned int) slot, symtab->aux[j].id,
+ fprintf (f, "%u %" PRI_LL "x %s %s\n",
+ (unsigned int) slot, symtab->aux[j].id,
lto_resolution_str[resolution],
symtab->syms[j].name);
}
struct plugin_symtab *symtab = &info->symtab;
struct ld_plugin_symbol *syms = symtab->syms;
- get_symbols (info->handle, symtab->nsyms, syms);
+ /* Version 2 of API supports IRONLY_EXP resolution that is
+ accepted by GCC-4.7 and newer. */
+ if (get_symbols_v2)
+ get_symbols_v2 (info->handle, symtab->nsyms, syms);
+ else
+ get_symbols (info->handle, symtab->nsyms, syms);
finish_conflict_resolution (symtab, &info->conflicts);
buf = s;
cont:
if (!fgets (buf, piece, f))
- break;
+ {
+ free (s);
+ break;
+ }
len = strlen (s);
if (s[len - 1] != '\n')
{
free (lto_argv);
- if (pass_through_items)
+ /* --pass-through is not needed when using gold 1.11 or later. */
+ if (pass_through_items && gold_version < 111)
{
unsigned int i;
for (i = 0; i < num_pass_through_items; i++)
{
SWAP (struct ld_plugin_symbol, *orig, *s);
SWAP (uint32_t, orig_aux->slot, aux->slot);
- SWAP (unsigned, orig_aux->id, aux->id);
+ SWAP (unsigned long long, orig_aux->id, aux->id);
/* Don't swap conflict chain pointer */
}
s = strrchr (name, '.');
if (s)
- sscanf (s, ".%x", &obj->out->id);
+ sscanf (s, ".%" PRI_LL "x", &obj->out->id);
secdata = xmalloc (length);
offset += obj->file->offset;
if (offset != lseek (obj->file->fd, offset, SEEK_SET)
/* We pass the offset of the actual file, not the archive header.
Can't use PRIx64, because that's C99, so we have to print the
64-bit hex int as two 32-bit ones. */
- int lo, hi;
+ int lo, hi, t;
lo = file->offset & 0xffffffff;
hi = ((int64_t)file->offset >> 32) & 0xffffffff;
- int t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
- : asprintf (&objname, "%s@0x%x", file->name, lo);
+ t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
+ : asprintf (&objname, "%s@0x%x", file->name, lo);
check (t >= 0, LDPL_FATAL, "asprintf failed");
lto_file.name = objname;
}
case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
break;
+ case LDPT_GET_SYMBOLS_V2:
+ get_symbols_v2 = p->tv_u.tv_get_symbols;
+ break;
case LDPT_GET_SYMBOLS:
get_symbols = p->tv_u.tv_get_symbols;
break;
case LDPT_OPTION:
process_option (p->tv_u.tv_string);
break;
+ case LDPT_GOLD_VERSION:
+ gold_version = p->tv_u.tv_val;
+ break;
default:
break;
}