coreboot-kgpe-d16/util/cbfstool/rmodule.h
Julius Werner 84446e6e54 rmodtool: Make memlayout symbols absolute and do not relocate them
Memlayout is a mechanism to define memory areas outside the normal
program segment constructed by the linker. Therefore, it generally
doesn't make sense to relocate memlayout symbols when the program is
relocated. They tend to refer to things that are always in one specific
spot, independent of where the program is loaded.

This hasn't really hurt us in the past because the use case we have for
rmodules (ramstage on x86) just happens to not really need to refer to
any memlayout-defined areas at the moment. But that use case may come up
in the future so it's still worth fixing.

This patch declares all memlayout-defined symbols as ABSOLUTE() in the
linker, which is then reflected in the symbol table of the generated
ELF. We can then use that distinction to have rmodtool skip them when
generating the relocation table for an rmodule. (Also rearrange rmodtool
a little to make the primary string table more easily accessible to the
rest of the code, so we can refer to symbol names in debug output.)

A similar problem can come up with userspace unit tests, but we cannot
modify the userspace relocation toolchain (and for unfortunate
historical reasons, it tries to relocate even absolute symbols). We'll
just disable PIC and make those binaries fully static to avoid that
issue.

Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ic51d9add3dc463495282b365c1b6d4a9bf11dbf2
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50629
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2021-02-18 02:32:06 +00:00

85 lines
2.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef TOOL_RMODULE_H
#define TOOL_RMODULE_H
#include "elfparsing.h"
#include "common.h"
struct arch_ops {
int arch;
/* Determine if relocation is a valid type for the architecture. */
int (*valid_type)(Elf64_Rela *rel);
/* Determine if relocation should be emitted. */
int (*should_emit)(Elf64_Rela *rel);
};
/*
* The fields in rmod_context are read-only to the user. These are
* exposed for easy shareability.
*/
struct rmod_context {
/* Ops to process relocations. */
const struct arch_ops *ops;
/* endian conversion ops */
struct xdr *xdr;
/* Parsed ELF structure. */
struct parsed_elf pelf;
/* Program segment. */
Elf64_Phdr *phdr;
/* Symbol string table. */
char *strtab;
/* Collection of relocation addresses fixup in the module. */
Elf64_Xword nrelocs;
Elf64_Addr *emitted_relocs;
/* The following fields are addresses within the linked program. */
Elf64_Addr parameters_begin;
Elf64_Addr parameters_end;
Elf64_Addr bss_begin;
Elf64_Addr bss_end;
};
struct reloc_filter {
/* Return < 0 on error. 0 to ignore relocation and 1 to include
* relocation. */
int (*filter)(struct reloc_filter *f, const Elf64_Rela *r);
/* Pointer for filter provides */
void *context;
};
/*
* Parse an ELF file within the elfin buffer and fill in the elfout buffer
* with a created rmodule in ELF format. Return 0 on success, < 0 on error.
*/
int rmodule_create(const struct buffer *elfin, struct buffer *elfout);
/*
* Initialize an rmodule context from an ELF buffer. Returns 0 on scucess, < 0
* on error.
*/
int rmodule_init(struct rmod_context *ctx, const struct buffer *elfin);
/*
* Collect all the relocations that apply to the program in
* nrelocs/emitted_relocs. One can optionally provide a reloc_filter object
* to help in relocation filtering. The filter function will be called twice:
* once for counting and once for emitting. The same response should be
* provided for each call. Returns 0 on success, < 0 on error.
*/
int rmodule_collect_relocations(struct rmod_context *c, struct reloc_filter *f);
/* Clean up the memory consumed by the rmodule context. */
void rmodule_cleanup(struct rmod_context *ctx);
/*
* Create an ELF file from the passed in rmodule in the buffer. The buffer
* contents will be replaced with an ELF file. Returns 1 if buff doesn't
* contain an rmodule and < 0 on failure, 0 on success.
*/
int rmodule_stage_to_elf(Elf64_Ehdr *ehdr, struct buffer *buff);
#endif /* TOOL_RMODULE_H */