ELF64 support (#220)
* include: Introduce elf64.h and elf.h
Added elf64.h for 64bit ELF support and moved common definitions
from elf32.h to elf.h. Also introduced Elf_xxx to be used in
common libraries such as binfmt.
* binfmt, include, modlib, module: Add support for ELF64
Elf_xxx must be used instead of Elf32_xxx to support ELF64.
To use ELF64, CONFIG_ELF_64BIT must be enabled.
* binfmt, modlib: Add support for relocate address
* arch: risc-v: Add include/elf.h
* libs: machine: Add risc-v related files.
NOTE: Currently only supports ELF64
* boards: maix-bit: Add elf and posix_spawn configurations
* boards: maix-bit: Add support for module configuration
This commit is contained in:
parent
e21c30cf9d
commit
81f1133174
40 changed files with 1847 additions and 300 deletions
86
arch/risc-v/include/elf.h
Normal file
86
arch/risc-v/include/elf.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/include/elf.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISCV_INCLUDE_ELF_H
|
||||
#define __ARCH_RISCV_INCLUDE_ELF_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md */
|
||||
|
||||
#define R_RISCV_NONE 0
|
||||
#define R_RISCV_32 1
|
||||
#define R_RISCV_64 2
|
||||
#define R_RISCV_RELATIVE 3
|
||||
#define R_RISCV_COPY 4
|
||||
#define R_RISCV_JUMP_SLOT 5
|
||||
#define R_RISCV_TLS_DTPMOD32 6
|
||||
#define R_RISCV_TLS_DTPMOD64 7
|
||||
#define R_RISCV_TLS_DTPREL32 8
|
||||
#define R_RISCV_TLS_DTPREL64 9
|
||||
#define R_RISCV_TLS_TPREL32 10
|
||||
#define R_RISCV_TLS_TPREL64 11
|
||||
|
||||
#define R_RISCV_BRANCH 16
|
||||
#define R_RISCV_JAL 17
|
||||
#define R_RISCV_CALL 18
|
||||
#define R_RISCV_CALL_PLT 19
|
||||
#define R_RISCV_GOT_HI20 20
|
||||
#define R_RISCV_TLS_GOT_HI20 21
|
||||
#define R_RISCV_TLS_GD_HI20 22
|
||||
#define R_RISCV_PCREL_HI20 23
|
||||
#define R_RISCV_PCREL_LO12_I 24
|
||||
#define R_RISCV_PCREL_LO12_S 25
|
||||
#define R_RISCV_HI20 26
|
||||
#define R_RISCV_LO12_I 27
|
||||
#define R_RISCV_LO12_S 28
|
||||
#define R_RISCV_TPREL_HI20 29
|
||||
#define R_RISCV_TPREL_LO12_I 30
|
||||
#define R_RISCV_TPREL_LO12_S 31
|
||||
#define R_RISCV_TPREL_ADD 32
|
||||
#define R_RISCV_ADD8 33
|
||||
#define R_RISCV_ADD16 34
|
||||
#define R_RISCV_ADD32 35
|
||||
#define R_RISCV_ADD64 36
|
||||
#define R_RISCV_SUB8 37
|
||||
#define R_RISCV_SUB16 38
|
||||
#define R_RISCV_SUB32 39
|
||||
#define R_RISCV_SUB64 40
|
||||
#define R_RISCV_GNU_VTINHERIT 41
|
||||
#define R_RISCV_GNU_VTENTRY 42
|
||||
#define R_RISCV_ALIGN 43
|
||||
#define R_RISCV_RVC_BRANCH 44
|
||||
#define R_RISCV_RVC_JUMP 45
|
||||
#define R_RISCV_RVC_LUI 46
|
||||
#define R_RISCV_GPREL_I 47
|
||||
#define R_RISCV_GPREL_S 48
|
||||
#define R_RISCV_TPREL_I 49
|
||||
#define R_RISCV_TPREL_S 50
|
||||
#define R_RISCV_RELAX 51
|
||||
#define R_RISCV_SUB6 52
|
||||
#define R_RISCV_SET6 53
|
||||
#define R_RISCV_SET8 54
|
||||
#define R_RISCV_SET16 55
|
||||
#define R_RISCV_SET32 56
|
||||
#define R_RISCV_32_PCREL 57
|
||||
|
||||
#endif /* __ARCH_RISCV_INCLUDE_ELF_H */
|
||||
|
|
@ -152,7 +152,7 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
|
|||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
binfo("Sections %d:\n", i);
|
||||
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config ELF_64BIT
|
||||
bool "64bit ELF support"
|
||||
default n
|
||||
---help---
|
||||
This option is used to load 64bit ELF files
|
||||
|
||||
config ELF_ALIGN_LOG2
|
||||
int "Log2 Section Alignment"
|
||||
default 2
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_verifyheader(FAR const Elf32_Ehdr *header);
|
||||
int elf_verifyheader(FAR const Elf_Ehdr *header);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_read
|
||||
|
|
@ -150,7 +150,7 @@ int elf_findsymtab(FAR struct elf_loadinfo_s *loadinfo);
|
|||
****************************************************************************/
|
||||
|
||||
int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf32_Sym *sym);
|
||||
FAR Elf_Sym *sym);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_symvalue
|
||||
|
|
@ -177,7 +177,7 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
||||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf_Sym *sym,
|
||||
FAR const struct symtab_s *exports, int nexports);
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -74,14 +74,14 @@
|
|||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct elf32_symcache_s
|
||||
struct elf_symcache_s
|
||||
{
|
||||
dq_entry_t entry;
|
||||
Elf32_Sym sym;
|
||||
Elf_Sym sym;
|
||||
int idx;
|
||||
};
|
||||
|
||||
typedef struct elf32_symcache_s elf32_symcache_t;
|
||||
typedef struct elf_symcache_s elf_symcache_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
|
@ -95,13 +95,13 @@ typedef struct elf32_symcache_s elf32_symcache_t;
|
|||
* Name: elf_readrels
|
||||
*
|
||||
* Description:
|
||||
* Read the (ELF32_Rel structure * buffer count) into memory.
|
||||
* Read the (ELF_Rel structure * buffer count) into memory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *relsec,
|
||||
int index, FAR Elf32_Rel *rels,
|
||||
FAR const Elf_Shdr *relsec,
|
||||
int index, FAR Elf_Rel *rels,
|
||||
int count)
|
||||
{
|
||||
off_t offset;
|
||||
|
|
@ -109,7 +109,7 @@ static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
|||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf32_Rel)))
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rel)))
|
||||
{
|
||||
berr("Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -117,8 +117,9 @@ static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
|||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = sizeof(Elf32_Rel) * index;
|
||||
size = sizeof(Elf32_Rel) * count;
|
||||
offset = sizeof(Elf_Rel) * index;
|
||||
size = sizeof(Elf_Rel) * count;
|
||||
|
||||
if (offset + size > relsec->sh_size)
|
||||
{
|
||||
size = relsec->sh_size - offset;
|
||||
|
|
@ -130,6 +131,46 @@ static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
|||
relsec->sh_offset + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_readrelas
|
||||
*
|
||||
* Description:
|
||||
* Read the (ELF_Rela structure * buffer count) into memory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int elf_readrelas(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const Elf_Shdr *relsec,
|
||||
int index, FAR Elf_Rela *relas,
|
||||
int count)
|
||||
{
|
||||
off_t offset;
|
||||
int size;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rela)))
|
||||
{
|
||||
berr("Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = sizeof(Elf_Rela) * index;
|
||||
size = sizeof(Elf_Rela) * count;
|
||||
|
||||
if (offset + size > relsec->sh_size)
|
||||
{
|
||||
size = relsec->sh_size - offset;
|
||||
}
|
||||
|
||||
/* And, finally, read the symbol table entry into memory */
|
||||
|
||||
return elf_read(loadinfo, (FAR uint8_t *)relas, size,
|
||||
relsec->sh_offset + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: elf_relocate and elf_relocateadd
|
||||
*
|
||||
|
|
@ -144,14 +185,13 @@ static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
|||
|
||||
static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
|
||||
{
|
||||
FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf32_Rel *rels;
|
||||
FAR Elf32_Rel *rel;
|
||||
FAR elf32_symcache_t *cache;
|
||||
FAR Elf32_Sym *sym;
|
||||
FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf_Rel *rels;
|
||||
FAR Elf_Rel *rel;
|
||||
FAR elf_symcache_t *cache;
|
||||
FAR Elf_Sym *sym;
|
||||
FAR dq_entry_t *e;
|
||||
dq_queue_t q;
|
||||
uintptr_t addr;
|
||||
|
|
@ -160,7 +200,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
int i;
|
||||
int j;
|
||||
|
||||
rels = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
||||
rels = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rel));
|
||||
if (rels == NULL)
|
||||
{
|
||||
berr("Failed to allocate memory for elf relocation\n");
|
||||
|
|
@ -176,7 +216,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
|
||||
ret = OK;
|
||||
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rel); i++)
|
||||
{
|
||||
/* Read the relocation entry into memory */
|
||||
|
||||
|
|
@ -198,14 +238,14 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
* in a bit-field within the r_info element.
|
||||
*/
|
||||
|
||||
symidx = ELF32_R_SYM(rel->r_info);
|
||||
symidx = ELF_R_SYM(rel->r_info);
|
||||
|
||||
/* First try the cache */
|
||||
|
||||
sym = NULL;
|
||||
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||
{
|
||||
cache = (FAR elf32_symcache_t *)e;
|
||||
cache = (FAR elf_symcache_t *)e;
|
||||
if (cache->idx == symidx)
|
||||
{
|
||||
dq_rem(&cache->entry, &q);
|
||||
|
|
@ -223,7 +263,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
{
|
||||
if (j < CONFIG_ELF_SYMBOL_CACHECOUNT)
|
||||
{
|
||||
cache = kmm_malloc(sizeof(elf32_symcache_t));
|
||||
cache = kmm_malloc(sizeof(elf_symcache_t));
|
||||
if (!cache)
|
||||
{
|
||||
berr("Failed to allocate memory for elf symbols\n");
|
||||
|
|
@ -235,7 +275,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
}
|
||||
else
|
||||
{
|
||||
cache = (FAR elf32_symcache_t *)dq_remlast(&q);
|
||||
cache = (FAR elf_symcache_t *)dq_remlast(&q);
|
||||
}
|
||||
|
||||
sym = &cache->sym;
|
||||
|
|
@ -268,12 +308,14 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
|
||||
if (ret == -ESRCH)
|
||||
{
|
||||
berr("Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
berr("Section %d reloc %d: "
|
||||
"Undefined symbol[%d] has no name: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
berr("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
||||
berr("Section %d reloc %d: "
|
||||
"Failed to get value of symbol[%d]: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
kmm_free(cache);
|
||||
break;
|
||||
|
|
@ -308,7 +350,8 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
ret = up_relocate(rel, sym, addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n",
|
||||
relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -326,8 +369,184 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
static int elf_relocateadd(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
berr("Not implemented\n");
|
||||
return -ENOSYS;
|
||||
FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf_Rela *relas;
|
||||
FAR Elf_Rela *rela;
|
||||
FAR elf_symcache_t *cache;
|
||||
FAR Elf_Sym *sym;
|
||||
FAR dq_entry_t *e;
|
||||
dq_queue_t q;
|
||||
uintptr_t addr;
|
||||
int symidx;
|
||||
int ret;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
relas = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rela));
|
||||
if (relas == NULL)
|
||||
{
|
||||
berr("Failed to allocate memory for elf relocation\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dq_init(&q);
|
||||
|
||||
/* Examine each relocation in the section. 'relsec' is the section
|
||||
* containing the relations. 'dstsec' is the section containing the data
|
||||
* to be relocated.
|
||||
*/
|
||||
|
||||
ret = OK;
|
||||
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rela); i++)
|
||||
{
|
||||
/* Read the relocation entry into memory */
|
||||
|
||||
rela = &relas[i % CONFIG_ELF_RELOCATION_BUFFERCOUNT];
|
||||
|
||||
if (!(i % CONFIG_ELF_RELOCATION_BUFFERCOUNT))
|
||||
{
|
||||
ret = elf_readrelas(loadinfo, relsec, i, relas,
|
||||
CONFIG_ELF_RELOCATION_BUFFERCOUNT);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("Section %d reloc %d: Failed to read relocation entry: %d\n",
|
||||
relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the symbol table index for the relocation. This is contained
|
||||
* in a bit-field within the r_info element.
|
||||
*/
|
||||
|
||||
symidx = ELF_R_SYM(rela->r_info);
|
||||
|
||||
/* First try the cache */
|
||||
|
||||
sym = NULL;
|
||||
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||
{
|
||||
cache = (FAR elf_symcache_t *)e;
|
||||
if (cache->idx == symidx)
|
||||
{
|
||||
dq_rem(&cache->entry, &q);
|
||||
dq_addfirst(&cache->entry, &q);
|
||||
sym = &cache->sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the symbol was not found in the cache, we will need to read the
|
||||
* symbol from the file.
|
||||
*/
|
||||
|
||||
if (sym == NULL)
|
||||
{
|
||||
if (j < CONFIG_ELF_SYMBOL_CACHECOUNT)
|
||||
{
|
||||
cache = kmm_malloc(sizeof(elf_symcache_t));
|
||||
if (!cache)
|
||||
{
|
||||
berr("Failed to allocate memory for elf symbols\n");
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = (FAR elf_symcache_t *)dq_remlast(&q);
|
||||
}
|
||||
|
||||
sym = &cache->sym;
|
||||
|
||||
/* Read the symbol table entry into memory */
|
||||
|
||||
ret = elf_readsym(loadinfo, symidx, sym);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
kmm_free(cache);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the value of the symbol (in sym.st_value) */
|
||||
|
||||
ret = elf_symvalue(loadinfo, sym, exports, nexports);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The special error -ESRCH is returned only in one condition: The
|
||||
* symbol has no name.
|
||||
*
|
||||
* There are a few relocations for a few architectures that do
|
||||
* no depend upon a named symbol. We don't know if that is the
|
||||
* case here, but we will use a NULL symbol pointer to indicate
|
||||
* that case to up_relocate(). That function can then do what
|
||||
* is best.
|
||||
*/
|
||||
|
||||
if (ret == -ESRCH)
|
||||
{
|
||||
berr("Section %d reloc %d: "
|
||||
"Undefined symbol[%d] has no name: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
berr("Section %d reloc %d: "
|
||||
"Failed to get value of symbol[%d]: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
kmm_free(cache);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cache->idx = symidx;
|
||||
dq_addfirst(&cache->entry, &q);
|
||||
}
|
||||
|
||||
if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0)
|
||||
{
|
||||
sym = NULL;
|
||||
}
|
||||
|
||||
/* Calculate the relocation address. */
|
||||
|
||||
if (rela->r_offset < 0 ||
|
||||
rela->r_offset > dstsec->sh_size)
|
||||
{
|
||||
berr("Section %d reloc %d: Relocation address out of range, "
|
||||
"offset %d size %d\n",
|
||||
relidx, i, rela->r_offset, dstsec->sh_size);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
addr = dstsec->sh_addr + rela->r_offset;
|
||||
|
||||
/* Now perform the architecture-specific relocation */
|
||||
|
||||
ret = up_relocateadd(rela, sym, addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n",
|
||||
relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
kmm_free(relas);
|
||||
while ((e = dq_peek(&q)))
|
||||
{
|
||||
dq_rem(e, &q);
|
||||
kmm_free(e);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr;
|
||||
FAR Elf_Shdr *shdr;
|
||||
size_t ctorsize;
|
||||
int ctoridx;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr;
|
||||
FAR Elf_Shdr *shdr;
|
||||
size_t dtorsize;
|
||||
int dtoridx;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo)
|
|||
/* Read the ELF ehdr from offset 0 */
|
||||
|
||||
ret = elf_read(loadinfo, (FAR uint8_t *)&loadinfo->ehdr,
|
||||
sizeof(Elf32_Ehdr), 0);
|
||||
sizeof(Elf_Ehdr), 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("Failed to read ELF header: %d\n", ret);
|
||||
|
|
@ -182,7 +182,7 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo)
|
|||
}
|
||||
|
||||
elf_dumpbuffer("ELF header", (FAR const uint8_t *)&loadinfo->ehdr,
|
||||
sizeof(Elf32_Ehdr));
|
||||
sizeof(Elf_Ehdr));
|
||||
|
||||
/* Verify the ELF header */
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
|
|
@ -164,7 +164,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
|
|
@ -286,7 +286,8 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
/* Allocate (and zero) memory for the ELF file. */
|
||||
|
||||
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize, heapsize);
|
||||
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize,
|
||||
heapsize);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@
|
|||
****************************************************************************/
|
||||
|
||||
static inline int elf_sectname(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *shdr)
|
||||
FAR const Elf_Shdr *shdr)
|
||||
{
|
||||
FAR Elf32_Shdr *shstr;
|
||||
FAR Elf_Shdr *shstr;
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
size_t readlen;
|
||||
|
|
@ -210,7 +210,7 @@ int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
/* Allocate memory to hold a working copy of the sector header table */
|
||||
|
||||
loadinfo->shdr = (FAR FAR Elf32_Shdr *)kmm_malloc(shdrsize);
|
||||
loadinfo->shdr = (FAR FAR Elf_Shdr *)kmm_malloc(shdrsize);
|
||||
if (!loadinfo->shdr)
|
||||
{
|
||||
berr("Failed to allocate the section header table. Size: %ld\n",
|
||||
|
|
@ -249,7 +249,7 @@ int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
|
|||
int elf_findsection(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const char *sectname)
|
||||
{
|
||||
FAR const Elf32_Shdr *shdr;
|
||||
FAR const Elf_Shdr *shdr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Sym *sym)
|
||||
FAR const Elf_Sym *sym)
|
||||
{
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
|
|
@ -215,14 +215,14 @@ int elf_findsymtab(FAR struct elf_loadinfo_s *loadinfo)
|
|||
****************************************************************************/
|
||||
|
||||
int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf32_Sym *sym)
|
||||
FAR Elf_Sym *sym)
|
||||
{
|
||||
FAR Elf32_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
FAR Elf_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
off_t offset;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (symtab->sh_size / sizeof(Elf32_Sym)))
|
||||
if (index < 0 || index > (symtab->sh_size / sizeof(Elf_Sym)))
|
||||
{
|
||||
berr("Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -230,11 +230,11 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
|||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = symtab->sh_offset + sizeof(Elf32_Sym) * index;
|
||||
offset = symtab->sh_offset + sizeof(Elf_Sym) * index;
|
||||
|
||||
/* And, finally, read the symbol table entry into memory */
|
||||
|
||||
return elf_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf32_Sym), offset);
|
||||
return elf_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf_Sym), offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -260,7 +260,7 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
||||
int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf_Sym *sym,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
|
|
@ -314,7 +314,8 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
|||
#endif
|
||||
if (!symbol)
|
||||
{
|
||||
berr("SHN_UNDEF: Exported symbol \"%s\" not found\n", loadinfo->iobuffer);
|
||||
berr("SHN_UNDEF: Exported symbol \"%s\" not found\n",
|
||||
loadinfo->iobuffer);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +325,7 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
|
|||
loadinfo->iobuffer, sym->st_value, symbol->sym_value,
|
||||
sym->st_value + symbol->sym_value);
|
||||
|
||||
sym->st_value += (Elf32_Word)((uintptr_t)symbol->sym_value);
|
||||
sym->st_value += (Elf_Word)((uintptr_t)symbol->sym_value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static const char g_elfmagic[EI_MAGIC_SIZE] =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int elf_verifyheader(FAR const Elf32_Ehdr *ehdr)
|
||||
int elf_verifyheader(FAR const Elf_Ehdr *ehdr)
|
||||
{
|
||||
if (!ehdr)
|
||||
{
|
||||
|
|
|
|||
59
boards/risc-v/k210/maix-bit/configs/elf/defconfig
Normal file
59
boards/risc-v/k210/maix-bit/configs/elf/defconfig
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="maix-bit"
|
||||
CONFIG_ARCH_BOARD_MAIX_BIT=y
|
||||
CONFIG_ARCH_CHIP="k210"
|
||||
CONFIG_ARCH_CHIP_K210=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BOARDCTL_APP_SYMTAB=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=46000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CXX_NEWLONG=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ELF=y
|
||||
CONFIG_ELF_64BIT=y
|
||||
CONFIG_ELF_ALIGN_LOG2=3
|
||||
CONFIG_EXAMPLES_ELF=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_LIB_BOARDCTL=y
|
||||
CONFIG_LIB_ENVPATH=y
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
CONFIG_NFILE_STREAMS=8
|
||||
CONFIG_PATH_INITIAL="/mnt/romfs"
|
||||
CONFIG_PIPES=y
|
||||
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=3072
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PREALLOC_WDOGS=16
|
||||
CONFIG_RAM_SIZE=2097152
|
||||
CONFIG_RAM_START=0x80400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=5
|
||||
CONFIG_START_MONTH=2
|
||||
CONFIG_START_YEAR=2020
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_TASK_NAME_SIZE=20
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_USERMAIN_STACKSIZE=3072
|
||||
CONFIG_USER_ENTRYPOINT="elf_main"
|
||||
CONFIG_WDOG_INTRESERVE=0
|
||||
61
boards/risc-v/k210/maix-bit/configs/module/defconfig
Normal file
61
boards/risc-v/k210/maix-bit/configs/module/defconfig
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="maix-bit"
|
||||
CONFIG_ARCH_BOARD_MAIX_BIT=y
|
||||
CONFIG_ARCH_CHIP="k210"
|
||||
CONFIG_ARCH_CHIP_K210=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BOARDCTL_APP_SYMTAB=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=46000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CXX_NEWLONG=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ELF=y
|
||||
CONFIG_ELF_64BIT=y
|
||||
CONFIG_ELF_ALIGN_LOG2=3
|
||||
CONFIG_EXAMPLES_MODULE=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_EXECFUNCS=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_LIB_BOARDCTL=y
|
||||
CONFIG_LIB_ENVPATH=y
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
CONFIG_MODULE=y
|
||||
CONFIG_NFILE_STREAMS=8
|
||||
CONFIG_PATH_INITIAL="/mnt/romfs"
|
||||
CONFIG_PIPES=y
|
||||
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=3072
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PREALLOC_WDOGS=16
|
||||
CONFIG_RAM_SIZE=2097152
|
||||
CONFIG_RAM_START=0x80400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=5
|
||||
CONFIG_START_MONTH=2
|
||||
CONFIG_START_YEAR=2020
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_TASK_NAME_SIZE=20
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_USERMAIN_STACKSIZE=3072
|
||||
CONFIG_USER_ENTRYPOINT="module_main"
|
||||
CONFIG_WDOG_INTRESERVE=0
|
||||
57
boards/risc-v/k210/maix-bit/configs/posix_spawn/defconfig
Normal file
57
boards/risc-v/k210/maix-bit/configs/posix_spawn/defconfig
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="maix-bit"
|
||||
CONFIG_ARCH_BOARD_MAIX_BIT=y
|
||||
CONFIG_ARCH_CHIP="k210"
|
||||
CONFIG_ARCH_CHIP_K210=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BOARDCTL_APP_SYMTAB=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=46000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ELF=y
|
||||
CONFIG_ELF_64BIT=y
|
||||
CONFIG_EXAMPLES_POSIXSPAWN=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_EXECFUNCS=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_LIB_BOARDCTL=y
|
||||
CONFIG_LIB_ENVPATH=y
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
CONFIG_NFILE_STREAMS=8
|
||||
CONFIG_PATH_INITIAL="/mnt/romfs"
|
||||
CONFIG_PIPES=y
|
||||
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=2048
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PREALLOC_WDOGS=16
|
||||
CONFIG_RAM_SIZE=2097152
|
||||
CONFIG_RAM_START=0x80400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=28
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2019
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_TASK_NAME_SIZE=20
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_USERMAIN_STACKSIZE=3072
|
||||
CONFIG_USER_ENTRYPOINT="posix_spawn_main"
|
||||
CONFIG_WDOG_INTRESERVE=0
|
||||
|
|
@ -94,10 +94,37 @@ CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
|||
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
|
||||
AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS)
|
||||
|
||||
# NXFLAT module definitions
|
||||
|
||||
NXFLATLDFLAGS1 = -r -d -warn-common
|
||||
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
|
||||
LDNXFLATFLAGS = -e main -s 2048
|
||||
|
||||
# Loadable module definitions
|
||||
|
||||
CMODULEFLAGS = $(CFLAGS)
|
||||
|
||||
LDMODULEFLAGS = -r -e module_initialize
|
||||
ifeq ($(WINTOOL),y)
|
||||
LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libs/libc/modlib/gnu-elf.ld}"
|
||||
else
|
||||
LDMODULEFLAGS += -T $(TOPDIR)/libs/libc/modlib/gnu-elf.ld
|
||||
endif
|
||||
|
||||
# ELF module definitions
|
||||
|
||||
CELFFLAGS = $(CFLAGS)
|
||||
CXXELFFLAGS = $(CXXFLAGS)
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
ifeq ($(WINTOOL),y)
|
||||
LDELFFLAGS += -T "${shell cygpath -w $(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/gnu-elf.ld}"
|
||||
else
|
||||
LDELFFLAGS += -T $(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/gnu-elf.ld
|
||||
endif
|
||||
|
||||
# File extensions
|
||||
|
||||
ASMEXT = .S
|
||||
OBJEXT = .o
|
||||
LIBEXT = .a
|
||||
|
|
|
|||
115
boards/risc-v/k210/maix-bit/scripts/gnu-elf.ld
Normal file
115
boards/risc-v/k210/maix-bit/scripts/gnu-elf.ld
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/k210/maix-bit/scripts/gnu-elf.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 :
|
||||
{
|
||||
_stext = . ;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.stub)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.jcr)
|
||||
|
||||
/* C++ support: The .init and .fini sections contain specific logic
|
||||
* to manage static constructors and destructors.
|
||||
*/
|
||||
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.init) /* Old ABI */
|
||||
*(.fini) /* Old ABI */
|
||||
_etext = . ;
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
_srodata = . ;
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
_erodata = . ;
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
_sdata = . ;
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(4);
|
||||
_edata = . ;
|
||||
}
|
||||
|
||||
/* C++ support. For each global and static local C++ object,
|
||||
* GCC creates a small subroutine to construct the object. Pointers
|
||||
* to these routines (not the routines themselves) are stored as
|
||||
* simple, linear arrays in the .ctors section of the object file.
|
||||
* Similarly, pointers to global/static destructor routines are
|
||||
* stored in .dtors.
|
||||
*/
|
||||
|
||||
.ctors :
|
||||
{
|
||||
_sctors = . ;
|
||||
*(.ctors) /* Old ABI: Unallocated */
|
||||
*(.init_array) /* New ABI: Allocated */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
_sdtors = . ;
|
||||
*(.dtors) /* Old ABI: Unallocated */
|
||||
*(.fini_array) /* New ABI: Allocated */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
_sbss = . ;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
_ebss = . ;
|
||||
}
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
||||
222
include/elf.h
Normal file
222
include/elf.h
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/****************************************************************************
|
||||
* include/elf.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_ELF_H
|
||||
#define __INCLUDE_ELF_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Values for Elf_Ehdr::e_type */
|
||||
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* Relocatable file */
|
||||
#define ET_EXEC 2 /* Executable file */
|
||||
#define ET_DYN 3 /* Shared object file */
|
||||
#define ET_CORE 4 /* Core file */
|
||||
#define ET_LOPROC 0xff00 /* Processor-specific */
|
||||
#define ET_HIPROC 0xffff /* Processor-specific */
|
||||
|
||||
/* Values for Elf_Ehdr::e_machine (most of this were not included in the
|
||||
* original SCO document but have been gleaned from elsewhere).
|
||||
*/
|
||||
|
||||
#define EM_NONE 0 /* No machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 486+ */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian */
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* PowerPC64 */
|
||||
#define EM_ARM 40 /* ARM */
|
||||
#define EM_SH 42 /* SuperH */
|
||||
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
|
||||
#define EM_H8_300 46
|
||||
#define EM_IA_64 50 /* HP/Intel IA-64 */
|
||||
#define EM_X86_64 62 /* AMD x86-64 */
|
||||
#define EM_S390 22 /* IBM S/390 */
|
||||
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
|
||||
#define EM_V850 87 /* NEC v850 */
|
||||
#define EM_M32R 88 /* Renesas M32R */
|
||||
#define EM_RISCV 243 /* RISC-V */
|
||||
#define EM_ALPHA 0x9026
|
||||
#define EM_CYGNUS_V850 0x9080
|
||||
#define EM_CYGNUS_M32R 0x9041
|
||||
#define EM_S390_OLD 0xa390
|
||||
#define EM_FRV 0x5441
|
||||
|
||||
/* Values for Elf_Ehdr::e_version */
|
||||
|
||||
#define EV_NONE 0 /* Invalid version */
|
||||
#define EV_CURRENT 1 /* The current version */
|
||||
|
||||
/* Table 2. Ehe ELF identifier */
|
||||
|
||||
#define EI_MAG0 0 /* File identification */
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4 /* File class */
|
||||
#define EI_DATA 5 /* Data encoding */
|
||||
#define EI_VERSION 6 /* File version */
|
||||
#define EI_PAD 7 /* Start of padding bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
#define EI_MAGIC_SIZE 4
|
||||
#define EI_MAGIC {0x7f, 'E', 'L', 'F'}
|
||||
|
||||
/* Table 3. Values for EI_CLASS */
|
||||
|
||||
#define ELFCLASSNONE 0 /* Invalid class */
|
||||
#define ELFCLASS32 1 /* 32-bit objects */
|
||||
#define ELFCLASS64 2 /* 64-bit objects */
|
||||
|
||||
/* Table 4. Values for EI_DATA */
|
||||
|
||||
#define ELFDATANONE 0 /* Invalid data encoding */
|
||||
#define ELFDATA2LSB 1 /* Least significant byte occupying the lowest address */
|
||||
#define ELFDATA2MSB 2 /* Most significant byte occupying the lowest address */
|
||||
|
||||
/* Table 7: Special Section Indexes */
|
||||
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LOPROC 0xff00
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
|
||||
/* Figure 4-9: Section Types, sh_type */
|
||||
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* Figure 4-11: Section Attribute Flags, sh_flags */
|
||||
|
||||
#define SHF_WRITE 1
|
||||
#define SHF_ALLOC 2
|
||||
#define SHF_EXECINSTR 4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
|
||||
/* Figure 4-16: Symbol Binding, ELF_ST_BIND */
|
||||
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
#define STB_LOPROC 13
|
||||
#define STB_HIPROC 15
|
||||
|
||||
/* Figure 4-17: Symbol Types, ELF_ST_TYPE */
|
||||
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define STT_LOPROC 13
|
||||
#define STT_HIPROC 15
|
||||
|
||||
/* Figure 5-2: Segment Types, p_type */
|
||||
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
/* Figure 5-3: Segment Flag Bits, p_flags */
|
||||
|
||||
#define PF_X 1 /* Execute */
|
||||
#define PF_W 2 /* Write */
|
||||
#define PF_R 4 /* Read */
|
||||
#define PF_MASKPROC 0xf0000000 /* Unspecified */
|
||||
|
||||
/* Figure 5-10: Dynamic Array Tags, d_tag */
|
||||
|
||||
#define DT_NULL 0 /* d_un=ignored */
|
||||
#define DT_NEEDED 1 /* d_un=d_val */
|
||||
#define DT_PLTRELSZ 2 /* d_un=d_val */
|
||||
#define DT_PLTGOT 3 /* d_un=d_ptr */
|
||||
#define DT_HASH 4 /* d_un=d_ptr */
|
||||
#define DT_STRTAB 5 /* d_un=d_ptr */
|
||||
#define DT_SYMTAB 6 /* d_un=d_ptr */
|
||||
#define DT_RELA 7 /* d_un=d_ptr */
|
||||
#define DT_RELASZ 8 /* d_un=d_val */
|
||||
#define DT_RELAENT 9 /* d_un=d_val */
|
||||
#define DT_STRSZ 10 /* d_un=d_val */
|
||||
#define DT_SYMENT 11 /* d_un=d_val */
|
||||
#define DT_INIT 12 /* d_un=d_ptr */
|
||||
#define DT_FINI 13 /* d_un=d_ptr */
|
||||
#define DT_SONAME 14 /* d_un=d_val */
|
||||
#define DT_RPATH 15 /* d_un=d_val */
|
||||
#define DT_SYMBOLIC 16 /* d_un=ignored */
|
||||
#define DT_REL 17 /* d_un=d_ptr */
|
||||
#define DT_RELSZ 18 /* d_un=d_val */
|
||||
#define DT_RELENT 19 /* d_un=d_val */
|
||||
#define DT_PLTREL 20 /* d_un=d_val */
|
||||
#define DT_DEBUG 21 /* d_un=d_ptr */
|
||||
#define DT_TEXTREL 22 /* d_un=ignored */
|
||||
#define DT_JMPREL 23 /* d_un=d_ptr */
|
||||
#define DT_BINDNOW 24 /* d_un=ignored */
|
||||
#define DT_LOPROC 0x70000000 /* d_un=unspecified */
|
||||
#define DT_HIPROC 0x7fffffff /* d_un= unspecified */
|
||||
|
||||
/* NOTE: elf64.h and elf32.h refer EI_NIDENT defined above */
|
||||
|
||||
#ifdef CONFIG_ELF_64BIT
|
||||
# include <elf64.h>
|
||||
#else
|
||||
# include <elf32.h>
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_ELF_H */
|
||||
193
include/elf32.h
193
include/elf32.h
|
|
@ -46,205 +46,23 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Values for Elf32_Ehdr::e_type */
|
||||
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* Relocatable file */
|
||||
#define ET_EXEC 2 /* Executable file */
|
||||
#define ET_DYN 3 /* Shared object file */
|
||||
#define ET_CORE 4 /* Core file */
|
||||
#define ET_LOPROC 0xff00 /* Processor-specific */
|
||||
#define ET_HIPROC 0xffff /* Processor-specific */
|
||||
|
||||
/* Values for Elf32_Ehdr::e_machine (most of this were not included in the
|
||||
* original SCO document but have been gleaned from elsewhere).
|
||||
*/
|
||||
|
||||
#define EM_NONE 0 /* No machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 486+ */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian */
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* PowerPC64 */
|
||||
#define EM_ARM 40 /* ARM */
|
||||
#define EM_SH 42 /* SuperH */
|
||||
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
|
||||
#define EM_IA_64 50 /* HP/Intel IA-64 */
|
||||
#define EM_X86_64 62 /* AMD x86-64 */
|
||||
#define EM_S390 22 /* IBM S/390 */
|
||||
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
|
||||
#define EM_V850 87 /* NEC v850 */
|
||||
#define EM_M32R 88 /* Renesas M32R */
|
||||
#define EM_H8_300 46
|
||||
#define EM_ALPHA 0x9026
|
||||
#define EM_CYGNUS_V850 0x9080
|
||||
#define EM_CYGNUS_M32R 0x9041
|
||||
#define EM_S390_OLD 0xa390
|
||||
#define EM_FRV 0x5441
|
||||
|
||||
/* Values for Elf32_Ehdr::e_version */
|
||||
|
||||
#define EV_NONE 0 /* Invalid version */
|
||||
#define EV_CURRENT 1 /* The current version */
|
||||
|
||||
/* Ehe ELF identifier */
|
||||
|
||||
#define EI_MAG0 0 /* File identification */
|
||||
#define EI_MAG1 1 /* " " " " */
|
||||
#define EI_MAG2 2 /* " " " " */
|
||||
#define EI_MAG3 3 /* " " " " */
|
||||
#define EI_CLASS 4 /* File class */
|
||||
#define EI_DATA 5 /* Data encoding */
|
||||
#define EI_VERSION 6 /* File version */
|
||||
#define EI_PAD 7 /* Start of padding bytes */
|
||||
#define EI_NIDENT 16 /* Size of eident[] */
|
||||
|
||||
#define EI_MAGIC_SIZE 4
|
||||
#define EI_MAGIC {0x7f, 'E', 'L', 'F'}
|
||||
|
||||
/* Values for EI_CLASS */
|
||||
|
||||
#define ELFCLASSNONE 0 /* Invalid class */
|
||||
#define ELFCLASS32 1 /* 32-bit objects */
|
||||
#define ELFCLASS64 2 /* 64-bit objects */
|
||||
|
||||
/* Values for EI_DATA */
|
||||
|
||||
#define ELFDATANONE 0 /* Invalid data encoding */
|
||||
#define ELFDATA2LSB 1 /* Least significant byte occupying the lowest address */
|
||||
#define ELFDATA2MSB 2 /* Most significant byte occupying the lowest address */
|
||||
|
||||
/* Figure 4-7: Special Section Indexes */
|
||||
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xff00
|
||||
#define SHN_LOPROC 0xff00
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
|
||||
/* Figure 4-9: Section Types, sh_type */
|
||||
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* Figure 4-11: Section Attribute Flags, sh_flags */
|
||||
|
||||
#define SHF_WRITE 1
|
||||
#define SHF_ALLOC 2
|
||||
#define SHF_EXECINSTR 4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
|
||||
/* Definitions for Elf32_Sym::st_info */
|
||||
|
||||
#define ELF32_ST_BIND(i) ((i) >> 4)
|
||||
#define ELF32_ST_TYPE(i) ((i) & 0xf)
|
||||
#define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf))
|
||||
|
||||
/* Figure 4-16: Symbol Binding, ELF32_ST_BIND */
|
||||
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
#define STB_LOPROC 13
|
||||
#define STB_HIPROC 15
|
||||
|
||||
/* Figure 4-17: Symbol Types, ELF32_ST_TYPE */
|
||||
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define STT_LOPROC 13
|
||||
#define STT_HIPROC 15
|
||||
|
||||
/* Definitions for Elf32_Rel*::r_info */
|
||||
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((i) & 0xff)
|
||||
#define ELF32_R_INFO(s,t) (((s)<< 8) | ((t) & 0xff))
|
||||
|
||||
/* Figure 5-2: Segment Types, p_type */
|
||||
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
/* Figure 5-3: Segment Flag Bits, p_flags */
|
||||
|
||||
#define PF_X 1 /* Execute */
|
||||
#define PF_W 2 /* Write */
|
||||
#define PF_R 4 /* Read */
|
||||
#define PF_MASKPROC 0xf0000000 /* Unspecified */
|
||||
|
||||
/* Figure 5-10: Dynamic Array Tags, d_tag */
|
||||
|
||||
#define DT_NULL 0 /* d_un=ignored */
|
||||
#define DT_NEEDED 1 /* d_un=d_val */
|
||||
#define DT_PLTRELSZ 2 /* d_un=d_val */
|
||||
#define DT_PLTGOT 3 /* d_un=d_ptr */
|
||||
#define DT_HASH 4 /* d_un=d_ptr */
|
||||
#define DT_STRTAB 5 /* d_un=d_ptr */
|
||||
#define DT_SYMTAB 6 /* d_un=d_ptr */
|
||||
#define DT_RELA 7 /* d_un=d_ptr */
|
||||
#define DT_RELASZ 8 /* d_un=d_val */
|
||||
#define DT_RELAENT 9 /* d_un=d_val */
|
||||
#define DT_STRSZ 10 /* d_un=d_val */
|
||||
#define DT_SYMENT 11 /* d_un=d_val */
|
||||
#define DT_INIT 12 /* d_un=d_ptr */
|
||||
#define DT_FINI 13 /* d_un=d_ptr */
|
||||
#define DT_SONAME 14 /* d_un=d_val */
|
||||
#define DT_RPATH 15 /* d_un=d_val */
|
||||
#define DT_SYMBOLIC 16 /* d_un=ignored */
|
||||
#define DT_REL 17 /* d_un=d_ptr */
|
||||
#define DT_RELSZ 18 /* d_un=d_val */
|
||||
#define DT_RELENT 19 /* d_un=d_val */
|
||||
#define DT_PLTREL 20 /* d_un=d_val */
|
||||
#define DT_DEBUG 21 /* d_un=d_ptr */
|
||||
#define DT_TEXTREL 22 /* d_un=ignored */
|
||||
#define DT_JMPREL 23 /* d_un=d_ptr */
|
||||
#define DT_BINDNOW 24 /* d_un=ignored */
|
||||
#define DT_LOPROC 0x70000000 /* d_un=unspecified */
|
||||
#define DT_HIPROC 0x7fffffff /* d_un= unspecified */
|
||||
#define ELF_R_SYM(i) ELF32_R_SYM(i)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
|
|
@ -347,6 +165,11 @@ typedef struct
|
|||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
//extern Elf32_Dyn _DYNAMIC[] ;
|
||||
typedef Elf32_Ehdr Elf_Ehdr;
|
||||
typedef Elf32_Rel Elf_Rel;
|
||||
typedef Elf32_Rela Elf_Rela;
|
||||
typedef Elf32_Sym Elf_Sym;
|
||||
typedef Elf32_Shdr Elf_Shdr;
|
||||
typedef Elf32_Word Elf_Word;
|
||||
|
||||
#endif /* __INCLUDE_ELF32_H */
|
||||
|
|
|
|||
157
include/elf64.h
Normal file
157
include/elf64.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/****************************************************************************
|
||||
* include/elf64.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_ELF64_H
|
||||
#define __INCLUDE_ELF64_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* See ELF-64 Object File Format: Version 1.5 Draft 2 */
|
||||
|
||||
/* Definitions for Elf64_Rel*::r_info */
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
|
||||
#define ELF64_R_INFO(s,t) (((s)<< 32) + ((t) & 0xffffffffL))
|
||||
|
||||
#define ELF_R_SYM(i) ELF64_R_SYM(i)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Table 1: ELF-64 Data Types */
|
||||
|
||||
typedef uint64_t Elf64_Addr; /* Unsigned program address */
|
||||
typedef uint64_t Elf64_Off; /* Unsigned file offset */
|
||||
typedef uint16_t Elf64_Half; /* Unsigned medium integer */
|
||||
typedef uint32_t Elf64_Word; /* Unsigned long integer */
|
||||
typedef int32_t Elf64_Sword; /* Signed integer */
|
||||
typedef uint64_t Elf64_Xword; /* Unsigned long integer */
|
||||
typedef int64_t Elf64_Sxword; /* Signed large integer */
|
||||
|
||||
/* Figure 2: ELF-64 Header */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
|
||||
Elf64_Half e_type; /* Object file type */
|
||||
Elf64_Half e_machine; /* Machine type */
|
||||
Elf64_Word e_version; /* Object file version */
|
||||
Elf64_Addr e_entry; /* Entry point address */
|
||||
Elf64_Off e_phoff; /* Program header offset */
|
||||
Elf64_Off e_shoff; /* Section header offset */
|
||||
Elf64_Word e_flags; /* Processor-specific flags */
|
||||
Elf64_Half e_ehsize; /* ELF header size */
|
||||
Elf64_Half e_phentsize; /* Size of program header entry */
|
||||
Elf64_Half e_phnum; /* Number of program header entry */
|
||||
Elf64_Half e_shentsize; /* Size of section header entry */
|
||||
Elf64_Half e_shnum; /* Number of section header entries */
|
||||
Elf64_Half e_shstrndx; /* Section name string table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* Figure 3: ELF-64 Section Header */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name */
|
||||
Elf64_Word sh_type; /* Section type */
|
||||
Elf64_Xword sh_flags; /* Section attributes */
|
||||
Elf64_Addr sh_addr; /* Virtual address in memory */
|
||||
Elf64_Off sh_offset; /* Offset in file */
|
||||
Elf64_Xword sh_size; /* Size of section */
|
||||
Elf64_Word sh_link; /* Link to other section */
|
||||
Elf64_Word sh_info; /* Miscellaneous information */
|
||||
Elf64_Xword sh_addralign; /* Address alignment boundary */
|
||||
Elf64_Xword sh_entsize; /* Size of entries, if section has table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* Figure 4: ELF-64 Symbol Table Entry */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name */
|
||||
unsigned char st_info; /* Type and Binding attributes */
|
||||
unsigned char st_other; /* Reserved */
|
||||
Elf64_Half st_shndx; /* Section table index */
|
||||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Size of object (e.g., common) */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* Figure 5: ELF-64 Relocation Entries */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address of reference */
|
||||
Elf64_Xword r_info; /* Symbol index and type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address of reference */
|
||||
Elf64_Xword r_info; /* Symbol index and type of relocation */
|
||||
Elf64_Sxword r_addend; /* Constant part of expression */
|
||||
} Elf64_Rela;
|
||||
|
||||
/* Figure 6: ELF-64 Program Header Table Entry */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type; /* Type of segment */
|
||||
Elf64_Word p_flags; /* Segment attributes */
|
||||
Elf64_Off p_offset; /* Offset in file */
|
||||
Elf64_Addr p_vaddr; /* Virtual address in memory */
|
||||
Elf64_Addr p_paddr; /* Reserved */
|
||||
Elf64_Word p_filesz; /* Size of segment in file */
|
||||
Elf64_Word p_memsz; /* Size of segment in memory */
|
||||
Elf64_Word p_align; /* Alignment of segment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* Figure 8: Dynamic Table Structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Sxword d_tag;
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
typedef Elf64_Ehdr Elf_Ehdr;
|
||||
typedef Elf64_Rel Elf_Rel;
|
||||
typedef Elf64_Rela Elf_Rela;
|
||||
typedef Elf64_Sym Elf_Sym;
|
||||
typedef Elf64_Shdr Elf_Shdr;
|
||||
typedef Elf64_Word Elf_Word;
|
||||
|
||||
#endif /* __INCLUDE_ELF64_H */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/binfmt/elf.h
|
||||
*
|
||||
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012, 2014, 2020 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <elf32.h>
|
||||
#include <elf.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
|
|
@ -54,6 +54,7 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_ELF_ALIGN_LOG2
|
||||
|
|
@ -110,8 +111,9 @@ struct elf_loadinfo_s
|
|||
size_t textsize; /* Size of the ELF .text memory allocation */
|
||||
size_t datasize; /* Size of the ELF .bss/.data memory allocation */
|
||||
off_t filelen; /* Length of the entire ELF file */
|
||||
Elf32_Ehdr ehdr; /* Buffered ELF file header */
|
||||
FAR Elf32_Shdr *shdr; /* Buffered ELF section headers */
|
||||
|
||||
Elf_Ehdr ehdr; /* Buffered ELF file header */
|
||||
FAR Elf_Shdr *shdr; /* Buffered ELF section headers */
|
||||
uint8_t *iobuffer; /* File I/O buffer */
|
||||
|
||||
/* Constructors and destructors */
|
||||
|
|
@ -145,7 +147,7 @@ struct elf_loadinfo_s
|
|||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <elf32.h>
|
||||
#include <elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
|
|
@ -68,7 +68,7 @@ extern "C"
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_ARCH_ELF
|
||||
bool up_checkarch(FAR const Elf32_Ehdr *hdr);
|
||||
bool up_checkarch(FAR const Elf_Ehdr *hdr);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -94,10 +94,10 @@ bool up_checkarch(FAR const Elf32_Ehdr *hdr);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_ARCH_ELF
|
||||
int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
|
||||
int up_relocate(FAR const Elf_Rel *rel, FAR const Elf_Sym *sym,
|
||||
uintptr_t addr);
|
||||
int up_relocateadd(FAR const Elf32_Rela *rel,
|
||||
FAR const Elf32_Sym *sym, uintptr_t addr);
|
||||
int up_relocateadd(FAR const Elf_Rela *rel,
|
||||
FAR const Elf_Sym *sym, uintptr_t addr);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -117,7 +117,7 @@ int up_relocateadd(FAR const Elf32_Rela *rel,
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CXX_EXCEPTION
|
||||
int up_init_exidx(Elf32_Addr address, Elf32_Word size);
|
||||
int up_init_exidx(Elf_Addr address, Elf_Word size);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/lib/modlib.h
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015, 2017, 2020 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <elf32.h>
|
||||
#include <elf.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/symtab.h>
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_MODLIB_MAXDEPEND
|
||||
|
|
@ -126,7 +127,7 @@ typedef CODE int (*mod_uninitializer_t)(FAR void *arg);
|
|||
* be returned if no uninitialization is needed (i.e, the
|
||||
* the module memory can be deallocated at any time).
|
||||
* arg - An argument that will be passed to the uninitialization
|
||||
function.
|
||||
* function.
|
||||
* exports - A symbol table exported by the module
|
||||
* nexports - The number of symbols in the exported symbol table.
|
||||
*/
|
||||
|
|
@ -206,8 +207,8 @@ struct mod_loadinfo_s
|
|||
size_t textsize; /* Size of the module .text memory allocation */
|
||||
size_t datasize; /* Size of the module .bss/.data memory allocation */
|
||||
off_t filelen; /* Length of the entire module file */
|
||||
Elf32_Ehdr ehdr; /* Buffered module file header */
|
||||
FAR Elf32_Shdr *shdr; /* Buffered module section headers */
|
||||
Elf_Ehdr ehdr; /* Buffered module file header */
|
||||
FAR Elf_Shdr *shdr; /* Buffered module section headers */
|
||||
uint8_t *iobuffer; /* File I/O buffer */
|
||||
|
||||
uint16_t symtabidx; /* Symbol table section index */
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ static void dldump_loadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
binfo("Sections %d:\n", i);
|
||||
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ config LIBM_ARCH_TRUNCF
|
|||
if ARCH_ARM
|
||||
source libs/libc/machine/arm/Kconfig
|
||||
endif
|
||||
if ARCH_RISCV
|
||||
source libs/libc/machine/risc-v/Kconfig
|
||||
endif
|
||||
if ARCH_SIM
|
||||
source libs/libc/machine/sim/Kconfig
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@
|
|||
ifeq ($(CONFIG_ARCH_ARM),y)
|
||||
include ${TOPDIR}/libs/libc/machine/arm/Make.defs
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_RISCV),y)
|
||||
include ${TOPDIR}/libs/libc/machine/risc-v/Make.defs
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_SIM),y)
|
||||
include ${TOPDIR}/libs/libc/machine/sim/Make.defs
|
||||
endif
|
||||
|
|
|
|||
9
libs/libc/machine/risc-v/Kconfig
Normal file
9
libs/libc/machine/risc-v/Kconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
if ARCH_RV64GC
|
||||
source libs/libc/machine/risc-v/rv64/Kconfig
|
||||
endif
|
||||
|
||||
23
libs/libc/machine/risc-v/Make.defs
Normal file
23
libs/libc/machine/risc-v/Make.defs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
############################################################################
|
||||
# libs/libc/machine/arm/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_RV64GC),y)
|
||||
include ${TOPDIR}/libs/libc/machine/risc-v/rv64/Make.defs
|
||||
endif
|
||||
4
libs/libc/machine/risc-v/rv64/Kconfig
Normal file
4
libs/libc/machine/risc-v/rv64/Kconfig
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
28
libs/libc/machine/risc-v/rv64/Make.defs
Normal file
28
libs/libc/machine/risc-v/rv64/Make.defs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
############################################################################
|
||||
# libs/libc/machine/risc-v/rv64/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_LIBC_ARCH_ELF),y)
|
||||
|
||||
CSRCS += arch_elf.c
|
||||
|
||||
DEPPATH += --dep-path machine/risc-v/rv64
|
||||
VPATH += :machine/risc-v/rv64
|
||||
|
||||
endif
|
||||
432
libs/libc/machine/risc-v/rv64/arch_elf.c
Normal file
432
libs/libc/machine/risc-v/rv64/arch_elf.c
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
/****************************************************************************
|
||||
* libs/libc/machine/risc-v/rv64/arch_elf.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <arch/elf.h>
|
||||
#include <nuttx/elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define OPCODE_SW 0x23
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_BINFMT_INFO
|
||||
struct rname_code_s
|
||||
{
|
||||
const char *name;
|
||||
int type;
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_BINFMT_INFO
|
||||
static struct rname_code_s _rname_table[] =
|
||||
{
|
||||
{"RELAX", R_RISCV_RELAX},
|
||||
{"RISCV_64", R_RISCV_64},
|
||||
{"PCREL_LO12_I", R_RISCV_PCREL_LO12_I},
|
||||
{"PCREL_LO12_S", R_RISCV_PCREL_LO12_S},
|
||||
{"PCREL_HI20", R_RISCV_PCREL_HI20},
|
||||
{"CALL", R_RISCV_CALL},
|
||||
{"BRANCH", R_RISCV_BRANCH},
|
||||
{"RVC_JUMP", R_RISCV_RVC_JUMP},
|
||||
{"RVC_BRANCH", R_RISCV_RVC_BRANCH},
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_BINFMT_INFO
|
||||
const char *_get_rname(int type)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(_rname_table) / sizeof(struct rname_code_s); i++)
|
||||
{
|
||||
if (_rname_table[i].type == type)
|
||||
{
|
||||
return _rname_table[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found in the table */
|
||||
|
||||
return "?????";
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _get_val, set_val, _add_val
|
||||
*
|
||||
* Description:
|
||||
* These functions are used when relocating an instruction because we can
|
||||
* not assume the instruction is word-aligned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t _get_val(uint16_t *addr)
|
||||
{
|
||||
uint32_t ret;
|
||||
ret = *addr | (*(addr + 1)) << 16;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _set_val(uint16_t *addr, uint32_t val)
|
||||
{
|
||||
*addr = (val & 0xffff);
|
||||
*(addr + 1) = (val >> 16);
|
||||
|
||||
/* NOTE: Ensure relocation before execution */
|
||||
|
||||
asm volatile ("fence.i");
|
||||
}
|
||||
|
||||
static void _add_val(uint16_t *addr, uint32_t val)
|
||||
{
|
||||
uint32_t cur = _get_val(addr);
|
||||
_set_val(addr, cur + val);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _calc_imm
|
||||
*
|
||||
* Description:
|
||||
* Given offset and obtain imm_hi (20bit) and imm_lo (12bit)
|
||||
*
|
||||
* Input Parameters:
|
||||
* offset - signed 64bit
|
||||
* imm_hi - signed 20bit
|
||||
* imm_lo - signed 12bit
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void _calc_imm(long offset, long *imm_hi, long *imm_lo)
|
||||
{
|
||||
long lo;
|
||||
long hi = offset / 4096;
|
||||
long r = offset % 4096;
|
||||
|
||||
if (2047 < r)
|
||||
{
|
||||
hi++;
|
||||
}
|
||||
else if (r <= -2048)
|
||||
{
|
||||
hi--;
|
||||
}
|
||||
|
||||
lo = offset - (hi * 4096);
|
||||
|
||||
binfo("offset=%ld: hi=%ld lo=%ld \n",
|
||||
offset, hi, lo);
|
||||
|
||||
ASSERT(-2048 <= lo && lo <= 2047);
|
||||
|
||||
*imm_lo = lo;
|
||||
*imm_hi = hi;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_checkarch
|
||||
*
|
||||
* Description:
|
||||
* Given the ELF header in 'hdr', verify that the ELF file is appropriate
|
||||
* for the current, configured architecture. Every architecture that uses
|
||||
* the ELF loader must provide this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* hdr - The ELF header read from the ELF file.
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the architecture supports this ELF file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool up_checkarch(FAR const Elf64_Ehdr *ehdr)
|
||||
{
|
||||
/* Make sure it's an RISCV executable */
|
||||
|
||||
if (ehdr->e_machine != EM_RISCV)
|
||||
{
|
||||
berr("ERROR: Not for RISCV: e_machine=%04x\n", ehdr->e_machine);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure that 64-bit objects are supported */
|
||||
|
||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
|
||||
{
|
||||
berr("ERROR: Need 64-bit objects: e_ident[EI_CLASS]=%02x\n",
|
||||
ehdr->e_ident[EI_CLASS]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Verify endian-ness */
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
|
||||
#else
|
||||
if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
#endif
|
||||
{
|
||||
berr("ERROR: Wrong endian-ness: e_ident[EI_DATA]=%02x\n",
|
||||
ehdr->e_ident[EI_DATA]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure the entry point address is properly aligned */
|
||||
|
||||
if ((ehdr->e_entry & 1) != 0)
|
||||
{
|
||||
berr("ERROR: Entry point is not properly aligned: %08x\n",
|
||||
ehdr->e_entry);
|
||||
}
|
||||
|
||||
/* TODO: Check ABI here. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_relocate and up_relocateadd
|
||||
*
|
||||
* Description:
|
||||
* Perform on architecture-specific ELF relocation. Every architecture
|
||||
* that uses the ELF loader must provide this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* rel - The relocation type
|
||||
* sym - The ELF symbol structure containing the fully resolved value.
|
||||
* There are a few relocation types for a few architectures that do
|
||||
* not require symbol information. For those, this value will be
|
||||
* NULL. Implementations of these functions must be able to handle
|
||||
* that case.
|
||||
* addr - The address that requires the relocation.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the relocation was successful. Otherwise, a negated errno
|
||||
* value indicating the cause of the relocation failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_relocate(FAR const Elf64_Rel *rel, FAR const Elf64_Sym *sym,
|
||||
uintptr_t addr)
|
||||
{
|
||||
berr("Not implemented\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int up_relocateadd(FAR const Elf64_Rela *rel, FAR const Elf64_Sym *sym,
|
||||
uintptr_t addr)
|
||||
{
|
||||
long offset;
|
||||
unsigned int relotype;
|
||||
|
||||
/* All relocations depend upon having valid symbol information */
|
||||
|
||||
relotype = ELF64_R_TYPE(rel->r_info);
|
||||
|
||||
if (relotype == R_RISCV_RELAX)
|
||||
{
|
||||
/* NOTE: RELAX has no symbol, so just return */
|
||||
|
||||
binfo("%s at %08lx [%08x] \n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (sym == NULL && relotype != R_RISCV_NONE)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Do relocation based on relocation type */
|
||||
|
||||
switch (relotype)
|
||||
{
|
||||
case R_RISCV_64:
|
||||
{
|
||||
binfo("%s at %08lx [%08x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
_set_val((uint16_t *)addr,
|
||||
(uint32_t)(sym->st_value + rel->r_addend));
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
case R_RISCV_PCREL_LO12_S:
|
||||
{
|
||||
binfo("%s at %08lx [%08x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
/* NOTE: imm value for mv has been adjusted in previous HI20 */
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_PCREL_HI20:
|
||||
case R_RISCV_CALL:
|
||||
{
|
||||
binfo("%s at %08lx [%08x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
offset = (long)sym->st_value - (long)addr;
|
||||
|
||||
long imm_hi;
|
||||
long imm_lo;
|
||||
|
||||
_calc_imm(offset, &imm_hi, &imm_lo);
|
||||
|
||||
/* Adjust auipc (add upper immediate to pc) : 20bit */
|
||||
|
||||
_add_val((uint16_t *)addr, (imm_hi << 12));
|
||||
|
||||
if ((_get_val((uint16_t *)(addr + 4)) & 0x7f) == OPCODE_SW)
|
||||
{
|
||||
/* Adjust imm for SW : S-type */
|
||||
|
||||
uint32_t val =
|
||||
(((int32_t)imm_lo >> 5) << 25) +
|
||||
(((int32_t)imm_lo & 0x1f) << 7);
|
||||
|
||||
binfo("imm_lo=%d (%x), val=%x \n", imm_lo, imm_lo, val);
|
||||
|
||||
_add_val((uint16_t *)(addr + 4), val);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Adjust imm for MV(ADDI)/JALR : I-type */
|
||||
|
||||
_add_val((uint16_t *)(addr + 4), ((int32_t)imm_lo << 20));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_BRANCH:
|
||||
{
|
||||
binfo("%s at %08lx [%08x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
/* P.23 Conditinal Branches : B type (imm=12bit) */
|
||||
|
||||
offset = (long)sym->st_value - (long)addr;
|
||||
uint32_t val = _get_val((uint16_t *)addr) & 0xfe000f80;
|
||||
|
||||
/* NOTE: we assume that a compiler adds an immediate value */
|
||||
|
||||
ASSERT(offset && val);
|
||||
|
||||
binfo("offset for Bx=%ld (0x%x) (val=0x%08x) already set! \n",
|
||||
offset, offset, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_RVC_JUMP:
|
||||
{
|
||||
binfo("%s at %08lx [%04x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
/* P.111 Table 16.6 : Instruction listings for RVC */
|
||||
|
||||
offset = ((long)sym->st_value - (long)addr);
|
||||
ASSERT(-2048 <= offset && offset <= 2047);
|
||||
|
||||
uint16_t val = (*(uint16_t *)addr) & 0x1ffc;
|
||||
|
||||
/* NOTE: we assume that a compiler adds an immediate value */
|
||||
|
||||
ASSERT(offset && val);
|
||||
|
||||
binfo("offset for C.J=%ld (0x%x) (val=0x%04x) already set! \n",
|
||||
offset, offset, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_RVC_BRANCH:
|
||||
{
|
||||
binfo("%s at %08lx [%04x] to sym=%p st_value=%08lx\n",
|
||||
_get_rname(relotype),
|
||||
(long)addr, _get_val((uint16_t *)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
/* P.111 Table 16.6 : Instruction listings for RVC */
|
||||
|
||||
offset = ((long)sym->st_value - (long)addr);
|
||||
ASSERT(-256 <= offset && offset <= 255);
|
||||
|
||||
uint16_t val = (*(uint16_t *)addr) & 0x1c7c;
|
||||
|
||||
/* NOTE: we assume that a compiler adds an immediate value */
|
||||
|
||||
ASSERT(offset && val);
|
||||
|
||||
binfo("offset for C.Bx=%ld (0x%x) (val=0x%04x) already set!\n",
|
||||
offset, offset, val);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
berr("ERROR: Unsupported relocation: %d\n",
|
||||
ELF64_R_TYPE(rel->r_info));
|
||||
ASSERT(false);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_verifyheader(FAR const Elf32_Ehdr *header);
|
||||
int modlib_verifyheader(FAR const Elf_Ehdr *header);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_findsymtab
|
||||
|
|
@ -98,7 +98,7 @@ int modlib_findsymtab(FAR struct mod_loadinfo_s *loadinfo);
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf32_Sym *sym);
|
||||
FAR Elf_Sym *sym);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_symvalue
|
||||
|
|
@ -125,7 +125,7 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_symvalue(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym);
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_loadshdrs
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@
|
|||
****************************************************************************/
|
||||
|
||||
/* REVISIT: This naming breaks the NuttX coding standard, but is consistent
|
||||
* with legacy naming of other ELF32 types.
|
||||
* with legacy naming of other ELF types.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dq_entry_t entry;
|
||||
Elf32_Sym sym;
|
||||
Elf_Sym sym;
|
||||
int idx;
|
||||
} Elf32_SymCache;
|
||||
} Elf_SymCache;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
|
@ -74,13 +74,13 @@ typedef struct
|
|||
* Name: modlib_readrels
|
||||
*
|
||||
* Description:
|
||||
* Read the (ELF32_Rel structure * buffer count) into memory.
|
||||
* Read the (ELF_Rel structure * buffer count) into memory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *relsec,
|
||||
int index, FAR Elf32_Rel *rels,
|
||||
FAR const Elf_Shdr *relsec,
|
||||
int index, FAR Elf_Rel *rels,
|
||||
int count)
|
||||
{
|
||||
off_t offset;
|
||||
|
|
@ -88,7 +88,7 @@ static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
|||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf32_Rel)))
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rel)))
|
||||
{
|
||||
berr("ERROR: Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -96,8 +96,8 @@ static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
|||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = sizeof(Elf32_Rel) * index;
|
||||
size = sizeof(Elf32_Rel) * count;
|
||||
offset = sizeof(Elf_Rel) * index;
|
||||
size = sizeof(Elf_Rel) * count;
|
||||
if (offset + size > relsec->sh_size)
|
||||
{
|
||||
size = relsec->sh_size - offset;
|
||||
|
|
@ -109,6 +109,45 @@ static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
|||
relsec->sh_offset + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_readrelas
|
||||
*
|
||||
* Description:
|
||||
* Read the (ELF_Rela structure * buffer count) into memory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int modlib_readrelas(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf_Shdr *relsec,
|
||||
int index, FAR Elf_Rela *relas,
|
||||
int count)
|
||||
{
|
||||
off_t offset;
|
||||
int size;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (relsec->sh_size / sizeof(Elf_Rela)))
|
||||
{
|
||||
berr("ERROR: Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = sizeof(Elf_Rela) * index;
|
||||
size = sizeof(Elf_Rela) * count;
|
||||
if (offset + size > relsec->sh_size)
|
||||
{
|
||||
size = relsec->sh_size - offset;
|
||||
}
|
||||
|
||||
/* And, finally, read the symbol table entry into memory */
|
||||
|
||||
return modlib_read(loadinfo, (FAR uint8_t *)relas, size,
|
||||
relsec->sh_offset + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_relocate and modlib_relocateadd
|
||||
*
|
||||
|
|
@ -125,12 +164,12 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
FAR struct mod_loadinfo_s *loadinfo, int relidx)
|
||||
|
||||
{
|
||||
FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf32_Rel *rels;
|
||||
FAR Elf32_Rel *rel;
|
||||
FAR Elf32_SymCache *cache;
|
||||
FAR Elf32_Sym *sym;
|
||||
FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf_Rel *rels;
|
||||
FAR Elf_Rel *rel;
|
||||
FAR Elf_SymCache *cache;
|
||||
FAR Elf_Sym *sym;
|
||||
FAR dq_entry_t *e;
|
||||
dq_queue_t q;
|
||||
uintptr_t addr;
|
||||
|
|
@ -139,7 +178,7 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
int i;
|
||||
int j;
|
||||
|
||||
rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
||||
rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rel));
|
||||
if (!rels)
|
||||
{
|
||||
berr("Failed to allocate memory for elf relocation rels\n");
|
||||
|
|
@ -155,7 +194,7 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
|
||||
ret = OK;
|
||||
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rel); i++)
|
||||
{
|
||||
/* Read the relocation entry into memory */
|
||||
|
||||
|
|
@ -176,14 +215,14 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
* in a bit-field within the r_info element.
|
||||
*/
|
||||
|
||||
symidx = ELF32_R_SYM(rel->r_info);
|
||||
symidx = ELF_R_SYM(rel->r_info);
|
||||
|
||||
/* First try the cache */
|
||||
|
||||
sym = NULL;
|
||||
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||
{
|
||||
cache = (FAR Elf32_SymCache *)e;
|
||||
cache = (FAR Elf_SymCache *)e;
|
||||
if (cache->idx == symidx)
|
||||
{
|
||||
dq_rem(&cache->entry, &q);
|
||||
|
|
@ -201,7 +240,7 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
{
|
||||
if (j < CONFIG_MODLIB_SYMBOL_CACHECOUNT)
|
||||
{
|
||||
cache = lib_malloc(sizeof(Elf32_SymCache));
|
||||
cache = lib_malloc(sizeof(Elf_SymCache));
|
||||
if (!cache)
|
||||
{
|
||||
berr("Failed to allocate memory for elf symbols\n");
|
||||
|
|
@ -212,7 +251,7 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
}
|
||||
else
|
||||
{
|
||||
cache = (FAR Elf32_SymCache *)dq_remlast(&q);
|
||||
cache = (FAR Elf_SymCache *)dq_remlast(&q);
|
||||
}
|
||||
|
||||
sym = &cache->sym;
|
||||
|
|
@ -301,8 +340,177 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
static int modlib_relocateadd(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, int relidx)
|
||||
{
|
||||
berr("ERROR: Not implemented\n");
|
||||
return -ENOSYS;
|
||||
FAR Elf_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||
FAR Elf_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||
FAR Elf_Rela *relas;
|
||||
FAR Elf_Rela *rela;
|
||||
FAR Elf_SymCache *cache;
|
||||
FAR Elf_Sym *sym;
|
||||
FAR dq_entry_t *e;
|
||||
dq_queue_t q;
|
||||
uintptr_t addr;
|
||||
int symidx;
|
||||
int ret;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
relas = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rela));
|
||||
if (!relas)
|
||||
{
|
||||
berr("Failed to allocate memory for elf relocation relas\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dq_init(&q);
|
||||
|
||||
/* Examine each relocation in the section. 'relsec' is the section
|
||||
* containing the relations. 'dstsec' is the section containing the data
|
||||
* to be relocated.
|
||||
*/
|
||||
|
||||
ret = OK;
|
||||
|
||||
for (i = j = 0; i < relsec->sh_size / sizeof(Elf_Rela); i++)
|
||||
{
|
||||
/* Read the relocation entry into memory */
|
||||
|
||||
rela = &relas[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT];
|
||||
|
||||
if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT))
|
||||
{
|
||||
ret = modlib_readrelas(loadinfo, relsec, i, relas, CONFIG_MODLIB_RELOCATION_BUFFERCOUNT);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Failed to read relocation entry: %d\n",
|
||||
relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the symbol table index for the relocation. This is contained
|
||||
* in a bit-field within the r_info element.
|
||||
*/
|
||||
|
||||
symidx = ELF_R_SYM(rela->r_info);
|
||||
|
||||
/* First try the cache */
|
||||
|
||||
sym = NULL;
|
||||
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||
{
|
||||
cache = (FAR Elf_SymCache *)e;
|
||||
if (cache->idx == symidx)
|
||||
{
|
||||
dq_rem(&cache->entry, &q);
|
||||
dq_addfirst(&cache->entry, &q);
|
||||
sym = &cache->sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the symbol was not found in the cache, we will need to read the
|
||||
* symbol from the file.
|
||||
*/
|
||||
|
||||
if (sym == NULL)
|
||||
{
|
||||
if (j < CONFIG_MODLIB_SYMBOL_CACHECOUNT)
|
||||
{
|
||||
cache = lib_malloc(sizeof(Elf_SymCache));
|
||||
if (!cache)
|
||||
{
|
||||
berr("Failed to allocate memory for elf symbols\n");
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = (FAR Elf_SymCache *)dq_remlast(&q);
|
||||
}
|
||||
|
||||
sym = &cache->sym;
|
||||
|
||||
/* Read the symbol table entry into memory */
|
||||
|
||||
ret = modlib_readsym(loadinfo, symidx, sym);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
lib_free(cache);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the value of the symbol (in sym.st_value) */
|
||||
|
||||
ret = modlib_symvalue(modp, loadinfo, sym);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The special error -ESRCH is returned only in one condition: The
|
||||
* symbol has no name.
|
||||
*
|
||||
* There are a few relocations for a few architectures that do
|
||||
* no depend upon a named symbol. We don't know if that is the
|
||||
* case here, but we will use a NULL symbol pointer to indicate
|
||||
* that case to up_relocate(). That function can then do what
|
||||
* is best.
|
||||
*/
|
||||
|
||||
if (ret == -ESRCH)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
||||
relidx, i, symidx, ret);
|
||||
lib_free(cache);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cache->idx = symidx;
|
||||
dq_addfirst(&cache->entry, &q);
|
||||
}
|
||||
|
||||
if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0)
|
||||
{
|
||||
sym = NULL;
|
||||
}
|
||||
|
||||
/* Calculate the relocation address. */
|
||||
|
||||
if (rela->r_offset < 0 || rela->r_offset > dstsec->sh_size - sizeof(uint32_t))
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Relocation address out of range, offset %d size %d\n",
|
||||
relidx, i, rela->r_offset, dstsec->sh_size);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
addr = dstsec->sh_addr + rela->r_offset;
|
||||
|
||||
/* Now perform the architecture-specific relocation */
|
||||
|
||||
ret = up_relocateadd(rela, sym, addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lib_free(relas);
|
||||
while ((e = dq_peek(&q)))
|
||||
{
|
||||
dq_rem(e, &q);
|
||||
lib_free(e);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ int modlib_initialize(FAR const char *filename,
|
|||
/* Read the ELF ehdr from offset 0 */
|
||||
|
||||
ret = modlib_read(loadinfo, (FAR uint8_t *)&loadinfo->ehdr,
|
||||
sizeof(Elf32_Ehdr), 0);
|
||||
sizeof(Elf_Ehdr), 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Failed to read ELF header: %d\n", ret);
|
||||
|
|
@ -178,7 +178,7 @@ int modlib_initialize(FAR const char *filename,
|
|||
}
|
||||
|
||||
modlib_dumpbuffer("ELF header", (FAR const uint8_t *)&loadinfo->ehdr,
|
||||
sizeof(Elf32_Ehdr));
|
||||
sizeof(Elf_Ehdr));
|
||||
|
||||
/* Verify the ELF header */
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ static void modlib_elfsize(struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
|
|
@ -157,7 +157,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution */
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@
|
|||
****************************************************************************/
|
||||
|
||||
static inline int modlib_sectname(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Shdr *shdr)
|
||||
FAR const Elf_Shdr *shdr)
|
||||
{
|
||||
FAR Elf32_Shdr *shstr;
|
||||
FAR Elf_Shdr *shstr;
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
size_t readlen;
|
||||
|
|
@ -203,7 +203,7 @@ int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
/* Allocate memory to hold a working copy of the sector header table */
|
||||
|
||||
loadinfo->shdr = (FAR FAR Elf32_Shdr *)lib_malloc(shdrsize);
|
||||
loadinfo->shdr = (FAR FAR Elf_Shdr *)lib_malloc(shdrsize);
|
||||
if (!loadinfo->shdr)
|
||||
{
|
||||
berr("ERROR: Failed to allocate the section header table. Size: %ld\n",
|
||||
|
|
@ -243,7 +243,7 @@ int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||
int modlib_findsection(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const char *sectname)
|
||||
{
|
||||
FAR const Elf32_Shdr *shdr;
|
||||
FAR const Elf_Shdr *shdr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ struct mod_exportinfo_s
|
|||
****************************************************************************/
|
||||
|
||||
static int modlib_symname(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf32_Sym *sym)
|
||||
FAR const Elf_Sym *sym)
|
||||
{
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
|
|
@ -276,14 +276,14 @@ int modlib_findsymtab(FAR struct mod_loadinfo_s *loadinfo)
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf32_Sym *sym)
|
||||
FAR Elf_Sym *sym)
|
||||
{
|
||||
FAR Elf32_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
FAR Elf_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
off_t offset;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
||||
if (index < 0 || index > (symtab->sh_size / sizeof(Elf32_Sym)))
|
||||
if (index < 0 || index > (symtab->sh_size / sizeof(Elf_Sym)))
|
||||
{
|
||||
berr("ERROR: Bad relocation symbol index: %d\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -291,11 +291,11 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
|
||||
/* Get the file offset to the symbol table entry */
|
||||
|
||||
offset = symtab->sh_offset + sizeof(Elf32_Sym) * index;
|
||||
offset = symtab->sh_offset + sizeof(Elf_Sym) * index;
|
||||
|
||||
/* And, finally, read the symbol table entry into memory */
|
||||
|
||||
return modlib_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf32_Sym), offset);
|
||||
return modlib_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf_Sym), offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -323,7 +323,7 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_symvalue(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym)
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
struct mod_exportinfo_s exportinfo;
|
||||
|
|
@ -416,7 +416,7 @@ int modlib_symvalue(FAR struct module_s *modp,
|
|||
loadinfo->iobuffer, sym->st_value, symbol->sym_value,
|
||||
sym->st_value + symbol->sym_value);
|
||||
|
||||
sym->st_value += (Elf32_Word)((uintptr_t)symbol->sym_value);
|
||||
sym->st_value += (Elf_Word)((uintptr_t)symbol->sym_value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static const char g_modmagic[EI_MAGIC_SIZE] =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_verifyheader(FAR const Elf32_Ehdr *ehdr)
|
||||
int modlib_verifyheader(FAR const Elf_Ehdr *ehdr)
|
||||
{
|
||||
if (!ehdr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
extern "C"
|
||||
{
|
||||
int up_init_exidx(Elf32_Addr start, Elf32_Word size)
|
||||
int up_init_exidx(Elf_Addr start, Elf_Word size)
|
||||
{
|
||||
__exidx_start_elf = (__EIT_entry *) start;
|
||||
__exidx_end_elf = __exidx_start_elf + size;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
binfo("Sections %d:\n", i);
|
||||
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue