Phase 2 of 2 cleanup to elf's internal structure.

Move and rename functions for cleanliness.

New files:
elf-machine.h - machine-specific interface, and helper macros
elf-x86-x86   - support specific standard ia32
elf-x86-amd64 - support specific to amd64

Modified files:
elf.c         - update the machine structure traversal for external structures
Makefile.inc  - support the new files

svn path=/trunk/yasm/; revision=1156
0.4
Michael Urman 20 years ago
parent 77713ed0fb
commit 02c79b209c
  1. 3
      modules/objfmts/elf/Makefile.inc
  2. 85
      modules/objfmts/elf/elf-machine.h
  3. 195
      modules/objfmts/elf/elf-x86-amd64.c
  4. 168
      modules/objfmts/elf/elf-x86-x86.c
  5. 345
      modules/objfmts/elf/elf.c

@ -5,6 +5,9 @@ pkglib_LTLIBRARIES += objfmt_elf.la
objfmt_elf_la_SOURCES = modules/objfmts/elf/elf.c
objfmt_elf_la_SOURCES += modules/objfmts/elf/elf.h
objfmt_elf_la_SOURCES += modules/objfmts/elf/elf-objfmt.c
objfmt_elf_la_SOURCES += modules/objfmts/elf/elf-machine.h
objfmt_elf_la_SOURCES += modules/objfmts/elf/elf-x86-x86.c
objfmt_elf_la_SOURCES += modules/objfmts/elf/elf-x86-amd64.c
objfmt_elf_la_LDFLAGS = -module -avoid-version -no-undefined
objfmt_elf_la_LIBADD = libyasm.la
YASM_MODULES += -dlopen objfmt_elf.la

@ -0,0 +1,85 @@
/* $Id:$
* ELF object machine specific format helpers
*
* Copyright (C) 2004 Michael Urman
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ELF_MACHINE_H_INCLUDED
#define ELF_MACHINE_H_INCLUDED
#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); } while (0)
#define YASM_WRITE_64Z_L(p, i) YASM_WRITE_64C_L(p, 0, i)
typedef int(*func_accepts_size_t)(size_t);
typedef void(*func_write_symtab_entry)(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn);
typedef void(*func_write_secthead)(unsigned char *bufp, elf_secthead *shead);
typedef void(*func_write_secthead_rel)(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex);
typedef unsigned int(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc);
typedef void(*func_write_reloc)(unsigned char *bufp,
elf_reloc_entry *reloc,
unsigned int r_type,
unsigned int r_sym);
typedef void (*func_write_proghead)(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index);
typedef struct {
const char *arch;
const char *machine;
const unsigned long symtab_entry_size;
const unsigned long symtab_entry_align;
const unsigned long reloc_entry_size;
const unsigned long secthead_size;
const unsigned long proghead_size;
func_accepts_size_t accepts_reloc_size;
func_write_symtab_entry write_symtab_entry;
func_write_secthead write_secthead;
func_write_secthead_rel write_secthead_rel;
func_map_reloc_info_to_type map_reloc_info_to_type;
func_write_reloc write_reloc;
func_write_proghead write_proghead;
} elf_machine_handler;
#endif /* ELF_MACHINE_H_INCLUDED */

