static void emit_rela_section()

in kvm/hyp/nvhe/gen-hyprel.c [360:423]


static void emit_rela_section(Elf64_Shdr *sh_rela)
{
	Elf64_Shdr *sh_orig = &elf.sh_table[elf32toh(sh_rela->sh_info)];
	const char *sh_orig_name = section_name(sh_orig);
	Elf64_Rela *rela;

	/* Skip all non-hyp sections. */
	if (!starts_with(sh_orig_name, HYP_SECTION_PREFIX))
		return;

	emit_section_prologue(sh_orig_name);

	for_each_rela(sh_rela, rela) {
		uint32_t type = (uint32_t)elf64toh(rela->r_info);

		/* Check that rela points inside the relocated section. */
		assert_lt(elf64toh(rela->r_offset), elf64toh(sh_orig->sh_size), "0x%lx");

		switch (type) {
		/*
		 * Data relocations to generate absolute addressing.
		 * Emit a hyp relocation.
		 */
		case R_AARCH64_ABS64:
			emit_rela_abs64(rela, sh_orig_name);
			break;
		/* Allow position-relative data relocations. */
		case R_AARCH64_PREL64:
		case R_AARCH64_PREL32:
		case R_AARCH64_PREL16:
		case R_AARCH64_PLT32:
			break;
		/* Allow relocations to generate PC-relative addressing. */
		case R_AARCH64_LD_PREL_LO19:
		case R_AARCH64_ADR_PREL_LO21:
		case R_AARCH64_ADR_PREL_PG_HI21:
		case R_AARCH64_ADR_PREL_PG_HI21_NC:
		case R_AARCH64_ADD_ABS_LO12_NC:
		case R_AARCH64_LDST8_ABS_LO12_NC:
		case R_AARCH64_LDST16_ABS_LO12_NC:
		case R_AARCH64_LDST32_ABS_LO12_NC:
		case R_AARCH64_LDST64_ABS_LO12_NC:
		case R_AARCH64_LDST128_ABS_LO12_NC:
			break;
		/* Allow relative relocations for control-flow instructions. */
		case R_AARCH64_TSTBR14:
		case R_AARCH64_CONDBR19:
		case R_AARCH64_JUMP26:
		case R_AARCH64_CALL26:
			break;
		/* Allow group relocations to create PC-relative offset inline. */
		case R_AARCH64_MOVW_PREL_G0:
		case R_AARCH64_MOVW_PREL_G0_NC:
		case R_AARCH64_MOVW_PREL_G1:
		case R_AARCH64_MOVW_PREL_G1_NC:
		case R_AARCH64_MOVW_PREL_G2:
		case R_AARCH64_MOVW_PREL_G2_NC:
		case R_AARCH64_MOVW_PREL_G3:
			break;
		default:
			fatal_error("Unexpected RELA type %u", type);
		}
	}
}