diff --git a/doc/changes.src b/doc/changes.src index 60a98e98..0e7899de 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -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 diff --git a/output/outelf.h b/output/outelf.h index 15373a3b..07305210 100644 --- a/output/outelf.h +++ b/output/outelf.h @@ -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 */ diff --git a/output/outelf32.c b/output/outelf32.c index 6e4b20d0..eefcbffc 100644 --- a/output/outelf32.c +++ b/output/outelf32.c @@ -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; - elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0); /* .strtab */ + + /* .strtab */ + elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true, + strslen, 0, 0, 1, 0); + p += strlen(p) + 1; + + /* 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; diff --git a/output/outelf64.c b/output/outelf64.c index 80fba870..d3b2c715 100644 --- a/output/outelf64.c +++ b/output/outelf64.c @@ -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; - elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0); /* .strtab */ + + /* .strtab */ + elf_section_header(p - shstrtab, SHT_SYMTAB, 0, strs, true, + strslen, 0, 0, 1, 0); + p += strlen(p) + 1; + + /* 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);