aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2013-06-14 16:43:15 +0100
committerIan Jackson <Ian.Jackson@eu.citrix.com>2013-06-14 16:43:15 +0100
commit9737484becab4a25159f1e985700eaee89690d34 (patch)
tree8380228a33de48c772d35c488371af9d2556ea67
parent3990446a39c17222729437e606f8d10641e3bdda (diff)
downloadxen-9737484becab4a25159f1e985700eaee89690d34.tar.gz
xen-9737484becab4a25159f1e985700eaee89690d34.tar.bz2
xen-9737484becab4a25159f1e985700eaee89690d34.zip
libelf: abolish libelf-relocate.c
This file is not actually used. It's not built in Xen's instance of libelf; in libxc's it's built but nothing in it is called. Do not compile it in libxc, and delete it. This reduces the amount of work we need to do in forthcoming patches to libelf (particularly since as libelf-relocate.c is not used it is probably full of bugs). This is part of the fix to a security issue, XSA-55. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com>
-rw-r--r--tools/libxc/Makefile2
-rw-r--r--xen/common/libelf/libelf-relocate.c372
2 files changed, 1 insertions, 373 deletions
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index ca38cbd6e3..d8c6a60a1c 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -53,7 +53,7 @@ vpath %.c ../../xen/common/libelf
CFLAGS += -I../../xen/common/libelf
GUEST_SRCS-y += libelf-tools.c libelf-loader.c
-GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
+GUEST_SRCS-y += libelf-dominfo.c
# new domain builder
GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c
diff --git a/xen/common/libelf/libelf-relocate.c b/xen/common/libelf/libelf-relocate.c
deleted file mode 100644
index 7ef4b01ca2..0000000000
--- a/xen/common/libelf/libelf-relocate.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * ELF relocation code (not used by xen kernel right now).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libelf-private.h"
-
-/* ------------------------------------------------------------------------ */
-
-static const char *rel_names_i386[] = {
- "R_386_NONE",
- "R_386_32",
- "R_386_PC32",
- "R_386_GOT32",
- "R_386_PLT32",
- "R_386_COPY",
- "R_386_GLOB_DAT",
- "R_386_JMP_SLOT",
- "R_386_RELATIVE",
- "R_386_GOTOFF",
- "R_386_GOTPC",
- "R_386_32PLT",
- "R_386_TLS_TPOFF",
- "R_386_TLS_IE",
- "R_386_TLS_GOTIE",
- "R_386_TLS_LE",
- "R_386_TLS_GD",
- "R_386_TLS_LDM",
- "R_386_16",
- "R_386_PC16",
- "R_386_8",
- "R_386_PC8",
- "R_386_TLS_GD_32",
- "R_386_TLS_GD_PUSH",
- "R_386_TLS_GD_CALL",
- "R_386_TLS_GD_POP",
- "R_386_TLS_LDM_32",
- "R_386_TLS_LDM_PUSH",
- "R_386_TLS_LDM_CALL",
- "R_386_TLS_LDM_POP",
- "R_386_TLS_LDO_32",
- "R_386_TLS_IE_32",
- "R_386_TLS_LE_32",
- "R_386_TLS_DTPMOD32",
- "R_386_TLS_DTPOFF32",
- "R_386_TLS_TPOFF32",
-};
-
-static int elf_reloc_i386(struct elf_binary *elf, int type,
- uint64_t addr, uint64_t value)
-{
- void *ptr = elf_get_ptr(elf, addr);
- uint32_t *u32;
-
- switch ( type )
- {
- case 1 /* R_386_32 */ :
- u32 = ptr;
- *u32 += elf->reloc_offset;
- break;
- case 2 /* R_386_PC32 */ :
- /* nothing */
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static const char *rel_names_x86_64[] = {
- "R_X86_64_NONE",
- "R_X86_64_64",
- "R_X86_64_PC32",
- "R_X86_64_GOT32",
- "R_X86_64_PLT32",
- "R_X86_64_COPY",
- "R_X86_64_GLOB_DAT",
- "R_X86_64_JUMP_SLOT",
- "R_X86_64_RELATIVE",
- "R_X86_64_GOTPCREL",
- "R_X86_64_32",
- "R_X86_64_32S",
- "R_X86_64_16",
- "R_X86_64_PC16",
- "R_X86_64_8",
- "R_X86_64_PC8",
- "R_X86_64_DTPMOD64",
- "R_X86_64_DTPOFF64",
- "R_X86_64_TPOFF64",
- "R_X86_64_TLSGD",
- "R_X86_64_TLSLD",
- "R_X86_64_DTPOFF32",
- "R_X86_64_GOTTPOFF",
- "R_X86_64_TPOFF32",
-};
-
-static int elf_reloc_x86_64(struct elf_binary *elf, int type,
- uint64_t addr, uint64_t value)
-{
- void *ptr = elf_get_ptr(elf, addr);
- uint64_t *u64;
- uint32_t *u32;
- int32_t *s32;
-
- switch ( type )
- {
- case 1 /* R_X86_64_64 */ :
- u64 = ptr;
- value += elf->reloc_offset;
- *u64 = value;
- break;
- case 2 /* R_X86_64_PC32 */ :
- u32 = ptr;
- *u32 = value - addr;
- if ( *u32 != (uint32_t)(value - addr) )
- {
- elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32
- " != 0x%" PRIx32 "\n",
- *u32, (uint32_t) (value - addr));
- return -1;
- }
- break;
- case 10 /* R_X86_64_32 */ :
- u32 = ptr;
- value += elf->reloc_offset;
- *u32 = value;
- if ( *u32 != value )
- {
- elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32
- " != 0x%" PRIx64 "\n",
- *u32, value);
- return -1;
- }
- break;
- case 11 /* R_X86_64_32S */ :
- s32 = ptr;
- value += elf->reloc_offset;
- *s32 = value;
- if ( *s32 != (int64_t) value )
- {
- elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32
- " != 0x%" PRIx64 "\n",
- *s32, (int64_t) value);
- return -1;
- }
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct relocs {
- const char **names;
- int count;
- int (*func) (struct elf_binary * elf, int type, uint64_t addr,
- uint64_t value);
-} relocs[] =
-/* *INDENT-OFF* */
-{
- [EM_386] = {
- .names = rel_names_i386,
- .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]),
- .func = elf_reloc_i386,
- },
- [EM_X86_64] = {
- .names = rel_names_x86_64,
- .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]),
- .func = elf_reloc_x86_64,
- }
-};
-/* *INDENT-ON* */
-
-/* ------------------------------------------------------------------------ */
-
-static const char *rela_name(int machine, int type)
-{
- if ( machine > sizeof(relocs) / sizeof(relocs[0]) )
- return "unknown mach";
- if ( !relocs[machine].names )
- return "unknown mach";
- if ( type > relocs[machine].count )
- return "unknown rela";
- return relocs[machine].names[type];
-}
-
-static int elf_reloc_section(struct elf_binary *elf,
- const elf_shdr * rels,
- const elf_shdr * sect, const elf_shdr * syms)
-{
- const void *ptr, *end;
- const elf_shdr *shdr;
- const elf_rela *rela;
- const elf_rel *rel;
- const elf_sym *sym;
- uint64_t s_type;
- uint64_t r_offset;
- uint64_t r_info;
- uint64_t r_addend;
- int r_type, r_sym;
- size_t rsize;
- uint64_t shndx, sbase, addr, value;
- const char *sname;
- int machine;
-
- machine = elf_uval(elf, elf->ehdr, e_machine);
- if ( (machine >= (sizeof(relocs) / sizeof(relocs[0]))) ||
- (relocs[machine].func == NULL) )
- {
- elf_err(elf, "%s: can't handle machine %d\n",
- __FUNCTION__, machine);
- return -1;
- }
- if ( elf_swap(elf) )
- {
- elf_err(elf, "%s: non-native byte order, relocation not supported\n",
- __FUNCTION__);
- return -1;
- }
-
- s_type = elf_uval(elf, rels, sh_type);
- rsize = (SHT_REL == s_type) ? elf_size(elf, rel) : elf_size(elf, rela);
- ptr = elf_section_start(elf, rels);
- end = elf_section_end(elf, rels);
-
- for ( ; ptr < end; ptr += rsize )
- {
- switch ( s_type )
- {
- case SHT_REL:
- rel = ptr;
- r_offset = elf_uval(elf, rel, r_offset);
- r_info = elf_uval(elf, rel, r_info);
- r_addend = 0;
- break;
- case SHT_RELA:
- rela = ptr;
- r_offset = elf_uval(elf, rela, r_offset);
- r_info = elf_uval(elf, rela, r_info);
- r_addend = elf_uval(elf, rela, r_addend);
- break;
- default:
- /* can't happen */
- return -1;
- }
- if ( elf_64bit(elf) )
- {
- r_type = ELF64_R_TYPE(r_info);
- r_sym = ELF64_R_SYM(r_info);
- }
- else
- {
- r_type = ELF32_R_TYPE(r_info);
- r_sym = ELF32_R_SYM(r_info);
- }
-
- sym = elf_sym_by_index(elf, r_sym);
- shndx = elf_uval(elf, sym, st_shndx);
- switch ( shndx )
- {
- case SHN_UNDEF:
- sname = "*UNDEF*";
- sbase = 0;
- break;
- case SHN_COMMON:
- elf_err(elf, "%s: invalid section: %" PRId64 "\n",
- __FUNCTION__, shndx);
- return -1;
- case SHN_ABS:
- sname = "*ABS*";
- sbase = 0;
- break;
- default:
- shdr = elf_shdr_by_index(elf, shndx);
- if ( shdr == NULL )
- {
- elf_err(elf, "%s: invalid section: %" PRId64 "\n",
- __FUNCTION__, shndx);
- return -1;
- }
- sname = elf_section_name(elf, shdr);
- sbase = elf_uval(elf, shdr, sh_addr);
- }
-
- addr = r_offset;
- value = elf_uval(elf, sym, st_value);
- value += r_addend;
-
- if ( elf->log_callback && (elf->verbose > 1) )
- {
- uint64_t st_name = elf_uval(elf, sym, st_name);
- const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
-
- elf_msg(elf,
- "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 ","
- " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]"
- " -> addr 0x%" PRIx64 " value 0x%" PRIx64 "\n",
- __FUNCTION__, rela_name(machine, r_type), r_type, r_offset,
- r_addend, name, elf_uval(elf, sym, st_value), sname, sbase,
- addr, value);
- }
-
- if ( relocs[machine].func(elf, r_type, addr, value) == -1 )
- {
- elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n",
- __FUNCTION__, rela_name(machine, r_type), r_type);
- return -1;
- }
- }
- return 0;
-}
-
-int elf_reloc(struct elf_binary *elf)
-{
- const elf_shdr *rels, *sect, *syms;
- uint64_t i, count, type;
-
- count = elf_shdr_count(elf);
- for ( i = 0; i < count; i++ )
- {
- rels = elf_shdr_by_index(elf, i);
- type = elf_uval(elf, rels, sh_type);
- if ( (type != SHT_REL) && (type != SHT_RELA) )
- continue;
-
- sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info));
- syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link));
- if ( NULL == sect || NULL == syms )
- continue;
-
- if ( !(elf_uval(elf, sect, sh_flags) & SHF_ALLOC) )
- {
- elf_msg(elf, "%s: relocations for %s, skipping\n",
- __FUNCTION__, elf_section_name(elf, sect));
- continue;
- }
-
- elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n",
- __FUNCTION__, elf_section_name(elf, sect),
- elf_uval(elf, sect, sh_addr));
- if ( elf_reloc_section(elf, rels, sect, syms) != 0 )
- return -1;
- }
- return 0;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */