ELF: eliminate hard-coded section numbers
authorH. Peter Anvin <hpa@zytor.com>
Thu, 25 Jun 2009 21:54:44 +0000 (14:54 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 25 Jun 2009 21:54:44 +0000 (14:54 -0700)
Eliminiate hard-coded section numbers, at least to the best of our
ability.  There is still a very odd piece of computation in
elf_build_reltab() which I can't really figure out...

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
doc/changes.src
output/outelf.h
output/outelf32.c
output/outelf64.c

index 60a98e9..0e7899d 100644 (file)
@@ -46,6 +46,9 @@ since 2007.
 
 \b The ELF backends no longer automatically generate a \c{.comment} section.
 
+\b Add additional "well-known" ELF sections with default attributes.  See
+   \k{elfsect}.
+
 
 \S{cl-2.05.01} Version 2.05.01
 
index 15373a3..0730521 100644 (file)
@@ -31,4 +31,33 @@ struct elf_known_section {
 };
 extern const struct elf_known_section elf_known_sections[];
 
+/*
+ * Special ELF sections (after the real sections but before debugging ones)
+ */
+#define sec_shstrtab           (nsects + 1)
+#define sec_symtab             (nsects + 2)
+#define sec_strtab             (nsects + 3)
+#define sec_numspecial         3
+
+/*
+ * Debugging ELF sections (last in the file)
+ */
+
+/* stabs */
+#define sec_stab               (nsections-3)
+#define sec_stabstr            (nsections-2)
+#define sec_rel_stab           (nsections-1)
+
+/* dwarf */
+#define sec_debug_aranges      (nsections-10)
+#define sec_rela_debug_aranges (nsections-9)
+#define sec_debug_pubnames     (nsections-8)
+#define sec_debug_info         (nsections-7)
+#define sec_rela_debug_info    (nsections-6)
+#define sec_debug_abbrev       (nsections-5)
+#define sec_debug_line         (nsections-4)
+#define sec_rela_debug_line    (nsections-3)
+#define sec_debug_frame                (nsections-2)
+#define sec_debug_loc          (nsections-1)
+
 #endif /* OUTPUT_OUTELF_H */
index 6e4b20d..eefcbff 100644 (file)
@@ -162,7 +162,6 @@ static int debug_immcall = 0;
 static struct linelist *stabslines = 0;
 static int numlinestabs = 0;
 static char *stabs_filename = 0;
-static int symtabsection;
 static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
 static int stablen, stabstrlen, stabrellen;
 
@@ -204,7 +203,7 @@ void saa_wleb128u(struct SAA *, int);
 void saa_wleb128s(struct SAA *, int);
 
 /*
- * Special section numbers which are used to define ELF special
+ * Special NASM section numbers which are used to define ELF special
  * symbols, which can be used with WRT to provide PIC and TLS
  * relocation types.
  */
@@ -326,8 +325,7 @@ static int elf_make_section(char *name, int type, int flags, int align)
     s->gsyms = NULL;
 
     if (nsects >= sectlen)
-        sects =
-            nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
+        sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
     sects[nsects++] = s;
 
     return nsects - 1;
@@ -940,7 +938,6 @@ static void elf_out(int32_t segto, const void *data,
 static void elf_write(void)
 {
     int align;
-    int scount;
     char *p;
     int i;
 
@@ -953,7 +950,7 @@ static void elf_write(void)
      * `.shstrtab', `.symtab' and `.strtab', then optionally
      * relocation sections for the user sections.
      */
-    nsections = 4;
+    nsections = sec_numspecial + 1;
     if (of_elf32.current_dfmt == &df_stabs)
         nsections += 3;
     else if (of_elf32.current_dfmt == &df_dwarf)
@@ -975,16 +972,10 @@ static void elf_write(void)
         add_sectname("", ".stab");
         add_sectname("", ".stabstr");
         add_sectname(".rel", ".stab");
-    }
-
-    else if (of_elf32.current_dfmt == &df_dwarf) {
+    } else if (of_elf32.current_dfmt == &df_dwarf) {
         /* the dwarf debug standard specifies the following ten sections,
            not all of which are currently implemented,
            although all of them are defined. */
-        #define debug_aranges (int32_t) (nsections-10)
-        #define debug_info (int32_t) (nsections-7)
-        #define debug_abbrev (int32_t) (nsections-5)
-        #define debug_line (int32_t) (nsections-4)
         add_sectname("", ".debug_aranges");
         add_sectname(".rela", ".debug_aranges");
         add_sectname("", ".debug_pubnames");
@@ -1010,15 +1001,15 @@ static void elf_write(void)
     fwriteint32_t(0L, elffp);      /* no entry point */
     fwriteint32_t(0L, elffp);      /* no program header table */
     fwriteint32_t(0x40L, elffp);   /* section headers straight after
-                                 * ELF header plus alignment */
+                                   * ELF header plus alignment */
     fwriteint32_t(0L, elffp);      /* 386 defines no special flags */
     fwriteint16_t(0x34, elffp);   /* size of ELF header */
     fwriteint16_t(0, elffp);      /* no program header table, again */
     fwriteint16_t(0, elffp);      /* still no program header table */
     fwriteint16_t(0x28, elffp);   /* size of section header */
     fwriteint16_t(nsections, elffp);      /* number of sections */
-    fwriteint16_t(nsects + 2, elffp);     /* string table section index for
-                                         * section header table */
+    fwriteint16_t(sec_shstrtab, elffp);   /* string table section index for
+                                          * section header table */
     fwriteint32_t(0L, elffp);      /* align to 0x40 bytes */
     fwriteint32_t(0L, elffp);
     fwriteint32_t(0L, elffp);
@@ -1042,30 +1033,43 @@ static void elf_write(void)
     elf_nsect = 0;
     elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
 
-    elf_section_header(0, 0, 0, NULL, false, 0L, 0, 0, 0, 0);   /* SHN_UNDEF */
-    scount = 1;                 /* needed for the stabs debugging to track the symtable section */
+    /* SHN_UNDEF */
+    elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
     p = shstrtab + 1;
+
+    /* The normal sections */
     for (i = 0; i < nsects; i++) {
         elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
                            (sects[i]->type == SHT_PROGBITS ?
                             sects[i]->data : NULL), true,
                            sects[i]->len, 0, 0, sects[i]->align, 0);
         p += strlen(p) + 1;
-        scount++;               /* dito */
     }
-    elf_section_header(p - shstrtab, 3, 0, shstrtab, false, (int32_t)shstrtablen, 0, 0, 1, 0);     /* .shstrtab */
-    scount++;                   /* dito */
+
+    /* .shstrtab */
+    elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
+                      shstrtablen, 0, 0, 1, 0);
     p += strlen(p) + 1;
-    elf_section_header(p - shstrtab, 2, 0, symtab, true, symtablen, nsects + 4, symtablocal, 4, 16);    /* .symtab */
-    symtabsection = scount;     /* now we got the symtab section index in the ELF file */
+
+    /* .symtab */
+    elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
+                      symtablen, sec_strtab, symtablocal, 4, 16);
+    p += strlen(p) + 1;
+
+    /* .strtab */
+    elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
+                      strslen, 0, 0, 1, 0);
     p += strlen(p) + 1;