@ -0,0 +1,195 @@
/*
* ELF object format helpers - x86:amd64
*
* Copyright (C) 2004 Michael Urman
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <util.h>
/*@unused@*/ RCSID("$Id:$");
#define YASM_LIB_INTERNAL
#define YASM_EXPR_INTERNAL
#include <libyasm.h>
#define YASM_OBJFMT_ELF_INTERNAL
#include "elf.h"
#include "elf-machine.h"
static int
elf_x86_amd64_accepts_reloc_size(size_t val)
{
return (val&(val-1)) ? 0 : ((val & (8|16|32|64)) != 0);
}
static void
elf_x86_amd64_write_symtab_entry(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn)
{
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
if (yasm_section_is_absolute(entry->sect)) {
YASM_WRITE_16_L(bufp, SHN_ABS);
} else {
elf_secthead *shead = yasm_section_get_data(entry->sect,
&elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
YASM_WRITE_16_L(bufp, shead->index);
}
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
YASM_WRITE_64I_L(bufp, value_intn);
YASM_WRITE_64I_L(bufp, size_intn);
}
static void
elf_x86_amd64_write_secthead(unsigned char *bufp, elf_secthead *shead)
{
YASM_WRITE_32_L(bufp, shead->name ? shead->name->index : 0);
YASM_WRITE_32_L(bufp, shead->type);
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);
if (shead->align)
YASM_WRITE_64I_L(bufp, shead->align);
else
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, shead->entsize);
}
static void
elf_x86_amd64_write_secthead_rel(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex)
{
yasm_intnum *nreloc;
yasm_intnum *relocsize;
YASM_WRITE_32_L(bufp, shead->rel_name ? shead->rel_name->index : 0);
YASM_WRITE_32_L(bufp, SHT_REL);
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, shead->rel_offset);
nreloc = yasm_intnum_create_uint(shead->nreloc);
relocsize = yasm_intnum_create_uint(RELOC64_SIZE);
yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
YASM_WRITE_64I_L(bufp, relocsize); /* size */
yasm_intnum_destroy(nreloc);
yasm_intnum_destroy(relocsize);
YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */
YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */
YASM_WRITE_64Z_L(bufp, RELOC64_ALIGN); /* align */
YASM_WRITE_64Z_L(bufp, RELOC64_SIZE); /* entity size */
}
static unsigned int
elf_x86_amd64_map_reloc_info_to_type(elf_reloc_entry *reloc)
{
if (reloc->rtype_rel) {
switch (reloc->valsize) {
case 8: return (unsigned char) R_X86_64_PC8;
case 16: return (unsigned char) R_X86_64_PC16;
case 32: return (unsigned char) R_X86_64_PC32;
default: yasm_internal_error(N_("Unsupported relocation size"));
}
} else {
switch (reloc->valsize) {
case 8: return (unsigned char) R_X86_64_8;
case 16: return (unsigned char) R_X86_64_16;
case 32: return (unsigned char) R_X86_64_32;
case 64: return (unsigned char) R_X86_64_64;
default: yasm_internal_error(N_("Unsupported relocation size"));
}
}
return 0;
}
static void
elf_x86_amd64_write_reloc(unsigned char *bufp, elf_reloc_entry *reloc,
unsigned int r_type, unsigned int r_sym)
{
YASM_WRITE_64I_L(bufp, reloc->reloc.addr);
/*YASM_WRITE_64_L(bufp, ELF64_R_INFO(r_sym, r_type));*/
YASM_WRITE_64C_L(bufp, r_sym, r_type);
}
static void
elf_x86_amd64_write_proghead(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index)
{
unsigned char *bufp = *bufpp;
unsigned char *buf = bufp-4;
YASM_WRITE_8(bufp, ELFCLASS64); /* elf class */
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);
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_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 */
YASM_WRITE_16_L(bufp, 0); /* e_phentsize */
YASM_WRITE_16_L(bufp, 0); /* e_phnum */
YASM_WRITE_16_L(bufp, SHDR64_SIZE); /* e_shentsize */
YASM_WRITE_16_L(bufp, secthead_count); /* e_shnum */
YASM_WRITE_16_L(bufp, shstrtab_index); /* e_shstrndx */
*bufpp = bufp;
}
const elf_machine_handler
elf_machine_handler_x86_amd64 = {
"x86", "amd64",
SYMTAB64_SIZE, SYMTAB64_ALIGN, RELOC64_SIZE, SHDR64_SIZE, EHDR64_SIZE,
elf_x86_amd64_accepts_reloc_size,
elf_x86_amd64_write_symtab_entry,
elf_x86_amd64_write_secthead,
elf_x86_amd64_write_secthead_rel,
elf_x86_amd64_map_reloc_info_to_type,
elf_x86_amd64_write_reloc,
elf_x86_amd64_write_proghead
};

