diff options
author | Rishi Raj <rishiraj45035@gmail.com> | 2023-07-06 18:44:40 +0530 |
---|---|---|
committer | Rishi Raj <rishiraj45035@gmail.com> | 2023-07-06 18:44:40 +0530 |
commit | 48ef456a8ec8b6df2f6e097a55872921b9f9b08c (patch) | |
tree | 99e30a500e266024ef915869a1c28c98d0684774 | |
parent | b13c0682ab290166a4a4c25513fec96beab5e211 (diff) | |
download | gcc-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.cc | 3 | ||||
-rw-r--r-- | include/simple-object.h | 10 | ||||
-rw-r--r-- | libiberty/simple-object-common.h | 18 | ||||
-rw-r--r-- | libiberty/simple-object-elf.c | 141 | ||||
-rw-r--r-- | libiberty/simple-object.c | 34 |
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); |