support elfloader for shared object and relocatable object

1. elfloader for shared object
example: TencentOS-tiny\examples\elfloader_shared_object
keil: TencentOS-tiny\board\TencentOS_tiny_EVB_MX_Plus\KEIL\elfloader_shared_object

2. elfloader for relocatable object:
example: TencentOS-tiny\examples\elfloader_relocatable_object
keil: TencentOS-tiny\board\TencentOS_tiny_EVB_MX_Plus\KEIL\elfloader_relocatable_object

3. TODO:
- add icache/dcache flush when module is loaded
- support more relocation type in elfloader_arch_relocate
This commit is contained in:
daishengdong
2020-06-09 19:30:38 +08:00
parent dc0c649c7c
commit 0a2d5a4e90
35 changed files with 7342 additions and 10 deletions

View File

@@ -0,0 +1,183 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _ELF32_H_
#define _ELF32_H_
#define EI_NIDENT 16
typedef int32_t elf32_sword;
typedef uint32_t elf32_word;
typedef uint16_t elf32_half;
typedef uint32_t elf32_off;
typedef uint32_t elf32_addr;
/* elf header */
typedef struct elf32_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
elf32_half e_type; /* file type */
elf32_half e_machine; /* target machine */
elf32_word e_version; /* file version */
elf32_addr e_entry; /* start address */
elf32_off e_phoff; /* phdr file offset */
elf32_off e_shoff; /* shdr file offset */
elf32_word e_flags; /* file flags */
elf32_half e_ehsize; /* sizeof ehdr */
elf32_half e_phentsize; /* sizeof phdr */
elf32_half e_phnum; /* number phdrs */
elf32_half e_shentsize; /* sizeof shdr */
elf32_half e_shnum; /* number shdrs */
elf32_half e_shstrndx; /* shdr string index */
} elf32_ehdr_t;
/* values for e_type. */
#define ET_NONE 0 /* unknown type. */
#define ET_REL 1 /* relocatable. */
#define ET_EXEC 2 /* executable. */
#define ET_DYN 3 /* shared object. */
/* section header */
typedef struct elf32_shdr {
elf32_word sh_name; /* section name */
elf32_word sh_type; /* SHT_... */
elf32_word sh_flags; /* SHF_... */
elf32_addr sh_addr; /* virtual address */
elf32_off sh_offset; /* file offset */
elf32_word sh_size; /* section size */
elf32_word sh_link; /* misc info */
elf32_word sh_info; /* misc info */
elf32_word sh_addralign; /* memory alignment */
elf32_word sh_entsize; /* entry size if table */
} elf32_shdr_t;
/* values for sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* values for sh_flags */
#define SHF_WRITE 1 /* writable */
#define SHF_ALLOC 2 /* occupies memory */
#define SHF_EXECINSTR 4 /* executable */
typedef struct elf32_rel {
elf32_addr r_offset; /* location to be relocated. */
elf32_word r_info; /* relocation type and symbol index. */
} elf32_rel_t;
typedef struct elf32_rela {
elf32_addr r_offset; /* location to be relocated. */
elf32_word r_info; /* relocation type and symbol index. */
elf32_sword r_addend; /* addend. */
} elf32_rela_t;
typedef struct elf32_sym {
elf32_word st_name; /* string table index of name. */
elf32_addr st_value; /* symbol value. */
elf32_word st_size; /* size of associated object. */
unsigned char st_info; /* type and binding information. */
unsigned char st_other; /* reserved (not used). */
elf32_half st_shndx; /* section index of symbol. */
} elf32_sym_t;
/* values for st_info(binding) */
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
/* values for st_info(type) */
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
/* values for st_shndx */
#define SHN_ABS 0xFFF1
#define SHN_COMMON 0xFFF2
#define SHN_UNDEF 0x0000
#define ELF32_SYM_BINDING(info) ((info) >> 4)
#define ELF32_SYM_TYPE(info) ((info) & 0x0F)
typedef struct elf32_dyn {
elf32_sword d_tag; /* DT_... */
union {
elf32_word d_val;
elf32_addr d_ptr;
} d_un;
} elf32_dyn_t;
/* values for d_tag */
#define DT_NULL 0x00
#define DT_PLTRELSZ 0x02
#define DT_PLTGOT 0x03
#define DT_HASH 0x04
#define DT_STRTAB 0x05
#define DT_SYMTAB 0x06
#define DT_STRSZ 0x0a
#define DT_SYMENT 0x0b
#define DT_REL 0x11
#define DT_RELSZ 0x12
#define DT_RELENT 0x13
#define DT_PLTREL 0x14
#define DT_JMPREL 0x17
/* program header */
typedef struct elf32_phdr {
elf32_word p_type; /* PHT_... */
elf32_off p_offset; /* file offset */
elf32_addr p_vaddr; /* virtual address */
elf32_addr p_paddr; /* physical address */
elf32_word p_filesz; /* file size */
elf32_word p_memsz; /* memory size */
elf32_word p_flags; /* read write properties */
elf32_word p_align; /* alignment attribute, 2 ^ p_align */
} elf32_phdr_t;
/* values for p_type */
#define PHT_LOAD 0x01
#define PHT_DYNAMIC 0x02
#define ELF32_R_SYM(info) ((info) >> 8)
#define ELF32_R_TYPE(info) ((unsigned char)(info))
#define ELF_MAGIC_HEADER "\177ELF\001\001\001"
#define ELF_MAGIC_HEADER_SIZE 7
static const unsigned char elf_header_magic[] = {
0x7f, 0x45, 0x4c, 0x46, /* Magic: 0x7f, 'E', 'L', 'F' */
0x01, /* Class: ELF32 */
0x01, /* Data: 2's complement, 'little endian */
0x01, /* Version: 1(current) */
};
#endif /* _ELF32_H_ */

View File

@@ -0,0 +1,74 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_H_
#define _TOS_ELFLOADER_H_
#include "tos_k.h"
#include "elf/elf32.h"
#include "tos_elfloader_err.h"
#include "tos_elfloader_fd_read.h"
#include "tos_elfloader_symbol.h"
#include "tos_elfloader_symtab.h"
#include "tos_elfloader_relocate.h"
typedef struct el_section_st {
uint8_t shndx;
void *address;
} el_section_t;
typedef struct el_obj_info_st {
el_section_t bss;
el_section_t data;
el_section_t rodata;
el_section_t text;
} el_obj_info_t;
typedef struct el_so_info_st {
int32_t load_bias;
} el_so_info_t;
typedef union el_info_un {
el_obj_info_t obj;
el_so_info_t so;
} el_info_t;
typedef struct el_module_st {
int fd;
void *base;
el_info_t info;
uint32_t symtab_offset;
uint32_t symtab_size;
uint32_t symtab_entsize;
uint32_t strtab_offset;
} el_module_t;
__API__ el_err_t tos_elfloader_load(el_module_t *module, int fd);
__API__ el_err_t tos_elfloader_unload(el_module_t *module);
__API__ void *tos_elfloader_find_symbol(el_module_t *module, char *symbol);
#endif /* _TOS_ELFLOADER_H_ */

View File

@@ -0,0 +1,38 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_ERR_H_
#define _TOS_ELFLOADER_ERR_H_
typedef enum elfloader_err_en {
ELFLOADER_ERR_NONE,
ELFLOADER_ERR_HEADER_INVALID,
ELFLOADER_ERR_TYPE_INVALID,
ELFLOADER_ERR_NO_DYN,
ELFLOADER_ERR_NO_SYMTAB,
ELFLOADER_ERR_NO_STRTAB,
ELFLOADER_ERR_NO_TEXT,
ELFLOADER_ERR_NO_LOAD_SEGMENTS,
ELFLOADER_ERR_FD_READ_FAILED,
ELFLOADER_ERR_SECTION_NOT_FOUND,
ELFLOADER_ERR_SYM_NOT_FOUND,
ELFLOADER_ERR_OUT_OF_MEMORY,
ELFLOADER_ERR_PTR_NULL,
} el_err_t;
#endif /* _TOS_ELFLOADER_ERR_H_ */

View File

@@ -0,0 +1,24 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_FD_READ_H_
#define _TOS_ELFLOADER_FD_READ_H_
__KNL__ el_err_t elfloader_fd_read(int fd, uint32_t offset, void *buf, size_t len);
#endif /* _TOS_ELFLOADER_FD_READ_H_ */

View File

@@ -0,0 +1,24 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_RELOCATE_H_
#define _TOS_ELFLOADER_RELOCATE_H_
__KNL__ void elfloader_arch_relocate(uint32_t reloc_addr, int32_t load_bias, uint32_t addr, elf32_rela_t *rela, int is_rela);
#endif /* _TOS_ELFLOADER_RELOCATE_H_ */

View File

@@ -0,0 +1,29 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_SYMBOL_H_
#define _TOS_ELFLOADER_SYMBOL_H_
typedef struct el_symbol_st {
const char *name;
void *value;
} el_symbol_t;
extern const el_symbol_t el_symbols[];
#endif /* _TOS_ELFLOADER_SYMBOL_H_ */

View File

@@ -0,0 +1,24 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ELFLOADER_SYMTAB_H_
#define _TOS_ELFLOADER_SYMTAB_H_
__KNL__ void *elfloader_symtab_lookup(char *name);
#endif /* _TOS_ELFLOADER_SYMTAB_H_ */

View File

@@ -0,0 +1,40 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_vfs.h"
#include "tos_elfloader.h"
/*
ATTENTION:
if you wanna load the so/obj laying on your flash, you should implement "elfloader_fd_read"
with flash driver read/write operation.
very easy to use whether your module is on a file system or raw flash.
*/
__KNL__ __WEAK__ el_err_t elfloader_fd_read(int fd, uint32_t offset, void *buf, size_t len)
{
if (tos_vfs_lseek(fd, (vfs_off_t)offset, VFS_SEEK_SET) < 0) {
return ELFLOADER_ERR_FD_READ_FAILED;
}
if (tos_vfs_read(fd, buf, len) < 0) {
return ELFLOADER_ERR_FD_READ_FAILED;
}
return ELFLOADER_ERR_NONE;
}

View File

@@ -0,0 +1,70 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_elfloader.h"
/* values for ELF32_R_TYPE(info) */
#define R_ARM_ABS32 2
#define R_ARM_THM_CALL 10
#define R_ARM_GLOB_DAT 21
#define R_ARM_JUMP_SLOT 22
#define R_ARM_RELATIVE 23
/*
- S (when used on its own) is the address of the symbol.
- A is the addend for the relocation.
- P is the address of the place being relocated (derived from r_offset).
- Pa is the adjusted address of the place being relocated, defined as (P & 0xFFFFFFFC).
- T is 1 if the target symbol S has type STT_FUNC and the symbol addresses a Thumb instruction; it is 0
otherwise.
- B(S) is the addressing origin of the output segment defining the symbol S. The origin is not required to be the
base address of the segment. This value must always be word-aligned.
- GOT_ORG is the addressing origin of the Global Offset Table (the indirection table for imported data
addresses). This value must always be word-aligned. See §4.6.1.8, Proxy generating relocations.
- GOT(S) is the address of the GOT entry for the symbol S.
*/
// TODO: support more relocation type
__KNL__ void elfloader_arch_relocate(uint32_t reloc_addr, int32_t load_bias, uint32_t addr, elf32_rela_t *rela, int is_rela)
{
/* ATTENTION:
different reloc_addr calculation algorithm for relocatable object and shared object
*/
switch (ELF32_R_TYPE(rela->r_info)) {
case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT:
/* (S + A) | T */
*(uint32_t *)reloc_addr = addr;
break;
case R_ARM_RELATIVE:
/* B(S) + A */
*(uint32_t *)reloc_addr += load_bias;
break;
case R_ARM_ABS32:
/* (S + A) | T */
*(uint32_t *)reloc_addr += addr;
break;
default:
printf("Unsupported Relocation Type: %d\n", ELF32_R_TYPE(rela->r_info));
break;
}
}

View File

@@ -0,0 +1,32 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_elfloader.h"
__KNL__ void *elfloader_symtab_lookup(char *name)
{
const el_symbol_t *symbol;
for (symbol = &el_symbols[0]; symbol; ++symbol) {
if (strcmp(name, symbol->name) == 0) {
return symbol->value;
}
}
return K_NULL;
}