Add elf x86 test case to verify it works properly.
Unsure about elf x86-64 status (relocations segfault my objdump), but
it's no *worse* than last commit.
svn path=/trunk/yasm/; revision=1029
elf_reloc_entry *reloc;
yasm_sym_vis vis;
- /* XXX: this can't be platform portable */
- if (valsize != 32) {
- yasm__error(bc->line, N_("elf: invalid relocation size"));
- return 1;
- }
-
vis = yasm_symrec_get_visibility(sym);
if (!(vis & (YASM_SYM_COMMON|YASM_SYM_EXTERN)))
{
*ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
}
- reloc = elf_reloc_entry_new(sym, bc->offset + offset, rel);
+ reloc = elf_reloc_entry_new(sym, bc->offset + offset, rel, valsize);
+ if (reloc == NULL) {
+ yasm__error(bc->line, N_("elf: invalid relocation size"));
+ return 1;
+ }
/* allocate .rel sections on a need-basis */
if (elf_secthead_append_reloc(info->shead, reloc))
elf_objfmt_parse_scnum++;
elf_reloc_entry *
elf_reloc_entry_new(yasm_symrec *sym,
elf_address addr,
- int rel)
-{
- elf_reloc_entry *entry = yasm_xmalloc(sizeof(elf_reloc_entry));
+ int rel,
+ size_t valsize)
+{
+ elf_reloc_entry *entry;
+ switch (cur_machine) {
+ case M_X86_32:
+ if (valsize != 32)
+ return NULL;
+ break;
+
+ case M_X86_64:
+ if (valsize != 8 && valsize != 16 && valsize != 32 && valsize != 64)
+ return NULL;
+ break;
+
+ default:
+ yasm_internal_error(N_("Unsupported machine for ELF output"));
+ }
+ entry = yasm_xmalloc(sizeof(elf_reloc_entry));
if (sym == NULL)
yasm_internal_error("sym is null");
entry->sym = sym;
entry->addr = addr;
entry->rtype_rel = rel;
+ entry->valsize = valsize;
return entry;
}
case ELF64:
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
-/* XXX */ YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
+ YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
elf_secthead *shead = yasm_section_get_of_data(entry->sect);
break;
case M_X86_64:
- r_type = (unsigned char)
- (reloc->rtype_rel ? R_X86_64_PC32 : R_X86_64_64);
+ if (reloc->rtype_rel) {
+ switch (reloc->valsize) {
+ case 8:
+ r_type = (unsigned char) R_X86_64_PC8;
+ break;
+ case 16:
+ r_type = (unsigned char) R_X86_64_PC16;
+ break;
+ case 32:
+ r_type = (unsigned char) R_X86_64_PC32;
+ break;
+ default:
+ yasm_internal_error(
+ N_("Unsupported relocation size"));
+ }
+ } else {
+ switch (reloc->valsize) {
+ case 8:
+ r_type = (unsigned char) R_X86_64_8;
+ break;
+ case 16:
+ r_type = (unsigned char) R_X86_64_16;
+ break;
+ case 32:
+ r_type = (unsigned char) R_X86_64_32;
+ break;
+ case 64:
+ r_type = (unsigned char) R_X86_64_64;
+ break;
+ default:
+ yasm_internal_error(
+ N_("Unsupported relocation size"));
+ }
+ }
break;
default:
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
#define ELF64_R_INFO(s,t) (((s)<<32) + ((t) & 0xffffffffL))
#define EHDR32_SIZE 52
elf_address addr;
yasm_symrec *sym;
int rtype_rel;
+ size_t valsize;
};
STAILQ_HEAD(elf_strtab_head, elf_strtab_entry);
/* reloc functions */
elf_reloc_entry *elf_reloc_entry_new(yasm_symrec *sym,
elf_address addr,
- int rel);
+ int rel,
+ size_t valsize);
void elf_reloc_entry_delete(elf_reloc_entry *entry);
elf_reloc_head *elf_relocs_new(void);
void elf_reloc_delete(elf_reloc_head *head);
EXTRA_DIST += modules/objfmts/elf/tests/elfglobal.asm
EXTRA_DIST += modules/objfmts/elf/tests/elfglobal.errwarn
EXTRA_DIST += modules/objfmts/elf/tests/elfglobal.hex
+EXTRA_DIST += modules/objfmts/elf/tests/elfreloc-err.asm
+EXTRA_DIST += modules/objfmts/elf/tests/elfreloc-err.errwarn
--- /dev/null
+EXTERN variable
+ mov eax, variable
+ mov ax, variable
+ mov al, variable
--- /dev/null
+-:3: elf: invalid relocation size
+-:4: elf: invalid relocation size