-    elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0);    /* .strtab */
+
+    /* The relocation sections */
     for (i = 0; i < nsects; i++)
         if (sects[i]->head) {
+            elf_section_header(p - shstrtab, SHT_REL, 0, sects[i]->rel, true,
+                               sects[i]->rellen, sec_symtab, i + 1, 4, 8);
             p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, 9, 0, sects[i]->rel, true,
-                               sects[i]->rellen, nsects + 3, i + 1, 4, 8);
+           
         }
+
     if (of_elf32.current_dfmt == &df_stabs) {
         /* for debugging information, create the last three sections
            which are the .stab , .stabstr and .rel.stab sections respectively */
@@ -1073,59 +1077,67 @@ static void elf_write(void)
         /* this function call creates the stab sections in memory */
         stabs32_generate();
 
-        if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
+        if (stabbuf && stabstrbuf && stabrelbuf) {
+            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
+                              stablen, sec_stabstr, 0, 4, 12);
             p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, 1, 0, stabbuf, false, stablen,
-                               nsections - 2, 0, 4, 12);
 
-            p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, 3, 0, stabstrbuf, false,
+            elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
                                stabstrlen, 0, 0, 4, 0);
-
             p += strlen(p) + 1;
+
             /* link -> symtable  info -> section to refer to */
-            elf_section_header(p - shstrtab, 9, 0, stabrelbuf, false,
-                               stabrellen, symtabsection, nsections - 3, 4,
-                               8);
+            elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
+                              stabrellen, sec_symtab, sec_stab, 4, 8);
+            p += strlen(p) + 1;
         }
-    }
-    else if (of_elf32.current_dfmt == &df_dwarf) {
+    } else if (of_elf32.current_dfmt == &df_dwarf) {
             /* for dwarf debugging information, create the ten dwarf sections */
 
             /* this function call creates the dwarf sections in memory */
-            if (dwarf_fsect) dwarf32_generate();
+            if (dwarf_fsect)
+               dwarf32_generate();
 
-            p += strlen(p) + 1;
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
                                arangeslen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
-                               arangesrellen, symtabsection, debug_aranges, 1, 12);
+                               arangesrellen, sec_symtab, sec_debug_aranges,
+                              1, 12);
             p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf, false,
-                               pubnameslen, 0, 0, 1, 0);
+
+            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
+                              false, pubnameslen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
                                infolen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
-                               inforellen, symtabsection, debug_info, 1, 12);
+                               inforellen, sec_symtab, sec_debug_info, 1, 12);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
                                abbrevlen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
                                linelen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
-                               linerellen, symtabsection, debug_line, 1, 12);
+                               linerellen, sec_symtab, sec_debug_line, 1, 12);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
                                framelen, 0, 0, 8, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
                                loclen, 0, 0, 1, 0);
-
+            p += strlen(p) + 1;
     }
     fwritezero(align, elffp);
 
@@ -1213,7 +1225,7 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
         WRITELONG(p, (uint32_t) 0);        /* offset zero */
         WRITELONG(p, (uint32_t) 0);        /* size zero */
         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
-        WRITESHORT(p, debug_info);       /* section id */
+        WRITESHORT(p, sec_debug_info);       /* section id */
         saa_wbytes(s, entry, 16L);
         *len += 16;
         (*local)++;
@@ -1223,7 +1235,7 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
         WRITELONG(p, (uint32_t) 0);        /* offset zero */
         WRITELONG(p, (uint32_t) 0);        /* size zero */
         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
-        WRITESHORT(p, debug_abbrev);       /* section id */
+        WRITESHORT(p, sec_debug_abbrev);       /* section id */
         saa_wbytes(s, entry, 16L);
         *len += 16;
         (*local)++;
@@ -1233,7 +1245,7 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
         WRITELONG(p, (uint32_t) 0);        /* offset zero */
         WRITELONG(p, (uint32_t) 0);        /* size zero */
         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
-        WRITESHORT(p, debug_line);       /* section id */
+        WRITESHORT(p, sec_debug_line);       /* section id */
         saa_wbytes(s, entry, 16L);
         *len += 16;
         (*local)++;
@@ -1277,8 +1289,9 @@ static struct SAA *elf_build_reltab(int32_t *len, struct Reloc *r)
         if (sym >= GLOBAL_TEMP_BASE)
         {
            if (of_elf32.current_dfmt == &df_dwarf)
-              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
-           else   sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
+              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
+          else
+              sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
         }
 
         p = entry;
index 80fba87..d3b2c71 100644 (file)
@@ -56,7 +56,7 @@ struct Section {
     uint64_t len, size;
     uint32_t nrelocs;
     int32_t index;             /* index into sects array */
-    uint32_t type;                     /* SHT_PROGBITS or SHT_NOBITS */
+    int type;                  /* SHT_PROGBITS or SHT_NOBITS */
     uint64_t align;                    /* alignment: power of two */
     uint64_t flags;                    /* section flags */
     char *name;
@@ -326,8 +326,7 @@ static int elf_make_section(char *name, int type, int flags, int align)
     s->gsyms = NULL;
 
     if (nsects >= sectlen)
-        sects =
-            nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
+        sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
     sects[nsects++] = s;
 
     return nsects - 1;
@@ -1023,7 +1022,6 @@ static void elf_out(int32_t segto, const void *data,
 static void elf_write(void)
 {
     int align;
-    int scount;
     char *p;
     int i;
 
@@ -1036,7 +1034,7 @@ static void elf_write(void)
      * `.shstrtab', `.symtab' and `.strtab', then optionally
      * relocation sections for the user sections.
      */
-    nsections = 4;
+    nsections = sec_numspecial + 1;
     if (of_elf64.current_dfmt == &df_stabs)
         nsections += 3;
     else if (of_elf64.current_dfmt == &df_dwarf)
@@ -1100,8 +1098,8 @@ static void elf_write(void)
     fwriteint16_t(0, elffp);      /* still no program header table */
     fwriteint16_t(sizeof(Elf64_Shdr), elffp);   /* size of section header */
     fwriteint16_t(nsections, elffp);      /* number of sections */
-    fwriteint16_t(nsects + 2, elffp);     /* string table section index for
-                                         * section header table */
+    fwriteint16_t(sec_shstrtab, elffp);   /* string table section index for
+                                          * section header table */
 
     /*
      * Build the symbol table and relocation tables.
@@ -1121,30 +1119,43 @@ static void elf_write(void)
     elf_foffs += align;
     elf_nsect = 0;
     elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
-    elf_section_header(0, 0, 0, NULL, false, 0L, 0, 0, 0, 0);   /* SHN_UNDEF */
-    scount = 1;                 /* needed for the stabs debugging to track the symtable section */
+
+    /* SHN_UNDEF */
+    elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
     p = shstrtab + 1;
+
+    /* The normal sections */
     for (i = 0; i < nsects; i++) {
         elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
                            (sects[i]->type == SHT_PROGBITS ?
                             sects[i]->data : NULL), true,
                            sects[i]->len, 0, 0, sects[i]->align, 0);
         p += strlen(p) + 1;
-        scount++;               /* ditto */
     }
-    elf_section_header(p - shstrtab, 3, 0, shstrtab, false, (int32_t)shstrtablen, 0, 0, 1, 0);     /* .shstrtab */
-    scount++;                   /* ditto */
+
+    /* .shstrtab */
+    elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
+                      shstrtablen, 0, 0, 1, 0);
     p += strlen(p) + 1;
-    elf_section_header(p - shstrtab, 2, 0, symtab, true, symtablen, nsects + 4, symtablocal, 4, 24);    /* .symtab */
-    symtabsection = scount;     /* now we got the symtab section index in the ELF file */
+
+    /* .symtab */
+    elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
+                      symtablen, sec_strtab, symtablocal, 4, 24);
+    p += strlen(p) + 1;
+
+    /* .strtab */
+    elf_section_header(p - shstrtab, SHT_SYMTAB, 0, strs, true,
+                      strslen, 0, 0, 1, 0);
     p += strlen(p) + 1;
-    elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0);    /* .strtab */
+
+    /* The relocation sections */
     for (i = 0; i < nsects; i++)
         if (sects[i]->head) {
+            elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
+                               sects[i]->rellen, sec_symtab, i + 1, 4, 24);
             p += strlen(p) + 1;
-            elf_section_header(p - shstrtab,SHT_RELA, 0, sects[i]->rel, true,
-                               sects[i]->rellen, nsects + 3, i + 1, 4, 24);
         }
+
     if (of_elf64.current_dfmt == &df_stabs) {
         /* for debugging information, create the last three sections
            which are the .stab , .stabstr and .rel.stab sections respectively */
@@ -1152,59 +1163,67 @@ static void elf_write(void)
         /* this function call creates the stab sections in memory */
         stabs64_generate();
 
-        if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
+        if (stabbuf && stabstrbuf && stabrelbuf) {
+            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
+                              stablen, sec_stabstr, 0, 4, 12);
             p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, 1, 0, stabbuf, false, stablen,
-                               nsections - 2, 0, 4, 12);
 
-            p += strlen(p) + 1;
-            elf_section_header(p - shstrtab, 3, 0, stabstrbuf, false,
+            elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
                                stabstrlen, 0, 0, 4, 0);
-
             p += strlen(p) + 1;
+
             /* link -> symtable  info -> section to refer to */
-            elf_section_header(p - shstrtab, 9, 0, stabrelbuf, false,
-                               stabrellen, symtabsection, nsections - 3, 4,
-                               16);
+            elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
+                               stabrellen, symtabsection, sec_stab, 4, 16);
+            p += strlen(p) + 1;
         }
     }
     else if (of_elf64.current_dfmt == &df_dwarf) {
             /* for dwarf debugging information, create the ten dwarf sections */
 
             /* this function call creates the dwarf sections in memory */
-            if (dwarf_fsect) dwarf64_generate();
+            if (dwarf_fsect)
+               dwarf64_generate();
 
-            p += strlen(p) + 1;
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
                                arangeslen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
                                arangesrellen, symtabsection, debug_aranges, 1, 24);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf, false,
                                pubnameslen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
                                infolen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
                                inforellen, symtabsection, debug_info, 1, 24);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
                                abbrevlen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
                                linelen, 0, 0, 1, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
                                linerellen, symtabsection, debug_line, 1, 24);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
                                framelen, 0, 0, 8, 0);
             p += strlen(p) + 1;
+
             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
                                loclen, 0, 0, 1, 0);
-
+            p += strlen(p) + 1;
     }
     fwritezero(align, elffp);
 
@@ -1356,8 +1375,9 @@ static struct SAA *elf_build_reltab(uint64_t *len, struct Reloc *r)
         if (sym >= GLOBAL_TEMP_BASE)
         {
            if (of_elf64.current_dfmt == &df_dwarf)
-              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
-           else   sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
+              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
+           else
+              sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
         }
         p = entry;
         WRITEDLONG(p, r->address);