mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 12:00:03 -05:00
Compare commits
3 Commits
devel/noth
...
devel/bypa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31ff5e249d | ||
|
|
48ef456a8e | ||
|
|
b13c0682ab |
@@ -1560,6 +1560,7 @@ OBJS = \
|
||||
lto-section-out.o \
|
||||
lto-opts.o \
|
||||
lto-compress.o \
|
||||
lto-object.o \
|
||||
mcf.o \
|
||||
mode-switching.o \
|
||||
modulo-sched.o \
|
||||
|
||||
@@ -1169,6 +1169,9 @@ fbtr-bb-exclusive
|
||||
Common Ignore
|
||||
Does nothing. Preserved for backward compatibility.
|
||||
|
||||
fbypass-asm=
|
||||
Common Joined Var(flag_bypass_asm)
|
||||
|
||||
fcallgraph-info
|
||||
Common RejectNegative Var(flag_callgraph_info) Init(NO_CALLGRAPH_INFO);
|
||||
Output callgraph information on a per-file basis.
|
||||
|
||||
@@ -38,6 +38,10 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "stor-layout.h"
|
||||
#include "cgraph.h"
|
||||
#include "debug.h"
|
||||
#include "function.h"
|
||||
#include "basic-block.h"
|
||||
#include "gimple.h"
|
||||
#include "lto-streamer.h"
|
||||
|
||||
/* Do nothing; in many cases the default hook. */
|
||||
|
||||
@@ -817,6 +821,19 @@ lhd_begin_section (const char *name)
|
||||
{
|
||||
section *section;
|
||||
|
||||
if (flag_bypass_asm)
|
||||
{
|
||||
static int initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
gcc_assert (asm_out_file == NULL);
|
||||
lto_set_current_out_file (lto_obj_file_open (asm_file_name, true));
|
||||
initialized = true;
|
||||
}
|
||||
lto_obj_begin_section (name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the old section so we can restore it in lto_end_asm_section. */
|
||||
gcc_assert (!saved_section);
|
||||
saved_section = in_section;
|
||||
@@ -833,8 +850,13 @@ lhd_begin_section (const char *name)
|
||||
implementation just calls assemble_string. */
|
||||
|
||||
void
|
||||
lhd_append_data (const void *data, size_t len, void *)
|
||||
lhd_append_data (const void *data, size_t len, void *v)
|
||||
{
|
||||
if (flag_bypass_asm)
|
||||
{
|
||||
lto_obj_append_data (data, len, v);
|
||||
return;
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
timevar_push (TV_IPA_LTO_OUTPUT);
|
||||
@@ -851,6 +873,11 @@ lhd_append_data (const void *data, size_t len, void *)
|
||||
void
|
||||
lhd_end_section (void)
|
||||
{
|
||||
if (flag_bypass_asm)
|
||||
{
|
||||
lto_obj_end_section ();
|
||||
return;
|
||||
}
|
||||
if (saved_section)
|
||||
{
|
||||
switch_to_section (saved_section);
|
||||
|
||||
@@ -21,9 +21,18 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "basic-block.h"
|
||||
#include "tree-ssa-alias.h"
|
||||
#include "internal-fn.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "is-a.h"
|
||||
#include "function.h"
|
||||
#include "gimple.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "lto.h"
|
||||
#include "tm.h"
|
||||
#include "cgraph.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "lto-section-names.h"
|
||||
#include "simple-object.h"
|
||||
|
||||
@@ -133,7 +142,13 @@ lto_obj_file_open (const char *filename, bool writable)
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (saved_attributes != NULL);
|
||||
if (!saved_attributes)
|
||||
{
|
||||
lto_file *tmp = lto_obj_file_open (flag_bypass_asm, false);
|
||||
if (!tmp)
|
||||
goto fail;
|
||||
lto_obj_file_close (tmp);
|
||||
}
|
||||
lo->sobj_w = simple_object_start_write (saved_attributes,
|
||||
LTO_SEGMENT_NAME,
|
||||
&errmsg, &err);
|
||||
@@ -148,7 +163,8 @@ fail_errmsg:
|
||||
error ("%s: %s", fname, errmsg);
|
||||
else
|
||||
error ("%s: %s: %s", fname, errmsg, xstrerror (err));
|
||||
|
||||
|
||||
fail:
|
||||
if (lo->fd != -1)
|
||||
lto_obj_file_close ((lto_file *) lo);
|
||||
free (lo);
|
||||
@@ -172,7 +188,8 @@ lto_obj_file_close (lto_file *file)
|
||||
int err;
|
||||
|
||||
gcc_assert (lo->base.offset == 0);
|
||||
|
||||
/*Add __gnu_lto_slim symbol*/
|
||||
simple_object_write_add_symbol (lo->sobj_w, "__gnu_lto_slim",1,1);
|
||||
errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err);
|
||||
if (errmsg != NULL)
|
||||
{
|
||||
@@ -255,15 +272,15 @@ lto_obj_add_section (void *data, const char *name, off_t offset,
|
||||
the start and size of each section in the .o file. */
|
||||
|
||||
htab_t
|
||||
lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
|
||||
lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list,
|
||||
htab_t section_hash_table)
|
||||
{
|
||||
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;
|
||||
@@ -764,6 +764,30 @@ public:
|
||||
lto_location_cache location_cache;
|
||||
};
|
||||
|
||||
/* Hash table entry to hold the start offset and length of an LTO
|
||||
section in a .o file. */
|
||||
struct lto_section_slot
|
||||
{
|
||||
const char *name;
|
||||
intptr_t start;
|
||||
size_t len;
|
||||
struct lto_section_slot *next;
|
||||
};
|
||||
|
||||
/* A list of section slots */
|
||||
struct lto_section_list
|
||||
{
|
||||
struct lto_section_slot *first, *last;
|
||||
};
|
||||
|
||||
/* A file. */
|
||||
struct lto_file
|
||||
{
|
||||
/* The name of the file. */
|
||||
const char *filename;
|
||||
/* The offset for the object inside an ar archive file (or zero). */
|
||||
off_t offset;
|
||||
};
|
||||
|
||||
/* In lto-section-in.cc */
|
||||
extern class lto_input_block * lto_create_simple_input_block (
|
||||
@@ -903,6 +927,17 @@ void lto_output_location_and_block (struct output_block *, struct bitpack_d *,
|
||||
void lto_output_init_mode_table (void);
|
||||
void lto_prepare_function_for_streaming (cgraph_node *);
|
||||
|
||||
/* In lto-elf.c or lto-coff.c */
|
||||
extern lto_file *lto_obj_file_open (const char *filename, bool writable);
|
||||
extern void lto_obj_file_close (lto_file *file);
|
||||
struct lto_section_list;
|
||||
extern htab_t lto_obj_build_section_table (lto_file *file, struct lto_section_list *list, htab_t section_hash_table);
|
||||
extern htab_t lto_obj_create_section_hash_table (void);
|
||||
extern void lto_obj_begin_section (const char *name);
|
||||
extern void lto_obj_append_data (const void *data, size_t len, void *block);
|
||||
extern void lto_obj_end_section (void);
|
||||
extern lto_file *lto_set_current_out_file (lto_file *file);
|
||||
extern lto_file *lto_get_current_out_file (void);
|
||||
|
||||
/* In lto-cgraph.cc */
|
||||
extern bool asm_nodes_output;
|
||||
|
||||
@@ -24,9 +24,9 @@ LTO_EXE = lto1$(exeext)
|
||||
LTO_DUMP_EXE = lto-dump$(exeext)
|
||||
LTO_DUMP_INSTALL_NAME := $(shell echo lto-dump|sed '$(program_transform_name)')
|
||||
# The LTO-specific object files inclued in $(LTO_EXE).
|
||||
LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-common.o
|
||||
LTO_OBJS = lto/lto-lang.o lto/lto.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-common.o
|
||||
lto_OBJS = $(LTO_OBJS)
|
||||
LTO_DUMP_OBJS = lto/lto-lang.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-dump.o lto/lto-common.o
|
||||
LTO_DUMP_OBJS = lto/lto-lang.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-dump.o lto/lto-common.o
|
||||
lto_dump_OBJS = $(LTO_DUMP_OBJS)
|
||||
|
||||
# this is only useful in a LTO bootstrap, but this does not work right
|
||||
|
||||
@@ -2326,7 +2326,8 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count)
|
||||
struct lto_section_list section_list;
|
||||
|
||||
memset (§ion_list, 0, sizeof (struct lto_section_list));
|
||||
section_hash_table = lto_obj_build_section_table (file, §ion_list);
|
||||
section_hash_table = lto_obj_create_section_hash_table ();
|
||||
section_hash_table = lto_obj_build_section_table (file, §ion_list, section_hash_table);
|
||||
|
||||
/* Dump the details of LTO objects. */
|
||||
if (flag_lto_dump_objects)
|
||||
|
||||
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "basic-block.h"
|
||||
#include "tree.h"
|
||||
#include "gimple.h"
|
||||
#include "cgraph.h"
|
||||
#include "stringpool.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "stor-layout.h"
|
||||
@@ -35,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "lto-tree.h"
|
||||
#include "lto.h"
|
||||
#include "lto-common.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "stringpool.h"
|
||||
#include "attribs.h"
|
||||
|
||||
|
||||
@@ -21,16 +21,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
#ifndef LTO_H
|
||||
#define LTO_H
|
||||
|
||||
|
||||
/* A file. */
|
||||
struct lto_file
|
||||
{
|
||||
/* The name of the file. */
|
||||
const char *filename;
|
||||
/* The offset for the object inside an ar archive file (or zero). */
|
||||
off_t offset;
|
||||
};
|
||||
|
||||
/* In lto-lang.cc */
|
||||
extern const char *resolution_file_name;
|
||||
|
||||
@@ -39,36 +29,8 @@ extern tree lto_eh_personality (void);
|
||||
extern void lto_main (void);
|
||||
extern void lto_read_all_file_options (void);
|
||||
|
||||
/* In lto-elf.c or lto-coff.c */
|
||||
extern lto_file *lto_obj_file_open (const char *filename, bool writable);
|
||||
extern void lto_obj_file_close (lto_file *file);
|
||||
struct lto_section_list;
|
||||
extern htab_t lto_obj_build_section_table (lto_file *file, struct lto_section_list *list);
|
||||
extern htab_t lto_obj_create_section_hash_table (void);
|
||||
extern void lto_obj_begin_section (const char *name);
|
||||
extern void lto_obj_append_data (const void *data, size_t len, void *block);
|
||||
extern void lto_obj_end_section (void);
|
||||
extern lto_file *lto_set_current_out_file (lto_file *file);
|
||||
extern lto_file *lto_get_current_out_file (void);
|
||||
|
||||
extern int lto_link_dump_id, decl_merge_dump_id, partition_dump_id;
|
||||
|
||||
/* Hash table entry to hold the start offset and length of an LTO
|
||||
section in a .o file. */
|
||||
struct lto_section_slot
|
||||
{
|
||||
const char *name;
|
||||
intptr_t start;
|
||||
size_t len;
|
||||
struct lto_section_slot *next;
|
||||
};
|
||||
|
||||
/* A list of section slots */
|
||||
struct lto_section_list
|
||||
{
|
||||
struct lto_section_slot *first, *last;
|
||||
};
|
||||
|
||||
extern unsigned int lto_option_lang_mask (void);
|
||||
|
||||
#endif /* LTO_H */
|
||||
|
||||
@@ -88,6 +88,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "ipa-modref.h"
|
||||
#include "ipa-param-manipulation.h"
|
||||
#include "dbgcnt.h"
|
||||
#include "lto-streamer.h"
|
||||
|
||||
#include "selftest.h"
|
||||
|
||||
@@ -539,6 +540,12 @@ compile_file (void)
|
||||
even when user did not ask for it. */
|
||||
if (flag_generate_lto && !flag_fat_lto_objects)
|
||||
{
|
||||
if (flag_bypass_asm)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
|
||||
ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
|
||||
HOST_WIDE_INT_1U, 8);
|
||||
@@ -550,12 +557,13 @@ compile_file (void)
|
||||
HOST_WIDE_INT_1U,
|
||||
HOST_WIDE_INT_1U);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach a special .ident directive to the end of the file to identify
|
||||
the version of GCC which compiled this code. The format of the .ident
|
||||
string is patterned after the ones produced by native SVR4 compilers. */
|
||||
if (!flag_no_ident)
|
||||
if (!flag_no_ident && !flag_bypass_asm)
|
||||
{
|
||||
const char *pkg_version = "(GNU) ";
|
||||
char *ident_str;
|
||||
@@ -577,7 +585,11 @@ compile_file (void)
|
||||
/* This must be at the end. Some target ports emit end of file directives
|
||||
into the assembly file here, and hence we cannot output anything to the
|
||||
assembly file after this point. */
|
||||
targetm.asm_out.file_end ();
|
||||
|
||||
if (flag_bypass_asm)
|
||||
lto_obj_file_close (lto_get_current_out_file ());
|
||||
else
|
||||
targetm.asm_out.file_end ();
|
||||
|
||||
timevar_stop (TV_PHASE_LATE_ASM);
|
||||
}
|
||||
@@ -1819,7 +1831,8 @@ lang_dependent_init (const char *name)
|
||||
|
||||
if (!flag_wpa)
|
||||
{
|
||||
init_asm_output (name);
|
||||
if (!flag_bypass_asm)
|
||||
init_asm_output (name);
|
||||
|
||||
if (!flag_generate_lto && !flag_compare_debug)
|
||||
{
|
||||
|
||||
@@ -156,6 +156,11 @@ simple_object_start_write (simple_object_attributes *attrs,
|
||||
|
||||
typedef struct simple_object_write_section_struct simple_object_write_section;
|
||||
|
||||
/* The type simple_object_symbol is a handle for a symbol
|
||||
which is being written. */
|
||||
|
||||
typedef struct simple_object_symbol_struct simple_object_symbol;
|
||||
|
||||
/* Add a section to SIMPLE_OBJECT. NAME is the name of the new
|
||||
section. ALIGN is the required alignment expressed as the number
|
||||
of required low-order 0 bits (e.g., 2 for alignment to a 32-bit
|
||||
@@ -190,6 +195,11 @@ simple_object_write_add_data (simple_object_write *simple_object,
|
||||
extern const char *
|
||||
simple_object_write_to_file (simple_object_write *simple_object,
|
||||
int descriptor, int *err);
|
||||
/*Add a symbol to sobj struct which will be written to common in simple_
|
||||
object_write_to_file function*/
|
||||
extern void
|
||||
simple_object_write_add_symbol(simple_object_write *sobj, const char *name,
|
||||
size_t size, unsigned int align);
|
||||
|
||||
/* Release all resources associated with SIMPLE_OBJECT, including any
|
||||
simple_object_write_section's that may have been created. */
|
||||
|
||||
@@ -58,6 +58,24 @@ struct simple_object_write_struct
|
||||
simple_object_write_section *last_section;
|
||||
/* Private data for the object file format. */
|
||||
void *data;
|
||||
/*The start of the list of symbols.*/
|
||||
simple_object_symbol *symbols;
|
||||
/*The last entry in the list of symbols*/
|
||||
simple_object_symbol *last_symbol;
|
||||
};
|
||||
|
||||
/*A symbol in object file being created*/
|
||||
struct simple_object_symbol_struct
|
||||
{
|
||||
/*Next in the list of symbols attached to an
|
||||
simple_object_write*/
|
||||
simple_object_symbol *next;
|
||||
/*The name of this symbol. */
|
||||
char *name;
|
||||
/* Symbol value */
|
||||
unsigned int align;
|
||||
/* Symbol size */
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* A section in an object file being created. */
|
||||
|
||||
@@ -787,9 +787,14 @@ simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
|
||||
++shnum;
|
||||
if (shnum > 0)
|
||||
{
|
||||
/* Add a section header for the dummy section and one for
|
||||
.shstrtab. */
|
||||
/* Add a section header for the dummy section,
|
||||
and .shstrtab*/
|
||||
shnum += 2;
|
||||
/*add section header for .symtab and .strtab
|
||||
if symbol exists
|
||||
*/
|
||||
if(sobj->symbols)
|
||||
shnum += 2;
|
||||
}
|
||||
|
||||
ehdr_size = (cl == ELFCLASS32
|
||||
@@ -882,6 +887,51 @@ simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
|
||||
errmsg, err);
|
||||
}
|
||||
|
||||
/* Write out an ELF Symbol*/
|
||||
|
||||
static int
|
||||
simple_object_elf_write_symbol(simple_object_write *sobj, int descriptor,
|
||||
off_t offset, unsigned int st_name, unsigned int st_value, size_t st_size,
|
||||
unsigned char st_info, unsigned char st_other, unsigned int st_shndx,
|
||||
const char **errmsg, int *err)
|
||||
{
|
||||
struct simple_object_elf_attributes *attrs =
|
||||
(struct simple_object_elf_attributes *) sobj->data;
|
||||
const struct elf_type_functions* fns;
|
||||
unsigned char cl;
|
||||
size_t sym_size;
|
||||
unsigned char buf[sizeof (Elf64_External_Shdr)];
|
||||
|
||||
fns = attrs->type_functions;
|
||||
cl = attrs->ei_class;
|
||||
|
||||
sym_size = (cl == ELFCLASS32
|
||||
? sizeof (Elf32_External_Shdr)
|
||||
: sizeof (Elf64_External_Shdr));
|
||||
memset (buf, 0, sizeof (Elf64_External_Shdr));
|
||||
|
||||
if(cl==ELFCLASS32)
|
||||
{
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_name, Elf_Word, st_name);
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_value, Elf_Addr, st_value);
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_size, Elf_Addr, st_size);
|
||||
buf[4]=st_info;
|
||||
buf[5]=st_other;
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_shndx, Elf_Half, st_shndx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_name, Elf_Word, st_name);
|
||||
buf[4]=st_info;
|
||||
buf[5]=st_other;
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_shndx, Elf_Half, st_shndx);
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_value, Elf_Addr, st_value);
|
||||
ELF_SET_FIELD(fns, cl, Sym, buf, st_size, Elf_Addr, st_size);
|
||||
}
|
||||
return simple_object_internal_write(descriptor, offset,buf,sym_size,
|
||||
errmsg,err);
|
||||
}
|
||||
|
||||
/* Write out a complete ELF file.
|
||||
Ehdr
|
||||
initial dummy Shdr
|
||||
@@ -932,8 +982,11 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
|
||||
if (shnum == 0)
|
||||
return NULL;
|
||||
|
||||
/* Add initial dummy Shdr and .shstrtab. */
|
||||
/* Add initial dummy Shdr and .shstrtab */
|
||||
shnum += 2;
|
||||
/*add initial .symtab and .strtab if symbol exists */
|
||||
if(sobj->symbols)
|
||||
shnum += 2;
|
||||
|
||||
shdr_offset = ehdr_size;
|
||||
sh_offset = shdr_offset + shnum * shdr_size;
|
||||
@@ -1035,7 +1088,74 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
|
||||
sh_name += strlen (section->name) + 1;
|
||||
sh_offset += sh_size;
|
||||
}
|
||||
/*Write out the whole .symtab and .strtab*/
|
||||
if(sobj->symbols)
|
||||
{
|
||||
unsigned int num_sym = 1;
|
||||
simple_object_symbol *symbol;
|
||||
|
||||
for(symbol=sobj->symbols; symbol!=NULL; symbol=symbol->next)
|
||||
{
|
||||
++num_sym;
|
||||
}
|
||||
|
||||
size_t sym_size = cl==ELFCLASS32?sizeof(Elf32_External_Sym):sizeof(Elf64_External_Sym);
|
||||
size_t sh_addralign = cl==ELFCLASS32?0x04:0x08;
|
||||
size_t sh_entsize = sym_size;
|
||||
size_t sh_size = num_sym*sym_size;
|
||||
unsigned int sh_info = 2;
|
||||
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
|
||||
sh_name, SHT_SYMTAB, 0, 0, sh_offset,
|
||||
sh_size, shnum-2, sh_info,
|
||||
sh_addralign,sh_entsize, &errmsg, err))
|
||||
return errmsg;
|
||||
shdr_offset += shdr_size;
|
||||
sh_name += strlen(".symtab")+1;
|
||||
/*Writes out the dummy symbol */
|
||||
|
||||
if(!simple_object_elf_write_symbol(sobj, descriptor, sh_offset,
|
||||
0,0,0,0,0,SHN_UNDEF,&errmsg,err))
|
||||
return errmsg;
|
||||
sh_offset += sym_size;
|
||||
unsigned int st_name=1;
|
||||
for(symbol=sobj->symbols; symbol!=NULL; symbol=symbol->next)
|
||||
{
|
||||
unsigned int st_value = 1;
|
||||
unsigned int st_size = 1;
|
||||
unsigned char st_info = 17;
|
||||
if(!simple_object_elf_write_symbol(sobj, descriptor, sh_offset,
|
||||
st_name,st_value,st_size,st_info,0,SHN_COMMON,&errmsg,err))
|
||||
return errmsg;
|
||||
sh_offset += sym_size;
|
||||
st_name += strlen(symbol->name)+1;
|
||||
|
||||
}
|
||||
|
||||
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
|
||||
sh_name, SHT_STRTAB, 0, 0, sh_offset,
|
||||
st_name, 0, 0,
|
||||
1, 0, &errmsg, err))
|
||||
return errmsg;
|
||||
shdr_offset += shdr_size;
|
||||
sh_name += strlen(".strtab")+1;
|
||||
/*.strtab has a leading zero byte*/
|
||||
zero = 0;
|
||||
if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
|
||||
&errmsg, err))
|
||||
return errmsg;
|
||||
++sh_offset;
|
||||
|
||||
for(symbol=sobj->symbols;symbol!=NULL;symbol=symbol->next)
|
||||
{
|
||||
size_t len=strlen(symbol->name)+1;
|
||||
if (!simple_object_internal_write (descriptor, sh_offset,
|
||||
(const unsigned char *) symbol->name,
|
||||
len, &errmsg, err))
|
||||
return errmsg;
|
||||
sh_offset += len;
|
||||
|
||||
}
|
||||
}
|
||||
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
|
||||
sh_name, SHT_STRTAB, 0, 0, sh_offset,
|
||||
sh_name + strlen (".shstrtab") + 1, 0, 0,
|
||||
@@ -1060,7 +1180,20 @@ simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
|
||||
return errmsg;
|
||||
sh_offset += len;
|
||||
}
|
||||
|
||||
/*Adds the name .symtab and .strtab*/
|
||||
if(sobj->symbols)
|
||||
{
|
||||
if (!simple_object_internal_write (descriptor, sh_offset,
|
||||
(const unsigned char *) ".symtab",
|
||||
strlen (".symtab") + 1, &errmsg, err))
|
||||
return errmsg;
|
||||
sh_offset += strlen(".symtab")+1;
|
||||
if (!simple_object_internal_write (descriptor, sh_offset,
|
||||
(const unsigned char *) ".strtab",
|
||||
strlen (".strtab") + 1, &errmsg, err))
|
||||
return errmsg;
|
||||
sh_offset += strlen(".strtab")+1;
|
||||
}
|
||||
if (!simple_object_internal_write (descriptor, sh_offset,
|
||||
(const unsigned char *) ".shstrtab",
|
||||
strlen (".shstrtab") + 1, &errmsg, err))
|
||||
|
||||
@@ -455,6 +455,8 @@ simple_object_start_write (simple_object_attributes *attrs,
|
||||
ret->sections = NULL;
|
||||
ret->last_section = NULL;
|
||||
ret->data = data;
|
||||
ret->symbols=NULL;
|
||||
ret->last_symbol=NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -538,6 +540,28 @@ simple_object_write_to_file (simple_object_write *sobj, int descriptor,
|
||||
{
|
||||
return sobj->functions->write_to_file (sobj, descriptor, err);
|
||||
}
|
||||
/*Adds a symbol in to common*/
|
||||
void
|
||||
simple_object_write_add_symbol(simple_object_write *sobj, const char *name,
|
||||
size_t size, unsigned int align)
|
||||
{
|
||||
simple_object_symbol *symbol;
|
||||
symbol=XNEW(simple_object_symbol);
|
||||
symbol->next=NULL;
|
||||
symbol->name=xstrdup(name);
|
||||
symbol->align=align;
|
||||
symbol->size=size;
|
||||
if(sobj->last_symbol==NULL)
|
||||
{
|
||||
sobj->symbols=symbol;
|
||||
sobj->last_symbol=symbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
sobj->last_symbol->next=symbol;
|
||||
sobj->last_symbol=symbol;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release an simple_object_write. */
|
||||
|
||||
@@ -571,6 +595,16 @@ simple_object_release_write (simple_object_write *sobj)
|
||||
XDELETE (section);
|
||||
section = next_section;
|
||||
}
|
||||
simple_object_symbol *symbol,*next_symbol;
|
||||
symbol=sobj->symbols;
|
||||
while(symbol!=NULL)
|
||||
{
|
||||
next_symbol=symbol->next;
|
||||
free(symbol->name);
|
||||
XDELETE(symbol);
|
||||
symbol=next_symbol;
|
||||
|
||||
}
|
||||
|
||||
sobj->functions->release_write (sobj->data);
|
||||
XDELETE (sobj);
|
||||
|
||||
Reference in New Issue
Block a user