Add new hook ld_plugin_register_open_and_read_symbols.
The hook can be used for parsing of symbol table while the file is not claimed.
This commit is contained in:
parent
790854ea76
commit
76f10e938b
@ -260,7 +260,14 @@ enum ld_plugin_status
|
|||||||
(*ld_plugin_claim_file_handler) (
|
(*ld_plugin_claim_file_handler) (
|
||||||
const struct ld_plugin_input_file *file, int *claimed);
|
const struct ld_plugin_input_file *file, int *claimed);
|
||||||
|
|
||||||
/* The plugin library's "all symbols read" handler. */
|
/* The plugin library's "parse symbols for file" handler. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
bool
|
||||||
|
(*ld_plugin_open_and_read_symbols_handler) (
|
||||||
|
const struct ld_plugin_input_file *file);
|
||||||
|
|
||||||
|
/* The plugin library's "read all symbols" handler. */
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
enum ld_plugin_status
|
enum ld_plugin_status
|
||||||
@ -278,6 +285,12 @@ typedef
|
|||||||
enum ld_plugin_status
|
enum ld_plugin_status
|
||||||
(*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
|
(*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
|
||||||
|
|
||||||
|
/* The linker's interface for registering the "read all symbols" handler. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_register_open_and_read_symbols) (ld_plugin_open_and_read_symbols_handler handler);
|
||||||
|
|
||||||
/* The linker's interface for registering the "all symbols read" handler. */
|
/* The linker's interface for registering the "all symbols read" handler. */
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
@ -520,7 +533,8 @@ enum ld_plugin_tag
|
|||||||
LDPT_GET_INPUT_SECTION_SIZE = 30,
|
LDPT_GET_INPUT_SECTION_SIZE = 30,
|
||||||
LDPT_REGISTER_NEW_INPUT_HOOK = 31,
|
LDPT_REGISTER_NEW_INPUT_HOOK = 31,
|
||||||
LDPT_GET_WRAP_SYMBOLS = 32,
|
LDPT_GET_WRAP_SYMBOLS = 32,
|
||||||
LDPT_ADD_SYMBOLS_V2 = 33
|
LDPT_ADD_SYMBOLS_V2 = 33,
|
||||||
|
LDPT_REGISTER_OPEN_AND_READ_SYMBOLS = 34
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The plugin transfer vector. */
|
/* The plugin transfer vector. */
|
||||||
@ -556,6 +570,7 @@ struct ld_plugin_tv
|
|||||||
ld_plugin_get_input_section_size tv_get_input_section_size;
|
ld_plugin_get_input_section_size tv_get_input_section_size;
|
||||||
ld_plugin_register_new_input tv_register_new_input;
|
ld_plugin_register_new_input tv_register_new_input;
|
||||||
ld_plugin_get_wrap_symbols tv_get_wrap_symbols;
|
ld_plugin_get_wrap_symbols tv_get_wrap_symbols;
|
||||||
|
ld_plugin_register_open_and_read_symbols tv_register_open_and_read_symbols;
|
||||||
} tv_u;
|
} tv_u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ static ld_plugin_add_input_file add_input_file;
|
|||||||
static ld_plugin_add_input_library add_input_library;
|
static ld_plugin_add_input_library add_input_library;
|
||||||
static ld_plugin_message message;
|
static ld_plugin_message message;
|
||||||
static ld_plugin_add_symbols add_symbols, add_symbols_v2;
|
static ld_plugin_add_symbols add_symbols, add_symbols_v2;
|
||||||
|
static ld_plugin_register_open_and_read_symbols register_open_and_read_symbols;
|
||||||
|
|
||||||
static struct plugin_file_info *claimed_files = NULL;
|
static struct plugin_file_info *claimed_files = NULL;
|
||||||
static unsigned int num_claimed_files = 0;
|
static unsigned int num_claimed_files = 0;
|
||||||
@ -1139,12 +1140,14 @@ process_offload_section (void *data, const char *name, off_t offset, off_t len)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback used by gold to check if the plugin will claim FILE. Writes
|
/* Check file and read symbol table for FILE. If CLAIM_FILE is true, then
|
||||||
the result in CLAIMED. */
|
register the file the claimed objects. */
|
||||||
|
|
||||||
static enum ld_plugin_status
|
static bool
|
||||||
claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
check_file_and_read_symbol_table (const struct ld_plugin_input_file *file,
|
||||||
|
bool claim_file)
|
||||||
{
|
{
|
||||||
|
bool contains_symbols = false;
|
||||||
enum ld_plugin_status status;
|
enum ld_plugin_status status;
|
||||||
struct plugin_objfile obj;
|
struct plugin_objfile obj;
|
||||||
struct plugin_file_info lto_file;
|
struct plugin_file_info lto_file;
|
||||||
@ -1172,14 +1175,13 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
}
|
}
|
||||||
lto_file.handle = file->handle;
|
lto_file.handle = file->handle;
|
||||||
|
|
||||||
*claimed = 0;
|
|
||||||
obj.file = file;
|
obj.file = file;
|
||||||
obj.found = 0;
|
obj.found = 0;
|
||||||
obj.offload = 0;
|
obj.offload = 0;
|
||||||
obj.out = <o_file.symtab;
|
obj.out = <o_file.symtab;
|
||||||
errmsg = NULL;
|
errmsg = NULL;
|
||||||
obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
|
obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
|
||||||
&errmsg, &err);
|
&errmsg, &err);
|
||||||
/* No file, but also no error code means unrecognized format; just skip it. */
|
/* No file, but also no error code means unrecognized format; just skip it. */
|
||||||
if (!obj.objfile && !err)
|
if (!obj.objfile && !err)
|
||||||
goto err;
|
goto err;
|
||||||
@ -1203,7 +1205,7 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
{
|
{
|
||||||
if (err && message)
|
if (err && message)
|
||||||
message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
|
message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
|
||||||
xstrerror (err));
|
xstrerror (err));
|
||||||
else if (message)
|
else if (message)
|
||||||
message (LDPL_FATAL, "%s: %s", file->name, errmsg);
|
message (LDPL_FATAL, "%s: %s", file->name, errmsg);
|
||||||
goto err;
|
goto err;
|
||||||
@ -1229,13 +1231,16 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
lto_file.symtab.syms);
|
lto_file.symtab.syms);
|
||||||
check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
|
check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
|
||||||
|
|
||||||
num_claimed_files++;
|
if (claim_file)
|
||||||
claimed_files =
|
{
|
||||||
xrealloc (claimed_files,
|
num_claimed_files++;
|
||||||
num_claimed_files * sizeof (struct plugin_file_info));
|
claimed_files
|
||||||
claimed_files[num_claimed_files - 1] = lto_file;
|
= xrealloc (claimed_files,
|
||||||
|
num_claimed_files * sizeof (struct plugin_file_info));
|
||||||
|
claimed_files[num_claimed_files - 1] = lto_file;
|
||||||
|
}
|
||||||
|
|
||||||
*claimed = 1;
|
contains_symbols = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offload_files == NULL)
|
if (offload_files == NULL)
|
||||||
@ -1250,7 +1255,7 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
/* If this is an LTO file without offload, and it is the first LTO file, save
|
/* If this is an LTO file without offload, and it is the first LTO file, save
|
||||||
the pointer to the last offload file in the list. Further offload LTO
|
the pointer to the last offload file in the list. Further offload LTO
|
||||||
files will be inserted after it, if any. */
|
files will be inserted after it, if any. */
|
||||||
if (*claimed && obj.offload == 0 && offload_files_last_lto == NULL)
|
if (contains_symbols && obj.offload == 0 && offload_files_last_lto == NULL)
|
||||||
offload_files_last_lto = offload_files_last;
|
offload_files_last_lto = offload_files_last;
|
||||||
|
|
||||||
if (obj.offload == 1)
|
if (obj.offload == 1)
|
||||||
@ -1264,8 +1269,8 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
ofld->name = lto_file.name;
|
ofld->name = lto_file.name;
|
||||||
ofld->next = NULL;
|
ofld->next = NULL;
|
||||||
|
|
||||||
if (*claimed && offload_files_last_lto == NULL && file->offset != 0
|
if (contains_symbols && offload_files_last_lto == NULL
|
||||||
&& gold_version == -1)
|
&& file->offset != 0 && gold_version == -1)
|
||||||
{
|
{
|
||||||
/* ld only: insert first LTO file from the archive after the last real
|
/* ld only: insert first LTO file from the archive after the last real
|
||||||
object file immediately preceding the archive, or at the begin of
|
object file immediately preceding the archive, or at the begin of
|
||||||
@ -1281,7 +1286,7 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
offload_files->next = ofld;
|
offload_files->next = ofld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*claimed && offload_files_last_lto != NULL)
|
else if (offload_files_last_lto != NULL)
|
||||||
{
|
{
|
||||||
/* Insert LTO file after the last LTO file in the list. */
|
/* Insert LTO file after the last LTO file in the list. */
|
||||||
ofld->next = offload_files_last_lto->next;
|
ofld->next = offload_files_last_lto->next;
|
||||||
@ -1296,7 +1301,7 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
offload_files_last = ofld;
|
offload_files_last = ofld;
|
||||||
if (file->offset == 0)
|
if (file->offset == 0)
|
||||||
offload_files_last_obj = ofld;
|
offload_files_last_obj = ofld;
|
||||||
if (*claimed)
|
if (contains_symbols)
|
||||||
offload_files_last_lto = ofld;
|
offload_files_last_lto = ofld;
|
||||||
num_offload_files++;
|
num_offload_files++;
|
||||||
}
|
}
|
||||||
@ -1311,9 +1316,29 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
|||||||
if (obj.objfile)
|
if (obj.objfile)
|
||||||
simple_object_release_read (obj.objfile);
|
simple_object_release_read (obj.objfile);
|
||||||
|
|
||||||
|
return contains_symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback used by gold to check if the plugin will claim FILE.
|
||||||
|
Writes the result in CLAIMED. */
|
||||||
|
|
||||||
|
static enum ld_plugin_status
|
||||||
|
claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
|
||||||
|
{
|
||||||
|
bool contains_symbols = check_file_and_read_symbol_table (file, true);
|
||||||
|
*claimed = contains_symbols;
|
||||||
|
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback used by mold to check if the FILE contains LTO symbols. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
open_and_read_symbols (const struct ld_plugin_input_file *file)
|
||||||
|
{
|
||||||
|
return check_file_and_read_symbol_table (file, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the plugin options. */
|
/* Parse the plugin options. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1393,6 +1418,10 @@ onload (struct ld_plugin_tv *tv)
|
|||||||
case LDPT_REGISTER_CLAIM_FILE_HOOK:
|
case LDPT_REGISTER_CLAIM_FILE_HOOK:
|
||||||
register_claim_file = p->tv_u.tv_register_claim_file;
|
register_claim_file = p->tv_u.tv_register_claim_file;
|
||||||
break;
|
break;
|
||||||
|
case LDPT_REGISTER_OPEN_AND_READ_SYMBOLS:
|
||||||
|
register_open_and_read_symbols
|
||||||
|
= p->tv_u.tv_register_open_and_read_symbols;
|
||||||
|
break;
|
||||||
case LDPT_ADD_SYMBOLS_V2:
|
case LDPT_ADD_SYMBOLS_V2:
|
||||||
add_symbols_v2 = p->tv_u.tv_add_symbols;
|
add_symbols_v2 = p->tv_u.tv_add_symbols;
|
||||||
break;
|
break;
|
||||||
@ -1437,11 +1466,26 @@ onload (struct ld_plugin_tv *tv)
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
|
|
||||||
check (add_symbols, LDPL_FATAL, "add_symbols not found");
|
check (add_symbols, LDPL_FATAL, "add_symbols not found");
|
||||||
status = register_claim_file (claim_file_handler);
|
|
||||||
check (status == LDPS_OK, LDPL_FATAL,
|
if (register_claim_file != NULL)
|
||||||
"could not register the claim_file callback");
|
{
|
||||||
|
status = register_claim_file (claim_file_handler);
|
||||||
|
check (status == LDPS_OK, LDPL_FATAL,
|
||||||
|
"could not register the claim_file callback");
|
||||||
|
}
|
||||||
|
else if (register_open_and_read_symbols != NULL)
|
||||||
|
{
|
||||||
|
status = register_open_and_read_symbols (open_and_read_symbols);
|
||||||
|
check (status == LDPS_OK, LDPL_FATAL,
|
||||||
|
"could not register the open_and_read_symbols callback");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"either claim_file or open_and_read_symbols must be registered");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
if (register_cleanup)
|
if (register_cleanup)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user