]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libiberty: lto: Addition of .symtab in elf file.
authorRishi Raj <rishiraj45035@gmail.com>
Thu, 6 Jul 2023 13:14:40 +0000 (18:44 +0530)
committerRishi Raj <rishiraj45035@gmail.com>
Thu, 6 Jul 2023 13:14:40 +0000 (18:44 +0530)
    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>
gcc/lto-object.cc
include/simple-object.h
libiberty/simple-object-common.h
libiberty/simple-object-elf.c
libiberty/simple-object.c

index cb1c3a6cfb3417efd935889f2399eaceef215095..33eca5a7d81f8eaf1e53990657f50e90f334698b 100644 (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)
        {
index 01f8a26f979925f2a04c58f0795d0a22375018f4..3a14184b12c1df76160451c57395e005c86fb4ff 100644 (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.  */
index b9d10550d88bc0eb8f7e6774d88fcd011350074d..df99c9d85acdf0df5023e3c6d3d65fbafd19618e 100644 (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.  */
index eee07039984da28d69a2c914da81995f1d1d0727..86b7a27dc7432594c0d6df5235193654ca4d2b5b 100644 (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))
index 163e58a2f3bf0cdfad570600299501079666ebbf..1f9141aedb4d9e8fcda27c6479990cab139b990a 100644 (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);