elf_secthead *shead;
yasm_section *sect;
unsigned long sindex;
- unsigned long addr;
} elf_objfmt_output_info;
static unsigned int elf_objfmt_parse_scnum; /* sect numbering in parser */
*ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
}
- reloc = elf_reloc_entry_new(sym, bc->offset + offset, rel, valsize);
+ reloc = elf_reloc_entry_new(sym,
+ yasm_intnum_new_uint(bc->offset + offset), rel, valsize);
if (reloc == NULL) {
yasm__error(bc->line, N_("elf: invalid relocation size"));
return 1;
yasm_xfree(bigbuf);
return 0;
}
+ else {
+ yasm_intnum *bcsize = yasm_intnum_new_uint(size);
+ yasm_intnum *mult = yasm_intnum_new_uint(multiple);
+
+ yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult, 0);
+ elf_secthead_add_size(info->shead, bcsize);
- elf_secthead_add_size(info->shead, multiple * size);
+ yasm_intnum_delete(bcsize);
+ yasm_intnum_delete(mult);
+ }
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
if (shead == NULL)
yasm_internal_error("no section header attached to section");
- /*elf_secthead_set_addr(shead, info->addr);*/
-
/* don't output header-only sections */
if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS)
{
yasm_bytecode *last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
- if (last)
- elf_secthead_add_size(shead, last->offset + last->len);
+ if (last) {
+ yasm_intnum *sectsize;
+ sectsize = yasm_intnum_new_uint(last->offset + last->len);
+ elf_secthead_add_size(shead, sectsize);
+ yasm_intnum_delete(sectsize);
+ }
elf_secthead_set_index(shead, ++info->sindex);
return 0;
}
elf_objfmt_output_bytecode);
/* Empty? Go on to next section */
- if (elf_secthead_get_size(shead) == 0)
+ if (elf_secthead_is_empty(shead))
return 0;
- info->addr += elf_secthead_get_size(shead);
elf_secthead_set_index(shead, ++info->sindex);
/* No relocations to output? Go on to next section */
unsigned long elf_symtab_nlocal;
info.f = f;
- info.addr = 0;
/* Allocate space for Ehdr by seeking forward */
if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) {
/* output known sections - includes reloc sections which aren't in yasm's
* list. Assign indices as we go. */
info.sindex = 3;
- info.addr = 0;
if (yasm_sections_traverse(sections, &info, elf_objfmt_output_section))
return;
unsigned long type = SHT_PROGBITS;
unsigned long flags = SHF_ALLOC;
unsigned long align = 4;
+ yasm_intnum *align_intn = NULL;
int flags_override = 0;
char *sectname;
int resonly = 0;
}
else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
if (0 /* win32 */) {
- /*@dependent@*/ /*@null@*/ const yasm_intnum *align_inum;
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
unsigned long addralign;
- align_inum = yasm_expr_get_intnum(&vp->param, NULL);
- if (!align_inum) {
+ align_expr = yasm_expr_get_intnum(&vp->param, NULL);
+ if (!align_expr) {
yasm__error(lindex,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
- addralign = yasm_intnum_get_uint(align_inum);
+ addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if ((addralign & (addralign - 1)) != 0) {
return NULL;
}
- /* Convert alignment into flags setting */
- align = addralign;
+ align_intn = yasm_intnum_copy(align_expr);
}
} else
yasm__warning(YASM_WARN_GENERAL, lindex,
esd = elf_secthead_new(name, type, flags,
elf_objfmt_parse_scnum++, 0, 0);
- if (align) elf_secthead_set_align(esd, align);
+ if (!align_intn)
+ align_intn = yasm_intnum_new_uint(align);
+ if (align_intn)
+ elf_secthead_set_align(esd, align_intn);
yasm_section_set_of_data(retval, &yasm_elf_LTX_objfmt, esd);
sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
1, lindex);
#define YASM_OBJFMT_ELF_INTERNAL
#include "elf.h"
-#define YASM_WRITE_64C_L(p,hi,lo) \
+#define YASM_WRITE_32I_L(p, i) do {\
+ assert(yasm_intnum_check_size(i, 32, 0, 2)); \
+ yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0, 0); \
+ p += 4; } while (0)
+
+#define YASM_WRITE_64I_L(p, i) do {\
+ assert(yasm_intnum_check_size(i, 64, 0, 2)); \
+ yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0, 0); \
+ p += 8; } while (0)
+
+#define YASM_WRITE_64C_L(p, hi, lo) do {\
YASM_WRITE_32_L(p, lo); \
- YASM_WRITE_32_L(p, hi)
+ YASM_WRITE_32_L(p, hi); } while (0)
+
+#define YASM_WRITE_64Z_L(p, i) YASM_WRITE_64C_L(p, 0, i)
static /*@dependent@*/ yasm_arch *cur_arch;
static enum {
}
/* reloc functions */
+/* takes ownership of addr */
elf_reloc_entry *
elf_reloc_entry_new(yasm_symrec *sym,
- elf_address addr,
+ yasm_intnum *addr,
int rel,
size_t valsize)
{
elf_reloc_entry *entry;
switch (cur_machine) {
case M_X86_32:
- if (valsize != 32)
+ if (valsize != 32) {
+ if (addr)
+ yasm_intnum_delete(addr);
return NULL;
+ }
break;
case M_X86_64:
if (valsize != 8 && valsize != 16 && valsize != 32 && valsize != 64)
+ {
+ if (addr)
+ yasm_intnum_delete(addr);
return NULL;
+ }
break;
default:
void
elf_reloc_entry_delete(elf_reloc_entry *entry)
{
+ if (entry->addr)
+ yasm_intnum_delete(entry->addr);
yasm_xfree(entry);
}
prev = NULL;
STAILQ_FOREACH(entry, symtab, qlink) {
- const yasm_intnum *size_intn;
+ yasm_intnum *size_intn=NULL, *value_intn=NULL;
bufp = buf;
/* get size (if specified); expr overrides stored integer */
if (entry->xsize) {
- size_intn = yasm_expr_get_intnum(&entry->xsize,
- yasm_common_calc_bc_dist);
- if (size_intn)
- entry->size = yasm_intnum_get_uint(size_intn);
- else
+ size_intn = yasm_intnum_copy(
+ yasm_expr_get_intnum(&entry->xsize, yasm_common_calc_bc_dist));
+ if (!size_intn)
yasm__error(entry->xsize->line,
- N_("size specifier not an integer expression"));
+ N_("size specifier not an integer expression"));
}
+ else
+ size_intn = yasm_intnum_new_uint(entry->size);
/* get EQU value for constants */
if (entry->sym) {
N_("EQU value not an integer expression"));
}
- entry->value = yasm_intnum_get_uint(equ_intn);
+ value_intn = yasm_intnum_copy(equ_intn);
entry->index = SHN_ABS;
yasm_expr_delete(equ_expr);
}
}
+ if (value_intn == NULL)
+ value_intn = yasm_intnum_new_uint(entry->value);
switch (cur_elf) {
case ELF32:
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
- YASM_WRITE_32_L(bufp, entry->value);
- YASM_WRITE_32_L(bufp, entry->size);
+ YASM_WRITE_32I_L(bufp, value_intn);
+ YASM_WRITE_32I_L(bufp, size_intn);
+
YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
- /* XXX: instead of turning arbitrary sized intnums to 32-bit
- * values above, write them directly here */
- YASM_WRITE_64C_L(bufp, 0, entry->value);
- YASM_WRITE_64C_L(bufp, 0, entry->size);
+ YASM_WRITE_64I_L(bufp, value_intn);
+ YASM_WRITE_64I_L(bufp, size_intn);
fwrite(buf, SYMTAB64_SIZE, 1, f);
size += SYMTAB64_SIZE;
break;
}
+
+ yasm_intnum_delete(size_intn);
+ yasm_intnum_delete(value_intn);
+
prev = entry;
}
return size;
esd->type = type;
esd->flags = flags;
- esd->addr = 0;
esd->offset = offset;
- esd->size = size;
+ esd->size = yasm_intnum_new_uint(size);
esd->link = 0;
esd->info = 0;
- esd->align = 0;
+ esd->align = NULL;
esd->entsize = 0;
esd->index = idx;
esd->nreloc = 0;
if (name && (strcmp(name->str, ".symtab") == 0)) {
- esd->align = 4;
switch (cur_elf) {
case ELF32:
esd->entsize = SYMTAB32_SIZE;
+ esd->align = yasm_intnum_new_uint(SYMTAB32_ALIGN);
break;
case ELF64:
esd->entsize = SYMTAB64_SIZE;
+ esd->align = yasm_intnum_new_uint(SYMTAB64_ALIGN);
break;
default:
if (shead == NULL)
yasm_internal_error(N_("shead is null"));
- if (shead->relocs) {
- elf_reloc_entry *r1, *r2;
- r1 = STAILQ_FIRST(shead->relocs);
- while (r1 != NULL) {
- r2 = STAILQ_NEXT(r1, qlink);
- yasm_xfree(r1);
- r1 = r2;
- }
- }
+ if (shead->align)
+ yasm_intnum_delete(shead->align);
+
+ if (shead->relocs)
+ elf_reloc_delete(shead->relocs);
+
yasm_xfree(shead);
}
fprintf(f, "EXEC ");
/*if (sect->flags & SHF_MASKPROC)
fprintf(f, "PROC-SPECIFIC"); */
- fprintf(f, "\n%*saddr=0x%lx\n", indent_level, "", sect->addr);
fprintf(f, "%*soffset=0x%lx\n", indent_level, "", sect->offset);
- fprintf(f, "%*ssize=0x%lx\n", indent_level, "", sect->size);
+ fprintf(f, "%*ssize=0x%lx\n", indent_level, "",
+ yasm_intnum_get_uint(sect->size));
fprintf(f, "%*slink=0x%x\n", indent_level, "", sect->link);
- fprintf(f, "%*salign=%ld\n", indent_level, "", sect->align);
+ fprintf(f, "%*salign=%ld\n", indent_level, "",
+ yasm_intnum_get_uint(sect->align));
fprintf(f, "%*snreloc=%ld\n", indent_level, "", sect->nreloc);
if (sect->nreloc) {
elf_reloc_entry *reloc;
fprintf(f, "%*soffset=0x%lx\n", indent_level+1, "", sect->rel_offset);
STAILQ_FOREACH(reloc, sect->relocs, qlink) {
fprintf(f, "%*s%s at 0x%lx\n", indent_level+2, "",
- yasm_symrec_get_name(reloc->sym), reloc->addr);
+ yasm_symrec_get_name(reloc->sym),
+ yasm_intnum_get_uint(reloc->addr));
}
}
}
YASM_WRITE_32_L(bufp, shead->name ? shead->name->index : 0);
YASM_WRITE_32_L(bufp, shead->type);
YASM_WRITE_32_L(bufp, shead->flags);
- YASM_WRITE_32_L(bufp, shead->addr);
+ YASM_WRITE_32_L(bufp, 0); /* vmem address */
YASM_WRITE_32_L(bufp, shead->offset);
- YASM_WRITE_32_L(bufp, shead->size);
+ YASM_WRITE_32I_L(bufp, shead->size);
YASM_WRITE_32_L(bufp, shead->link);
YASM_WRITE_32_L(bufp, shead->info);
- YASM_WRITE_32_L(bufp, shead->align);
+ if (shead->align)
+ YASM_WRITE_32I_L(bufp, shead->align);
+ else
+ YASM_WRITE_32_L(bufp, 0);
YASM_WRITE_32_L(bufp, shead->entsize);
if (fwrite(buf, SHDR32_SIZE, 1, f))
case ELF64:
YASM_WRITE_32_L(bufp, shead->name ? shead->name->index : 0);
YASM_WRITE_32_L(bufp, shead->type);
- YASM_WRITE_64C_L(bufp, 0, shead->flags);
- YASM_WRITE_64C_L(bufp, 0, shead->addr);
- YASM_WRITE_64C_L(bufp, 0, shead->offset);
- YASM_WRITE_64C_L(bufp, 0, shead->size);
+ YASM_WRITE_64Z_L(bufp, shead->flags);
+ YASM_WRITE_64Z_L(bufp, 0); /* vmem address */
+ YASM_WRITE_64Z_L(bufp, shead->offset);
+ YASM_WRITE_64I_L(bufp, shead->size);
YASM_WRITE_32_L(bufp, shead->link);
YASM_WRITE_32_L(bufp, shead->info);
- YASM_WRITE_64C_L(bufp, 0, shead->align);
- YASM_WRITE_64C_L(bufp, 0, shead->entsize);
+ if (shead->align)
+ YASM_WRITE_64I_L(bufp, shead->align);
+ else
+ YASM_WRITE_64Z_L(bufp, 0);
+ YASM_WRITE_64Z_L(bufp, shead->entsize);
if (fwrite(buf, SHDR64_SIZE, 1, f))
return SHDR64_SIZE;
shead->rel_index = sindex;
switch (cur_elf) {
+ yasm_intnum *nreloc;
+ yasm_intnum *relocsize;
+
case ELF32:
YASM_WRITE_32_L(bufp, shead->rel_name ? shead->rel_name->index : 0);
YASM_WRITE_32_L(bufp, SHT_REL);
YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */
YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */
- YASM_WRITE_32_L(bufp, 4); /* align */
+ YASM_WRITE_32_L(bufp, RELOC32_ALIGN); /* align */
YASM_WRITE_32_L(bufp, RELOC32_SIZE); /* entity size */
if (fwrite(buf, SHDR32_SIZE, 1, f))
case ELF64:
YASM_WRITE_32_L(bufp, shead->rel_name ? shead->rel_name->index : 0);
YASM_WRITE_32_L(bufp, SHT_REL);
- YASM_WRITE_64C_L(bufp, 0, 0);
- YASM_WRITE_64C_L(bufp, 0, 0);
- YASM_WRITE_64C_L(bufp, 0, shead->rel_offset);
- YASM_WRITE_64C_L(bufp, 0, RELOC64_SIZE * shead->nreloc); /* size */
+ YASM_WRITE_64Z_L(bufp, 0);
+ YASM_WRITE_64Z_L(bufp, 0);
+ YASM_WRITE_64Z_L(bufp, shead->rel_offset);
+
+ nreloc = yasm_intnum_new_uint(shead->nreloc);
+ relocsize = yasm_intnum_new_uint(RELOC64_SIZE);
+ yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
+ YASM_WRITE_64I_L(bufp, relocsize); /* size */
+ yasm_intnum_delete(nreloc);
+ yasm_intnum_delete(relocsize);
YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */
YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */
- YASM_WRITE_64C_L(bufp, 0, 8); /* align */
- YASM_WRITE_64C_L(bufp, 0, RELOC64_SIZE); /* entity size */
+ YASM_WRITE_64Z_L(bufp, RELOC64_ALIGN); /* align */
+ YASM_WRITE_64Z_L(bufp, RELOC64_SIZE); /* entity size */
if (fwrite(buf, SHDR64_SIZE, 1, f))
return SHDR64_SIZE;
bufp = buf;
switch (cur_elf) {
case ELF32:
- YASM_WRITE_32_L(bufp, reloc->addr);
+ YASM_WRITE_32I_L(bufp, reloc->addr);
YASM_WRITE_32_L(bufp, ELF32_R_INFO(r_sym, r_type));
fwrite(buf, RELOC32_SIZE, 1, f);
size += RELOC32_SIZE;
break;
case ELF64:
- YASM_WRITE_64C_L(bufp, 0, reloc->addr);
+ YASM_WRITE_64I_L(bufp, reloc->addr);
/*YASM_WRITE_64_L(bufp, ELF64_R_INFO(r_sym, r_type));*/
YASM_WRITE_64C_L(bufp, r_sym, r_type);
fwrite(buf, RELOC64_SIZE, 1, f);
return shead->type;
}
-elf_size
-elf_secthead_get_size(elf_secthead *shead)
+int
+elf_secthead_is_empty(elf_secthead *shead)
{
- return shead->size;
+ return yasm_intnum_is_zero(shead->size);
}
yasm_symrec *
return shead->sym;
}
-elf_address
-elf_secthead_set_addr(elf_secthead *shead, elf_address addr)
-{
- return shead->addr = addr;
-}
-
-elf_address
-elf_secthead_set_align(elf_secthead *shead, elf_address align)
+const yasm_intnum *
+elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align)
{
+ if (shead->align != NULL)
+ yasm_intnum_delete(shead->align);
+
return shead->align = align;
}
return shead->sym = sym;
}
-unsigned long
-elf_secthead_add_size(elf_secthead *shead, unsigned long size)
+void
+elf_secthead_add_size(elf_secthead *shead, yasm_intnum *size)
{
- return shead->size += size;
+ if (size) {
+ yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size, 0);
+ }
}
long
elf_secthead_set_file_offset(elf_secthead *shead, long pos)
{
- unsigned long align = shead->align;
+ unsigned long align = yasm_intnum_get_uint(shead->align);
if (align == 0 || align == 1) {
shead->offset = (unsigned long)pos;
YASM_WRITE_8(bufp, ELFDATA2LSB); /* data encoding :: MSB? */
YASM_WRITE_8(bufp, EV_CURRENT); /* elf version */
YASM_WRITE_8(bufp, ELFOSABI_SYSV); /* os/abi */
- YASM_WRITE_8(bufp, 0); /* SYSV v3 ABI=0 */
- while (bufp-buf < EI_NIDENT) /* e_ident padding */
+ YASM_WRITE_8(bufp, 0); /* SYSV v3 ABI=0 */
+ while (bufp-buf < EI_NIDENT) /* e_ident padding */
YASM_WRITE_8(bufp, 0);
YASM_WRITE_16_L(bufp, ET_REL); /* e_type - object file */
YASM_WRITE_16_L(bufp, EM_X86_64); /* e_machine - or others */
YASM_WRITE_32_L(bufp, EV_CURRENT); /* elf version */
- YASM_WRITE_64C_L(bufp, 0, 0); /* e_entry */
- YASM_WRITE_64C_L(bufp, 0, 0); /* e_phoff */
- YASM_WRITE_64C_L(bufp, 0, secthead_addr);/* e_shoff secthead off */
+ YASM_WRITE_64Z_L(bufp, 0); /* e_entry */
+ YASM_WRITE_64Z_L(bufp, 0); /* e_phoff */
+ YASM_WRITE_64Z_L(bufp, secthead_addr); /* e_shoff secthead off */
YASM_WRITE_32_L(bufp, 0); /* e_flags */
YASM_WRITE_16_L(bufp, EHDR64_SIZE); /* e_ehsize */