@ -0,0 +1,168 @@
/*
* ELF object format helpers - x86:x86
*
* Copyright (C) 2004 Michael Urman
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <util.h>
/*@unused@*/ RCSID("$Id:$");
#define YASM_LIB_INTERNAL
#define YASM_EXPR_INTERNAL
#include <libyasm.h>
#define YASM_OBJFMT_ELF_INTERNAL
#include "elf.h"
#include "elf-machine.h"
static int
elf_x86_x86_accepts_reloc_size(size_t val)
{
return val == 32;
}
static void
elf_x86_x86_write_symtab_entry(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn)
{
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
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) {
if (yasm_section_is_absolute(entry->sect)) {
YASM_WRITE_16_L(bufp, SHN_ABS);
} else {
elf_secthead *shead = yasm_section_get_data(entry->sect,
&elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
YASM_WRITE_16_L(bufp, shead->index);
}
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
}
static void
elf_x86_x86_write_secthead(unsigned char *bufp, elf_secthead *shead)
{
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, 0); /* vmem address */
YASM_WRITE_32_L(bufp, shead->offset);
YASM_WRITE_32I_L(bufp, shead->size);
YASM_WRITE_32_L(bufp, shead->link);
YASM_WRITE_32_L(bufp, shead->info);
if (shead->align)
YASM_WRITE_32I_L(bufp, shead->align);
else
YASM_WRITE_32_L(bufp, 0);
YASM_WRITE_32_L(bufp, shead->entsize);
}
static void
elf_x86_x86_write_secthead_rel(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex)
{
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, 0);
YASM_WRITE_32_L(bufp, 0);
YASM_WRITE_32_L(bufp, shead->rel_offset);
YASM_WRITE_32_L(bufp, RELOC32_SIZE * shead->nreloc);/* size */
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, RELOC32_ALIGN); /* align */
YASM_WRITE_32_L(bufp, RELOC32_SIZE); /* entity size */
}
static unsigned int
elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc)
{
return (reloc->rtype_rel ? R_386_PC32 : R_386_32);
}
static void
elf_x86_x86_write_reloc(unsigned char *bufp, elf_reloc_entry *reloc,
unsigned int r_type, unsigned int r_sym)
{
YASM_WRITE_32I_L(bufp, reloc->reloc.addr);
YASM_WRITE_32_L(bufp, ELF32_R_INFO((unsigned char)r_sym, (unsigned char)r_type));
}
static void
elf_x86_x86_write_proghead(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index)
{
unsigned char *bufp = *bufpp;
unsigned char *buf = bufp-4;
YASM_WRITE_8(bufp, ELFCLASS32); /* elf class */
YASM_WRITE_8(bufp, ELFDATA2LSB); /* data encoding :: MSB? */
YASM_WRITE_8(bufp, EV_CURRENT); /* elf version */
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_386); /* e_machine - or others */
YASM_WRITE_32_L(bufp, EV_CURRENT); /* elf version */
YASM_WRITE_32_L(bufp, 0); /* e_entry exection startaddr */
YASM_WRITE_32_L(bufp, 0); /* e_phoff program header off */
YASM_WRITE_32_L(bufp, secthead_addr); /* e_shoff section header off */
YASM_WRITE_32_L(bufp, 0); /* e_flags also by arch */
YASM_WRITE_16_L(bufp, EHDR32_SIZE); /* e_ehsize */
YASM_WRITE_16_L(bufp, 0); /* e_phentsize */
YASM_WRITE_16_L(bufp, 0); /* e_phnum */
YASM_WRITE_16_L(bufp, SHDR32_SIZE); /* e_shentsize */
YASM_WRITE_16_L(bufp, secthead_count); /* e_shnum */
YASM_WRITE_16_L(bufp, shstrtab_index); /* e_shstrndx */
*bufpp = bufp;
}
const elf_machine_handler
elf_machine_handler_x86_x86 = {
"x86", "x86",
SYMTAB32_SIZE, SYMTAB32_ALIGN, RELOC32_SIZE, SHDR32_SIZE, EHDR32_SIZE,
elf_x86_x86_accepts_reloc_size,
elf_x86_x86_write_symtab_entry,
elf_x86_x86_write_secthead,
elf_x86_x86_write_secthead_rel,
elf_x86_x86_map_reloc_info_to_type,
elf_x86_x86_write_reloc,
elf_x86_x86_write_proghead
};

