aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRishi Raj <rishiraj45035@gmail.com>2023-07-06 18:44:40 +0530
committerRishi Raj <rishiraj45035@gmail.com>2023-07-06 18:44:40 +0530
commit48ef456a8ec8b6df2f6e097a55872921b9f9b08c (patch)
tree99e30a500e266024ef915869a1c28c98d0684774
parentb13c0682ab290166a4a4c25513fec96beab5e211 (diff)
downloadgcc-48ef456a8ec8b6df2f6e097a55872921b9f9b08c.zip
gcc-48ef456a8ec8b6df2f6e097a55872921b9f9b08c.tar.gz
gcc-48ef456a8ec8b6df2f6e097a55872921b9f9b08c.tar.bz2
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>
-rw-r--r--gcc/lto-object.cc3
-rw-r--r--include/simple-object.h10
-rw-r--r--libiberty/simple-object-common.h18
-rw-r--r--libiberty/simple-object-elf.c141
-rw-r--r--libiberty/simple-object.c34
5 files changed, 201 insertions, 5 deletions
diff --git a/gcc/lto-object.cc b/gcc/lto-object.cc
index cb1c3a6..33eca5a 100644
--- a/gcc/lto-object.cc
+++ b/gcc/lto-object.cc
@@ -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)
{
diff --git a/include/simple-object.h b/include/simple-object.h
index 01f8a26..3a14184 100644
--- a/include/simple-object.h
+++ b/include/simple-object.h
@@ -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. */
diff --git a/libiberty/simple-object-common.h b/libiberty/simple-object-common.h
index b9d1055..df99c9d 100644
--- a/libiberty/simple-object-common.h
+++ b/libiberty/simple-object-common.h
@@ -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. */
diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c
index eee0703..86b7a27 100644
--- a/libiberty/simple-object-elf.c
+++ b/libiberty/simple-object-elf.c
@@ -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))
diff --git a/libiberty/simple-object.c b/libiberty/simple-object.c
index 163e58a..1f9141a 100644
--- a/libiberty/simple-object.c
+++ b/libiberty/simple-object.c
@@ -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);