mirror of git://gcc.gnu.org/git/gcc.git
libiberty: lto: Addition of .symtab in elf file.
This patch is continutaion of previous patch (bypass-asm: Bypass assembler when
generating LTO object files.).
Now the emitted object file contains .symtab along with __gnu_lto_slim symbol.
gcc/ChangeLog:
* lto-object.cc (lto_obj_file_close):
include/ChangeLog:
* simple-object.h (simple_object_write_add_symbol):
libiberty/ChangeLog:
* simple-object-common.h (struct simple_object_symbol_struct):
* simple-object-elf.c (simple_object_elf_write_ehdr):
(simple_object_elf_write_symbol):
(simple_object_elf_write_to_file):
* simple-object.c (simple_object_start_write):
(simple_object_write_add_symbol):
(simple_object_release_write):
Signed-off-by: Rishi Raj <rishiraj45035@gmail.com>
This commit is contained in:
parent
b13c0682ab
commit
48ef456a8e
|
|
@ -187,7 +187,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue