mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 01:03:07 +00:00
libdrgn: add stub s390 and s390x architectures with relocation implementation
The only relocation type I saw in Debian's kernel module debug info was R_390_32. R_390_8, R_390_16, R_390_64, R_390_PC16, R_390_PC32, and R_390_PC64 are trivial to support, as well. The Linux kernel supports many more, but hopefully they won't show up for debug info. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
6ad80feb83
commit
9ee1ccff98
@ -954,6 +954,12 @@ class Architecture(enum.Enum):
|
||||
RISCV32 = ...
|
||||
"""The 32-bit RISC-V architecture."""
|
||||
|
||||
S390X = ...
|
||||
"""The s390x architecture, a.k.a. IBM Z or z/Architecture."""
|
||||
|
||||
S390 = ...
|
||||
"""The 32-bit s390 architecture, a.k.a. System/390."""
|
||||
|
||||
UNKNOWN = ...
|
||||
"""
|
||||
An architecture which is not known to drgn. Certain features are not
|
||||
|
@ -35,6 +35,7 @@ libdrgnimpl_la_SOURCES = $(ARCH_DEFS_PYS:_defs.py=.c) \
|
||||
arch_arm.c \
|
||||
arch_i386.c \
|
||||
arch_riscv.c \
|
||||
arch_s390x.c \
|
||||
array.h \
|
||||
binary_buffer.c \
|
||||
binary_buffer.h \
|
||||
|
57
libdrgn/arch_s390x.c
Normal file
57
libdrgn/arch_s390x.c
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "platform.h" // IWYU pragma: associated
|
||||
|
||||
static struct drgn_error *
|
||||
apply_elf_reloc_s390(const struct drgn_relocating_section *relocating,
|
||||
uint64_t r_offset, uint32_t r_type,
|
||||
const int64_t *r_addend, uint64_t sym_value)
|
||||
{
|
||||
switch (r_type) {
|
||||
case R_390_NONE:
|
||||
return NULL;
|
||||
case R_390_8:
|
||||
return drgn_reloc_add8(relocating, r_offset, r_addend,
|
||||
sym_value);
|
||||
case R_390_16:
|
||||
return drgn_reloc_add16(relocating, r_offset, r_addend,
|
||||
sym_value);
|
||||
case R_390_32:
|
||||
return drgn_reloc_add32(relocating, r_offset, r_addend,
|
||||
sym_value);
|
||||
case R_390_PC32:
|
||||
return drgn_reloc_add32(relocating, r_offset, r_addend,
|
||||
sym_value
|
||||
- (relocating->addr + r_offset));
|
||||
case R_390_PC16:
|
||||
return drgn_reloc_add16(relocating, r_offset, r_addend,
|
||||
sym_value
|
||||
- (relocating->addr + r_offset));
|
||||
case R_390_64:
|
||||
return drgn_reloc_add64(relocating, r_offset, r_addend,
|
||||
sym_value);
|
||||
case R_390_PC64:
|
||||
return drgn_reloc_add64(relocating, r_offset, r_addend,
|
||||
sym_value
|
||||
- (relocating->addr + r_offset));
|
||||
default:
|
||||
return DRGN_UNKNOWN_RELOCATION_TYPE(r_type);
|
||||
}
|
||||
}
|
||||
|
||||
const struct drgn_architecture_info arch_info_s390x = {
|
||||
.name = "s390x",
|
||||
.arch = DRGN_ARCH_S390X,
|
||||
.default_flags = DRGN_PLATFORM_IS_64_BIT,
|
||||
.register_by_name = drgn_register_by_name_unknown,
|
||||
.apply_elf_reloc = apply_elf_reloc_s390,
|
||||
};
|
||||
|
||||
const struct drgn_architecture_info arch_info_s390 = {
|
||||
.name = "s390",
|
||||
.arch = DRGN_ARCH_S390,
|
||||
.default_flags = 0,
|
||||
.register_by_name = drgn_register_by_name_unknown,
|
||||
.apply_elf_reloc = apply_elf_reloc_s390,
|
||||
};
|
@ -375,6 +375,8 @@ enum drgn_architecture {
|
||||
DRGN_ARCH_PPC64,
|
||||
DRGN_ARCH_RISCV64,
|
||||
DRGN_ARCH_RISCV32,
|
||||
DRGN_ARCH_S390X,
|
||||
DRGN_ARCH_S390,
|
||||
};
|
||||
|
||||
/** Flags describing a @ref drgn_platform. */
|
||||
|
@ -36,6 +36,10 @@ static struct drgn_error *drgn_platform_from_kdump(kdump_ctx_t *ctx,
|
||||
else if (strcmp(str, KDUMP_ARCH_PPC64) == 0)
|
||||
arch = &arch_info_ppc64;
|
||||
/* libkdumpfile doesn't support RISC-V */
|
||||
else if (strcmp(str, KDUMP_ARCH_S390X) == 0)
|
||||
arch = &arch_info_s390x;
|
||||
else if (strcmp(str, KDUMP_ARCH_S390) == 0)
|
||||
arch = &arch_info_s390;
|
||||
else
|
||||
arch = &arch_info_unknown;
|
||||
|
||||
|
@ -38,6 +38,11 @@ LIBDRGN_PUBLIC const struct drgn_platform drgn_host_platform = {
|
||||
#else
|
||||
#error "unknown __riscv_xlen"
|
||||
#endif
|
||||
#elif __s390x__
|
||||
.arch = &arch_info_s390x,
|
||||
// __s390__ is also defined for s390x, so the order is important.
|
||||
#elif __s390__
|
||||
.arch = &arch_info_s390,
|
||||
#else
|
||||
.arch = &arch_info_unknown,
|
||||
#endif
|
||||
@ -77,6 +82,12 @@ drgn_platform_create(enum drgn_architecture arch,
|
||||
case DRGN_ARCH_RISCV32:
|
||||
arch_info = &arch_info_riscv32;
|
||||
break;
|
||||
case DRGN_ARCH_S390X:
|
||||
arch_info = &arch_info_s390x;
|
||||
break;
|
||||
case DRGN_ARCH_S390:
|
||||
arch_info = &arch_info_s390;
|
||||
break;
|
||||
default:
|
||||
return drgn_error_create(DRGN_ERROR_INVALID_ARGUMENT,
|
||||
"invalid architecture");
|
||||
@ -162,6 +173,12 @@ void drgn_platform_from_elf(GElf_Ehdr *ehdr, struct drgn_platform *ret)
|
||||
else
|
||||
arch = &arch_info_riscv32;
|
||||
break;
|
||||
case EM_S390:
|
||||
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
|
||||
arch = &arch_info_s390x;
|
||||
else
|
||||
arch = &arch_info_s390;
|
||||
break;
|
||||
default:
|
||||
arch = &arch_info_unknown;
|
||||
break;
|
||||
|
@ -372,6 +372,8 @@ extern const struct drgn_architecture_info arch_info_arm;
|
||||
extern const struct drgn_architecture_info arch_info_ppc64;
|
||||
extern const struct drgn_architecture_info arch_info_riscv64;
|
||||
extern const struct drgn_architecture_info arch_info_riscv32;
|
||||
extern const struct drgn_architecture_info arch_info_s390x;
|
||||
extern const struct drgn_architecture_info arch_info_s390;
|
||||
|
||||
struct drgn_platform {
|
||||
const struct drgn_architecture_info *arch;
|
||||
|
Loading…
Reference in New Issue
Block a user