rmodule: use program.ld for linking
Bring rmodule linking into the common linking method.
The __rmodule_entry symbol was removed while using
a more common _start symbol. The rmodtool will honor
the entry point found within the ELF header. Add
ENV_RMODULE so that one can distinguish the environment
when generating linker scripts for rmodules. Lastly,
directly use program.ld for the rmodule.ld linker script.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built rambi and analyzed the relocatable ramstage,
     sipi_vector, and smm rmodules.
Change-Id: Iaa499eb229d8171272add9ee6d27cff75e7534ac
Signed-off-by: Aaron Durbin <adubin@chromium.org>
Reviewed-on: http://review.coreboot.org/11517
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
			
			
This commit is contained in:
		@@ -72,6 +72,9 @@ classes-y := ramstage romstage bootblock smm smmstub cpu_microcode libverstage v
 | 
			
		||||
# Add dynamic classes for rmodules
 | 
			
		||||
$(foreach supported_arch,$(ARCH_SUPPORTED), \
 | 
			
		||||
	    $(eval $(call define_class,rmodules_$(supported_arch),$(supported_arch))))
 | 
			
		||||
# Provide a macro to determine environment for free standing rmodules.
 | 
			
		||||
$(foreach supported_arch,$(ARCH_SUPPORTED), \
 | 
			
		||||
	$(eval rmodules_$(supported_arch)-generic-ccopts += -D__RMODULE__))
 | 
			
		||||
 | 
			
		||||
#######################################################################
 | 
			
		||||
# Helper functions for math and various file placement matters.
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@
 | 
			
		||||
 * Foundation, Inc.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <rules.h>
 | 
			
		||||
 | 
			
		||||
/* We use ELF as output format. So that we can debug the code in some form. */
 | 
			
		||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
 | 
			
		||||
OUTPUT_ARCH(aarch64)
 | 
			
		||||
@@ -26,7 +28,13 @@ PHDRS
 | 
			
		||||
	to_load PT_LOAD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __BOOTBLOCK__
 | 
			
		||||
#if ENV_BOOTBLOCK
 | 
			
		||||
TARGET(binary)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* secmon uses rmodules */
 | 
			
		||||
#if ENV_RMODULE
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
#else
 | 
			
		||||
ENTRY(stage_entry)
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -136,12 +136,12 @@ ENDPROC(arm64_c_environment)
 | 
			
		||||
	2002:
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
ENTRY(__rmodule_entry)
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
	split_bsp_path
 | 
			
		||||
	/* Save the arguments to secmon in x25 */
 | 
			
		||||
	mov	x25, x0
 | 
			
		||||
	b	arm64_c_environment
 | 
			
		||||
ENDPROC(__rmodule_entry)
 | 
			
		||||
ENDPROC(_start)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup SCTLR so that:
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,6 @@ thread_stacks:
 | 
			
		||||
	.code32
 | 
			
		||||
#endif
 | 
			
		||||
	.globl _start
 | 
			
		||||
	.globl __rmodule_entry
 | 
			
		||||
__rmodule_entry:
 | 
			
		||||
_start:
 | 
			
		||||
	cli
 | 
			
		||||
	lgdt	%cs:gdtaddr
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ PHDRS
 | 
			
		||||
	to_load PT_LOAD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENV_RAMSTAGE
 | 
			
		||||
#if ENV_RAMSTAGE || ENV_RMODULE
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
#elif ENV_ROMSTAGE
 | 
			
		||||
ENTRY(protected_start)
 | 
			
		||||
 
 | 
			
		||||
@@ -20,9 +20,9 @@ $(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules_$(ARCH-ramstage-y).o
 | 
			
		||||
	$(CC_rmodules_$(ARCH-ramstage-y)) $(CFLAGS_rmodules_$(ARCH-ramstage-y)) -nostdlib -r -o $@ $^
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
 | 
			
		||||
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0,x86_32))
 | 
			
		||||
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_DOTO), 0,x86_32))
 | 
			
		||||
else
 | 
			
		||||
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0,x86_64))
 | 
			
		||||
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_DOTO), 0,x86_64))
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
$(SIPI_BIN): $(SIPI_RMOD)
 | 
			
		||||
 
 | 
			
		||||
@@ -56,10 +56,8 @@ ap_count:
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.code16
 | 
			
		||||
.global ap_start
 | 
			
		||||
.global __rmodule_entry
 | 
			
		||||
__rmodule_entry:
 | 
			
		||||
ap_start:
 | 
			
		||||
.global _start
 | 
			
		||||
_start:
 | 
			
		||||
	cli
 | 
			
		||||
	xorl	%eax, %eax
 | 
			
		||||
	movl	%eax, %cr3    /* Invalidate TLB*/
 | 
			
		||||
@@ -74,9 +72,9 @@ ap_start:
 | 
			
		||||
 | 
			
		||||
	/* The gdtaddr needs to be releative to the data segment in order
 | 
			
		||||
	 * to properly dereference it. The .text section comes first in an
 | 
			
		||||
	 * rmodule so ap_start can be used as a proxy for the load address. */
 | 
			
		||||
	 * rmodule so _start can be used as a proxy for the load address. */
 | 
			
		||||
	movl	$(gdtaddr), %ebx
 | 
			
		||||
	sub	$(ap_start), %ebx
 | 
			
		||||
	sub	$(_start), %ebx
 | 
			
		||||
 | 
			
		||||
	data32 lgdt (%ebx)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,10 +59,8 @@ fallback_stack_top:
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.code16
 | 
			
		||||
.global smm_handler_start
 | 
			
		||||
.global __rmodule_entry
 | 
			
		||||
__rmodule_entry:
 | 
			
		||||
smm_handler_start:
 | 
			
		||||
.global _start
 | 
			
		||||
_start:
 | 
			
		||||
	movl	$(smm_relocate_gdt), %ebx
 | 
			
		||||
	data32	lgdt (%ebx)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -43,9 +43,9 @@
 | 
			
		||||
#define ARCH_STAGE_HAS_BSS_SECTION 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Default is that currently ramstage and smm only has a heap. */
 | 
			
		||||
/* Default is that currently ramstage, smm, and rmodules have a heap. */
 | 
			
		||||
#ifndef ARCH_STAGE_HAS_HEAP_SECTION
 | 
			
		||||
#define ARCH_STAGE_HAS_HEAP_SECTION (ENV_RAMSTAGE || ENV_SMM)
 | 
			
		||||
#define ARCH_STAGE_HAS_HEAP_SECTION (ENV_RAMSTAGE || ENV_SMM || ENV_RMODULE)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define STR(x) #x
 | 
			
		||||
 
 | 
			
		||||
@@ -73,9 +73,9 @@ struct rmodule {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if IS_ENABLED(CONFIG_RELOCATABLE_MODULES)
 | 
			
		||||
/* Rmodules have an entry point of named __rmodule_entry. */
 | 
			
		||||
/* Rmodules have an entry point of named _start. */
 | 
			
		||||
#define RMODULE_ENTRY(entry_) \
 | 
			
		||||
	void __rmodule_entry(void *) __attribute__((alias (STRINGIFY(entry_))))
 | 
			
		||||
	void _start(void *) __attribute__((alias (STRINGIFY(entry_))))
 | 
			
		||||
#else
 | 
			
		||||
#define RMODULE_ENTRY(entry_)
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__ROMSTAGE__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
@@ -38,6 +39,7 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__SMM__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
@@ -46,6 +48,7 @@
 | 
			
		||||
#define ENV_SMM 1
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__SECMON__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
@@ -54,6 +57,7 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 1
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__VERSTAGE__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
@@ -62,6 +66,7 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 1
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__RAMSTAGE__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
@@ -70,6 +75,16 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
 | 
			
		||||
#elif defined(__RMODULE__)
 | 
			
		||||
#define ENV_BOOTBLOCK 0
 | 
			
		||||
#define ENV_ROMSTAGE 0
 | 
			
		||||
#define ENV_RAMSTAGE 0
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 1
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
/*
 | 
			
		||||
@@ -84,6 +99,7 @@
 | 
			
		||||
#define ENV_SMM 0
 | 
			
		||||
#define ENV_SECMON 0
 | 
			
		||||
#define ENV_VERSTAGE 0
 | 
			
		||||
#define ENV_RMODULE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* For romstage and ramstage always build with simple device model, ie.
 | 
			
		||||
 
 | 
			
		||||
@@ -38,14 +38,14 @@
 | 
			
		||||
	*(.text);
 | 
			
		||||
	*(.text.*);
 | 
			
		||||
 | 
			
		||||
#if ENV_RAMSTAGE || ENV_ROMSTAGE
 | 
			
		||||
#if ENV_RAMSTAGE || ENV_ROMSTAGE || ENV_RMODULE
 | 
			
		||||
	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 | 
			
		||||
	_cbmem_init_hooks = .;
 | 
			
		||||
	KEEP(*(.rodata.cbmem_init_hooks));
 | 
			
		||||
	_ecbmem_init_hooks = .;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENV_RAMSTAGE
 | 
			
		||||
#if ENV_RAMSTAGE || ENV_RMODULE
 | 
			
		||||
	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 | 
			
		||||
	_pci_drivers = .;
 | 
			
		||||
	KEEP(*(.rodata.pci_driver));
 | 
			
		||||
@@ -79,13 +79,20 @@
 | 
			
		||||
.data : {
 | 
			
		||||
	. = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
 | 
			
		||||
	_data = .;
 | 
			
		||||
 | 
			
		||||
#if ENV_RMODULE
 | 
			
		||||
	_rmodule_params = .;
 | 
			
		||||
	KEEP(*(.module_parameters));
 | 
			
		||||
	_ermodule_params = .;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	*(.data);
 | 
			
		||||
	*(.data.*);
 | 
			
		||||
 | 
			
		||||
#ifdef __PRE_RAM__
 | 
			
		||||
	PROVIDE(_preram_cbmem_console = .);
 | 
			
		||||
	PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
 | 
			
		||||
#elif ENV_RAMSTAGE
 | 
			
		||||
#elif ENV_RAMSTAGE || ENV_RMODULE
 | 
			
		||||
	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 | 
			
		||||
	_bs_init_begin = .;
 | 
			
		||||
	KEEP(*(.bs_init));
 | 
			
		||||
@@ -116,7 +123,7 @@
 | 
			
		||||
.heap : {
 | 
			
		||||
	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 | 
			
		||||
	_heap = .;
 | 
			
		||||
	. += CONFIG_HEAP_SIZE;
 | 
			
		||||
	. += (ENV_RMODULE ? __heap_size : CONFIG_HEAP_SIZE);
 | 
			
		||||
	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 | 
			
		||||
	_eheap = .;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,103 +12,14 @@
 | 
			
		||||
 * won't be a consistent mapping between the flat blob and the loaded program.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
BASE_ADDRESS = 0x00000;
 | 
			
		||||
 | 
			
		||||
ENTRY(__rmodule_entry);
 | 
			
		||||
#include <memlayout.h>
 | 
			
		||||
#include <arch/header.ld>
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
	. = BASE_ADDRESS;
 | 
			
		||||
	SET_COUNTER(rmodule, 0x00000000)
 | 
			
		||||
 | 
			
		||||
	.payload :  {
 | 
			
		||||
		/* C code of the module. */
 | 
			
		||||
		_program = .;
 | 
			
		||||
		*(.text._start);
 | 
			
		||||
		*(.text.stage_entry);
 | 
			
		||||
		*(.text);
 | 
			
		||||
		*(.text.*);
 | 
			
		||||
		/* C read-only data. */
 | 
			
		||||
		. = ALIGN(16);
 | 
			
		||||
 | 
			
		||||
#if IS_ENABLED(CONFIG_COVERAGE)
 | 
			
		||||
		__CTOR_LIST__ = .;
 | 
			
		||||
		*(.ctors);
 | 
			
		||||
		LONG(0);
 | 
			
		||||
		LONG(0);
 | 
			
		||||
		__CTOR_END__ = .;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* The driver sections are to allow linking coreboot's
 | 
			
		||||
		 * ramstage with the rmodule linker. Any changes made in
 | 
			
		||||
		 * ramstage.ld should be made here as well. */
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
		_pci_drivers = . ;
 | 
			
		||||
		KEEP(*(.rodata.pci_driver));
 | 
			
		||||
		_epci_drivers = . ;
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
		_cpu_drivers = . ;
 | 
			
		||||
		KEEP(*(.rodata.cpu_driver));
 | 
			
		||||
		_ecpu_drivers = . ;
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
		_bs_init_begin = .;
 | 
			
		||||
		KEEP(*(.bs_init));
 | 
			
		||||
		LONG(0);
 | 
			
		||||
		LONG(0);
 | 
			
		||||
		_bs_init_end = .;
 | 
			
		||||
		_cbmem_init_hooks = .;
 | 
			
		||||
		KEEP(*(.rodata.cbmem_init_hooks));
 | 
			
		||||
		_ecbmem_init_hooks = .;
 | 
			
		||||
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
		*(.rodata);
 | 
			
		||||
		*(.rodata.*);
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
		/* The parameters section can be used to pass parameters
 | 
			
		||||
		 * to a module, however there has to be an prior agreement
 | 
			
		||||
		 * on how to interpret the parameters. */
 | 
			
		||||
		_module_params_begin = .;
 | 
			
		||||
		KEEP(*(.module_parameters));
 | 
			
		||||
		_module_params_end = .;
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
		/* Data section. */
 | 
			
		||||
		. = ALIGN(64);	/* Mirror cache line alignment from ramstage. */
 | 
			
		||||
		_sdata = .;
 | 
			
		||||
		*(.data);
 | 
			
		||||
		*(.data.*);
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
		_edata = .;
 | 
			
		||||
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.bss (NOLOAD) : {
 | 
			
		||||
		/* C uninitialized data of the module. */
 | 
			
		||||
		_bss = .;
 | 
			
		||||
		*(.bss);
 | 
			
		||||
		*(.bss.*)
 | 
			
		||||
		*(.sbss)
 | 
			
		||||
		*(.sbss.*)
 | 
			
		||||
		*(COMMON);
 | 
			
		||||
		. = ALIGN(8);
 | 
			
		||||
		_ebss = .;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Place the heap after BSS. The heap size is passed in by
 | 
			
		||||
		 * by way of ld --defsym=__heap_size=<>
 | 
			
		||||
		 */
 | 
			
		||||
		_heap = .;
 | 
			
		||||
		. = . + __heap_size;
 | 
			
		||||
		_eheap = .;
 | 
			
		||||
		_eprogram = .;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/DISCARD/ : {
 | 
			
		||||
		/* Drop unnecessary sections. */
 | 
			
		||||
		*(.eh_frame);
 | 
			
		||||
		*(.note);
 | 
			
		||||
		*(.note.*);
 | 
			
		||||
	}
 | 
			
		||||
	/* program.ld is directly included because there's no one particular
 | 
			
		||||
	 * class that rmodule is used on. */
 | 
			
		||||
	#include <lib/program.ld>
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -402,11 +402,11 @@ static int populate_program_info(struct rmod_context *ctx)
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (populate_sym(ctx, "_module_params_begin", &ctx->parameters_begin,
 | 
			
		||||
	if (populate_sym(ctx, "_rmodule_params", &ctx->parameters_begin,
 | 
			
		||||
	                 nsyms, strtab))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	if (populate_sym(ctx, "_module_params_end", &ctx->parameters_end,
 | 
			
		||||
	if (populate_sym(ctx, "_ermodule_params", &ctx->parameters_end,
 | 
			
		||||
	                 nsyms, strtab))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
@@ -416,8 +416,8 @@ static int populate_program_info(struct rmod_context *ctx)
 | 
			
		||||
	if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, strtab))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	if (populate_sym(ctx, "__rmodule_entry", &ctx->entry, nsyms, strtab))
 | 
			
		||||
		return -1;
 | 
			
		||||
	/* Honor the entry point within the ELF header. */
 | 
			
		||||
	ctx->entry = ehdr->e_entry;
 | 
			
		||||
 | 
			
		||||
	/* Link address is the virtual address of the program segment. */
 | 
			
		||||
	ctx->link_addr = ctx->phdr->p_vaddr;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user