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:
Rishi Raj 2023-07-06 18:44:40 +05:30
parent b13c0682ab
commit 48ef456a8e
5 changed files with 201 additions and 5 deletions

View File

@ -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)
{

View File

@ -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. */

View File

@ -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. */

View File

@ -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))

View File

@ -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);