Commit 6b3456d1 by Ian Lance Taylor Committed by Ian Lance Taylor

lto-object.c: New file.

	* lto-object.c: New file.
	* lto-elf.c: Remove file.
	* lto-macho.c: Remove file.
	* lto-macho.h: Remove file.
	* lto-coff.c: Remove file.
	* lto-coff.h: Remove file.
	* Make-lang.in (LTO_OBJS): Change lto/$(LTO_BINARY_READER).o to
	lto/lto-object.o.
	($(LTO_EXE)): Remove $(LTO_USE_LIBELF)
	(lto/lto-objfile.o): New target.
	(lto/lto-elf.o, lto/lto-coff.o, lto/lto-macho.o): Remove targets.
	(lto/lto.o): Remove $(LIBIBERTY_H).

From-SVN: r166187
parent 1cfabf34
2010-11-02 Ian Lance Taylor <iant@google.com>
* lto-object.c: New file.
* lto-elf.c: Remove file.
* lto-macho.c: Remove file.
* lto-macho.h: Remove file.
* lto-coff.c: Remove file.
* lto-coff.h: Remove file.
* Make-lang.in (LTO_OBJS): Change lto/$(LTO_BINARY_READER).o to
lto/lto-object.o.
($(LTO_EXE)): Remove $(LTO_USE_LIBELF)
(lto/lto-objfile.o): New target.
(lto/lto-elf.o, lto/lto-coff.o, lto/lto-macho.o): Remove targets.
(lto/lto.o): Remove $(LIBIBERTY_H).
2010-10-22 Jan Hubicka <jh@suse.cz> 2010-10-22 Jan Hubicka <jh@suse.cz>
* lto.c (add_cgraph_node_to_partition, * lto.c (add_cgraph_node_to_partition,
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
# The name of the LTO compiler. # The name of the LTO compiler.
LTO_EXE = lto1$(exeext) LTO_EXE = lto1$(exeext)
# The LTO-specific object files inclued in $(LTO_EXE). # The LTO-specific object files inclued in $(LTO_EXE).
LTO_OBJS = lto/lto-lang.o lto/lto.o lto/$(LTO_BINARY_READER).o attribs.o LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o
LTO_H = lto/lto.h $(HASHTAB_H) LTO_H = lto/lto.h $(HASHTAB_H)
LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h
LTO_TREE_H = lto/lto-tree.h $(LINKER_PLUGIN_API_H) LTO_TREE_H = lto/lto-tree.h $(LINKER_PLUGIN_API_H)
...@@ -73,7 +73,7 @@ lto-warn = $(STRICT_WARN) ...@@ -73,7 +73,7 @@ lto-warn = $(STRICT_WARN)
$(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS) $(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS) $(LTO_USE_LIBELF) $(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS)
# Dependencies # Dependencies
lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \ lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \
...@@ -81,19 +81,14 @@ lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \ ...@@ -81,19 +81,14 @@ lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \
$(TARGET_H) $(LTO_H) $(GIMPLE_H) gtype-lto.h gt-lto-lto-lang.h \ $(TARGET_H) $(LTO_H) $(GIMPLE_H) gtype-lto.h gt-lto-lto-lang.h \
$(EXPR_H) $(EXPR_H)
lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h opts.h \ lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h opts.h \
toplev.h $(TREE_H) $(DIAGNOSTIC_CORE_H) $(TM_H) $(LIBIBERTY_H) \ toplev.h $(TREE_H) $(DIAGNOSTIC_CORE_H) $(TM_H) \
$(CGRAPH_H) $(GGC_H) tree-ssa-operands.h $(TREE_PASS_H) \ $(CGRAPH_H) $(GGC_H) tree-ssa-operands.h $(TREE_PASS_H) \
langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \ langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \
$(COMMON_H) debug.h $(TIMEVAR_H) $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \ $(COMMON_H) debug.h $(TIMEVAR_H) $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \
$(LTO_TAGS_H) $(LTO_STREAMER_H) $(SPLAY_TREE_H) gt-lto-lto.h $(PARAMS_H) $(LTO_TAGS_H) $(LTO_STREAMER_H) $(SPLAY_TREE_H) gt-lto-lto.h $(PARAMS_H)
lto/lto-elf.o: lto/lto-elf.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \ lto/lto-object.o: lto/lto-object.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
toplev.h $(LTO_H) $(TM_H) $(LIBIBERTY_H) $(GGC_H) $(LTO_STREAMER_H) $(DIAGNOSTIC_CORE_H) $(TOPLEV_H) $(LTO_H) $(TM_H) $(LTO_STREAMER_H) \
lto/lto-coff.o: lto/lto-coff.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \ ../include/simple-object.h
toplev.h $(LTO_H) $(TM_H) $(LIBIBERTY_H) $(GGC_H) $(LTO_STREAMER_H) \
lto/lto-coff.h
lto/lto-macho.o: lto/lto-macho.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \
toplev.h $(LTO_H) $(TM_H) $(LIBIBERTY_H) $(GGC_H) $(LTO_STREAMER_H) \
lto/lto-macho.h lto/lto-endian.h
# LTO testing is done as part of C/C++/Fortran etc. testing. # LTO testing is done as part of C/C++/Fortran etc. testing.
check-lto: check-lto:
/* LTO routines for Mach-O object files.
Copyright 2010 Free Software Foundation, Inc.
Contributed by Steven Bosscher.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef LTO_MACH_O_H
#define LTO_MACH_O_H
/* On-disk file structures. */
/* Mach-O header (32 bits version). */
struct mach_o_header_32
{
unsigned char magic[4]; /* Magic number. */
unsigned char cputype[4]; /* CPU that this object is for. */
unsigned char cpusubtype[4]; /* CPU subtype. */
unsigned char filetype[4]; /* Type of file. */
unsigned char ncmds[4]; /* Number of load commands. */
unsigned char sizeofcmds[4]; /* Total size of load commands. */
unsigned char flags[4]; /* Flags for special featues. */
};
typedef struct mach_o_header_32 mach_o_header_32;
/* Mach-O header (64 bits version). */
struct mach_o_header_64
{
unsigned char magic[4]; /* Magic number. */
unsigned char cputype[4]; /* CPU that this object is for. */
unsigned char cpusubtype[4]; /* CPU subtype. */
unsigned char filetype[4]; /* Type of file. */
unsigned char ncmds[4]; /* Number of load commands. */
unsigned char sizeofcmds[4]; /* Total size of load commands. */
unsigned char flags[4]; /* Flags for special featues. */
unsigned char reserved[4]; /* Reserved. Duh. */
};
typedef struct mach_o_header_64 mach_o_header_64;
/* Magic number. */
#define MACH_O_MH_MAGIC 0xfeedface
#define MACH_O_MH_CIGAM 0xcefaedfe
#define MACH_O_MH_MAGIC_64 0xfeedfacf
#define MACH_O_MH_CIGAM_64 0xcffaedfe
/* Supported CPU types. */
#define MACH_O_CPU_TYPE_I386 7
#define MACH_O_CPU_TYPE_X86_64 7 + 0x1000000
#define MACH_O_CPU_TYPE_POWERPC 18
#define MACH_O_CPU_TYPE_POWERPC_64 18 + 0x1000000
/* Supported file types. */
#define MACH_O_MH_OBJECT 0x01
/* Mach-O load command data structure. */
struct mach_o_load_command
{
unsigned char cmd[4]; /* The type of load command. */
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
};
typedef struct mach_o_load_command mach_o_load_command;
/* Supported load commands. We support only the segment load commands. */
#define MACH_O_LC_SEGMENT 0x01
#define MACH_O_LC_SEGMENT_64 0x19
/* LC_SEGMENT load command. */
struct mach_o_segment_command_32
{
unsigned char cmd[4]; /* The type of load command (LC_SEGMENT). */
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
unsigned char segname[16]; /* Name of this segment. */
unsigned char vmaddr[4]; /* Virtual memory address of this segment. */
unsigned char vmsize[4]; /* Size there, in bytes. */
unsigned char fileoff[4]; /* Offset in bytes of the data to be mapped. */
unsigned char filesize[4]; /* Size in bytes on disk. */
unsigned char maxprot[4]; /* Maximum permitted vmem protection. */
unsigned char initprot[4]; /* Initial vmem protection. */
unsigned char nsects[4]; /* Number of sections in this segment. */
unsigned char flags[4]; /* Flags that affect the loading. */
};
typedef struct mach_o_segment_command_32 mach_o_segment_command_32;
/* LC_SEGMENT_64 load command. Only nsects matters for us, really. */
struct mach_o_segment_command_64
{
unsigned char cmd[4]; /* The type of load command (LC_SEGMENT_64). */
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
unsigned char segname[16]; /* Name of this segment. */
unsigned char vmaddr[8]; /* Virtual memory address of this segment. */
unsigned char vmsize[8]; /* Size there, in bytes. */
unsigned char fileoff[8]; /* Offset in bytes of the data to be mapped. */
unsigned char filesize[8]; /* Size in bytes on disk. */
unsigned char maxprot[4]; /* Maximum permitted vmem protection. */
unsigned char initprot[4]; /* Initial vmem protection. */
unsigned char nsects[4]; /* Number of sections in this segment. */
unsigned char flags[4]; /* Flags that affect the loading. */
};
typedef struct mach_o_segment_command_64 mach_o_segment_command_64;
/* A Mach-O 32-bits section. */
struct mach_o_section_32
{
unsigned char sectname[16]; /* Section name. */
unsigned char segname[16]; /* Segment that the section belongs to. */
unsigned char addr[4]; /* Address of this section in memory. */
unsigned char size[4]; /* Size in bytes of this section. */
unsigned char offset[4]; /* File offset of this section. */
unsigned char align[4]; /* log2 of this section's alignment. */
unsigned char reloff[4]; /* File offset of this section's relocs. */
unsigned char nreloc[4]; /* Number of relocs for this section. */
unsigned char flags[4]; /* Section flags/attributes. */
unsigned char reserved1[4];
unsigned char reserved2[4];
};
typedef struct mach_o_section_32 mach_o_section_32;
/* A Mach-O 64-bits section. */
struct mach_o_section_64
{
unsigned char sectname[16]; /* Section name. */
unsigned char segname[16]; /* Segment that the section belongs to. */
unsigned char addr[8]; /* Address of this section in memory. */
unsigned char size[8]; /* Size in bytes of this section. */
unsigned char offset[4]; /* File offset of this section. */
unsigned char align[4]; /* log2 of this section's alignment. */
unsigned char reloff[4]; /* File offset of this section's relocs. */
unsigned char nreloc[4]; /* Number of relocs for this section. */
unsigned char flags[4]; /* Section flags/attributes. */
unsigned char reserved1[4];
unsigned char reserved2[4];
unsigned char reserved3[4];
};
typedef struct mach_o_section_64 mach_o_section_64;
/* Flags for Mach-O sections. LTO sections are marked with S_ATTR_DEBUG
to instruct the linker to ignore the sections. */
#define MACH_O_S_ATTR_DEBUG 0x02000000
/* In-memory file structures. */
/* Section data in output files is made of these. */
struct lto_mach_o_data_d
{
/* Pointer to data block. */
void *d_buf;
/* Size of data block. */
ssize_t d_size;
/* Next data block for this section. */
struct lto_mach_o_data_d *next;
};
typedef struct lto_mach_o_data_d *lto_mach_o_data;
/* This struct tracks the data for a section. */
struct lto_mach_o_section_d
{
/* Singly-linked list of section's data blocks. */
lto_mach_o_data data_chain;
/* Offset in string table of the section name. */
size_t strtab_offs;
/* Section name. */
const char *name;
/* Number of trailing padding bytes needed. */
ssize_t pad_needed;
/* Raw section header data. */
size_t section_size;
union {
struct {
char sectname[16];
char segname[16];
} section;
mach_o_section_32 section_32;
mach_o_section_64 section_64;
} u;
/* Next section for this file. */
struct lto_mach_o_section_d *next;
};
typedef struct lto_mach_o_section_d *lto_mach_o_section;
DEF_VEC_P (lto_mach_o_section);
DEF_VEC_ALLOC_P (lto_mach_o_section, heap);
/* A Mach-O file. */
struct lto_mach_o_file_d
{
/* The base information. */
lto_file base;
/* Common file members: */
/* The system file descriptor for the file. */
int fd;
/* The file's overall header. */
union {
/* We make use here of the fact that section_32 and section_64
have the same layout (except for section_64.reserved3). We
read the struct of proper size, but only address the first
member of this union. */
mach_o_header_64 header;
mach_o_header_32 header_32;
mach_o_header_64 header_64;
} u;
/* All sections in a varray. */
VEC(lto_mach_o_section, heap) *section_vec;
/* Readable file members: */
/* File total size. */
off_t file_size;
/* True if this file is open for writing. */
bool writable;
/* Section containing the __section_names section. */
lto_mach_o_section section_names_section;
/* Writable file members: */
/* The currently active section. */
lto_mach_o_section scn;
/* Linked list of data which must be freed *after* the file has been
closed. This is an annoying limitation of libelf. Which has been
faithfully reproduced here. */
struct lto_char_ptr_base *data;
};
typedef struct lto_mach_o_file_d lto_mach_o_file;
#endif /* LTO_MACH_O_H */
/* LTO routines to use object files.
Copyright 2010 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "toplev.h"
#include "lto.h"
#include "tm.h"
#include "lto-streamer.h"
#include "libiberty.h"
#include "simple-object.h"
/* 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
/* Segment name for LTO sections. This is only used for Mach-O.
FIXME: This needs to be kept in sync with darwin.c. */
#define LTO_SEGMENT_NAME "__GNU_LTO"
/* An LTO file wrapped around an simple_object. */
struct lto_simple_object
{
/* The base information. */
lto_file base;
/* The system file descriptor. */
int fd;
/* The simple_object if we are reading the file. */
simple_object_read *sobj_r;
/* The simple_object if we are writing the file. */
simple_object_write *sobj_w;
/* The currently active section. */
simple_object_write_section *section;
};
/* Saved simple_object attributes. FIXME: Once set, this is never
cleared. */
static simple_object_attributes *saved_attributes;
/* Initialize FILE, an LTO file object for FILENAME. */
static void
lto_file_init (lto_file *file, const char *filename, off_t offset)
{
file->filename = filename;
file->offset = offset;
}
/* Open the file FILENAME. It WRITABLE is true, the file is opened
for write and, if necessary, created. Otherwise, the file is
opened for reading. Returns the opened file. */
lto_file *
lto_obj_file_open (const char *filename, bool writable)
{
const char *offset_p;
long loffset;
int consumed;
char *fname;
off_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
&& 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
{
fname = xstrdup (filename);
offset = 0;
}
lo = XCNEW (struct lto_simple_object);
lto_file_init ((lto_file *) lo, fname, offset);
lo->fd = open (fname,
(writable
? O_WRONLY | O_CREAT | O_BINARY
: O_RDONLY | O_BINARY),
0666);
if (lo->fd == -1)
{
error ("open %s failed: %s", fname, xstrerror (errno));
goto fail;
}
if (!writable)
{
simple_object_attributes *attrs;
lo->sobj_r = simple_object_start_read (lo->fd, offset, LTO_SEGMENT_NAME,
&errmsg, &err);
if (lo->sobj_r == NULL)
goto fail_errmsg;
attrs = simple_object_fetch_attributes (lo->sobj_r, &errmsg, &err);
if (attrs == NULL)
goto fail_errmsg;
if (saved_attributes == NULL)
saved_attributes = attrs;
else
{
errmsg = simple_object_attributes_compare (saved_attributes, attrs,
&err);
if (errmsg != NULL)
goto fail_errmsg;
}
}
else
{
gcc_assert (saved_attributes != NULL);
lo->sobj_w = simple_object_start_write (saved_attributes,
LTO_SEGMENT_NAME,
&errmsg, &err);
if (lo->sobj_w == NULL)
goto fail_errmsg;
}
return &lo->base;
fail_errmsg:
if (err == 0)
error ("%s: %s", fname, errmsg);
else
error ("%s: %s: %s", fname, errmsg, xstrerror (err));
fail:
if (lo != NULL)
lto_obj_file_close ((lto_file *) lo);
return NULL;
}
/* Close FILE. If FILE was opened for writing, it is written out
now. */
void
lto_obj_file_close (lto_file *file)
{
struct lto_simple_object *lo = (struct lto_simple_object *) file;
if (lo->sobj_r != NULL)
simple_object_release_read (lo->sobj_r);
else if (lo->sobj_w != NULL)
{
const char *errmsg;
int err;
gcc_assert (lo->base.offset == 0);
errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err);
if (errmsg != NULL)
{
if (err == 0)
fatal_error ("%s", errmsg);
else
fatal_error ("%s: %s", errmsg, xstrerror (err));
}
simple_object_release_write (lo->sobj_w);
}
if (lo->fd != -1)
{
if (close (lo->fd) < 0)
fatal_error ("close: %s", xstrerror (errno));
}
}
/* This is passed to lto_obj_add_section. */
struct lto_obj_add_section_data
{
/* The hash table of sections. */
htab_t section_hash_table;
/* The offset of this file. */
off_t base_offset;
};
/* This is called for each section in the file. */
static int
lto_obj_add_section (void *data, const char *name, off_t offset,
off_t length)
{
struct lto_obj_add_section_data *loasd =
(struct lto_obj_add_section_data *) data;
htab_t section_hash_table = (htab_t) loasd->section_hash_table;
char *new_name;
struct lto_section_slot s_slot;
void **slot;
if (strncmp (name, LTO_SECTION_NAME_PREFIX,
strlen (LTO_SECTION_NAME_PREFIX)) != 0)
return 1;
new_name = xstrdup (name);
s_slot.name = new_name;
slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
if (*slot == NULL)
{
struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
new_slot->name = new_name;
new_slot->start = loasd->base_offset + offset;
new_slot->len = length;
*slot = new_slot;
}
else
{
error ("two or more sections for %s", new_name);
return 0;
}
return 1;
}
/* Build a hash table whose key is the section name and whose data is
the start and size of each section in the .o file. */
htab_t
lto_obj_build_section_table (lto_file *lto_file)
{
struct lto_simple_object *lo = (struct lto_simple_object *) lto_file;
htab_t section_hash_table;
struct lto_obj_add_section_data loasd;
const char *errmsg;
int err;
section_hash_table = lto_obj_create_section_hash_table ();
gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL);
loasd.section_hash_table = section_hash_table;
loasd.base_offset = lo->base.offset;
errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section,
&loasd, &err);
if (errmsg != NULL)
{
if (err == 0)
error ("%s", errmsg);
else
error ("%s: %s", errmsg, xstrerror (err));
htab_delete (section_hash_table);
return NULL;
}
return section_hash_table;
}
/* The current output file. */
static lto_file *current_out_file;
/* Set the current output file. Return the old one. */
lto_file *
lto_set_current_out_file (lto_file *file)
{
lto_file *old_file;
old_file = current_out_file;
current_out_file = file;
return old_file;
}
/* Return the current output file. */
lto_file *
lto_get_current_out_file (void)
{
return current_out_file;
}
/* Begin writing a new section named NAME in the current output
file. */
void
lto_obj_begin_section (const char *name)
{
struct lto_simple_object *lo;
int align;
const char *errmsg;
int err;
lo = (struct lto_simple_object *) current_out_file;
gcc_assert (lo != NULL
&& lo->sobj_r == NULL
&& lo->sobj_w != NULL
&& lo->section == NULL);
align = exact_log2 (POINTER_SIZE / BITS_PER_UNIT);
lo->section = simple_object_write_create_section (lo->sobj_w, name, align,
&errmsg, &err);
if (lo->section == NULL)
{
if (err == 0)
fatal_error ("%s", errmsg);
else
fatal_error ("%s: %s", errmsg, xstrerror (errno));
}
}
/* Add data to a section. BLOCK is a pointer to memory containing
DATA. */
void
lto_obj_append_data (const void *data, size_t len, void *block)
{
struct lto_simple_object *lo;
const char *errmsg;
int err;
lo = (struct lto_simple_object *) current_out_file;
gcc_assert (lo != NULL && lo->section != NULL);
errmsg = simple_object_write_add_data (lo->sobj_w, lo->section, data, len,
1, &err);
if (errmsg != NULL)
{
if (err == 0)
fatal_error ("%s", errmsg);
else
fatal_error ("%s: %s", errmsg, xstrerror (errno));
}
free (block);
}
/* Stop writing to the current output section. */
void
lto_obj_end_section (void)
{
struct lto_simple_object *lo;
lo = (struct lto_simple_object *) current_out_file;
gcc_assert (lo != NULL && lo->section != NULL);
lo->section = NULL;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment