diff options
author | Marat Dukhan <maratek@gmail.com> | 2013-09-20 18:54:49 -0400 |
---|---|---|
committer | Cyrill Gorcunov <gorcunov@gmail.com> | 2013-09-21 13:09:03 +0400 |
commit | 91c43d789a6f8a873393dae8c7ff4f9e7a7bcf91 (patch) | |
tree | 0e8c0554b06d8661045e82fb2fcfce347e9b71ef /output | |
parent | b775985beefc968f9862d45764f7c7ad8e949299 (diff) | |
download | nasm-91c43d789a6f8a873393dae8c7ff4f9e7a7bcf91.tar.gz nasm-91c43d789a6f8a873393dae8c7ff4f9e7a7bcf91.tar.bz2 nasm-91c43d789a6f8a873393dae8c7ff4f9e7a7bcf91.zip |
coff: Support for section names longer than 8 bytes
http://bugzilla.nasm.us/show_bug.cgi?id=3392233
Signed-off-by: Marat Dukhan <maratek@gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Diffstat (limited to 'output')
-rw-r--r-- | output/outcoff.c | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/output/outcoff.c b/output/outcoff.c index 258363f..b404347 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -137,7 +137,8 @@ struct Section { int32_t index; struct Reloc *head, **tail; uint32_t flags; /* section flags */ - char name[9]; + char *name; + int32_t namepos; /* Offset of name into the strings table */ int32_t pos, relpos; }; @@ -215,7 +216,7 @@ static uint32_t strslen; static void coff_gen_init(void); static void coff_sect_write(struct Section *, const uint8_t *, uint32_t); static void coff_write(void); -static void coff_section_header(char *, int32_t, int32_t, int32_t, int32_t, int, int32_t); +static void coff_section_header(char *, int32_t, int32_t, int32_t, int32_t, int32_t, int, int32_t); static void coff_write_relocs(struct Section *); static void coff_write_symbols(void); @@ -272,6 +273,7 @@ static void coff_cleanup(int debuginfo) sects[i]->head = sects[i]->head->next; nasm_free(r); } + nasm_free(sects[i]->name); nasm_free(sects[i]); } nasm_free(sects); @@ -284,6 +286,7 @@ static void coff_cleanup(int debuginfo) static int coff_make_section(char *name, uint32_t flags) { struct Section *s; + size_t namelen; s = nasm_zalloc(sizeof(*s)); @@ -294,8 +297,20 @@ static int coff_make_section(char *name, uint32_t flags) s->index = def_seg; else s->index = seg_alloc(); - strncpy(s->name, name, 8); - s->name[8] = '\0'; + s->namepos = -1; + namelen = strlen(name); + if (namelen > 8) { + if (win32 || win64) { + s->namepos = strslen + 4; + saa_wbytes(strs, name, namelen + 1); + strslen += namelen + 1; + } else { + namelen = 8; + } + } + s->name = nasm_malloc(namelen + 1); + strncpy(s->name, name, namelen); + s->name[namelen] = '\0'; s->flags = flags; if (nsects >= sectlen) { @@ -337,9 +352,11 @@ static int32_t coff_section_names(char *name, int pass, int *bits) if (*p) *p++ = '\0'; if (strlen(name) > 8) { - nasm_error(ERR_WARNING, "COFF section names limited to 8 characters:" - " truncating"); - name[8] = '\0'; + if (!win32 && !win64) { + nasm_error(ERR_WARNING, + "COFF section names limited to 8 characters: truncating"); + name[8] = '\0'; + } } flags = 0; @@ -914,7 +931,7 @@ static void coff_write(void) */ vsize = 0L; for (i = 0; i < nsects; i++) { - coff_section_header(sects[i]->name, vsize, sects[i]->len, + coff_section_header(sects[i]->name, sects[i]->namepos, vsize, sects[i]->len, sects[i]->pos, sects[i]->relpos, sects[i]->nrelocs, sects[i]->flags); vsize += sects[i]->len; @@ -937,7 +954,7 @@ static void coff_write(void) saa_fpwrite(strs, ofile); } -static void coff_section_header(char *name, int32_t vsize, +static void coff_section_header(char *name, int32_t namepos, int32_t vsize, int32_t datalen, int32_t datapos, int32_t relpos, int nrelocs, int32_t flags) { @@ -945,8 +962,32 @@ static void coff_section_header(char *name, int32_t vsize, (void)vsize; - strncpy(padname, name, 8); - fwrite(padname, 8, 1, ofile); + if (namepos == -1) { + strncpy(padname, name, 8); + fwrite(padname, 8, 1, ofile); + } else { + /* + * If name is longer than 8 bytes, write '/' followed + * by offset into the strings table represented as + * decimal number. + */ + namepos = namepos % 100000000; + padname[0] = '/'; + padname[1] = '0' + (namepos / 1000000); + namepos = namepos % 1000000; + padname[2] = '0' + (namepos / 100000); + namepos = namepos % 100000; + padname[3] = '0' + (namepos / 10000); + namepos = namepos % 10000; + padname[4] = '0' + (namepos / 1000); + namepos = namepos % 1000; + padname[5] = '0' + (namepos / 100); + namepos = namepos % 100; + padname[6] = '0' + (namepos / 10); + namepos = namepos % 10; + padname[7] = '0' + (namepos); + fwrite(padname, 8, 1, ofile); + } fwriteint32_t(0, ofile); /* Virtual size field - set to 0 or vsize */ fwriteint32_t(0L, ofile); /* RVA/offset - we ignore */ |