const char *p;
const char *orig_infile = infile;
- off_t inoff = 0;
- long loffset;
+ int64_t inoff = 0;
int consumed;
if ((p = strrchr (infile, '@'))
&& p != infile
- && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
+ && sscanf (p, "@%" PRIi64 "%n", &inoff, &consumed) >= 1
&& strlen (p) == (unsigned int) consumed)
{
char *fname = xstrdup (infile);
fname[p - infile] = '\0';
infile = fname;
- inoff = (off_t) loffset;
}
int infd = open (infile, O_RDONLY | O_BINARY);
if (infd == -1)
{
char *p;
int fd;
- off_t file_offset = 0;
- long loffset;
+ int64_t file_offset = 0;
int consumed;
char *filename = argv[i];
if ((p = strrchr (argv[i], '@'))
&& p != argv[i]
- && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
+ && sscanf (p, "@%" PRIi64 "%n", &file_offset, &consumed) >= 1
&& strlen (p) == (unsigned int) consumed)
{
filename = XNEWVEC (char, p - argv[i] + 1);
memcpy (filename, argv[i], p - argv[i]);
filename[p - argv[i]] = '\0';
- file_offset = (off_t) loffset;
}
fd = open (filename, O_RDONLY | O_BINARY);
/* Linker plugin passes -fresolution and -flinker-output options.
for (i = 0; i < num_offload_files; i++)
{
char *p;
- long loffset;
int fd, consumed;
- off_t file_offset = 0;
+ int64_t file_offset = 0;
char *filename = offload_argv[i];
if ((p = strrchr (offload_argv[i], '@'))
&& p != offload_argv[i]
- && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
+ && sscanf (p, "@%" PRIi64 "%n", &file_offset, &consumed) >= 1
&& strlen (p) == (unsigned int) consumed)
{
filename = XNEWVEC (char, p - offload_argv[i] + 1);
memcpy (filename, offload_argv[i], p - offload_argv[i]);
filename[p - offload_argv[i]] = '\0';
- file_offset = (off_t) loffset;
}
fd = open (filename, O_RDONLY | O_BINARY);
if (fd == -1)
static char *
lto_read_section_data (struct lto_file_decl_data *file_data,
- intptr_t offset, size_t len)
+ off_t offset, size_t len)
{
char *result;
static int fd = -1;
static char *fd_name;
#if LTO_MMAP_IO
- intptr_t computed_len;
- intptr_t computed_offset;
- intptr_t diff;
+ size_t computed_len;
+ off_t computed_offset;
+ off_t diff;
#endif
/* Keep a single-entry file-descriptor cache. The last file we
page_mask = ~(page_size - 1);
}
- computed_offset = offset & page_mask;
+ computed_offset = offset & ((off_t) page_mask);
diff = offset - computed_offset;
- computed_len = len + diff;
+ if (len > (size_t) (SSIZE_MAX - diff))
+ {
+ fatal_error (input_location, "Cannot map %s: section is too long",
+ file_data->file_name);
+ return NULL;
+ }
+ computed_len = (size_t) diff + len;
result = (char *) mmap (NULL, computed_len, PROT_READ, MAP_PRIVATE,
fd, computed_offset);
lto_obj_file_open (const char *filename, bool writable)
{
const char *offset_p;
- long loffset;
int consumed;
char *fname;
- off_t offset;
+ int64_t offset;
struct lto_simple_object *lo;
const char *errmsg;
int err;
offset_p = strrchr (filename, '@');
if (offset_p != NULL
&& offset_p != filename
- && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1
+ && sscanf (offset_p, "@%" PRIi64 "%n", &offset, &consumed) >= 1
&& strlen (offset_p) == (unsigned int) consumed)
{
fname = XNEWVEC (char, offset_p - filename + 1);
memcpy (fname, filename, offset_p - filename);
fname[offset_p - filename] = '\0';
- offset = (off_t) loffset;
}
else
{
struct lto_section_slot
{
const char *name;
- intptr_t start;
+ off_t start;
size_t len;
struct lto_section_slot *next;
};
--- /dev/null
+/* { dg-lto-do ar-link } */
+/* { dg-lto-options { { -flto=auto -ffat-lto-objects } } } */
+
+extern int bar_7 (int);
+
+int main (void)
+{
+ return bar_7 (42);
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_1;
+
+A_1 a1_1 = {1};
+A_1 a2_1 = {2};
+
+int bar_1 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_2;
+
+A_2 a1_2 = {1};
+A_2 a2_2 = {2};
+
+int bar_2 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_3;
+
+A_3 a1_3 = {1};
+A_3 a2_3 = {2};
+
+int bar_3 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_4;
+
+A_4 a1_4 = {1};
+A_4 a2_4 = {2};
+
+int bar_4 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_5;
+
+A_5 a1_5 = {1};
+A_5 a2_5 = {2};
+
+int bar_5 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_6;
+
+A_6 a1_6 = {1};
+A_6 a2_6 = {2};
+
+int bar_6 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_7;
+
+A_7 a1_7 = {1};
+A_7 a2_7 = {2};
+
+int bar_7 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_8;
+
+A_8 a1_8 = {1};
+A_8 a2_8 = {2};
+
+int bar_8 (int i)
+{
+ return i++;
+}
--- /dev/null
+typedef struct {
+ int num;
+ int foo[40000000];
+} A_9;
+
+A_9 a1_9 = {1};
+A_9 a2_9 = {2};
+
+int bar_9 (int i)
+{
+ return i++;
+}
${tool}_check_compile "$testcase $dest assemble" $optstr $dest $comp_output
}
+proc lto-build-archive { testname objlist dest } {
+ global testcase
+ global tool
+ global GCC_UNDER_TEST
+
+ upvar dg-messages-by-file dg-messages-by-file
+
+ verbose "lto-build-archive" 2
+ file_on_host delete $dest
+
+ # Check that all of the objects were built successfully.
+ foreach obj [split $objlist] {
+ if ![file_on_host exists $obj] then {
+ unresolved "$testcase $testname build-archive"
+ return
+ }
+ }
+
+ # Hack up the gcc-ar command from $GCC_UNDER_TEST.
+ set ar_cmd [file dirname [lindex $GCC_UNDER_TEST 0]]
+ set ar_cmd "$ar_cmd/gcc-ar [lrange $GCC_UNDER_TEST 1 end]"
+ set ar_output [remote_exec host "$ar_cmd rcs $dest $objlist"]
+ set retval [lindex $ar_output 0]
+ set retmsg [lindex $ar_output 1]
+
+ # If any message remains, we fail. Don't bother overriding tool since
+ # we're not really looking to match any specific error or warning patterns
+ # here.
+ if ![string match "0" $retval] then {
+ ${tool}_fail $testcase "ar returned $retval: $retmsg"
+ return 0
+ } else {
+ ${tool}_pass $testcase "archive"
+ return 0
+ }
+}
+
# lto-link-and-maybe-run -- link the object files and run the executable
# if compile_type is set to "run"
#
}
# Return if we only needed to link.
- if { ![string compare "link" $compile_type] } {
+ if { ![string compare "link" $compile_type] \
+ || ![string compare "ar-link" $compile_type] } {
return
}
set compile_type "run"
} elseif { ![string compare "link" $dgdo] } {
set compile_type "link"
+ } elseif { ![string compare "ar-link" $dgdo] } {
+ set compile_type "ar-link"
} else {
warning "lto.exp does not support dg-lto-do $dgdo"
}
# Get the base name of this test, for use in messages.
set testcase [lindex ${src_list} 0]
+ # The test needs to build all but the main file into an archive and then
+ # link them all together.
+ if { ![string compare "ar-link" $compile_type] } {
+ set arname "${sid}_${base}.a"
+ }
+
# Remove the $srcdir and $tmpdir prefixes from $src1. (It would
# be possible to use "regsub" here, if we were careful to escape
# all regular expression characters in $srcdir and $tmpdir, but
incr i
}
+ # Bundle all but the main file into an archive. Update objlist to only
+ # have the archive and the last file.
+ if { ![string compare "ar-link" $compile_type] } {
+ set mainsrc [lindex $obj_list 0]
+ set obj_list [lrange $obj_list 1 end]
+ lto-build-archive \
+ "[lindex $obj_list 1]-[lindex $obj_list end]" \
+ $obj_list $arname
+
+ set obj_list ""
+ lappend obj_list $mainsrc
+ lappend obj_list $arname
+ set num_srcs 2
+ }
+
# Link (using the compiler under test), run, and clean up tests.
if { ![string compare "run" $compile_type] \
+ || ![string compare "ar-link" $compile_type] \
|| ![string compare "link" $compile_type] } {
# Filter out any link options we were asked to suppress.
"[lindex $obj_list 0]-[lindex $obj_list end]" \
$obj_list $execname $filtered ${dg-extra-ld-options} \
$filtered
+
+ if (![string compare "ar-link" $compile_type]) {
+ file_on_host delete $arname
+ }
}
unset testname_with_flags
if { ![string compare "run" $compile_type] \
+ || ![string compare "ar-link" $compile_type] \
|| ![string compare "link" $compile_type] } {
file_on_host delete $execname
}