📄 outelf64.c
字号:
add_sectname("", ".debug_aranges");
add_sectname(".rela", ".debug_aranges");
add_sectname("", ".debug_pubnames");
add_sectname("", ".debug_info");
add_sectname(".rela", ".debug_info");
add_sectname("", ".debug_abbrev");
add_sectname("", ".debug_line");
add_sectname(".rela", ".debug_line");
add_sectname("", ".debug_frame");
add_sectname("", ".debug_loc");
}
/*
* Do the comment.
*/
*comment = '\0';
commlen =
2 + sprintf(comment + 1, "The Netwide Assembler %s", NASM_VER);
/*
* Output the ELF header.
*/
fwrite("\177ELF\2\1\1", 7, 1, elffp);
fputc(elf_osabi, elffp);
fputc(elf_abiver, elffp);
fwrite("\0\0\0\0\0\0\0", 7, 1, elffp);
fwriteint16_t(ET_REL, elffp); /* relocatable file */
fwriteint16_t(EM_X86_64, elffp); /* processor ID */
fwriteint32_t(1L, elffp); /* EV_CURRENT file format version */
fwriteint64_t(0L, elffp); /* no entry point */
fwriteint64_t(0L, elffp); /* no program header table */
fwriteint64_t(0x40L, elffp); /* section headers straight after
* ELF header plus alignment */
fwriteint32_t(0L, elffp); /* 386 defines no special flags */
fwriteint16_t(0x40, 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(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 */
/*
* Build the symbol table and relocation tables.
*/
symtab = elf_build_symtab(&symtablen, &symtablocal);
for (i = 0; i < nsects; i++)
if (sects[i]->head)
sects[i]->rel = elf_build_reltab(§s[i]->rellen,
sects[i]->head);
/*
* Now output the section header table.
*/
elf_foffs = 0x40 + sizeof(Elf64_Shdr) * nsections;
align = ((elf_foffs + SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
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 */
p = shstrtab + 1;
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, 1, 0, comment, false, (int32_t)commlen, 0, 0, 1, 0); /* .comment */
scount++; /* ditto */
p += strlen(p) + 1;
elf_section_header(p - shstrtab, 3, 0, shstrtab, false, (int32_t)shstrtablen, 0, 0, 1, 0); /* .shstrtab */
scount++; /* ditto */
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 */
p += strlen(p) + 1;
elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0); /* .strtab */
for (i = 0; i < nsects; i++)
if (sects[i]->head) {
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 */
/* this function call creates the stab sections in memory */
stabs64_generate();
if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
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,
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);
}
}
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();
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);
}
fwrite(align_str, align, 1, elffp);
/*
* Now output the sections.
*/
elf_write_sections();
nasm_free(elf_sects);
saa_free(symtab);
}
static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
{
struct SAA *s = saa_init(1L);
struct Symbol *sym;
uint8_t entry[24], *p;
int i;
*len = *local = 0;
/*
* First, an all-zeros entry, required by the ELF spec.
*/
saa_wbytes(s, NULL, 24L); /* null symbol table entry */
*len += 24;
(*local)++;
/*
* Next, an entry for the file name.
*/
p = entry;
WRITELONG(p, 1); /* we know it's 1st entry in strtab */
WRITESHORT(p, STT_FILE); /* type FILE */
WRITESHORT(p, SHN_ABS);
WRITEDLONG(p, (uint64_t) 0); /* no value */
WRITEDLONG(p, (uint64_t) 0); /* no size either */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
/*
* Now some standard symbols defining the segments, for relocation
* purposes.
*/
for (i = 1; i <= nsects; i++) {
p = entry;
WRITELONG(p, 0); /* no symbol name */
WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
WRITESHORT(p, i); /* section id */
WRITEDLONG(p, (uint64_t) 0); /* offset zero */
WRITEDLONG(p, (uint64_t) 0); /* size zero */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
}
/*
* Now the other local symbols.
*/
saa_rewind(syms);
while ((sym = saa_rstruct(syms))) {
if (sym->type & SYM_GLOBAL)
continue;
p = entry;
WRITELONG(p, sym->strpos); /* index into symbol string table */
WRITECHAR(p, sym->type); /* type and binding */
WRITECHAR(p, sym->other); /* visibility */
WRITESHORT(p, sym->section); /* index into section header table */
WRITEDLONG(p, (int64_t)sym->value); /* value of symbol */
WRITEDLONG(p, (int64_t)sym->size); /* size of symbol */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
}
/*
* dwarf needs symbols for debug sections
* which are relocation targets.
*/
if (of_elf64.current_dfmt == &df_dwarf) {
dwarf_infosym = *local;
p = entry;
WRITELONG(p, 0); /* no symbol name */
WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
WRITESHORT(p, debug_info); /* section id */
WRITEDLONG(p, (uint64_t) 0); /* offset zero */
WRITEDLONG(p, (uint64_t) 0); /* size zero */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
dwarf_abbrevsym = *local;
p = entry;
WRITELONG(p, 0); /* no symbol name */
WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
WRITESHORT(p, debug_abbrev); /* section id */
WRITEDLONG(p, (uint64_t) 0); /* offset zero */
WRITEDLONG(p, (uint64_t) 0); /* size zero */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
dwarf_linesym = *local;
p = entry;
WRITELONG(p, 0); /* no symbol name */
WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
WRITESHORT(p, debug_line); /* section id */
WRITEDLONG(p, (uint64_t) 0); /* offset zero */
WRITEDLONG(p, (uint64_t) 0); /* size zero */
saa_wbytes(s, entry, 24L);
*len += 24;
(*local)++;
}
/*
* Now the global symbols.
*/
saa_rewind(syms);
while ((sym = saa_rstruct(syms))) {
if (!(sym->type & SYM_GLOBAL))
continue;
p = entry;
WRITELONG(p, sym->strpos);
WRITECHAR(p, sym->type); /* type and binding */
WRITECHAR(p, sym->other); /* visibility */
WRITESHORT(p, sym->section);
WRITEDLONG(p, (int64_t)sym->value);
WRITEDLONG(p, (int64_t)sym->size);
saa_wbytes(s, entry, 24L);
*len += 24;
}
return s;
}
static struct SAA *elf_build_reltab(uint64_t *len, struct Reloc *r)
{
struct SAA *s;
uint8_t *p, entry[24];
if (!r)
return NULL;
s = saa_init(1L);
*len = 0;
while (r) {
int64_t sym = r->symbol;
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;
}
p = entry;
WRITEDLONG(p, r->address);
WRITEDLONG(p, (sym << 32) + r->type);
WRITEDLONG(p, r->offset);
saa_wbytes(s, entry, 24L);
*len += 24;
r = r->next;
}
return s;
}
static void elf_section_header(int name, int type, uint64_t flags,
void *data, bool is_saa, uint64_t datalen,
int link, int info, int align, int eltsize)
{
elf_sects[elf_nsect].data = data;
elf_sects[elf_nsect].len = datalen;
elf_sects[elf_nsect].is_saa = is_saa;
elf_nsect++;
fwriteint32_t((int32_t)name, elffp);
fwriteint32_t((int32_t)type, elffp);
fwriteint64_t((int64_t)flags, elffp);
fwriteint64_t(0L, elffp); /* no address, ever, in object files */
fwriteint64_t(type == 0 ? 0L : elf_foffs, elffp);
fwriteint64_t(datalen, elffp);
if (data)
elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1;
fwriteint32_t((int32_t)link, elffp);
fwriteint32_t((int32_t)info, elffp);
fwriteint64_t((int64_t)align, elffp);
fwriteint64_t((int64_t)eltsize, elffp);
}
static void elf_write_sections(void)
{
int i;
for (i = 0; i < elf_nsect; i++)
if (elf_sects[i].data) {
int32_t len = elf_sects[i].len;
int32_t reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1;
int32_t align = reallen - len;
if (elf_sects[i].is_saa)
saa_fpwrite(elf_sects[i].data, elffp);
else
fwrite(elf_sects[i].data, len, 1, elffp);
fwrite(align_str, align, 1, elffp);
}
}
static void elf_sect_write(struct Section *sect, const void *data, size_t len)
{
saa_wbytes(sect->data, data, len);
sect->len += len;
}
static void elf_sect_writeaddr(struct Section *sect, int64_t data, size_t len)
{
saa_writeaddr(sect->data, data, len);
sect->len += len;
}
static int32_t elf_segbase(int32_t segment)
{
return segment;
}
static int elf_directive(char *directive, char *value, int pass)
{
bool err;
int64_t n;
char *p;
if (!strcmp(directive, "osabi")) {
if (pass == 2)
return 1; /* ignore in pass 2 */
n = readnum(value, &err);
if (err) {
error(ERR_NONFATAL, "`osabi' directive requires a parameter");
return 1;
}
if (n < 0 || n > 255) {
error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
return 1;
}
elf_osabi = n;
elf_abiver = 0;
if ((p = strchr(value,',')) == NULL)
return 1;
n = readnum(p+1, &err);
if (err || n < 0 || n > 255) {
error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
return 1;
}
elf_abiver = n;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -