diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2018-01-29 10:28:32 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@dabbelt.com> | 2018-01-29 10:37:27 -0800 |
commit | 7f33b09c65e3fdb6b6a1af8816918bcce977b38a (patch) | |
tree | 820a99249081334d21f7a4eb7fa621c05d2337ca /sysdeps/unix/sysv/linux/riscv/readelflib.c | |
parent | 36960f0c763a904d6d1f028e2c33b7bbe43c2a3a (diff) | |
download | glibc-7f33b09c65e3fdb6b6a1af8816918bcce977b38a.tar.gz glibc-7f33b09c65e3fdb6b6a1af8816918bcce977b38a.tar.xz glibc-7f33b09c65e3fdb6b6a1af8816918bcce977b38a.zip |
RISC-V: Linux ABI
Linux-specific code that is required for maintaining ABI compatibility. This doesn't contain the actual system call interface, that is split out in order to avoid having a patch that's too big. 2018-01-29 Palmer Dabbelt <palmer@sifive.com> * sysdeps/riscv/nptl/pthread-offsets.h: New file. * sysdeps/riscv/nptl/pthreaddef.h: Likewise. * sysdeps/unix/sysv/linux/riscv/bits/fcntl.h: Likewise. * sysdeps/unix/sysv/linux/riscv/bits/mman.h: Likewise. * sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h: Likewise. * sysdeps/unix/sysv/linux/riscv/dl-cache.h: Likewise. * sysdeps/unix/sysv/linux/riscv/flush-icache.c: Likewise. * sysdeps/unix/sysv/linux/riscv/getcontext.S: Likewise. * sysdeps/unix/sysv/linux/riscv/init-first.c: Likewise. * sysdeps/unix/sysv/linux/riscv/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/riscv/makecontext.c: Likewise. * sysdeps/unix/sysv/linux/riscv/readelflib.c: Likewise. * sysdeps/unix/sysv/linux/riscv/register-dump.h: Likewise. * sysdeps/unix/sysv/linux/riscv/setcontext.S: Likewise. * sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h: Likewise. * sysdeps/unix/sysv/linux/riscv/swapcontext.S: Likewise. * sysdeps/unix/sysv/linux/riscv/sys/cachectl.h: Likewise. * sysdeps/unix/sysv/linux/riscv/sys/procfs.h: Likewise. * sysdeps/unix/sysv/linux/riscv/sys/ucontext.h: Likewise. * sysdeps/unix/sysv/linux/riscv/sys/user.h: Likewise. * sysdeps/unix/sysv/linux/riscv/ucontext-macros.h: Likewise. * sysdeps/unix/sysv/linux/riscv/ucontext_i.sym: Likewise.
Diffstat (limited to 'sysdeps/unix/sysv/linux/riscv/readelflib.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/riscv/readelflib.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/riscv/readelflib.c b/sysdeps/unix/sysv/linux/riscv/readelflib.c new file mode 100644 index 0000000000..6e249ff82f --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/readelflib.c @@ -0,0 +1,96 @@ +/* Support for reading ELF files. + Copyright (C) 1999-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +int process_elf32_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, + void *file_contents, size_t file_length); +int process_elf64_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, + void *file_contents, size_t file_length); + +/* The ELF flags supported by our current glibc port: + - EF_RISCV_FLOAT_ABI: We support the soft and double ABIs. + - EF_RISCV_RVC: While the Linux ABI mandates the presence of the C + extension, we can still support libraries compiled without that extension + so we just ignore this flag. + - EF_RISCV_RVE: glibc (and Linux) don't support RV32E based systems. + - EF_RISCV_TSO: The TSO extension isn't supported, as doing so would require + some mechanism to ensure that the TSO extension is enabled which doesn't + currently exist. */ +#define SUPPORTED_ELF_FLAGS (EF_RISCV_FLOAT_ABI | EF_RISCV_RVC) + +/* Returns 0 if everything is ok, != 0 in case of error. */ +int +process_elf_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, void *file_contents, + size_t file_length) +{ + ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; + Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header; + int ret; + long flags; + + /* RISC-V libraries are always libc.so.6+. */ + *flag = FLAG_ELF_LIBC6; + + if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) + { + ret = process_elf32_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + flags = elf32_header->e_flags; + } + else + { + ret = process_elf64_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + flags = elf32_header->e_flags; + } + + /* RISC-V linkers encode the floating point ABI as part of the ELF headers. */ + switch (flags & EF_RISCV_FLOAT_ABI) + { + case EF_RISCV_FLOAT_ABI_SOFT: + *flag |= FLAG_RISCV_FLOAT_ABI_SOFT; + break; + case EF_RISCV_FLOAT_ABI_DOUBLE: + *flag |= FLAG_RISCV_FLOAT_ABI_DOUBLE; + break; + default: + return 1; + } + + /* If there are any other ELF flags set then glibc doesn't support this + library. */ + if (flags & ~SUPPORTED_ELF_FLAGS) + return 1; + + return ret; +} + +#undef __ELF_NATIVE_CLASS +#undef process_elf_file +#define process_elf_file process_elf32_file +#define __ELF_NATIVE_CLASS 32 +#include "elf/readelflib.c" + +#undef __ELF_NATIVE_CLASS +#undef process_elf_file +#define process_elf_file process_elf64_file +#define __ELF_NATIVE_CLASS 64 +#include "elf/readelflib.c" |