@ -33,22 +33,7 @@
#include <libyasm.h>
#define YASM_OBJFMT_ELF_INTERNAL
#include "elf.h"
#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); } while (0)
#define YASM_WRITE_64Z_L(p, i) YASM_WRITE_64C_L(p, 0, i)
#include "elf-machine.h"
static void elf_section_data_destroy(void *data);
static void elf_secthead_print(void *data, FILE *f, int indent_level);
@ -66,317 +51,15 @@ const yasm_assoc_data_callback elf_symrec_data = {
elf_symtab_entry_print
};
typedef int(*func_accepts_size_t)(size_t);
typedef void(*func_write_symtab_entry)(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn);
typedef void(*func_write_secthead)(unsigned char *bufp, elf_secthead *shead);
typedef void(*func_write_secthead_rel)(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex);
typedef unsigned char(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc);
typedef void(*func_write_reloc)(unsigned char *bufp,
elf_reloc_entry *reloc,
unsigned char r_type,
unsigned char r_sym);
typedef void (*func_write_proghead)(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index);
typedef struct {
const char *arch;
const char *machine;
const unsigned long symtab_entry_size;
const unsigned long symtab_entry_align;
const unsigned long reloc_entry_size;
const unsigned long secthead_size;
const unsigned long proghead_size;
func_accepts_size_t accepts_reloc_size;
func_write_symtab_entry write_symtab_entry;
func_write_secthead write_secthead;
func_write_secthead_rel write_secthead_rel;
func_map_reloc_info_to_type map_reloc_info_to_type;
func_write_reloc write_reloc;
func_write_proghead write_proghead;
} elf_machine_handler;
static int elf_accept_32(size_t val)
{
return val == 32;
}
static int elf_accept_8_16_32_64(size_t val)
{
return (val&(val-1)) ? 0 : ((val & (8|16|32|64)) != 0);
}
static void elf_write_symtab_entry_x86(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn)
{
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
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) {
if (yasm_section_is_absolute(entry->sect)) {
YASM_WRITE_16_L(bufp, SHN_ABS);
} else {
elf_secthead *shead = yasm_section_get_data(entry->sect,
&elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
YASM_WRITE_16_L(bufp, shead->index);
}
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
}
static void elf_write_symtab_entry_x86_64(unsigned char *bufp,
elf_symtab_entry *entry,
yasm_intnum *value_intn,
yasm_intnum *size_intn)
{
YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
if (yasm_section_is_absolute(entry->sect)) {
YASM_WRITE_16_L(bufp, SHN_ABS);
} else {
elf_secthead *shead = yasm_section_get_data(entry->sect,
&elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
YASM_WRITE_16_L(bufp, shead->index);
}
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
YASM_WRITE_64I_L(bufp, value_intn);
YASM_WRITE_64I_L(bufp, size_intn);
}
static void elf_write_secthead_x86(unsigned char *bufp, elf_secthead *shead)
{
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, 0); /* vmem address */
YASM_WRITE_32_L(bufp, shead->offset);
YASM_WRITE_32I_L(bufp, shead->size);
YASM_WRITE_32_L(bufp, shead->link);
YASM_WRITE_32_L(bufp, shead->info);
if (shead->align)
YASM_WRITE_32I_L(bufp, shead->align);
else
YASM_WRITE_32_L(bufp, 0);
YASM_WRITE_32_L(bufp, shead->entsize);
}
static void elf_write_secthead_x86_64(unsigned char *bufp, elf_secthead *shead)
{
YASM_WRITE_32_L(bufp, shead->name ? shead->name->index : 0);
YASM_WRITE_32_L(bufp, shead->type);
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);
if (shead->align)
YASM_WRITE_64I_L(bufp, shead->align);
else
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, shead->entsize);
}
static void elf_write_secthead_rel_x86(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex)
{
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, 0);
YASM_WRITE_32_L(bufp, 0);
YASM_WRITE_32_L(bufp, shead->rel_offset);
YASM_WRITE_32_L(bufp, RELOC32_SIZE * shead->nreloc);/* size */
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, RELOC32_ALIGN); /* align */
YASM_WRITE_32_L(bufp, RELOC32_SIZE); /* entity size */
}
static void elf_write_secthead_rel_x86_64(unsigned char *bufp,
elf_secthead *shead,
elf_section_index symtab_idx,
elf_section_index sindex)
{
yasm_intnum *nreloc;
yasm_intnum *relocsize;
YASM_WRITE_32_L(bufp, shead->rel_name ? shead->rel_name->index : 0);
YASM_WRITE_32_L(bufp, SHT_REL);
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, shead->rel_offset);
nreloc = yasm_intnum_create_uint(shead->nreloc);
relocsize = yasm_intnum_create_uint(RELOC64_SIZE);
yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
YASM_WRITE_64I_L(bufp, relocsize); /* size */
yasm_intnum_destroy(nreloc);
yasm_intnum_destroy(relocsize);
YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */
YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */
YASM_WRITE_64Z_L(bufp, RELOC64_ALIGN); /* align */
YASM_WRITE_64Z_L(bufp, RELOC64_SIZE); /* entity size */
}
static unsigned char elf_map_reloc_info_to_type_x86(elf_reloc_entry *reloc)
{
return (unsigned char)(reloc->rtype_rel ? R_386_PC32 : R_386_32);
}
static unsigned char elf_map_reloc_info_to_type_x86_64(elf_reloc_entry *reloc)
{
if (reloc->rtype_rel) {
switch (reloc->valsize) {
case 8: return (unsigned char) R_X86_64_PC8;
case 16: return (unsigned char) R_X86_64_PC16;
case 32: return (unsigned char) R_X86_64_PC32;
default: yasm_internal_error(N_("Unsupported relocation size"));
}
} else {
switch (reloc->valsize) {
case 8: return (unsigned char) R_X86_64_8;
case 16: return (unsigned char) R_X86_64_16;
case 32: return (unsigned char) R_X86_64_32;
case 64: return (unsigned char) R_X86_64_64;
default: yasm_internal_error(N_("Unsupported relocation size"));
}
}
return 0;
}
static void elf_write_reloc_x86(unsigned char *bufp, elf_reloc_entry *reloc,
unsigned char r_type, unsigned char r_sym)
{
YASM_WRITE_32I_L(bufp, reloc->reloc.addr);
YASM_WRITE_32_L(bufp, ELF32_R_INFO(r_sym, r_type));
}
static void elf_write_reloc_x86_64(unsigned char *bufp, elf_reloc_entry *reloc,
unsigned char r_type, unsigned char r_sym)
{
YASM_WRITE_64I_L(bufp, reloc->reloc.addr);
/*YASM_WRITE_64_L(bufp, ELF64_R_INFO(r_sym, r_type));*/
YASM_WRITE_64C_L(bufp, r_sym, r_type);
}
extern elf_machine_handler
elf_machine_handler_x86_x86,
elf_machine_handler_x86_amd64;
static void elf_write_proghead_x86(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index)
static const elf_machine_handler *elf_machine_handlers[] =
{
unsigned char *bufp = *bufpp;
unsigned char *buf = bufp-4;
YASM_WRITE_8(bufp, ELFCLASS32); /* elf class */
YASM_WRITE_8(bufp, ELFDATA2LSB); /* data encoding :: MSB? */
YASM_WRITE_8(bufp, EV_CURRENT); /* elf version */
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_386); /* e_machine - or others */
YASM_WRITE_32_L(bufp, EV_CURRENT); /* elf version */
YASM_WRITE_32_L(bufp, 0); /* e_entry exection startaddr */
YASM_WRITE_32_L(bufp, 0); /* e_phoff program header off */
YASM_WRITE_32_L(bufp, secthead_addr); /* e_shoff section header off */
YASM_WRITE_32_L(bufp, 0); /* e_flags also by arch */
YASM_WRITE_16_L(bufp, EHDR32_SIZE); /* e_ehsize */
YASM_WRITE_16_L(bufp, 0); /* e_phentsize */
YASM_WRITE_16_L(bufp, 0); /* e_phnum */
YASM_WRITE_16_L(bufp, SHDR32_SIZE); /* e_shentsize */
YASM_WRITE_16_L(bufp, secthead_count); /* e_shnum */
YASM_WRITE_16_L(bufp, shstrtab_index); /* e_shstrndx */
*bufpp = bufp;
}
static void elf_write_proghead_x86_64(unsigned char **bufpp,
elf_offset secthead_addr,
unsigned long secthead_count,
elf_section_index shstrtab_index)
{
unsigned char *bufp = *bufpp;
unsigned char *buf = bufp-4;
YASM_WRITE_8(bufp, ELFCLASS64); /* elf class */
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);
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_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 */
YASM_WRITE_16_L(bufp, 0); /* e_phentsize */
YASM_WRITE_16_L(bufp, 0); /* e_phnum */
YASM_WRITE_16_L(bufp, SHDR64_SIZE); /* e_shentsize */
YASM_WRITE_16_L(bufp, secthead_count); /* e_shnum */
YASM_WRITE_16_L(bufp, shstrtab_index); /* e_shstrndx */
*bufpp = bufp;
}
static const elf_machine_handler elf_machine_handlers[] =
{
{ "x86", "x86",
SYMTAB32_SIZE, SYMTAB32_ALIGN, RELOC32_SIZE, SHDR32_SIZE, EHDR32_SIZE,
elf_accept_32,
elf_write_symtab_entry_x86,
elf_write_secthead_x86,
elf_write_secthead_rel_x86,
elf_map_reloc_info_to_type_x86,
elf_write_reloc_x86,
elf_write_proghead_x86
},
{ "x86", "amd64",
SYMTAB64_SIZE, SYMTAB64_ALIGN, RELOC64_SIZE, SHDR64_SIZE, EHDR64_SIZE,
elf_accept_8_16_32_64,
elf_write_symtab_entry_x86_64,
elf_write_secthead_x86_64,
elf_write_secthead_rel_x86_64,
elf_map_reloc_info_to_type_x86_64,
elf_write_reloc_x86_64,
elf_write_proghead_x86_64
},
{ NULL }
&elf_machine_handler_x86_x86,
&elf_machine_handler_x86_amd64,
NULL
};
static elf_machine_handler const *elf_march;
@ -384,13 +67,17 @@ int
elf_set_arch(yasm_arch *arch)
{
const char *machine = yasm_arch_get_machine(arch);
int i;
/* TODO: support more than x86:x86, x86:amd64 */
for (elf_march = elf_machine_handlers; elf_march->arch != NULL; elf_march++)
for (i=0, elf_march = elf_machine_handlers[0];
elf_march != NULL;
elf_march = elf_machine_handlers[++i])
{
if (yasm__strcasecmp(yasm_arch_keyword(arch), elf_march->arch)==0)
if (yasm__strcasecmp(machine, elf_march->machine)==0)
break;
return elf_march->arch != NULL;
}
return elf_march != NULL;
}
/* reloc functions */
@ -935,7 +622,7 @@ elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
while (reloc) {
yasm_sym_vis vis;
unsigned char r_type=0, r_sym;
unsigned int r_type=0, r_sym;
elf_symtab_entry *esym;
esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data);

Loading…
Cancel
Save