Print this page
4383 libelf can't write extended sections when ELF_F_LAYOUT

@@ -345,11 +345,11 @@
         Elf_Scn *       s;
         register Lword  sz;
         Ehdr *          eh = elf->ed_ehdr;
         unsigned        ver = eh->e_version;
         register char   *p = (char *)eh->e_ident;
-
+        size_t          scncnt;
 
         /*
          * Ehdr and Phdr table go first
          */
         p[EI_MAG0] = ELFMAG0;

@@ -382,26 +382,26 @@
          * Loop through sections, skipping index zero.
          * Compute section size before changing hi.
          * Allow null buffers for NOBITS.
          */
 
-        if ((s = elf->ed_hdscn) == 0)
+        if ((s = elf->ed_hdscn) == 0) {
                 eh->e_shnum = 0;
-        else {
-                eh->e_shnum = 1;
-                *(Shdr*)s->s_shdr = _elf_snode_init.sb_shdr;
+                scncnt = 0;
+        } else {
+                scncnt = 1;
                 s = s->s_next;
         }
         for (; s != 0; s = s->s_next) {
                 register Dnode  *d;
                 register Lword  fsz, j;
                 Shdr *sh = s->s_shdr;
 
                 if ((s->s_myflags & SF_READY) == 0)
                         (void) _elfxx_cookscn(s);
 
-                ++eh->e_shnum;
+                ++scncnt;
                 sz = 0;
                 for (d = s->s_hdnode; d != 0; d = d->db_next) {
                         if ((fsz = elf_fsize(d->db_data.d_type, 1,
                             ver)) == 0)
                                 return (0);

@@ -423,17 +423,26 @@
         }
 
         /*
          * Shdr table last.  Comment above for phnum/phoff applies here.
          */
-        if (eh->e_shnum != 0)
+        if (scncnt != 0) {
                 /* LINTED */
                 eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver);
-        else
+                if (scncnt < SHN_LORESERVE) {
+                        eh->e_shnum = scncnt;
+                } else {
+                        Shdr *sh;
+                        sh = (Shdr *)elf->ed_hdscn->s_shdr;
+                        sh->sh_size = scncnt;
+                        eh->e_shnum = 0;
+                }
+        } else {
                 eh->e_shentsize = 0;
+        }
 
-        if ((sz = eh->e_shoff + eh->e_shentsize * eh->e_shnum) > hi)
+        if ((sz = eh->e_shoff + eh->e_shentsize * scncnt) > hi)
                 hi = sz;
 
 #ifdef TEST_SIZE
         if (test_size(hi) == 0)
                 return (0);