From 87e0e76be5b17d1dd27274d58ac9b58cdf71c0ca Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Sat, 13 Sep 2014 12:09:16 +1000 Subject: Refactor code into the RTEMS Toolkit. --- linkers/ConvertUTF.c | 539 --- linkers/ConvertUTF.h | 149 - linkers/README | 18 +- linkers/SimpleIni.h | 3385 --------------- linkers/elftoolchain/common/Makefile | 15 - linkers/elftoolchain/common/_elftc.h | 176 - linkers/elftoolchain/common/elfdefinitions.h | 2560 ------------ linkers/elftoolchain/common/native-elf-format | 47 - linkers/elftoolchain/common/os.Linux.mk | 13 - linkers/elftoolchain/common/uthash.h | 906 ---- linkers/elftoolchain/libelf/Makefile | 158 - linkers/elftoolchain/libelf/Version.map | 97 - linkers/elftoolchain/libelf/_libelf.h | 211 - linkers/elftoolchain/libelf/_libelf_ar.h | 56 - linkers/elftoolchain/libelf/_libelf_config.h | 197 - linkers/elftoolchain/libelf/elf.3 | 589 --- linkers/elftoolchain/libelf/elf.c | 40 - linkers/elftoolchain/libelf/elf_begin.3 | 311 -- linkers/elftoolchain/libelf/elf_begin.c | 276 -- linkers/elftoolchain/libelf/elf_cntl.3 | 111 - linkers/elftoolchain/libelf/elf_cntl.c | 58 - linkers/elftoolchain/libelf/elf_data.c | 247 -- linkers/elftoolchain/libelf/elf_end.3 | 76 - linkers/elftoolchain/libelf/elf_end.c | 93 - linkers/elftoolchain/libelf/elf_errmsg.3 | 107 - linkers/elftoolchain/libelf/elf_errmsg.c | 85 - linkers/elftoolchain/libelf/elf_errno.c | 43 - linkers/elftoolchain/libelf/elf_fill.3 | 52 - linkers/elftoolchain/libelf/elf_fill.c | 39 - linkers/elftoolchain/libelf/elf_flag.c | 195 - linkers/elftoolchain/libelf/elf_flagdata.3 | 194 - linkers/elftoolchain/libelf/elf_getarhdr.3 | 97 - linkers/elftoolchain/libelf/elf_getarhdr.c | 47 - linkers/elftoolchain/libelf/elf_getarsym.3 | 130 - linkers/elftoolchain/libelf/elf_getarsym.c | 58 - linkers/elftoolchain/libelf/elf_getbase.3 | 71 - linkers/elftoolchain/libelf/elf_getbase.c | 48 - linkers/elftoolchain/libelf/elf_getdata.3 | 229 - linkers/elftoolchain/libelf/elf_getident.3 | 83 - linkers/elftoolchain/libelf/elf_getident.c | 68 - linkers/elftoolchain/libelf/elf_getphdrnum.3 | 86 - linkers/elftoolchain/libelf/elf_getphnum.3 | 93 - linkers/elftoolchain/libelf/elf_getscn.3 | 151 - linkers/elftoolchain/libelf/elf_getshdrnum.3 | 78 - linkers/elftoolchain/libelf/elf_getshdrstrndx.3 | 79 - linkers/elftoolchain/libelf/elf_getshnum.3 | 84 - linkers/elftoolchain/libelf/elf_getshstrndx.3 | 94 - linkers/elftoolchain/libelf/elf_hash.3 | 57 - linkers/elftoolchain/libelf/elf_hash.c | 56 - linkers/elftoolchain/libelf/elf_kind.3 | 71 - linkers/elftoolchain/libelf/elf_kind.c | 44 - linkers/elftoolchain/libelf/elf_memory.3 | 122 - linkers/elftoolchain/libelf/elf_memory.c | 92 - linkers/elftoolchain/libelf/elf_next.3 | 96 - linkers/elftoolchain/libelf/elf_next.c | 62 - linkers/elftoolchain/libelf/elf_phnum.c | 67 - linkers/elftoolchain/libelf/elf_rand.3 | 118 - linkers/elftoolchain/libelf/elf_rand.c | 59 - linkers/elftoolchain/libelf/elf_rawfile.3 | 76 - linkers/elftoolchain/libelf/elf_rawfile.c | 53 - linkers/elftoolchain/libelf/elf_scn.c | 232 -- linkers/elftoolchain/libelf/elf_shnum.c | 67 - linkers/elftoolchain/libelf/elf_shstrndx.c | 82 - linkers/elftoolchain/libelf/elf_strptr.3 | 116 - linkers/elftoolchain/libelf/elf_strptr.c | 130 - linkers/elftoolchain/libelf/elf_types.m4 | 309 -- linkers/elftoolchain/libelf/elf_update.3 | 378 -- linkers/elftoolchain/libelf/elf_update.c | 1184 ------ linkers/elftoolchain/libelf/elf_version.3 | 95 - linkers/elftoolchain/libelf/elf_version.c | 52 - linkers/elftoolchain/libelf/gelf.3 | 201 - linkers/elftoolchain/libelf/gelf.h | 108 - linkers/elftoolchain/libelf/gelf_cap.c | 144 - linkers/elftoolchain/libelf/gelf_checksum.3 | 115 - linkers/elftoolchain/libelf/gelf_checksum.c | 58 - linkers/elftoolchain/libelf/gelf_dyn.c | 143 - linkers/elftoolchain/libelf/gelf_ehdr.c | 167 - linkers/elftoolchain/libelf/gelf_fsize.3 | 96 - linkers/elftoolchain/libelf/gelf_fsize.c | 62 - linkers/elftoolchain/libelf/gelf_getcap.3 | 121 - linkers/elftoolchain/libelf/gelf_getclass.3 | 61 - linkers/elftoolchain/libelf/gelf_getclass.c | 39 - linkers/elftoolchain/libelf/gelf_getdyn.3 | 123 - linkers/elftoolchain/libelf/gelf_getehdr.3 | 123 - linkers/elftoolchain/libelf/gelf_getmove.3 | 120 - linkers/elftoolchain/libelf/gelf_getphdr.3 | 141 - linkers/elftoolchain/libelf/gelf_getrel.3 | 121 - linkers/elftoolchain/libelf/gelf_getrela.3 | 121 - linkers/elftoolchain/libelf/gelf_getshdr.3 | 115 - linkers/elftoolchain/libelf/gelf_getsym.3 | 125 - linkers/elftoolchain/libelf/gelf_getsyminfo.3 | 115 - linkers/elftoolchain/libelf/gelf_getsymshndx.3 | 162 - linkers/elftoolchain/libelf/gelf_move.c | 150 - linkers/elftoolchain/libelf/gelf_newehdr.3 | 185 - linkers/elftoolchain/libelf/gelf_newphdr.3 | 133 - linkers/elftoolchain/libelf/gelf_phdr.c | 177 - linkers/elftoolchain/libelf/gelf_rel.c | 152 - linkers/elftoolchain/libelf/gelf_rela.c | 155 - linkers/elftoolchain/libelf/gelf_shdr.c | 130 - linkers/elftoolchain/libelf/gelf_sym.c | 153 - linkers/elftoolchain/libelf/gelf_syminfo.c | 145 - linkers/elftoolchain/libelf/gelf_symshndx.c | 128 - linkers/elftoolchain/libelf/gelf_update_ehdr.3 | 123 - linkers/elftoolchain/libelf/gelf_xlate.c | 81 - linkers/elftoolchain/libelf/gelf_xlatetof.3 | 247 -- linkers/elftoolchain/libelf/libelf.h | 258 -- linkers/elftoolchain/libelf/libelf_align.c | 137 - linkers/elftoolchain/libelf/libelf_allocate.c | 214 - linkers/elftoolchain/libelf/libelf_ar.c | 461 --- linkers/elftoolchain/libelf/libelf_ar_util.c | 354 -- linkers/elftoolchain/libelf/libelf_checksum.c | 100 - linkers/elftoolchain/libelf/libelf_convert.m4 | 1086 ----- linkers/elftoolchain/libelf/libelf_data.c | 88 - linkers/elftoolchain/libelf/libelf_ehdr.c | 204 - linkers/elftoolchain/libelf/libelf_extended.c | 136 - linkers/elftoolchain/libelf/libelf_fsize.m4 | 159 - linkers/elftoolchain/libelf/libelf_msize.m4 | 108 - linkers/elftoolchain/libelf/libelf_phdr.c | 156 - linkers/elftoolchain/libelf/libelf_shdr.c | 56 - linkers/elftoolchain/libelf/libelf_xlate.c | 150 - linkers/elftoolchain/libelf/mmap_win32.c | 247 -- linkers/elftoolchain/libelf/os.FreeBSD.mk | 7 - linkers/elftoolchain/libelf/os.NetBSD.mk | 7 - linkers/fastlz.c | 551 --- linkers/fastlz.h | 100 - linkers/libiberty/ansidecl.h | 423 -- linkers/libiberty/concat.c | 234 -- linkers/libiberty/cp-demangle.c | 5064 ----------------------- linkers/libiberty/cp-demangle.h | 168 - linkers/libiberty/cplus-dem.c | 4728 --------------------- linkers/libiberty/demangle.h | 616 --- linkers/libiberty/libiberty.h | 342 -- linkers/libiberty/make-temp-file.c | 217 - linkers/libiberty/mkstemps.c | 147 - linkers/libiberty/pex-common.c | 646 --- linkers/libiberty/pex-common.h | 153 - linkers/libiberty/pex-djgpp.c | 294 -- linkers/libiberty/pex-msdos.c | 317 -- linkers/libiberty/pex-one.c | 43 - linkers/libiberty/pex-unix.c | 788 ---- linkers/libiberty/pex-win32.c | 943 ----- linkers/libiberty/safe-ctype.c | 255 -- linkers/libiberty/safe-ctype.h | 150 - linkers/libiberty/stpcpy.c | 43 - linkers/pkgconfig.cpp | 165 - linkers/pkgconfig.h | 72 - linkers/rld-cc.cpp | 608 --- linkers/rld-cc.h | 215 - linkers/rld-compression.cpp | 303 -- linkers/rld-compression.h | 228 - linkers/rld-config.cpp | 251 -- linkers/rld-config.h | 271 -- linkers/rld-elf-types.h | 60 - linkers/rld-elf.cpp | 1210 ------ linkers/rld-elf.h | 756 ---- linkers/rld-files.cpp | 1586 ------- linkers/rld-files.h | 988 ----- linkers/rld-outputter.cpp | 469 --- linkers/rld-outputter.h | 125 - linkers/rld-path.cpp | 214 - linkers/rld-path.h | 150 - linkers/rld-process.cpp | 561 --- linkers/rld-process.h | 260 -- linkers/rld-rap.cpp | 1668 -------- linkers/rld-rap.h | 97 - linkers/rld-resolver.cpp | 243 -- linkers/rld-resolver.h | 54 - linkers/rld-rtems.cpp | 205 - linkers/rld-rtems.h | 86 - linkers/rld-symbols.cpp | 389 -- linkers/rld-symbols.h | 297 -- linkers/rld.cpp | 319 -- linkers/rld.h | 251 -- linkers/rtems-utils.cpp | 162 - linkers/rtems-utils.h | 53 - linkers/wscript | 345 +- 176 files changed, 38 insertions(+), 53470 deletions(-) delete mode 100644 linkers/ConvertUTF.c delete mode 100644 linkers/ConvertUTF.h delete mode 100644 linkers/SimpleIni.h delete mode 100644 linkers/elftoolchain/common/Makefile delete mode 100644 linkers/elftoolchain/common/_elftc.h delete mode 100644 linkers/elftoolchain/common/elfdefinitions.h delete mode 100755 linkers/elftoolchain/common/native-elf-format delete mode 100644 linkers/elftoolchain/common/os.Linux.mk delete mode 100644 linkers/elftoolchain/common/uthash.h delete mode 100644 linkers/elftoolchain/libelf/Makefile delete mode 100644 linkers/elftoolchain/libelf/Version.map delete mode 100644 linkers/elftoolchain/libelf/_libelf.h delete mode 100644 linkers/elftoolchain/libelf/_libelf_ar.h delete mode 100644 linkers/elftoolchain/libelf/_libelf_config.h delete mode 100644 linkers/elftoolchain/libelf/elf.3 delete mode 100644 linkers/elftoolchain/libelf/elf.c delete mode 100644 linkers/elftoolchain/libelf/elf_begin.3 delete mode 100644 linkers/elftoolchain/libelf/elf_begin.c delete mode 100644 linkers/elftoolchain/libelf/elf_cntl.3 delete mode 100644 linkers/elftoolchain/libelf/elf_cntl.c delete mode 100644 linkers/elftoolchain/libelf/elf_data.c delete mode 100644 linkers/elftoolchain/libelf/elf_end.3 delete mode 100644 linkers/elftoolchain/libelf/elf_end.c delete mode 100644 linkers/elftoolchain/libelf/elf_errmsg.3 delete mode 100644 linkers/elftoolchain/libelf/elf_errmsg.c delete mode 100644 linkers/elftoolchain/libelf/elf_errno.c delete mode 100644 linkers/elftoolchain/libelf/elf_fill.3 delete mode 100644 linkers/elftoolchain/libelf/elf_fill.c delete mode 100644 linkers/elftoolchain/libelf/elf_flag.c delete mode 100644 linkers/elftoolchain/libelf/elf_flagdata.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getarhdr.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getarhdr.c delete mode 100644 linkers/elftoolchain/libelf/elf_getarsym.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getarsym.c delete mode 100644 linkers/elftoolchain/libelf/elf_getbase.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getbase.c delete mode 100644 linkers/elftoolchain/libelf/elf_getdata.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getident.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getident.c delete mode 100644 linkers/elftoolchain/libelf/elf_getphdrnum.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getphnum.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getscn.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getshdrnum.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getshdrstrndx.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getshnum.3 delete mode 100644 linkers/elftoolchain/libelf/elf_getshstrndx.3 delete mode 100644 linkers/elftoolchain/libelf/elf_hash.3 delete mode 100644 linkers/elftoolchain/libelf/elf_hash.c delete mode 100644 linkers/elftoolchain/libelf/elf_kind.3 delete mode 100644 linkers/elftoolchain/libelf/elf_kind.c delete mode 100644 linkers/elftoolchain/libelf/elf_memory.3 delete mode 100644 linkers/elftoolchain/libelf/elf_memory.c delete mode 100644 linkers/elftoolchain/libelf/elf_next.3 delete mode 100644 linkers/elftoolchain/libelf/elf_next.c delete mode 100644 linkers/elftoolchain/libelf/elf_phnum.c delete mode 100644 linkers/elftoolchain/libelf/elf_rand.3 delete mode 100644 linkers/elftoolchain/libelf/elf_rand.c delete mode 100644 linkers/elftoolchain/libelf/elf_rawfile.3 delete mode 100644 linkers/elftoolchain/libelf/elf_rawfile.c delete mode 100644 linkers/elftoolchain/libelf/elf_scn.c delete mode 100644 linkers/elftoolchain/libelf/elf_shnum.c delete mode 100644 linkers/elftoolchain/libelf/elf_shstrndx.c delete mode 100644 linkers/elftoolchain/libelf/elf_strptr.3 delete mode 100644 linkers/elftoolchain/libelf/elf_strptr.c delete mode 100644 linkers/elftoolchain/libelf/elf_types.m4 delete mode 100644 linkers/elftoolchain/libelf/elf_update.3 delete mode 100644 linkers/elftoolchain/libelf/elf_update.c delete mode 100644 linkers/elftoolchain/libelf/elf_version.3 delete mode 100644 linkers/elftoolchain/libelf/elf_version.c delete mode 100644 linkers/elftoolchain/libelf/gelf.3 delete mode 100644 linkers/elftoolchain/libelf/gelf.h delete mode 100644 linkers/elftoolchain/libelf/gelf_cap.c delete mode 100644 linkers/elftoolchain/libelf/gelf_checksum.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_checksum.c delete mode 100644 linkers/elftoolchain/libelf/gelf_dyn.c delete mode 100644 linkers/elftoolchain/libelf/gelf_ehdr.c delete mode 100644 linkers/elftoolchain/libelf/gelf_fsize.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_fsize.c delete mode 100644 linkers/elftoolchain/libelf/gelf_getcap.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getclass.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getclass.c delete mode 100644 linkers/elftoolchain/libelf/gelf_getdyn.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getehdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getmove.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getphdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getrel.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getrela.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getshdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getsym.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getsyminfo.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_getsymshndx.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_move.c delete mode 100644 linkers/elftoolchain/libelf/gelf_newehdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_newphdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_phdr.c delete mode 100644 linkers/elftoolchain/libelf/gelf_rel.c delete mode 100644 linkers/elftoolchain/libelf/gelf_rela.c delete mode 100644 linkers/elftoolchain/libelf/gelf_shdr.c delete mode 100644 linkers/elftoolchain/libelf/gelf_sym.c delete mode 100644 linkers/elftoolchain/libelf/gelf_syminfo.c delete mode 100644 linkers/elftoolchain/libelf/gelf_symshndx.c delete mode 100644 linkers/elftoolchain/libelf/gelf_update_ehdr.3 delete mode 100644 linkers/elftoolchain/libelf/gelf_xlate.c delete mode 100644 linkers/elftoolchain/libelf/gelf_xlatetof.3 delete mode 100644 linkers/elftoolchain/libelf/libelf.h delete mode 100644 linkers/elftoolchain/libelf/libelf_align.c delete mode 100644 linkers/elftoolchain/libelf/libelf_allocate.c delete mode 100644 linkers/elftoolchain/libelf/libelf_ar.c delete mode 100644 linkers/elftoolchain/libelf/libelf_ar_util.c delete mode 100644 linkers/elftoolchain/libelf/libelf_checksum.c delete mode 100644 linkers/elftoolchain/libelf/libelf_convert.m4 delete mode 100644 linkers/elftoolchain/libelf/libelf_data.c delete mode 100644 linkers/elftoolchain/libelf/libelf_ehdr.c delete mode 100644 linkers/elftoolchain/libelf/libelf_extended.c delete mode 100644 linkers/elftoolchain/libelf/libelf_fsize.m4 delete mode 100644 linkers/elftoolchain/libelf/libelf_msize.m4 delete mode 100644 linkers/elftoolchain/libelf/libelf_phdr.c delete mode 100644 linkers/elftoolchain/libelf/libelf_shdr.c delete mode 100644 linkers/elftoolchain/libelf/libelf_xlate.c delete mode 100644 linkers/elftoolchain/libelf/mmap_win32.c delete mode 100644 linkers/elftoolchain/libelf/os.FreeBSD.mk delete mode 100644 linkers/elftoolchain/libelf/os.NetBSD.mk delete mode 100644 linkers/fastlz.c delete mode 100644 linkers/fastlz.h delete mode 100644 linkers/libiberty/ansidecl.h delete mode 100644 linkers/libiberty/concat.c delete mode 100644 linkers/libiberty/cp-demangle.c delete mode 100644 linkers/libiberty/cp-demangle.h delete mode 100644 linkers/libiberty/cplus-dem.c delete mode 100644 linkers/libiberty/demangle.h delete mode 100644 linkers/libiberty/libiberty.h delete mode 100644 linkers/libiberty/make-temp-file.c delete mode 100644 linkers/libiberty/mkstemps.c delete mode 100644 linkers/libiberty/pex-common.c delete mode 100644 linkers/libiberty/pex-common.h delete mode 100644 linkers/libiberty/pex-djgpp.c delete mode 100644 linkers/libiberty/pex-msdos.c delete mode 100644 linkers/libiberty/pex-one.c delete mode 100644 linkers/libiberty/pex-unix.c delete mode 100644 linkers/libiberty/pex-win32.c delete mode 100644 linkers/libiberty/safe-ctype.c delete mode 100644 linkers/libiberty/safe-ctype.h delete mode 100644 linkers/libiberty/stpcpy.c delete mode 100644 linkers/pkgconfig.cpp delete mode 100644 linkers/pkgconfig.h delete mode 100644 linkers/rld-cc.cpp delete mode 100644 linkers/rld-cc.h delete mode 100644 linkers/rld-compression.cpp delete mode 100644 linkers/rld-compression.h delete mode 100644 linkers/rld-config.cpp delete mode 100644 linkers/rld-config.h delete mode 100644 linkers/rld-elf-types.h delete mode 100644 linkers/rld-elf.cpp delete mode 100644 linkers/rld-elf.h delete mode 100644 linkers/rld-files.cpp delete mode 100644 linkers/rld-files.h delete mode 100644 linkers/rld-outputter.cpp delete mode 100644 linkers/rld-outputter.h delete mode 100644 linkers/rld-path.cpp delete mode 100644 linkers/rld-path.h delete mode 100644 linkers/rld-process.cpp delete mode 100644 linkers/rld-process.h delete mode 100644 linkers/rld-rap.cpp delete mode 100644 linkers/rld-rap.h delete mode 100644 linkers/rld-resolver.cpp delete mode 100644 linkers/rld-resolver.h delete mode 100644 linkers/rld-rtems.cpp delete mode 100644 linkers/rld-rtems.h delete mode 100644 linkers/rld-symbols.cpp delete mode 100644 linkers/rld-symbols.h delete mode 100644 linkers/rld.cpp delete mode 100644 linkers/rld.h delete mode 100644 linkers/rtems-utils.cpp delete mode 100644 linkers/rtems-utils.h (limited to 'linkers') diff --git a/linkers/ConvertUTF.c b/linkers/ConvertUTF.c deleted file mode 100644 index 9b3deeb..0000000 --- a/linkers/ConvertUTF.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "ConvertUTF.h" for complete documentation. - ------------------------------------------------------------------------- */ - - -#include "ConvertUTF.h" -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define false 0 -#define true 1 - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG -if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); -} -#endif - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (source+length > sourceEnd) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/linkers/ConvertUTF.h b/linkers/ConvertUTF.h deleted file mode 100644 index 14d7b70..0000000 --- a/linkers/ConvertUTF.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -#ifdef __cplusplus -} -#endif - -/* --------------------------------------------------------------------- */ diff --git a/linkers/README b/linkers/README index 95ed6a2..9327a15 100644 --- a/linkers/README +++ b/linkers/README @@ -1,18 +1,10 @@ -RTEMS Dynamic Loader Project -============================ -Chris Johns - -RTEMS Linker ------------- - -This package contains the RTEMS linker used to create dynamically loadable -applications. +RTEMS Linkers. +============== -To build download and install waf (http://code.google.com/p/waf/). Then: - - $ waf configure build +Chris Johns -You will have a linker. +This directory contains the RTEMS linkers and various tools to help managed +them. License ------- diff --git a/linkers/SimpleIni.h b/linkers/SimpleIni.h deleted file mode 100644 index fd37c4b..0000000 --- a/linkers/SimpleIni.h +++ /dev/null @@ -1,3385 +0,0 @@ -/** @mainpage - - -
Library SimpleIni -
File SimpleIni.h -
Author Brodie Thiesfield [code at jellycan dot com] -
Source https://github.com/brofield/simpleini -
Version 4.17 -
- - Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation. - - @section intro INTRODUCTION - - This component allows an INI-style configuration file to be used on both - Windows and Linux/Unix. It is fast, simple and source code using this - component will compile unchanged on either OS. - - - @section features FEATURES - - - MIT Licence allows free use in all software (including GPL and commercial) - - multi-platform (Windows 95/98/ME/NT/2K/XP/2003, Windows CE, Linux, Unix) - - loading and saving of INI-style configuration files - - configuration files can have any newline format on all platforms - - liberal acceptance of file format - - key/values with no section - - removal of whitespace around sections, keys and values - - support for multi-line values (values with embedded newline characters) - - optional support for multiple keys with the same name - - optional case-insensitive sections and keys (for ASCII characters only) - - saves files with sections and keys in the same order as they were loaded - - preserves comments on the file, section and keys where possible. - - supports both char or wchar_t programming interfaces - - supports both MBCS (system locale) and UTF-8 file encodings - - system locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file - - support for non-ASCII characters in section, keys, values and comments - - support for non-standard character types or file encodings - via user-written converter classes - - support for adding/modifying values programmatically - - compiles cleanly in the following compilers: - - Windows/VC6 (warning level 3) - - Windows/VC.NET 2003 (warning level 4) - - Windows/VC 2005 (warning level 4) - - Linux/gcc (-Wall) - - - @section usage USAGE SUMMARY - - -# Define the appropriate symbol for the converter you wish to use and - include the SimpleIni.h header file. If no specific converter is defined - then the default converter is used. The default conversion mode uses - SI_CONVERT_WIN32 on Windows and SI_CONVERT_GENERIC on all other - platforms. If you are using ICU then SI_CONVERT_ICU is supported on all - platforms. - -# Declare an instance the appropriate class. Note that the following - definitions are just shortcuts for commonly used types. Other types - (PRUnichar, unsigned short, unsigned char) are also possible. - -
Interface Case-sensitive Load UTF-8 Load MBCS Typedef -
SI_CONVERT_GENERIC -
char No Yes Yes #1 CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
wchar_t No Yes Yes CSimpleIniW -
wchar_t Yes Yes Yes CSimpleIniCaseW -
SI_CONVERT_WIN32 -
char No No #2 Yes CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
wchar_t No Yes Yes CSimpleIniW -
wchar_t Yes Yes Yes CSimpleIniCaseW -
SI_CONVERT_ICU -
char No Yes Yes CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
UChar No Yes Yes CSimpleIniW -
UChar Yes Yes Yes CSimpleIniCaseW -
- #1 On Windows you are better to use CSimpleIniA with SI_CONVERT_WIN32.
- #2 Only affects Windows. On Windows this uses MBCS functions and - so may fold case incorrectly leading to uncertain results. - -# Call LoadData() or LoadFile() to load and parse the INI configuration file - -# Access and modify the data of the file using the following functions - -
GetAllSections Return all section names -
GetAllKeys Return all key names within a section -
GetAllValues Return all values within a section & key -
GetSection Return all key names and values in a section -
GetSectionSize Return the number of keys in a section -
GetValue Return a value for a section & key -
SetValue Add or update a value for a section & key -
Delete Remove a section, or a key from a section -
- -# Call Save() or SaveFile() to save the INI configuration data - - @section iostreams IO STREAMS - - SimpleIni supports reading from and writing to STL IO streams. Enable this - by defining SI_SUPPORT_IOSTREAMS before including the SimpleIni.h header - file. Ensure that if the streams are backed by a file (e.g. ifstream or - ofstream) then the flag ios_base::binary has been used when the file was - opened. - - @section multiline MULTI-LINE VALUES - - Values that span multiple lines are created using the following format. - -
-        key = <<
-
-    Note the following:
-    - The text used for ENDTAG can be anything and is used to find
-      where the multi-line text ends.
-    - The newline after ENDTAG in the start tag, and the newline
-      before ENDTAG in the end tag is not included in the data value.
-    - The ending tag must be on it's own line with no whitespace before
-      or after it.
-    - The multi-line value is modified at load so that each line in the value
-      is delimited by a single '\\n' character on all platforms. At save time
-      it will be converted into the newline format used by the current
-      platform.
-
-    @section comments COMMENTS
-
-    Comments are preserved in the file within the following restrictions:
-    - Every file may have a single "file comment". It must start with the
-      first character in the file, and will end with the first non-comment
-      line in the file.
-    - Every section may have a single "section comment". It will start
-      with the first comment line following the file comment, or the last
-      data entry. It ends at the beginning of the section.
-    - Every key may have a single "key comment". This comment will start
-      with the first comment line following the section start, or the file
-      comment if there is no section name.
-    - Comments are set at the time that the file, section or key is first
-      created. The only way to modify a comment on a section or a key is to
-      delete that entry and recreate it with the new comment. There is no
-      way to change the file comment.
-
-    @section save SAVE ORDER
-
-    The sections and keys are written out in the same order as they were
-    read in from the file. Sections and keys added to the data after the
-    file has been loaded will be added to the end of the file when it is
-    written. There is no way to specify the location of a section or key
-    other than in first-created, first-saved order.
-
-    @section notes NOTES
-
-    - To load UTF-8 data on Windows 95, you need to use Microsoft Layer for
-      Unicode, or SI_CONVERT_GENERIC, or SI_CONVERT_ICU.
-    - When using SI_CONVERT_GENERIC, ConvertUTF.c must be compiled and linked.
-    - When using SI_CONVERT_ICU, ICU header files must be on the include
-      path and icuuc.lib must be linked in.
-    - To load a UTF-8 file on Windows AND expose it with SI_CHAR == char,
-      you should use SI_CONVERT_GENERIC.
-    - The collation (sorting) order used for sections and keys returned from
-      iterators is NOT DEFINED. If collation order of the text is important
-      then it should be done yourself by either supplying a replacement
-      SI_STRLESS class, or by sorting the strings external to this library.
-    - Usage of the  header on Windows can be disabled by defining
-      SI_NO_MBCS. This is defined automatically on Windows CE platforms.
-
-    @section contrib CONTRIBUTIONS
-
-    - 2010/05/03: Tobias Gehrig: added GetDoubleValue()
-
-    @section licence MIT LICENCE
-
-    The licence text below is the boilerplate "MIT Licence" used from:
-    http://www.opensource.org/licenses/mit-license.php
-
-    Copyright (c) 2006-2012, Brodie Thiesfield
-
-    Permission is hereby granted, free of charge, to any person obtaining a copy
-    of this software and associated documentation files (the "Software"), to deal
-    in the Software without restriction, including without limitation the rights
-    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-    copies of the Software, and to permit persons to whom the Software is furnished
-    to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be included in
-    all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef INCLUDED_SimpleIni_h
-#define INCLUDED_SimpleIni_h
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-// Disable these warnings in MSVC:
-//  4127 "conditional expression is constant" as the conversion classes trigger
-//  it with the statement if (sizeof(SI_CHAR) == sizeof(char)). This test will
-//  be optimized away in a release build.
-//  4503 'insert' : decorated name length exceeded, name was truncated
-//  4702 "unreachable code" as the MS STL header causes it in release mode.
-//  Again, the code causing the warning will be cleaned up by the compiler.
-//  4786 "identifier truncated to 256 characters" as this is thrown hundreds
-//  of times VC6 as soon as STL is used.
-#ifdef _MSC_VER
-# pragma warning (push)
-# pragma warning (disable: 4127 4503 4702 4786)
-#endif
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#ifdef SI_SUPPORT_IOSTREAMS
-# include 
-#endif // SI_SUPPORT_IOSTREAMS
-
-#ifdef _DEBUG
-# ifndef assert
-#  include 
-# endif
-# define SI_ASSERT(x)   assert(x)
-#else
-# define SI_ASSERT(x)
-#endif
-
-enum SI_Error {
-    SI_OK       =  0,   //!< No error
-    SI_UPDATED  =  1,   //!< An existing value was updated
-    SI_INSERTED =  2,   //!< A new value was inserted
-
-    // note: test for any error with (retval < 0)
-    SI_FAIL     = -1,   //!< Generic failure
-    SI_NOMEM    = -2,   //!< Out of memory error
-    SI_FILE     = -3    //!< File error (see errno for detail error)
-};
-
-#define SI_UTF8_SIGNATURE     "\xEF\xBB\xBF"
-
-#ifdef _WIN32
-# define SI_NEWLINE_A   "\r\n"
-# define SI_NEWLINE_W   L"\r\n"
-#else // !_WIN32
-# define SI_NEWLINE_A   "\n"
-# define SI_NEWLINE_W   L"\n"
-#endif // _WIN32
-
-#if defined(SI_CONVERT_ICU)
-# include 
-#endif
-
-#if defined(_WIN32)
-# define SI_HAS_WIDE_FILE
-# define SI_WCHAR_T     wchar_t
-#elif defined(SI_CONVERT_ICU)
-# define SI_HAS_WIDE_FILE
-# define SI_WCHAR_T     UChar
-#endif
-
-
-// ---------------------------------------------------------------------------
-//                              MAIN TEMPLATE CLASS
-// ---------------------------------------------------------------------------
-
-/** Simple INI file reader.
-
-    This can be instantiated with the choice of unicode or native characterset,
-    and case sensitive or insensitive comparisons of section and key names.
-    The supported combinations are pre-defined with the following typedefs:
-
-    
-        
Interface Case-sensitive Typedef -
char No CSimpleIniA -
char Yes CSimpleIniCaseA -
wchar_t No CSimpleIniW -
wchar_t Yes CSimpleIniCaseW -
- - Note that using other types for the SI_CHAR is supported. For instance, - unsigned char, unsigned short, etc. Note that where the alternative type - is a different size to char/wchar_t you may need to supply new helper - classes for SI_STRLESS and SI_CONVERTER. - */ -template -class CSimpleIniTempl -{ -public: - typedef SI_CHAR SI_CHAR_T; - - /** key entry */ - struct Entry { - const SI_CHAR * pItem; - const SI_CHAR * pComment; - int nOrder; - - Entry(const SI_CHAR * a_pszItem = NULL, int a_nOrder = 0) - : pItem(a_pszItem) - , pComment(NULL) - , nOrder(a_nOrder) - { } - Entry(const SI_CHAR * a_pszItem, const SI_CHAR * a_pszComment, int a_nOrder) - : pItem(a_pszItem) - , pComment(a_pszComment) - , nOrder(a_nOrder) - { } - Entry(const Entry & rhs) { operator=(rhs); } - Entry & operator=(const Entry & rhs) { - pItem = rhs.pItem; - pComment = rhs.pComment; - nOrder = rhs.nOrder; - return *this; - } - -#if defined(_MSC_VER) && _MSC_VER <= 1200 - /** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */ - bool operator<(const Entry & rhs) const { return LoadOrder()(*this, rhs); } - bool operator>(const Entry & rhs) const { return LoadOrder()(rhs, *this); } -#endif - - /** Strict less ordering by name of key only */ - struct KeyOrder : std::binary_function { - bool operator()(const Entry & lhs, const Entry & rhs) const { - const static SI_STRLESS isLess = SI_STRLESS(); - return isLess(lhs.pItem, rhs.pItem); - } - }; - - /** Strict less ordering by order, and then name of key */ - struct LoadOrder : std::binary_function { - bool operator()(const Entry & lhs, const Entry & rhs) const { - if (lhs.nOrder != rhs.nOrder) { - return lhs.nOrder < rhs.nOrder; - } - return KeyOrder()(lhs.pItem, rhs.pItem); - } - }; - }; - - /** map keys to values */ - typedef std::multimap TKeyVal; - - /** map sections to key/value map */ - typedef std::map TSection; - - /** set of dependent string pointers. Note that these pointers are - dependent on memory owned by CSimpleIni. - */ - typedef std::list TNamesDepend; - - /** interface definition for the OutputWriter object to pass to Save() - in order to output the INI file data. - */ - class OutputWriter { - public: - OutputWriter() { } - virtual ~OutputWriter() { } - virtual void Write(const char * a_pBuf) = 0; - private: - OutputWriter(const OutputWriter &); // disable - OutputWriter & operator=(const OutputWriter &); // disable - }; - - /** OutputWriter class to write the INI data to a file */ - class FileWriter : public OutputWriter { - FILE * m_file; - public: - FileWriter(FILE * a_file) : m_file(a_file) { } - void Write(const char * a_pBuf) { - fputs(a_pBuf, m_file); - } - private: - FileWriter(const FileWriter &); // disable - FileWriter & operator=(const FileWriter &); // disable - }; - - /** OutputWriter class to write the INI data to a string */ - class StringWriter : public OutputWriter { - std::string & m_string; - public: - StringWriter(std::string & a_string) : m_string(a_string) { } - void Write(const char * a_pBuf) { - m_string.append(a_pBuf); - } - private: - StringWriter(const StringWriter &); // disable - StringWriter & operator=(const StringWriter &); // disable - }; - -#ifdef SI_SUPPORT_IOSTREAMS - /** OutputWriter class to write the INI data to an ostream */ - class StreamWriter : public OutputWriter { - std::ostream & m_ostream; - public: - StreamWriter(std::ostream & a_ostream) : m_ostream(a_ostream) { } - void Write(const char * a_pBuf) { - m_ostream << a_pBuf; - } - private: - StreamWriter(const StreamWriter &); // disable - StreamWriter & operator=(const StreamWriter &); // disable - }; -#endif // SI_SUPPORT_IOSTREAMS - - /** Characterset conversion utility class to convert strings to the - same format as is used for the storage. - */ - class Converter : private SI_CONVERTER { - public: - Converter(bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) { - m_scratch.resize(1024); - } - Converter(const Converter & rhs) { operator=(rhs); } - Converter & operator=(const Converter & rhs) { - m_scratch = rhs.m_scratch; - return *this; - } - bool ConvertToStore(const SI_CHAR * a_pszString) { - size_t uLen = SI_CONVERTER::SizeToStore(a_pszString); - if (uLen == (size_t)(-1)) { - return false; - } - while (uLen > m_scratch.size()) { - m_scratch.resize(m_scratch.size() * 2); - } - return SI_CONVERTER::ConvertToStore( - a_pszString, - const_cast(m_scratch.data()), - m_scratch.size()); - } - const char * Data() { return m_scratch.data(); } - private: - std::string m_scratch; - }; - -public: - /*-----------------------------------------------------------------------*/ - - /** Default constructor. - - @param a_bIsUtf8 See the method SetUnicode() for details. - @param a_bMultiKey See the method SetMultiKey() for details. - @param a_bMultiLine See the method SetMultiLine() for details. - */ - CSimpleIniTempl( - bool a_bIsUtf8 = false, - bool a_bMultiKey = false, - bool a_bMultiLine = false - ); - - /** Destructor */ - ~CSimpleIniTempl(); - - /** Deallocate all memory stored by this object */ - void Reset(); - - /** Has any data been loaded */ - bool IsEmpty() const { return m_data.empty(); } - - /*-----------------------------------------------------------------------*/ - /** @{ @name Settings */ - - /** Set the storage format of the INI data. This affects both the loading - and saving of the INI data using all of the Load/Save API functions. - This value cannot be changed after any INI data has been loaded. - - If the file is not set to Unicode (UTF-8), then the data encoding is - assumed to be the OS native encoding. This encoding is the system - locale on Linux/Unix and the legacy MBCS encoding on Windows NT/2K/XP. - If the storage format is set to Unicode then the file will be loaded - as UTF-8 encoded data regardless of the native file encoding. If - SI_CHAR == char then all of the char* parameters take and return UTF-8 - encoded data regardless of the system locale. - - \param a_bIsUtf8 Assume UTF-8 encoding for the source? - */ - void SetUnicode(bool a_bIsUtf8 = true) { - if (!m_pData) m_bStoreIsUtf8 = a_bIsUtf8; - } - - /** Get the storage format of the INI data. */ - bool IsUnicode() const { return m_bStoreIsUtf8; } - - /** Should multiple identical keys be permitted in the file. If set to false - then the last value encountered will be used as the value of the key. - If set to true, then all values will be available to be queried. For - example, with the following input: - -
-        [section]
-        test=value1
-        test=value2
-        
- - Then with SetMultiKey(true), both of the values "value1" and "value2" - will be returned for the key test. If SetMultiKey(false) is used, then - the value for "test" will only be "value2". This value may be changed - at any time. - - \param a_bAllowMultiKey Allow multi-keys in the source? - */ - void SetMultiKey(bool a_bAllowMultiKey = true) { - m_bAllowMultiKey = a_bAllowMultiKey; - } - - /** Get the storage format of the INI data. */ - bool IsMultiKey() const { return m_bAllowMultiKey; } - - /** Should data values be permitted to span multiple lines in the file. If - set to false then the multi-line construct << - SI_CHAR FORMAT - char same format as when loaded (MBCS or UTF-8) - wchar_t UTF-8 - other UTF-8 - - - Note that comments from the original data is preserved as per the - documentation on comments. The order of the sections and values - from the original file will be preserved. - - Any data prepended or appended to the output device must use the the - same format (MBCS or UTF-8). You may use the GetConverter() method to - convert text to the correct format regardless of the output format - being used by SimpleIni. - - To add a BOM to UTF-8 data, write it out manually at the very beginning - like is done in SaveFile when a_bUseBOM is true. - - @param a_oOutput Output writer to write the data to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the OutputWriter. - - @return SI_Error See error definitions - */ - SI_Error Save( - OutputWriter & a_oOutput, - bool a_bAddSignature = false - ) const; - -#ifdef SI_SUPPORT_IOSTREAMS - /** Save the INI data to an ostream. See Save() for details. - - @param a_ostream String to have the INI data appended to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the stream. - - @return SI_Error See error definitions - */ - SI_Error Save( - std::ostream & a_ostream, - bool a_bAddSignature = false - ) const - { - StreamWriter writer(a_ostream); - return Save(writer, a_bAddSignature); - } -#endif // SI_SUPPORT_IOSTREAMS - - /** Append the INI data to a string. See Save() for details. - - @param a_sBuffer String to have the INI data appended to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the string. - - @return SI_Error See error definitions - */ - SI_Error Save( - std::string & a_sBuffer, - bool a_bAddSignature = false - ) const - { - StringWriter writer(a_sBuffer); - return Save(writer, a_bAddSignature); - } - - /*-----------------------------------------------------------------------*/ - /** @} - @{ @name Accessing INI Data */ - - /** Retrieve all section names. The list is returned as an STL vector of - names and can be iterated or searched as necessary. Note that the - sort order of the returned strings is NOT DEFINED. You can sort - the names into the load order if desired. Search this file for ".sort" - for an example. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these pointers - are in use! - - @param a_names Vector that will receive all of the section - names. See note above! - */ - void GetAllSections( - TNamesDepend & a_names - ) const; - - /** Retrieve all unique key names in a section. The sort order of the - returned strings is NOT DEFINED. You can sort the names into the load - order if desired. Search this file for ".sort" for an example. Only - unique key names are returned. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these strings - are in use! - - @param a_pSection Section to request data for - @param a_names List that will receive all of the key - names. See note above! - - @return true Section was found. - @return false Matching section was not found. - */ - bool GetAllKeys( - const SI_CHAR * a_pSection, - TNamesDepend & a_names - ) const; - - /** Retrieve all values for a specific key. This method can be used when - multiple keys are both enabled and disabled. Note that the sort order - of the returned strings is NOT DEFINED. You can sort the names into - the load order if desired. Search this file for ".sort" for an example. - - NOTE! The returned values are pointers to string data stored in memory - owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed - or Reset while you are using this pointer! - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_values List to return if the key is not found - - @return true Key was found. - @return false Matching section/key was not found. - */ - bool GetAllValues( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - TNamesDepend & a_values - ) const; - - /** Query the number of keys in a specific section. Note that if multiple - keys are enabled, then this value may be different to the number of - keys returned by GetAllKeys. - - @param a_pSection Section to request data for - - @return -1 Section does not exist in the file - @return >=0 Number of keys in the section - */ - int GetSectionSize( - const SI_CHAR * a_pSection - ) const; - - /** Retrieve all key and value pairs for a section. The data is returned - as a pointer to an STL map and can be iterated or searched as - desired. Note that multiple entries for the same key may exist when - multiple keys have been enabled. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these strings - are in use! - - @param a_pSection Name of the section to return - @return boolean Was a section matching the supplied - name found. - */ - const TKeyVal * GetSection( - const SI_CHAR * a_pSection - ) const; - - /** Retrieve the value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - NOTE! The returned value is a pointer to string data stored in memory - owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed - or Reset while you are using this pointer! - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_pDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_pDefault Key was not found in the section - @return other Value of the key - */ - const SI_CHAR * GetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pDefault = NULL, - bool * a_pHasMultiple = NULL - ) const; - - /** Retrieve a numeric value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_nDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_nDefault Key was not found in the section - @return other Value of the key - */ - long GetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nDefault = 0, - bool * a_pHasMultiple = NULL - ) const; - - /** Retrieve a numeric value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_nDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_nDefault Key was not found in the section - @return other Value of the key - */ - double GetDoubleValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - double a_nDefault = 0, - bool * a_pHasMultiple = NULL - ) const; - - /** Retrieve a boolean value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - Strings starting with "t", "y", "on" or "1" are returned as logically true. - Strings starting with "f", "n", "of" or "0" are returned as logically false. - For all other values the default is returned. Character comparisons are - case-insensitive. - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_bDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_nDefault Key was not found in the section - @return other Value of the key - */ - bool GetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bDefault = false, - bool * a_pHasMultiple = NULL - ) const; - - /** Add or update a section or value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. Set to NULL to - create an empty section. - @param a_pValue Value to set. Set to NULL to create an - empty section. - @param a_pComment Comment to be associated with the section or the - key. If a_pKey is NULL then it will be associated - with the section, otherwise the key. Note that a - comment may be set ONLY when the section or key is - first created (i.e. when this function returns the - value SI_INSERTED). If you wish to create a section - with a comment then you need to create the section - separately to the key. The comment string must be - in full comment form already (have a comment - character starting every line). - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetValue and SetValue - with a_bForceReplace = true, is that the load - order and comment will be preserved this way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment = NULL, - bool a_bForceReplace = false - ) - { - return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace, true); - } - - /** Add or update a numeric value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. - @param a_nValue Value to set. - @param a_pComment Comment to be associated with the key. See the - notes on SetValue() for comments. - @param a_bUseHex By default the value will be written to the file - in decimal format. Set this to true to write it - as hexadecimal. - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetLongValue and - SetLongValue with a_bForceReplace = true, is that - the load order and comment will be preserved this - way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nValue, - const SI_CHAR * a_pComment = NULL, - bool a_bUseHex = false, - bool a_bForceReplace = false - ); - - /** Add or update a double value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. - @param a_nValue Value to set. - @param a_pComment Comment to be associated with the key. See the - notes on SetValue() for comments. - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetDoubleValue and - SetDoubleValue with a_bForceReplace = true, is that - the load order and comment will be preserved this - way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetDoubleValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - double a_nValue, - const SI_CHAR * a_pComment = NULL, - bool a_bForceReplace = false - ); - - /** Add or update a boolean value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. - @param a_bValue Value to set. - @param a_pComment Comment to be associated with the key. See the - notes on SetValue() for comments. - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetBoolValue and - SetBoolValue with a_bForceReplace = true, is that - the load order and comment will be preserved this - way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bValue, - const SI_CHAR * a_pComment = NULL, - bool a_bForceReplace = false - ); - - /** Delete an entire section, or a key from a section. Note that the - data returned by GetSection is invalid and must not be used after - anything has been deleted from that section using this method. - Note when multiple keys is enabled, this will delete all keys with - that name; there is no way to selectively delete individual key/values - in this situation. - - @param a_pSection Section to delete key from, or if - a_pKey is NULL, the section to remove. - @param a_pKey Key to remove from the section. Set to - NULL to remove the entire section. - @param a_bRemoveEmpty If the section is empty after this key has - been deleted, should the empty section be - removed? - - @return true Key or section was deleted. - @return false Key or section was not found. - */ - bool Delete( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bRemoveEmpty = false - ); - - /*-----------------------------------------------------------------------*/ - /** @} - @{ @name Converter */ - - /** Return a conversion object to convert text to the same encoding - as is used by the Save(), SaveFile() and SaveString() functions. - Use this to prepare the strings that you wish to append or prepend - to the output INI data. - */ - Converter GetConverter() const { - return Converter(m_bStoreIsUtf8); - } - - /*-----------------------------------------------------------------------*/ - /** @} */ - -private: - // copying is not permitted - CSimpleIniTempl(const CSimpleIniTempl &); // disabled - CSimpleIniTempl & operator=(const CSimpleIniTempl &); // disabled - - /** Parse the data looking for a file comment and store it if found. - */ - SI_Error FindFileComment( - SI_CHAR *& a_pData, - bool a_bCopyStrings - ); - - /** Parse the data looking for the next valid entry. The memory pointed to - by a_pData is modified by inserting NULL characters. The pointer is - updated to the current location in the block of text. - */ - bool FindEntry( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pSection, - const SI_CHAR *& a_pKey, - const SI_CHAR *& a_pVal, - const SI_CHAR *& a_pComment - ) const; - - /** Add the section/key/value to our data. - - @param a_pSection Section name. Sections will be created if they - don't already exist. - @param a_pKey Key name. May be NULL to create an empty section. - Existing entries will be updated. New entries will - be created. - @param a_pValue Value for the key. - @param a_pComment Comment to be associated with the section or the - key. If a_pKey is NULL then it will be associated - with the section, otherwise the key. This must be - a string in full comment form already (have a - comment character starting every line). - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/AddEntry and AddEntry - with a_bForceReplace = true, is that the load - order and comment will be preserved this way. - @param a_bCopyStrings Should copies of the strings be made or not. - If false then the pointers will be used as is. - */ - SI_Error AddEntry( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace, - bool a_bCopyStrings - ); - - /** Is the supplied character a whitespace character? */ - inline bool IsSpace(SI_CHAR ch) const { - return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); - } - - /** Does the supplied character start a comment line? */ - inline bool IsComment(SI_CHAR ch) const { - return (ch == ';' || ch == '#'); - } - - - /** Skip over a newline character (or characters) for either DOS or UNIX */ - inline void SkipNewLine(SI_CHAR *& a_pData) const { - a_pData += (*a_pData == '\r' && *(a_pData+1) == '\n') ? 2 : 1; - } - - /** Make a copy of the supplied string, replacing the original pointer */ - SI_Error CopyString(const SI_CHAR *& a_pString); - - /** Delete a string from the copied strings buffer if necessary */ - void DeleteString(const SI_CHAR * a_pString); - - /** Internal use of our string comparison function */ - bool IsLess(const SI_CHAR * a_pLeft, const SI_CHAR * a_pRight) const { - const static SI_STRLESS isLess = SI_STRLESS(); - return isLess(a_pLeft, a_pRight); - } - - bool IsMultiLineTag(const SI_CHAR * a_pData) const; - bool IsMultiLineData(const SI_CHAR * a_pData) const; - bool LoadMultiLineText( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pVal, - const SI_CHAR * a_pTagName, - bool a_bAllowBlankLinesInComment = false - ) const; - bool IsNewLineChar(SI_CHAR a_c) const; - - bool OutputMultiLineText( - OutputWriter & a_oOutput, - Converter & a_oConverter, - const SI_CHAR * a_pText - ) const; - -private: - /** Copy of the INI file data in our character format. This will be - modified when parsed to have NULL characters added after all - interesting string entries. All of the string pointers to sections, - keys and values point into this block of memory. - */ - SI_CHAR * m_pData; - - /** Length of the data that we have stored. Used when deleting strings - to determine if the string is stored here or in the allocated string - buffer. - */ - size_t m_uDataLen; - - /** File comment for this data, if one exists. */ - const SI_CHAR * m_pFileComment; - - /** Parsed INI data. Section -> (Key -> Value). */ - TSection m_data; - - /** This vector stores allocated memory for copies of strings that have - been supplied after the file load. It will be empty unless SetValue() - has been called. - */ - TNamesDepend m_strings; - - /** Is the format of our datafile UTF-8 or MBCS? */ - bool m_bStoreIsUtf8; - - /** Are multiple values permitted for the same key? */ - bool m_bAllowMultiKey; - - /** Are data values permitted to span multiple lines? */ - bool m_bAllowMultiLine; - - /** Should spaces be written out surrounding the equals sign? */ - bool m_bSpaces; - - /** Next order value, used to ensure sections and keys are output in the - same order that they are loaded/added. - */ - int m_nOrder; -}; - -// --------------------------------------------------------------------------- -// IMPLEMENTATION -// --------------------------------------------------------------------------- - -template -CSimpleIniTempl::CSimpleIniTempl( - bool a_bIsUtf8, - bool a_bAllowMultiKey, - bool a_bAllowMultiLine - ) - : m_pData(0) - , m_uDataLen(0) - , m_pFileComment(NULL) - , m_bStoreIsUtf8(a_bIsUtf8) - , m_bAllowMultiKey(a_bAllowMultiKey) - , m_bAllowMultiLine(a_bAllowMultiLine) - , m_bSpaces(true) - , m_nOrder(0) -{ } - -template -CSimpleIniTempl::~CSimpleIniTempl() -{ - Reset(); -} - -template -void -CSimpleIniTempl::Reset() -{ - // remove all data - delete[] m_pData; - m_pData = NULL; - m_uDataLen = 0; - m_pFileComment = NULL; - if (!m_data.empty()) { - m_data.erase(m_data.begin(), m_data.end()); - } - - // remove all strings - if (!m_strings.empty()) { - typename TNamesDepend::iterator i = m_strings.begin(); - for (; i != m_strings.end(); ++i) { - delete[] const_cast(i->pItem); - } - m_strings.erase(m_strings.begin(), m_strings.end()); - } -} - -template -SI_Error -CSimpleIniTempl::LoadFile( - const char * a_pszFile - ) -{ - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - fopen_s(&fp, a_pszFile, "rb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = fopen(a_pszFile, "rb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) { - return SI_FILE; - } - SI_Error rc = LoadFile(fp); - fclose(fp); - return rc; -} - -#ifdef SI_HAS_WIDE_FILE -template -SI_Error -CSimpleIniTempl::LoadFile( - const SI_WCHAR_T * a_pwszFile - ) -{ -#ifdef _WIN32 - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - _wfopen_s(&fp, a_pwszFile, L"rb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = _wfopen(a_pwszFile, L"rb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = LoadFile(fp); - fclose(fp); - return rc; -#else // !_WIN32 (therefore SI_CONVERT_ICU) - char szFile[256]; - u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); - return LoadFile(szFile); -#endif // _WIN32 -} -#endif // SI_HAS_WIDE_FILE - -template -SI_Error -CSimpleIniTempl::LoadFile( - FILE * a_fpFile - ) -{ - // load the raw file data - int retval = fseek(a_fpFile, 0, SEEK_END); - if (retval != 0) { - return SI_FILE; - } - long lSize = ftell(a_fpFile); - if (lSize < 0) { - return SI_FILE; - } - if (lSize == 0) { - return SI_OK; - } - - // allocate and ensure NULL terminated - char * pData = new char[lSize+1]; - if (!pData) { - return SI_NOMEM; - } - pData[lSize] = 0; - - // load data into buffer - fseek(a_fpFile, 0, SEEK_SET); - size_t uRead = fread(pData, sizeof(char), lSize, a_fpFile); - if (uRead != (size_t) lSize) { - delete[] pData; - return SI_FILE; - } - - // convert the raw data to unicode - SI_Error rc = LoadData(pData, uRead); - delete[] pData; - return rc; -} - -template -SI_Error -CSimpleIniTempl::LoadData( - const char * a_pData, - size_t a_uDataLen - ) -{ - SI_CONVERTER converter(m_bStoreIsUtf8); - - if (a_uDataLen == 0) { - return SI_OK; - } - - // consume the UTF-8 BOM if it exists - if (m_bStoreIsUtf8 && a_uDataLen >= 3) { - if (memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) { - a_pData += 3; - a_uDataLen -= 3; - } - } - - // determine the length of the converted data - size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen); - if (uLen == (size_t)(-1)) { - return SI_FAIL; - } - - // allocate memory for the data, ensure that there is a NULL - // terminator wherever the converted data ends - SI_CHAR * pData = new SI_CHAR[uLen+1]; - if (!pData) { - return SI_NOMEM; - } - memset(pData, 0, sizeof(SI_CHAR)*(uLen+1)); - - // convert the data - if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) { - delete[] pData; - return SI_FAIL; - } - - // parse it - const static SI_CHAR empty = 0; - SI_CHAR * pWork = pData; - const SI_CHAR * pSection = ∅ - const SI_CHAR * pItem = NULL; - const SI_CHAR * pVal = NULL; - const SI_CHAR * pComment = NULL; - - // We copy the strings if we are loading data into this class when we - // already have stored some. - bool bCopyStrings = (m_pData != NULL); - - // find a file comment if it exists, this is a comment that starts at the - // beginning of the file and continues until the first blank line. - SI_Error rc = FindFileComment(pWork, bCopyStrings); - if (rc < 0) return rc; - - // add every entry in the file to the data table - while (FindEntry(pWork, pSection, pItem, pVal, pComment)) { - rc = AddEntry(pSection, pItem, pVal, pComment, false, bCopyStrings); - if (rc < 0) return rc; - } - - // store these strings if we didn't copy them - if (bCopyStrings) { - delete[] pData; - } - else { - m_pData = pData; - m_uDataLen = uLen+1; - } - - return SI_OK; -} - -#ifdef SI_SUPPORT_IOSTREAMS -template -SI_Error -CSimpleIniTempl::LoadData( - std::istream & a_istream - ) -{ - std::string strData; - char szBuf[512]; - do { - a_istream.get(szBuf, sizeof(szBuf), '\0'); - strData.append(szBuf); - } - while (a_istream.good()); - return LoadData(strData); -} -#endif // SI_SUPPORT_IOSTREAMS - -template -SI_Error -CSimpleIniTempl::FindFileComment( - SI_CHAR *& a_pData, - bool a_bCopyStrings - ) -{ - // there can only be a single file comment - if (m_pFileComment) { - return SI_OK; - } - - // Load the file comment as multi-line text, this will modify all of - // the newline characters to be single \n chars - if (!LoadMultiLineText(a_pData, m_pFileComment, NULL, false)) { - return SI_OK; - } - - // copy the string if necessary - if (a_bCopyStrings) { - SI_Error rc = CopyString(m_pFileComment); - if (rc < 0) return rc; - } - - return SI_OK; -} - -template -bool -CSimpleIniTempl::FindEntry( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pSection, - const SI_CHAR *& a_pKey, - const SI_CHAR *& a_pVal, - const SI_CHAR *& a_pComment - ) const -{ - a_pComment = NULL; - - SI_CHAR * pTrail = NULL; - while (*a_pData) { - // skip spaces and empty lines - while (*a_pData && IsSpace(*a_pData)) { - ++a_pData; - } - if (!*a_pData) { - break; - } - - // skip processing of comment lines but keep a pointer to - // the start of the comment. - if (IsComment(*a_pData)) { - LoadMultiLineText(a_pData, a_pComment, NULL, true); - continue; - } - - // process section names - if (*a_pData == '[') { - // skip leading spaces - ++a_pData; - while (*a_pData && IsSpace(*a_pData)) { - ++a_pData; - } - - // find the end of the section name (it may contain spaces) - // and convert it to lowercase as necessary - a_pSection = a_pData; - while (*a_pData && *a_pData != ']' && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // if it's an invalid line, just skip it - if (*a_pData != ']') { - continue; - } - - // remove trailing spaces from the section - pTrail = a_pData - 1; - while (pTrail >= a_pSection && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // skip to the end of the line - ++a_pData; // safe as checked that it == ']' above - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - a_pKey = NULL; - a_pVal = NULL; - return true; - } - - // find the end of the key name (it may contain spaces) - // and convert it to lowercase as necessary - a_pKey = a_pData; - while (*a_pData && *a_pData != '=' && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // if it's an invalid line, just skip it - if (*a_pData != '=') { - continue; - } - - // empty keys are invalid - if (a_pKey == a_pData) { - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - continue; - } - - // remove trailing spaces from the key - pTrail = a_pData - 1; - while (pTrail >= a_pKey && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // skip leading whitespace on the value - ++a_pData; // safe as checked that it == '=' above - while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) { - ++a_pData; - } - - // find the end of the value which is the end of this line - a_pVal = a_pData; - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // remove trailing spaces from the value - pTrail = a_pData - 1; - if (*a_pData) { // prepare for the next round - SkipNewLine(a_pData); - } - while (pTrail >= a_pVal && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // check for multi-line entries - if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) { - // skip the "<<<" to get the tag that will end the multiline - const SI_CHAR * pTagName = a_pVal + 3; - return LoadMultiLineText(a_pData, a_pVal, pTagName); - } - - // return the standard entry - return true; - } - - return false; -} - -template -bool -CSimpleIniTempl::IsMultiLineTag( - const SI_CHAR * a_pVal - ) const -{ - // check for the "<<<" prefix for a multi-line entry - if (*a_pVal++ != '<') return false; - if (*a_pVal++ != '<') return false; - if (*a_pVal++ != '<') return false; - return true; -} - -template -bool -CSimpleIniTempl::IsMultiLineData( - const SI_CHAR * a_pData - ) const -{ - // data is multi-line if it has any of the following features: - // * whitespace prefix - // * embedded newlines - // * whitespace suffix - - // empty string - if (!*a_pData) { - return false; - } - - // check for prefix - if (IsSpace(*a_pData)) { - return true; - } - - // embedded newlines - while (*a_pData) { - if (IsNewLineChar(*a_pData)) { - return true; - } - ++a_pData; - } - - // check for suffix - if (IsSpace(*--a_pData)) { - return true; - } - - return false; -} - -template -bool -CSimpleIniTempl::IsNewLineChar( - SI_CHAR a_c - ) const -{ - return (a_c == '\n' || a_c == '\r'); -} - -template -bool -CSimpleIniTempl::LoadMultiLineText( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pVal, - const SI_CHAR * a_pTagName, - bool a_bAllowBlankLinesInComment - ) const -{ - // we modify this data to strip all newlines down to a single '\n' - // character. This means that on Windows we need to strip out some - // characters which will make the data shorter. - // i.e. LINE1-LINE1\r\nLINE2-LINE2\0 will become - // LINE1-LINE1\nLINE2-LINE2\0 - // The pDataLine entry is the pointer to the location in memory that - // the current line needs to start to run following the existing one. - // This may be the same as pCurrLine in which case no move is needed. - SI_CHAR * pDataLine = a_pData; - SI_CHAR * pCurrLine; - - // value starts at the current line - a_pVal = a_pData; - - // find the end tag. This tag must start in column 1 and be - // followed by a newline. No whitespace removal is done while - // searching for this tag. - SI_CHAR cEndOfLineChar = *a_pData; - for(;;) { - // if we are loading comments then we need a comment character as - // the first character on every line - if (!a_pTagName && !IsComment(*a_pData)) { - // if we aren't allowing blank lines then we're done - if (!a_bAllowBlankLinesInComment) { - break; - } - - // if we are allowing blank lines then we only include them - // in this comment if another comment follows, so read ahead - // to find out. - SI_CHAR * pCurr = a_pData; - int nNewLines = 0; - while (IsSpace(*pCurr)) { - if (IsNewLineChar(*pCurr)) { - ++nNewLines; - SkipNewLine(pCurr); - } - else { - ++pCurr; - } - } - - // we have a comment, add the blank lines to the output - // and continue processing from here - if (IsComment(*pCurr)) { - for (; nNewLines > 0; --nNewLines) *pDataLine++ = '\n'; - a_pData = pCurr; - continue; - } - - // the comment ends here - break; - } - - // find the end of this line - pCurrLine = a_pData; - while (*a_pData && !IsNewLineChar(*a_pData)) ++a_pData; - - // move this line down to the location that it should be if necessary - if (pDataLine < pCurrLine) { - size_t nLen = (size_t) (a_pData - pCurrLine); - memmove(pDataLine, pCurrLine, nLen * sizeof(SI_CHAR)); - pDataLine[nLen] = '\0'; - } - - // end the line with a NULL - cEndOfLineChar = *a_pData; - *a_pData = 0; - - // if are looking for a tag then do the check now. This is done before - // checking for end of the data, so that if we have the tag at the end - // of the data then the tag is removed correctly. - if (a_pTagName && - (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine))) - { - break; - } - - // if we are at the end of the data then we just automatically end - // this entry and return the current data. - if (!cEndOfLineChar) { - return true; - } - - // otherwise we need to process this newline to ensure that it consists - // of just a single \n character. - pDataLine += (a_pData - pCurrLine); - *a_pData = cEndOfLineChar; - SkipNewLine(a_pData); - *pDataLine++ = '\n'; - } - - // if we didn't find a comment at all then return false - if (a_pVal == a_pData) { - a_pVal = NULL; - return false; - } - - // the data (which ends at the end of the last line) needs to be - // null-terminated BEFORE before the newline character(s). If the - // user wants a new line in the multi-line data then they need to - // add an empty line before the tag. - *--pDataLine = '\0'; - - // if looking for a tag and if we aren't at the end of the data, - // then move a_pData to the start of the next line. - if (a_pTagName && cEndOfLineChar) { - SI_ASSERT(IsNewLineChar(cEndOfLineChar)); - *a_pData = cEndOfLineChar; - SkipNewLine(a_pData); - } - - return true; -} - -template -SI_Error -CSimpleIniTempl::CopyString( - const SI_CHAR *& a_pString - ) -{ - size_t uLen = 0; - if (sizeof(SI_CHAR) == sizeof(char)) { - uLen = strlen((const char *)a_pString); - } - else if (sizeof(SI_CHAR) == sizeof(wchar_t)) { - uLen = wcslen((const wchar_t *)a_pString); - } - else { - for ( ; a_pString[uLen]; ++uLen) /*loop*/ ; - } - ++uLen; // NULL character - SI_CHAR * pCopy = new SI_CHAR[uLen]; - if (!pCopy) { - return SI_NOMEM; - } - memcpy(pCopy, a_pString, sizeof(SI_CHAR)*uLen); - m_strings.push_back(pCopy); - a_pString = pCopy; - return SI_OK; -} - -template -SI_Error -CSimpleIniTempl::AddEntry( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace, - bool a_bCopyStrings - ) -{ - SI_Error rc; - bool bInserted = false; - - SI_ASSERT(!a_pComment || IsComment(*a_pComment)); - - // if we are copying strings then make a copy of the comment now - // because we will need it when we add the entry. - if (a_bCopyStrings && a_pComment) { - rc = CopyString(a_pComment); - if (rc < 0) return rc; - } - - // create the section entry if necessary - typename TSection::iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - // if the section doesn't exist then we need a copy as the - // string needs to last beyond the end of this function - if (a_bCopyStrings) { - rc = CopyString(a_pSection); - if (rc < 0) return rc; - } - - // only set the comment if this is a section only entry - Entry oSection(a_pSection, ++m_nOrder); - if (a_pComment && (!a_pKey || !a_pValue)) { - oSection.pComment = a_pComment; - } - - typename TSection::value_type oEntry(oSection, TKeyVal()); - typedef typename TSection::iterator SectionIterator; - std::pair i = m_data.insert(oEntry); - iSection = i.first; - bInserted = true; - } - if (!a_pKey || !a_pValue) { - // section only entries are specified with pItem and pVal as NULL - return bInserted ? SI_INSERTED : SI_UPDATED; - } - - // check for existence of the key - TKeyVal & keyval = iSection->second; - typename TKeyVal::iterator iKey = keyval.find(a_pKey); - - // remove all existing entries but save the load order and - // comment of the first entry - int nLoadOrder = ++m_nOrder; - if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) { - const SI_CHAR * pComment = NULL; - while (iKey != keyval.end() && !IsLess(a_pKey, iKey->first.pItem)) { - if (iKey->first.nOrder < nLoadOrder) { - nLoadOrder = iKey->first.nOrder; - pComment = iKey->first.pComment; - } - ++iKey; - } - if (pComment) { - DeleteString(a_pComment); - a_pComment = pComment; - CopyString(a_pComment); - } - Delete(a_pSection, a_pKey); - iKey = keyval.end(); - } - - // make string copies if necessary - bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace; - if (a_bCopyStrings) { - if (bForceCreateNewKey || iKey == keyval.end()) { - // if the key doesn't exist then we need a copy as the - // string needs to last beyond the end of this function - // because we will be inserting the key next - rc = CopyString(a_pKey); - if (rc < 0) return rc; - } - - // we always need a copy of the value - rc = CopyString(a_pValue); - if (rc < 0) return rc; - } - - // create the key entry - if (iKey == keyval.end() || bForceCreateNewKey) { - Entry oKey(a_pKey, nLoadOrder); - if (a_pComment) { - oKey.pComment = a_pComment; - } - typename TKeyVal::value_type oEntry(oKey, static_cast(NULL)); - iKey = keyval.insert(oEntry); - bInserted = true; - } - iKey->second = a_pValue; - return bInserted ? SI_INSERTED : SI_UPDATED; -} - -template -const SI_CHAR * -CSimpleIniTempl::GetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pDefault, - bool * a_pHasMultiple - ) const -{ - if (a_pHasMultiple) { - *a_pHasMultiple = false; - } - if (!a_pSection || !a_pKey) { - return a_pDefault; - } - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return a_pDefault; - } - typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return a_pDefault; - } - - // check for multiple entries with the same key - if (m_bAllowMultiKey && a_pHasMultiple) { - typename TKeyVal::const_iterator iTemp = iKeyVal; - if (++iTemp != iSection->second.end()) { - if (!IsLess(a_pKey, iTemp->first.pItem)) { - *a_pHasMultiple = true; - } - } - } - - return iKeyVal->second; -} - -template -long -CSimpleIniTempl::GetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nDefault, - bool * a_pHasMultiple - ) const -{ - // return the default if we don't have a value - const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); - if (!pszValue || !*pszValue) return a_nDefault; - - // convert to UTF-8/MBCS which for a numeric value will be the same as ASCII - char szValue[64] = { 0 }; - SI_CONVERTER c(m_bStoreIsUtf8); - if (!c.ConvertToStore(pszValue, szValue, sizeof(szValue))) { - return a_nDefault; - } - - // handle the value as hex if prefaced with "0x" - long nValue = a_nDefault; - char * pszSuffix = szValue; - if (szValue[0] == '0' && (szValue[1] == 'x' || szValue[1] == 'X')) { - if (!szValue[2]) return a_nDefault; - nValue = ::strtol(&szValue[2], &pszSuffix, 16); - } - else { - nValue = ::strtol(szValue, &pszSuffix, 10); - } - - // any invalid strings will return the default value - if (*pszSuffix) { - return a_nDefault; - } - - return nValue; -} - -template -SI_Error -CSimpleIniTempl::SetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nValue, - const SI_CHAR * a_pComment, - bool a_bUseHex, - bool a_bForceReplace - ) -{ - // use SetValue to create sections - if (!a_pSection || !a_pKey) return SI_FAIL; - - // convert to an ASCII string - char szInput[64]; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - sprintf_s(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); -#else // !__STDC_WANT_SECURE_LIB__ - sprintf(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); -#endif // __STDC_WANT_SECURE_LIB__ - - // convert to output text - SI_CHAR szOutput[64]; - SI_CONVERTER c(m_bStoreIsUtf8); - c.ConvertFromStore(szInput, strlen(szInput) + 1, - szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); - - // actually add it - return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); -} - -template -double -CSimpleIniTempl::GetDoubleValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - double a_nDefault, - bool * a_pHasMultiple - ) const -{ - // return the default if we don't have a value - const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); - if (!pszValue || !*pszValue) return a_nDefault; - - // convert to UTF-8/MBCS which for a numeric value will be the same as ASCII - char szValue[64] = { 0 }; - SI_CONVERTER c(m_bStoreIsUtf8); - if (!c.ConvertToStore(pszValue, szValue, sizeof(szValue))) { - return a_nDefault; - } - - char * pszSuffix = NULL; - double nValue = strtod(szValue, &pszSuffix); - - // any invalid strings will return the default value - if (!pszSuffix || *pszSuffix) { - return a_nDefault; - } - - return nValue; -} - -template -SI_Error -CSimpleIniTempl::SetDoubleValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - double a_nValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace - ) -{ - // use SetValue to create sections - if (!a_pSection || !a_pKey) return SI_FAIL; - - // convert to an ASCII string - char szInput[64]; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - sprintf_s(szInput, "%f", a_nValue); -#else // !__STDC_WANT_SECURE_LIB__ - sprintf(szInput, "%f", a_nValue); -#endif // __STDC_WANT_SECURE_LIB__ - - // convert to output text - SI_CHAR szOutput[64]; - SI_CONVERTER c(m_bStoreIsUtf8); - c.ConvertFromStore(szInput, strlen(szInput) + 1, - szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); - - // actually add it - return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); -} - -template -bool -CSimpleIniTempl::GetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bDefault, - bool * a_pHasMultiple - ) const -{ - // return the default if we don't have a value - const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); - if (!pszValue || !*pszValue) return a_bDefault; - - // we only look at the minimum number of characters - switch (pszValue[0]) { - case 't': case 'T': // true - case 'y': case 'Y': // yes - case '1': // 1 (one) - return true; - - case 'f': case 'F': // false - case 'n': case 'N': // no - case '0': // 0 (zero) - return false; - - case 'o': case 'O': - if (pszValue[1] == 'n' || pszValue[1] == 'N') return true; // on - if (pszValue[1] == 'f' || pszValue[1] == 'F') return false; // off - break; - } - - // no recognized value, return the default - return a_bDefault; -} - -template -SI_Error -CSimpleIniTempl::SetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace - ) -{ - // use SetValue to create sections - if (!a_pSection || !a_pKey) return SI_FAIL; - - // convert to an ASCII string - const char * pszInput = a_bValue ? "true" : "false"; - - // convert to output text - SI_CHAR szOutput[64]; - SI_CONVERTER c(m_bStoreIsUtf8); - c.ConvertFromStore(pszInput, strlen(pszInput) + 1, - szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); - - // actually add it - return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); -} - -template -bool -CSimpleIniTempl::GetAllValues( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - TNamesDepend & a_values - ) const -{ - a_values.clear(); - - if (!a_pSection || !a_pKey) { - return false; - } - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return false; - } - - // insert all values for this key - a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); - if (m_bAllowMultiKey) { - ++iKeyVal; - while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)) { - a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); - ++iKeyVal; - } - } - - return true; -} - -template -int -CSimpleIniTempl::GetSectionSize( - const SI_CHAR * a_pSection - ) const -{ - if (!a_pSection) { - return -1; - } - - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return -1; - } - const TKeyVal & section = iSection->second; - - // if multi-key isn't permitted then the section size is - // the number of keys that we have. - if (!m_bAllowMultiKey || section.empty()) { - return (int) section.size(); - } - - // otherwise we need to count them - int nCount = 0; - const SI_CHAR * pLastKey = NULL; - typename TKeyVal::const_iterator iKeyVal = section.begin(); - for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) { - if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { - ++nCount; - pLastKey = iKeyVal->first.pItem; - } - } - return nCount; -} - -template -const typename CSimpleIniTempl::TKeyVal * -CSimpleIniTempl::GetSection( - const SI_CHAR * a_pSection - ) const -{ - if (a_pSection) { - typename TSection::const_iterator i = m_data.find(a_pSection); - if (i != m_data.end()) { - return &(i->second); - } - } - return 0; -} - -template -void -CSimpleIniTempl::GetAllSections( - TNamesDepend & a_names - ) const -{ - a_names.clear(); - typename TSection::const_iterator i = m_data.begin(); - for (int n = 0; i != m_data.end(); ++i, ++n ) { - a_names.push_back(i->first); - } -} - -template -bool -CSimpleIniTempl::GetAllKeys( - const SI_CHAR * a_pSection, - TNamesDepend & a_names - ) const -{ - a_names.clear(); - - if (!a_pSection) { - return false; - } - - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - - const TKeyVal & section = iSection->second; - const SI_CHAR * pLastKey = NULL; - typename TKeyVal::const_iterator iKeyVal = section.begin(); - for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n ) { - if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { - a_names.push_back(iKeyVal->first); - pLastKey = iKeyVal->first.pItem; - } - } - - return true; -} - -template -SI_Error -CSimpleIniTempl::SaveFile( - const char * a_pszFile, - bool a_bAddSignature - ) const -{ - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - fopen_s(&fp, a_pszFile, "wb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = fopen(a_pszFile, "wb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = SaveFile(fp, a_bAddSignature); - fclose(fp); - return rc; -} - -#ifdef SI_HAS_WIDE_FILE -template -SI_Error -CSimpleIniTempl::SaveFile( - const SI_WCHAR_T * a_pwszFile, - bool a_bAddSignature - ) const -{ -#ifdef _WIN32 - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - _wfopen_s(&fp, a_pwszFile, L"wb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = _wfopen(a_pwszFile, L"wb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = SaveFile(fp, a_bAddSignature); - fclose(fp); - return rc; -#else // !_WIN32 (therefore SI_CONVERT_ICU) - char szFile[256]; - u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); - return SaveFile(szFile, a_bAddSignature); -#endif // _WIN32 -} -#endif // SI_HAS_WIDE_FILE - -template -SI_Error -CSimpleIniTempl::SaveFile( - FILE * a_pFile, - bool a_bAddSignature - ) const -{ - FileWriter writer(a_pFile); - return Save(writer, a_bAddSignature); -} - -template -SI_Error -CSimpleIniTempl::Save( - OutputWriter & a_oOutput, - bool a_bAddSignature - ) const -{ - Converter convert(m_bStoreIsUtf8); - - // add the UTF-8 signature if it is desired - if (m_bStoreIsUtf8 && a_bAddSignature) { - a_oOutput.Write(SI_UTF8_SIGNATURE); - } - - // get all of the sections sorted in load order - TNamesDepend oSections; - GetAllSections(oSections); -#if defined(_MSC_VER) && _MSC_VER <= 1200 - oSections.sort(); -#elif defined(__BORLANDC__) - oSections.sort(Entry::LoadOrder()); -#else - oSections.sort(typename Entry::LoadOrder()); -#endif - - // write the file comment if we have one - bool bNeedNewLine = false; - if (m_pFileComment) { - if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) { - return SI_FAIL; - } - bNeedNewLine = true; - } - - // iterate through our sections and output the data - typename TNamesDepend::const_iterator iSection = oSections.begin(); - for ( ; iSection != oSections.end(); ++iSection ) { - // write out the comment if there is one - if (iSection->pComment) { - if (bNeedNewLine) { - a_oOutput.Write(SI_NEWLINE_A); - a_oOutput.Write(SI_NEWLINE_A); - } - if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) { - return SI_FAIL; - } - bNeedNewLine = false; - } - - if (bNeedNewLine) { - a_oOutput.Write(SI_NEWLINE_A); - a_oOutput.Write(SI_NEWLINE_A); - bNeedNewLine = false; - } - - // write the section (unless there is no section name) - if (*iSection->pItem) { - if (!convert.ConvertToStore(iSection->pItem)) { - return SI_FAIL; - } - a_oOutput.Write("["); - a_oOutput.Write(convert.Data()); - a_oOutput.Write("]"); - a_oOutput.Write(SI_NEWLINE_A); - } - - // get all of the keys sorted in load order - TNamesDepend oKeys; - GetAllKeys(iSection->pItem, oKeys); -#if defined(_MSC_VER) && _MSC_VER <= 1200 - oKeys.sort(); -#elif defined(__BORLANDC__) - oKeys.sort(Entry::LoadOrder()); -#else - oKeys.sort(typename Entry::LoadOrder()); -#endif - - // write all keys and values - typename TNamesDepend::const_iterator iKey = oKeys.begin(); - for ( ; iKey != oKeys.end(); ++iKey) { - // get all values for this key - TNamesDepend oValues; - GetAllValues(iSection->pItem, iKey->pItem, oValues); - - typename TNamesDepend::const_iterator iValue = oValues.begin(); - for ( ; iValue != oValues.end(); ++iValue) { - // write out the comment if there is one - if (iValue->pComment) { - a_oOutput.Write(SI_NEWLINE_A); - if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) { - return SI_FAIL; - } - } - - // write the key - if (!convert.ConvertToStore(iKey->pItem)) { - return SI_FAIL; - } - a_oOutput.Write(convert.Data()); - - // write the value - if (!convert.ConvertToStore(iValue->pItem)) { - return SI_FAIL; - } - a_oOutput.Write(m_bSpaces ? " = " : "="); - if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) { - // multi-line data needs to be processed specially to ensure - // that we use the correct newline format for the current system - a_oOutput.Write("<<pItem)) { - return SI_FAIL; - } - a_oOutput.Write("END_OF_TEXT"); - } - else { - a_oOutput.Write(convert.Data()); - } - a_oOutput.Write(SI_NEWLINE_A); - } - } - - bNeedNewLine = true; - } - - return SI_OK; -} - -template -bool -CSimpleIniTempl::OutputMultiLineText( - OutputWriter & a_oOutput, - Converter & a_oConverter, - const SI_CHAR * a_pText - ) const -{ - const SI_CHAR * pEndOfLine; - SI_CHAR cEndOfLineChar = *a_pText; - while (cEndOfLineChar) { - // find the end of this line - pEndOfLine = a_pText; - for (; *pEndOfLine && *pEndOfLine != '\n'; ++pEndOfLine) /*loop*/ ; - cEndOfLineChar = *pEndOfLine; - - // temporarily null terminate, convert and output the line - *const_cast(pEndOfLine) = 0; - if (!a_oConverter.ConvertToStore(a_pText)) { - return false; - } - *const_cast(pEndOfLine) = cEndOfLineChar; - a_pText += (pEndOfLine - a_pText) + 1; - a_oOutput.Write(a_oConverter.Data()); - a_oOutput.Write(SI_NEWLINE_A); - } - return true; -} - -template -bool -CSimpleIniTempl::Delete( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bRemoveEmpty - ) -{ - if (!a_pSection) { - return false; - } - - typename TSection::iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - - // remove a single key if we have a keyname - if (a_pKey) { - typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return false; - } - - // remove any copied strings and then the key - typename TKeyVal::iterator iDelete; - do { - iDelete = iKeyVal++; - - DeleteString(iDelete->first.pItem); - DeleteString(iDelete->second); - iSection->second.erase(iDelete); - } - while (iKeyVal != iSection->second.end() - && !IsLess(a_pKey, iKeyVal->first.pItem)); - - // done now if the section is not empty or we are not pruning away - // the empty sections. Otherwise let it fall through into the section - // deletion code - if (!a_bRemoveEmpty || !iSection->second.empty()) { - return true; - } - } - else { - // delete all copied strings from this section. The actual - // entries will be removed when the section is removed. - typename TKeyVal::iterator iKeyVal = iSection->second.begin(); - for ( ; iKeyVal != iSection->second.end(); ++iKeyVal) { - DeleteString(iKeyVal->first.pItem); - DeleteString(iKeyVal->second); - } - } - - // delete the section itself - DeleteString(iSection->first.pItem); - m_data.erase(iSection); - - return true; -} - -template -void -CSimpleIniTempl::DeleteString( - const SI_CHAR * a_pString - ) -{ - // strings may exist either inside the data block, or they will be - // individually allocated and stored in m_strings. We only physically - // delete those stored in m_strings. - if (a_pString < m_pData || a_pString >= m_pData + m_uDataLen) { - typename TNamesDepend::iterator i = m_strings.begin(); - for (;i != m_strings.end(); ++i) { - if (a_pString == i->pItem) { - delete[] const_cast(i->pItem); - m_strings.erase(i); - break; - } - } - } -} - -// --------------------------------------------------------------------------- -// CONVERSION FUNCTIONS -// --------------------------------------------------------------------------- - -// Defines the conversion classes for different libraries. Before including -// SimpleIni.h, set the converter that you wish you use by defining one of the -// following symbols. -// -// SI_CONVERT_GENERIC Use the Unicode reference conversion library in -// the accompanying files ConvertUTF.h/c -// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires -// ICU headers on include path and icuuc.lib -// SI_CONVERT_WIN32 Use the Win32 API functions for conversion. - -#if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU) -# ifdef _WIN32 -# define SI_CONVERT_WIN32 -# else -# define SI_CONVERT_GENERIC -# endif -#endif - -/** - * Generic case-sensitive less than comparison. This class returns numerically - * ordered ASCII case-sensitive text for all possible sizes and types of - * SI_CHAR. - */ -template -struct SI_GenericCase { - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - long cmp; - for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { - cmp = (long) *pLeft - (long) *pRight; - if (cmp != 0) { - return cmp < 0; - } - } - return *pRight != 0; - } -}; - -/** - * Generic ASCII case-insensitive less than comparison. This class returns - * numerically ordered ASCII case-insensitive text for all possible sizes - * and types of SI_CHAR. It is not safe for MBCS text comparison where - * ASCII A-Z characters are used in the encoding of multi-byte characters. - */ -template -struct SI_GenericNoCase { - inline SI_CHAR locase(SI_CHAR ch) const { - return (ch < 'A' || ch > 'Z') ? ch : (ch - 'A' + 'a'); - } - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - long cmp; - for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { - cmp = (long) locase(*pLeft) - (long) locase(*pRight); - if (cmp != 0) { - return cmp < 0; - } - } - return *pRight != 0; - } -}; - -/** - * Null conversion class for MBCS/UTF-8 to char (or equivalent). - */ -template -class SI_ConvertA { - bool m_bStoreIsUtf8; -protected: - SI_ConvertA() { } -public: - SI_ConvertA(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } - - /* copy and assignment */ - SI_ConvertA(const SI_ConvertA & rhs) { operator=(rhs); } - SI_ConvertA & operator=(const SI_ConvertA & rhs) { - m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - (void)a_pInputData; - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - // ASCII/MBCS/UTF-8 needs no conversion - return a_uInputDataLen; - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - // ASCII/MBCS/UTF-8 needs no conversion - if (a_uInputDataLen > a_uOutputDataSize) { - return false; - } - memcpy(a_pOutputData, a_pInputData, a_uInputDataLen); - return true; - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - // ASCII/MBCS/UTF-8 needs no conversion - return strlen((const char *)a_pInputData) + 1; - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_uOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - // calc input string length (SI_CHAR type and size independent) - size_t uInputLen = strlen((const char *)a_pInputData) + 1; - if (uInputLen > a_uOutputDataSize) { - return false; - } - - // ascii/UTF-8 needs no conversion - memcpy(a_pOutputData, a_pInputData, uInputLen); - return true; - } -}; - - -// --------------------------------------------------------------------------- -// SI_CONVERT_GENERIC -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_GENERIC - -#define SI_Case SI_GenericCase -#define SI_NoCase SI_GenericNoCase - -#include -#include "ConvertUTF.h" - -/** - * Converts UTF-8 to a wchar_t (or equivalent) using the Unicode reference - * library functions. This can be used on all platforms. - */ -template -class SI_ConvertW { - bool m_bStoreIsUtf8; -protected: - SI_ConvertW() { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - if (m_bStoreIsUtf8) { - // worst case scenario for UTF-8 to wchar_t is 1 char -> 1 wchar_t - // so we just return the same number of characters required as for - // the source text. - return a_uInputDataLen; - } - -#if defined(SI_NO_MBSTOWCS_NULL) || (!defined(_MSC_VER) && !defined(_linux)) - // fall back processing for platforms that don't support a NULL dest to mbstowcs - // worst case scenario is 1:1, this will be a sufficient buffer size - (void)a_pInputData; - return a_uInputDataLen; -#else - // get the actual required buffer size - return mbstowcs(NULL, a_pInputData, a_uInputDataLen); -#endif - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - if (m_bStoreIsUtf8) { - // This uses the Unicode reference implementation to do the - // conversion from UTF-8 to wchar_t. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - const UTF8 * pUtf8 = (const UTF8 *) a_pInputData; - if (sizeof(wchar_t) == sizeof(UTF32)) { - UTF32 * pUtf32 = (UTF32 *) a_pOutputData; - retval = ConvertUTF8toUTF32( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf32, pUtf32 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(wchar_t) == sizeof(UTF16)) { - UTF16 * pUtf16 = (UTF16 *) a_pOutputData; - retval = ConvertUTF8toUTF16( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf16, pUtf16 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - - // convert to wchar_t - size_t retval = mbstowcs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t)(-1); - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - if (m_bStoreIsUtf8) { - // worst case scenario for wchar_t to UTF-8 is 1 wchar_t -> 6 char - size_t uLen = 0; - while (a_pInputData[uLen]) { - ++uLen; - } - return (6 * uLen) + 1; - } - else { - size_t uLen = wcstombs(NULL, a_pInputData, 0); - if (uLen == (size_t)(-1)) { - return uLen; - } - return uLen + 1; // include NULL terminator - } - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_uOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize - ) - { - if (m_bStoreIsUtf8) { - // calc input string length (SI_CHAR type and size independent) - size_t uInputLen = 0; - while (a_pInputData[uInputLen]) { - ++uInputLen; - } - ++uInputLen; // include the NULL char - - // This uses the Unicode reference implementation to do the - // conversion from wchar_t to UTF-8. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - UTF8 * pUtf8 = (UTF8 *) a_pOutputData; - if (sizeof(wchar_t) == sizeof(UTF32)) { - const UTF32 * pUtf32 = (const UTF32 *) a_pInputData; - retval = ConvertUTF32toUTF8( - &pUtf32, pUtf32 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(wchar_t) == sizeof(UTF16)) { - const UTF16 * pUtf16 = (const UTF16 *) a_pInputData; - retval = ConvertUTF16toUTF8( - &pUtf16, pUtf16 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - else { - size_t retval = wcstombs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t) -1; - } - } -}; - -#endif // SI_CONVERT_GENERIC - - -// --------------------------------------------------------------------------- -// SI_CONVERT_ICU -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_ICU - -#define SI_Case SI_GenericCase -#define SI_NoCase SI_GenericNoCase - -#include - -/** - * Converts MBCS/UTF-8 to UChar using ICU. This can be used on all platforms. - */ -template -class SI_ConvertW { - const char * m_pEncoding; - UConverter * m_pConverter; -protected: - SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) : m_pConverter(NULL) { - m_pEncoding = a_bStoreIsUtf8 ? "UTF-8" : NULL; - } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_pEncoding = rhs.m_pEncoding; - m_pConverter = NULL; - return *this; - } - ~SI_ConvertW() { if (m_pConverter) ucnv_close(m_pConverter); } - - /** Calculate the number of UChar required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to UChar. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of UChar required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return (size_t) -1; - } - } - - nError = U_ZERO_ERROR; - int32_t nLen = ucnv_toUChars(m_pConverter, NULL, 0, - a_pInputData, (int32_t) a_uInputDataLen, &nError); - if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) { - return (size_t) -1; - } - - return (size_t) nLen; - } - - /** Convert the input string from the storage format to UChar. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to UChar. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in UChar. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - UChar * a_pOutputData, - size_t a_uOutputDataSize) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return false; - } - } - - nError = U_ZERO_ERROR; - ucnv_toUChars(m_pConverter, - a_pOutputData, (int32_t) a_uOutputDataSize, - a_pInputData, (int32_t) a_uInputDataLen, &nError); - if (U_FAILURE(nError)) { - return false; - } - - return true; - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const UChar * a_pInputData) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return (size_t) -1; - } - } - - nError = U_ZERO_ERROR; - int32_t nLen = ucnv_fromUChars(m_pConverter, NULL, 0, - a_pInputData, -1, &nError); - if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) { - return (size_t) -1; - } - - return (size_t) nLen + 1; - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_pOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const UChar * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return false; - } - } - - nError = U_ZERO_ERROR; - ucnv_fromUChars(m_pConverter, - a_pOutputData, (int32_t) a_uOutputDataSize, - a_pInputData, -1, &nError); - if (U_FAILURE(nError)) { - return false; - } - - return true; - } -}; - -#endif // SI_CONVERT_ICU - - -// --------------------------------------------------------------------------- -// SI_CONVERT_WIN32 -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_WIN32 - -#define SI_Case SI_GenericCase - -// Windows CE doesn't have errno or MBCS libraries -#ifdef _WIN32_WCE -# ifndef SI_NO_MBCS -# define SI_NO_MBCS -# endif -#endif - -#include -#ifdef SI_NO_MBCS -# define SI_NoCase SI_GenericNoCase -#else // !SI_NO_MBCS -/** - * Case-insensitive comparison class using Win32 MBCS functions. This class - * returns a case-insensitive semi-collation order for MBCS text. It may not - * be safe for UTF-8 text returned in char format as we don't know what - * characters will be folded by the function! Therefore, if you are using - * SI_CHAR == char and SetUnicode(true), then you need to use the generic - * SI_NoCase class instead. - */ -#include -template -struct SI_NoCase { - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - if (sizeof(SI_CHAR) == sizeof(char)) { - return _mbsicmp((const unsigned char *)pLeft, - (const unsigned char *)pRight) < 0; - } - if (sizeof(SI_CHAR) == sizeof(wchar_t)) { - return _wcsicmp((const wchar_t *)pLeft, - (const wchar_t *)pRight) < 0; - } - return SI_GenericNoCase()(pLeft, pRight); - } -}; -#endif // SI_NO_MBCS - -/** - * Converts MBCS and UTF-8 to a wchar_t (or equivalent) on Windows. This uses - * only the Win32 functions and doesn't require the external Unicode UTF-8 - * conversion library. It will not work on Windows 95 without using Microsoft - * Layer for Unicode in your application. - */ -template -class SI_ConvertW { - UINT m_uCodePage; -protected: - SI_ConvertW() { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) { - m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP; - } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_uCodePage = rhs.m_uCodePage; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - int retval = MultiByteToWideChar( - m_uCodePage, 0, - a_pInputData, (int) a_uInputDataLen, - 0, 0); - return (size_t)(retval > 0 ? retval : -1); - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - int nSize = MultiByteToWideChar( - m_uCodePage, 0, - a_pInputData, (int) a_uInputDataLen, - (wchar_t *) a_pOutputData, (int) a_uOutputDataSize); - return (nSize > 0); - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - int retval = WideCharToMultiByte( - m_uCodePage, 0, - (const wchar_t *) a_pInputData, -1, - 0, 0, 0, 0); - return (size_t) (retval > 0 ? retval : -1); - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_pOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - int retval = WideCharToMultiByte( - m_uCodePage, 0, - (const wchar_t *) a_pInputData, -1, - a_pOutputData, (int) a_uOutputDataSize, 0, 0); - return retval > 0; - } -}; - -#endif // SI_CONVERT_WIN32 - - -// --------------------------------------------------------------------------- -// TYPE DEFINITIONS -// --------------------------------------------------------------------------- - -typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniA; -typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniCaseA; - -#if defined(SI_CONVERT_ICU) -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; -#else -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; -#endif - -#ifdef _UNICODE -# define CSimpleIni CSimpleIniW -# define CSimpleIniCase CSimpleIniCaseW -# define SI_NEWLINE SI_NEWLINE_W -#else // !_UNICODE -# define CSimpleIni CSimpleIniA -# define CSimpleIniCase CSimpleIniCaseA -# define SI_NEWLINE SI_NEWLINE_A -#endif // _UNICODE - -#ifdef _MSC_VER -# pragma warning (pop) -#endif - -#endif // INCLUDED_SimpleIni_h - diff --git a/linkers/elftoolchain/common/Makefile b/linkers/elftoolchain/common/Makefile deleted file mode 100644 index b7b5372..0000000 --- a/linkers/elftoolchain/common/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Id: Makefile 2140 2011-11-10 14:27:03Z jkoshy $ - -TOP= .. - -INCS= elfdefinitions.h -INCSDIR?= /usr/include - -.PHONY: all clean clobber depend obj - -all depend obj: - -clean clobber: - rm -f ${CLEANFILES} - -.include "${TOP}/mk/elftoolchain.inc.mk" diff --git a/linkers/elftoolchain/common/_elftc.h b/linkers/elftoolchain/common/_elftc.h deleted file mode 100644 index 9ee8db1..0000000 --- a/linkers/elftoolchain/common/_elftc.h +++ /dev/null @@ -1,176 +0,0 @@ -/*- - * Copyright (c) 2009 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _elftc.h 2064 2011-10-26 15:12:32Z jkoshy $ - */ - -/** - ** Miscellanous definitions needed by multiple components. - **/ - -#ifndef _ELFTC_H -#define _ELFTC_H - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -#ifndef offsetof -#define offsetof(T, M) ((int) &((T*) 0) -> M) -#endif - -/* - * Supply macros missing from - */ - -#ifndef STAILQ_FOREACH_SAFE -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) -#endif - -#ifndef STAILQ_LAST -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ - ((char *)((head)->stqh_last) - offsetof(struct type, field)))) -#endif - -#ifndef TAILQ_FOREACH_SAFE -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) -#endif - -/* - * VCS Ids. - */ - -#ifndef ELFTC_VCSID - -#if defined(__FreeBSD__) -#define ELFTC_VCSID(ID) __FBSDID(ID) -#endif - -#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) -#if defined(__GNUC__) -#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") -#else -#define ELFTC_VCSID(ID) /**/ -#endif -#endif - -#if defined(__NetBSD__) -#define ELFTC_VCSID(ID) __RCSID(ID) -#endif - -#endif /* ELFTC_VCSID */ - -/* - * Provide an equivalent for getprogname(3). - */ - -#ifndef ELFTC_GETPROGNAME - -#if defined(__FreeBSD__) || defined(__NetBSD__) - -#include - -#define ELFTC_GETPROGNAME() getprogname() - -#endif /* defined(__FreeBSD__) || defined(__NetBSD__) */ - - -#if defined(__linux__) - -/* - * GLIBC based systems have a global 'char *' pointer referencing - * the executable's name. - */ -extern const char *program_invocation_short_name; - -#define ELFTC_GETPROGNAME() program_invocation_short_name - -#endif /* __linux__ */ - -#endif /* ELFTC_GETPROGNAME */ - -/** - ** Per-OS configuration. - **/ - -#if defined(__linux__) - -#include - -#define ELFTC_BYTE_ORDER __BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN - -/* - * Debian GNU/Linux is missing strmode(3). - */ -#define ELFTC_HAVE_STRMODE 0 - -/* Whether we need to supply {be,le}32dec. */ -#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 - -#define roundup2 roundup - -#endif /* __linux__ */ - - -#if defined(__FreeBSD__) - -#include -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_STRMODE 1 -#if __FreeBSD_version <= 900000 -#define ELFTC_BROKEN_YY_NO_INPUT 1 -#endif -#endif /* __FreeBSD__ */ - - -#if defined(__NetBSD__) - -#include - -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN - -#define ELFTC_HAVE_STRMODE 1 -#define ELFTC_BROKEN_YY_NO_INPUT 1 -#endif /* __NetBSD __ */ - -#endif /* _ELFTC_H */ diff --git a/linkers/elftoolchain/common/elfdefinitions.h b/linkers/elftoolchain/common/elfdefinitions.h deleted file mode 100644 index 79b6e7f..0000000 --- a/linkers/elftoolchain/common/elfdefinitions.h +++ /dev/null @@ -1,2560 +0,0 @@ -/*- - * Copyright (c) 2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elfdefinitions.h 2132 2011-11-10 08:27:41Z jkoshy $ - */ - -/* - * These definitions are based on: - * - The public specification of the ELF format as defined in the - * October 2009 draft of System V ABI. - * See: http://www.sco.com/developers/gabi/latest/ch4.intro.html - * - The May 1998 (version 1.5) draft of "The ELF-64 object format". - * - Processor-specific ELF ABI definitions for sparc, i386, amd64, mips, - * ia64, and powerpc processors. - * - The "Linkers and Libraries Guide", from Sun Microsystems. - */ - -#ifndef _ELFDEFINITIONS_H_ -#define _ELFDEFINITIONS_H_ - -#include - -/* - * Types of capabilities. - */ - -#define _ELF_DEFINE_CAPABILITIES() \ -_ELF_DEFINE_CA(CA_SUNW_NULL, 0, "ignored") \ -_ELF_DEFINE_CA(CA_SUNW_HW_1, 1, "hardware capability") \ -_ELF_DEFINE_CA(CA_SUNW_SW_1, 2, "software capability") - -#undef _ELF_DEFINE_CA -#define _ELF_DEFINE_CA(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_CAPABILITIES() - CA__LAST__ -}; - -/* - * Flags used with dynamic linking entries. - */ - -#define _ELF_DEFINE_DYN_FLAGS() \ -_ELF_DEFINE_DF(DF_ORIGIN, 0x1, \ - "object being loaded may refer to $ORIGIN") \ -_ELF_DEFINE_DF(DF_SYMBOLIC, 0x2, \ - "search library for references before executable") \ -_ELF_DEFINE_DF(DF_TEXTREL, 0x4, \ - "relocation entries may modify text segment") \ -_ELF_DEFINE_DF(DF_BIND_NOW, 0x8, \ - "process relocation entries at load time") \ -_ELF_DEFINE_DF(DF_STATIC_TLS, 0x10, \ - "uses static thread-local storage") -#undef _ELF_DEFINE_DF -#define _ELF_DEFINE_DF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_DYN_FLAGS() - DF__LAST__ -}; - - -/* - * Dynamic linking entry types. - */ - -#define _ELF_DEFINE_DYN_TYPES() \ -_ELF_DEFINE_DT(DT_NULL, 0, "end of array") \ -_ELF_DEFINE_DT(DT_NEEDED, 1, "names a needed library") \ -_ELF_DEFINE_DT(DT_PLTRELSZ, 2, \ - "size in bytes of associated relocation entries") \ -_ELF_DEFINE_DT(DT_PLTGOT, 3, \ - "address associated with the procedure linkage table") \ -_ELF_DEFINE_DT(DT_HASH, 4, \ - "address of the symbol hash table") \ -_ELF_DEFINE_DT(DT_STRTAB, 5, \ - "address of the string table") \ -_ELF_DEFINE_DT(DT_SYMTAB, 6, \ - "address of the symbol table") \ -_ELF_DEFINE_DT(DT_RELA, 7, \ - "address of the relocation table") \ -_ELF_DEFINE_DT(DT_RELASZ, 8, "size of the DT_RELA table") \ -_ELF_DEFINE_DT(DT_RELAENT, 9, "size of each DT_RELA entry") \ -_ELF_DEFINE_DT(DT_STRSZ, 10, "size of the string table") \ -_ELF_DEFINE_DT(DT_SYMENT, 11, \ - "size of a symbol table entry") \ -_ELF_DEFINE_DT(DT_INIT, 12, \ - "address of the initialization function") \ -_ELF_DEFINE_DT(DT_FINI, 13, \ - "address of the finalization function") \ -_ELF_DEFINE_DT(DT_SONAME, 14, "names the shared object") \ -_ELF_DEFINE_DT(DT_RPATH, 15, \ - "runtime library search path") \ -_ELF_DEFINE_DT(DT_SYMBOLIC, 16, \ - "alter symbol resolution algorithm") \ -_ELF_DEFINE_DT(DT_REL, 17, \ - "address of the DT_REL table") \ -_ELF_DEFINE_DT(DT_RELSZ, 18, "size of the DT_REL table") \ -_ELF_DEFINE_DT(DT_RELENT, 19, "size of each DT_REL entry") \ -_ELF_DEFINE_DT(DT_PLTREL, 20, \ - "type of relocation entry in the procedure linkage table") \ -_ELF_DEFINE_DT(DT_DEBUG, 21, "used for debugging") \ -_ELF_DEFINE_DT(DT_TEXTREL, 22, \ - "text segment may be written to during relocation") \ -_ELF_DEFINE_DT(DT_JMPREL, 23, \ - "address of relocation entries associated with the procedure linkage table") \ -_ELF_DEFINE_DT(DT_BIND_NOW, 24, \ - "bind symbols at loading time") \ -_ELF_DEFINE_DT(DT_INIT_ARRAY, 25, \ - "pointers to initialization functions") \ -_ELF_DEFINE_DT(DT_FINI_ARRAY, 26, \ - "pointers to termination functions") \ -_ELF_DEFINE_DT(DT_INIT_ARRAYSZ, 27, "size of the DT_INIT_ARRAY") \ -_ELF_DEFINE_DT(DT_FINI_ARRAYSZ, 28, "size of the DT_FINI_ARRAY") \ -_ELF_DEFINE_DT(DT_RUNPATH, 29, \ - "index of library search path string") \ -_ELF_DEFINE_DT(DT_FLAGS, 30, \ - "flags specific to the object being loaded") \ -_ELF_DEFINE_DT(DT_ENCODING, 32, "standard semantics") \ -_ELF_DEFINE_DT(DT_PREINIT_ARRAY, 32, \ - "pointers to pre-initialization functions") \ -_ELF_DEFINE_DT(DT_PREINIT_ARRAYSZ, 33, \ - "size of pre-initialization array") \ -_ELF_DEFINE_DT(DT_MAXPOSTAGS, 34, \ - "the number of positive tags") \ -_ELF_DEFINE_DT(DT_LOOS, 0x6000000DUL, \ - "start of OS-specific types") \ -_ELF_DEFINE_DT(DT_SUNW_AUXILIARY, 0x6000000DUL, \ - "offset of string naming auxiliary filtees") \ -_ELF_DEFINE_DT(DT_SUNW_RTLDINF, 0x6000000EUL, "rtld internal use") \ -_ELF_DEFINE_DT(DT_SUNW_FILTER, 0x6000000FUL, \ - "offset of string naming standard filtees") \ -_ELF_DEFINE_DT(DT_SUNW_CAP, 0x60000010UL, \ - "address of hardware capabilities section") \ -_ELF_DEFINE_DT(DT_HIOS, 0x6FFFF000UL, \ - "end of OS-specific types") \ -_ELF_DEFINE_DT(DT_VALRNGLO, 0x6FFFFD00UL, \ - "start of range using the d_val field") \ -_ELF_DEFINE_DT(DT_GNU_PRELINKED, 0x6FFFFDF5UL, \ - "prelinking timestamp") \ -_ELF_DEFINE_DT(DT_GNU_CONFLICTSZ, 0x6FFFFDF6UL, \ - "size of conflict section") \ -_ELF_DEFINE_DT(DT_GNU_LIBLISTSZ, 0x6FFFFDF7UL, \ - "size of library list") \ -_ELF_DEFINE_DT(DT_CHECKSUM, 0x6FFFFDF8UL, \ - "checksum for the object") \ -_ELF_DEFINE_DT(DT_PLTPADSZ, 0x6FFFFDF9UL, \ - "size of PLT padding") \ -_ELF_DEFINE_DT(DT_MOVEENT, 0x6FFFFDFAUL, \ - "size of DT_MOVETAB entries") \ -_ELF_DEFINE_DT(DT_MOVESZ, 0x6FFFFDFBUL, \ - "total size of the MOVETAB table") \ -_ELF_DEFINE_DT(DT_FEATURE_1, 0x6FFFFDFCUL, "feature values") \ -_ELF_DEFINE_DT(DT_POSFLAG_1, 0x6FFFFDFDUL, \ - "dynamic position flags") \ -_ELF_DEFINE_DT(DT_SYMINSZ, 0x6FFFFDFEUL, \ - "size of the DT_SYMINFO table") \ -_ELF_DEFINE_DT(DT_SYMINENT, 0x6FFFFDFFUL, \ - "size of a DT_SYMINFO entry") \ -_ELF_DEFINE_DT(DT_VALRNGHI, 0x6FFFFDFFUL, \ - "end of range using the d_val field") \ -_ELF_DEFINE_DT(DT_ADDRRNGLO, 0x6FFFFE00UL, \ - "start of range using the d_ptr field") \ -_ELF_DEFINE_DT(DT_GNU_HASH, 0x6FFFFEF5UL, \ - "GNU style hash tables") \ -_ELF_DEFINE_DT(DT_GNU_CONFLICT, 0x6FFFFEF8UL, \ - "address of conflict section") \ -_ELF_DEFINE_DT(DT_GNU_LIBLIST, 0x6FFFFEF9UL, \ - "address of conflict section") \ -_ELF_DEFINE_DT(DT_CONFIG, 0x6FFFFEFAUL, \ - "configuration file") \ -_ELF_DEFINE_DT(DT_DEPAUDIT, 0x6FFFFEFBUL, \ - "string defining audit libraries") \ -_ELF_DEFINE_DT(DT_AUDIT, 0x6FFFFEFCUL, \ - "string defining audit libraries") \ -_ELF_DEFINE_DT(DT_PLTPAD, 0x6FFFFEFDUL, "PLT padding") \ -_ELF_DEFINE_DT(DT_MOVETAB, 0x6FFFFEFEUL, \ - "address of a move table") \ -_ELF_DEFINE_DT(DT_SYMINFO, 0x6FFFFEFFUL, \ - "address of the symbol information table") \ -_ELF_DEFINE_DT(DT_ADDRRNGHI, 0x6FFFFEFFUL, \ - "end of range using the d_ptr field") \ -_ELF_DEFINE_DT(DT_VERSYM, 0x6FFFFFF0UL, \ - "address of the version section") \ -_ELF_DEFINE_DT(DT_RELACOUNT, 0x6FFFFFF9UL, \ - "count of RELA relocations") \ -_ELF_DEFINE_DT(DT_RELCOUNT, 0x6FFFFFFAUL, \ - "count of REL relocations") \ -_ELF_DEFINE_DT(DT_FLAGS_1, 0x6FFFFFFBUL, "flag values") \ -_ELF_DEFINE_DT(DT_VERDEF, 0x6FFFFFFCUL, \ - "address of the version definition segment") \ -_ELF_DEFINE_DT(DT_VERDEFNUM, 0x6FFFFFFDUL, \ - "the number of version definition entries") \ -_ELF_DEFINE_DT(DT_VERNEED, 0x6FFFFFFEUL, \ - "address of section with needed versions") \ -_ELF_DEFINE_DT(DT_VERNEEDNUM, 0x6FFFFFFFUL, \ - "the number of version needed entries") \ -_ELF_DEFINE_DT(DT_LOPROC, 0x70000000UL, \ - "start of processor-specific types") \ -_ELF_DEFINE_DT(DT_ARM_SYMTABSZ, 0x70000001UL, \ - "number of entries in the dynamic symbol table") \ -_ELF_DEFINE_DT(DT_SPARC_REGISTER, 0x70000001UL, \ - "index of an STT_SPARC_REGISTER symbol") \ -_ELF_DEFINE_DT(DT_ARM_PREEMPTMAP, 0x70000002UL, \ - "address of the preemption map") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_VERSION, 0x70000001UL, \ - "version ID for runtime linker interface") \ -_ELF_DEFINE_DT(DT_MIPS_TIME_STAMP, 0x70000002UL, \ - "timestamp") \ -_ELF_DEFINE_DT(DT_MIPS_ICHECKSUM, 0x70000003UL, \ - "checksum of all external strings and common sizes") \ -_ELF_DEFINE_DT(DT_MIPS_IVERSION, 0x70000004UL, \ - "string table index of a version string") \ -_ELF_DEFINE_DT(DT_MIPS_FLAGS, 0x70000005UL, \ - "MIPS-specific flags") \ -_ELF_DEFINE_DT(DT_MIPS_BASE_ADDRESS, 0x70000006UL, \ - "base address for the executable/DSO") \ -_ELF_DEFINE_DT(DT_MIPS_CONFLICT, 0x70000008UL, \ - "address of .conflict section") \ -_ELF_DEFINE_DT(DT_MIPS_LIBLIST, 0x70000009UL, \ - "address of .liblist section") \ -_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTNO, 0x7000000AUL, \ - "number of local GOT entries") \ -_ELF_DEFINE_DT(DT_MIPS_CONFLICTNO, 0x7000000BUL, \ - "number of entries in the .conflict section") \ -_ELF_DEFINE_DT(DT_MIPS_LIBLISTNO, 0x70000010UL, \ - "number of entries in the .liblist section") \ -_ELF_DEFINE_DT(DT_MIPS_SYMTABNO, 0x70000011UL, \ - "number of entries in the .dynsym section") \ -_ELF_DEFINE_DT(DT_MIPS_UNREFEXTNO, 0x70000012UL, \ - "index of first external dynamic symbol not ref'ed locally") \ -_ELF_DEFINE_DT(DT_MIPS_GOTSYM, 0x70000013UL, \ - "index of first dynamic symbol corresponds to a GOT entry") \ -_ELF_DEFINE_DT(DT_MIPS_HIPAGENO, 0x70000014UL, \ - "number of page table entries in GOT") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_MAP, 0x70000016UL, \ - "address of runtime linker map") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS, 0x70000017UL, \ - "Delta C++ class definition") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS_NO, 0x70000018UL, \ - "number of entries in DT_MIPS_DELTA_CLASS") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE, 0x70000019UL, \ - "Delta C++ class instances") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE_NO, 0x7000001AUL, \ - "number of entries in DT_MIPS_DELTA_INSTANCE") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC, 0x7000001BUL, \ - "Delta relocations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC_NO, 0x7000001CUL, \ - "number of entries in DT_MIPS_DELTA_RELOC") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM, 0x7000001DUL, \ - "Delta symbols refered by Delta relocations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM_NO, 0x7000001EUL, \ - "number of entries in DT_MIPS_DELTA_SYM") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM, 0x70000020UL, \ - "Delta symbols for class declarations") \ -_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM_NO, 0x70000021UL, \ - "number of entries in DT_MIPS_DELTA_CLASSSYM") \ -_ELF_DEFINE_DT(DT_MIPS_CXX_FLAGS, 0x70000022UL, \ - "C++ flavor flags") \ -_ELF_DEFINE_DT(DT_MIPS_PIXIE_INIT, 0x70000023UL, \ - "address of an initialization routine created by pixie") \ -_ELF_DEFINE_DT(DT_MIPS_SYMBOL_LIB, 0x70000024UL, \ - "address of .MIPS.symlib section") \ -_ELF_DEFINE_DT(DT_MIPS_LOCALPAGE_GOTIDX, 0x70000025UL, \ - "GOT index of first page table entry for a segment") \ -_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTIDX, 0x70000026UL, \ - "GOT index of first page table entry for a local symbol") \ -_ELF_DEFINE_DT(DT_MIPS_HIDDEN_GOTIDX, 0x70000027UL, \ - "GOT index of first page table entry for a hidden symbol") \ -_ELF_DEFINE_DT(DT_MIPS_PROTECTED_GOTIDX, 0x70000028UL, \ - "GOT index of first page table entry for a protected symbol") \ -_ELF_DEFINE_DT(DT_MIPS_OPTIONS, 0x70000029UL, \ - "address of .MIPS.options section") \ -_ELF_DEFINE_DT(DT_MIPS_INTERFACE, 0x7000002AUL, \ - "address of .MIPS.interface section") \ -_ELF_DEFINE_DT(DT_MIPS_DYNSTR_ALIGN, 0x7000002BUL, "???") \ -_ELF_DEFINE_DT(DT_MIPS_INTERFACE_SIZE, 0x7000002CUL, \ - "size of .MIPS.interface section") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_TEXT_RESOLVE_ADDR, 0x7000002DUL, \ - "address of _rld_text_resolve in GOT") \ -_ELF_DEFINE_DT(DT_MIPS_PERF_SUFFIX, 0x7000002EUL, \ - "default suffix of DSO to be appended by dlopen") \ -_ELF_DEFINE_DT(DT_MIPS_COMPACT_SIZE, 0x7000002FUL, \ - "size of a ucode compact relocation record (o32)") \ -_ELF_DEFINE_DT(DT_MIPS_GP_VALUE, 0x70000030UL, \ - "GP value of a specified GP relative range") \ -_ELF_DEFINE_DT(DT_MIPS_AUX_DYNAMIC, 0x70000031UL, \ - "address of an auxiliary dynamic table") \ -_ELF_DEFINE_DT(DT_MIPS_PLTGOT, 0x70000032UL, \ - "address of the PLTGOT") \ -_ELF_DEFINE_DT(DT_MIPS_RLD_OBJ_UPDATE, 0x70000033UL, \ - "object list update callback") \ -_ELF_DEFINE_DT(DT_MIPS_RWPLT, 0x70000034UL, \ - "address of a writable PLT") \ -_ELF_DEFINE_DT(DT_PPC_GOT, 0x70000000UL, \ - "value of _GLOBAL_OFFSET_TABLE_") \ -_ELF_DEFINE_DT(DT_PPC_TLSOPT, 0x70000001UL, \ - "TLS descriptor should be optimized") \ -_ELF_DEFINE_DT(DT_PPC64_GLINK, 0x70000000UL, \ - "address of .glink section") \ -_ELF_DEFINE_DT(DT_PPC64_OPD, 0x70000001UL, \ - "address of .opd section") \ -_ELF_DEFINE_DT(DT_PPC64_OPDSZ, 0x70000002UL, \ - "size of .opd section") \ -_ELF_DEFINE_DT(DT_PPC64_TLSOPT, 0x70000003UL, \ - "TLS descriptor should be optimized") \ -_ELF_DEFINE_DT(DT_AUXILIARY, 0x7FFFFFFDUL, \ - "offset of string naming auxiliary filtees") \ -_ELF_DEFINE_DT(DT_USED, 0x7FFFFFFEUL, "ignored") \ -_ELF_DEFINE_DT(DT_FILTER, 0x7FFFFFFFUL, \ - "index of string naming filtees") \ -_ELF_DEFINE_DT(DT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific types") - -#undef _ELF_DEFINE_DT -#define _ELF_DEFINE_DT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_DYN_TYPES() - DT__LAST__ = DT_HIPROC -}; - -#define DT_DEPRECATED_SPARC_REGISTER DT_SPARC_REGISTER - -/* - * Flags used in the executable header (field: e_flags). - */ -#define _ELF_DEFINE_EHDR_FLAGS() \ -_ELF_DEFINE_EF(EF_ARM_RELEXEC, 0x00000001UL, \ - "dynamic segment describes only how to relocate segments") \ -_ELF_DEFINE_EF(EF_ARM_HASENTRY, 0x00000002UL, \ - "e_entry contains a program entry point") \ -_ELF_DEFINE_EF(EF_ARM_SYMSARESORTED, 0x00000004UL, \ - "subsection of symbol table is sorted by symbol value") \ -_ELF_DEFINE_EF(EF_ARM_DYNSYMSUSESEGIDX, 0x00000008UL, \ - "dynamic symbol st_shndx = containing segment index + 1") \ -_ELF_DEFINE_EF(EF_ARM_MAPSYMSFIRST, 0x00000010UL, \ - "mapping symbols precede other local symbols in symtab") \ -_ELF_DEFINE_EF(EF_ARM_BE8, 0x00800000UL, \ - "file contains BE-8 code") \ -_ELF_DEFINE_EF(EF_ARM_LE8, 0x00400000UL, \ - "file contains LE-8 code") \ -_ELF_DEFINE_EF(EF_ARM_EABIMASK, 0xFF000000UL, \ - "mask for ARM EABI version number (0 denotes GNU or unknown)") \ -_ELF_DEFINE_EF(EF_ARM_INTERWORK, 0x00000004UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_APCS_26, 0x00000008UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_APCS_FLOAT, 0x00000010UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_PIC, 0x00000020UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_ALIGN8, 0x00000040UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_NEW_ABI, 0x00000080UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_OLD_ABI, 0x00000100UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_SOFT_FLOAT, 0x00000200UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_VFP_FLOAT, 0x00000400UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_ARM_MAVERICK_FLOAT, 0x00000800UL, \ - "GNU EABI extension") \ -_ELF_DEFINE_EF(EF_MIPS_NOREORDER, 0x00000001UL, \ - "at least one .noreorder directive appeared in the source") \ -_ELF_DEFINE_EF(EF_MIPS_PIC, 0x00000002UL, \ - "file contains position independent code") \ -_ELF_DEFINE_EF(EF_MIPS_CPIC, 0x00000004UL, \ - "file's code uses standard conventions for calling PIC") \ -_ELF_DEFINE_EF(EF_MIPS_UCODE, 0x00000010UL, \ - "file contains UCODE (obsolete)") \ -_ELF_DEFINE_EF(EF_MIPS_ABI2, 0x00000020UL, \ - "file follows MIPS III 32-bit ABI") \ -_ELF_DEFINE_EF(EF_MIPS_OPTIONS_FIRST, 0x00000080UL, \ - "ld(1) should process .MIPS.options section first") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE, 0x0F000000UL, \ - "file uses application-specific architectural extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_MDMX, 0x08000000UL, \ - "file uses MDMX multimedia extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_M16, 0x04000000UL, \ - "file uses MIPS-16 ISA extensions") \ -_ELF_DEFINE_EF(EF_MIPS_ARCH, 0xF0000000UL, \ - "4-bit MIPS architecture field") \ -_ELF_DEFINE_EF(EF_PPC_EMB, 0x80000000UL, \ - "Embedded PowerPC flag") \ -_ELF_DEFINE_EF(EF_PPC_RELOCATABLE, 0x00010000UL, \ - "-mrelocatable flag") \ -_ELF_DEFINE_EF(EF_PPC_RELOCATABLE_LIB, 0x00008000UL, \ - "-mrelocatable-lib flag") \ -_ELF_DEFINE_EF(EF_SPARC_EXT_MASK, 0x00ffff00UL, \ - "Vendor Extension mask") \ -_ELF_DEFINE_EF(EF_SPARC_32PLUS, 0x00000100UL, \ - "Generic V8+ features") \ -_ELF_DEFINE_EF(EF_SPARC_SUN_US1, 0x00000200UL, \ - "Sun UltraSPARCTM 1 Extensions") \ -_ELF_DEFINE_EF(EF_SPARC_HAL_R1, 0x00000400UL, "HAL R1 Extensions") \ -_ELF_DEFINE_EF(EF_SPARC_SUN_US3, 0x00000800UL, \ - "Sun UltraSPARC 3 Extensions") \ -_ELF_DEFINE_EF(EF_SPARCV9_MM, 0x00000003UL, \ - "Mask for Memory Model") \ -_ELF_DEFINE_EF(EF_SPARCV9_TSO, 0x00000000UL, \ - "Total Store Ordering") \ -_ELF_DEFINE_EF(EF_SPARCV9_PSO, 0x00000001UL, \ - "Partial Store Ordering") \ -_ELF_DEFINE_EF(EF_SPARCV9_RMO, 0x00000002UL, \ - "Relaxed Memory Ordering") - -#undef _ELF_DEFINE_EF -#define _ELF_DEFINE_EF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_EHDR_FLAGS() - EF__LAST__ -}; - -/* - * Offsets in the `ei_ident[]` field of an ELF executable header. - */ -#define _ELF_DEFINE_EI_OFFSETS() \ -_ELF_DEFINE_EI(EI_MAG0, 0, "magic number") \ -_ELF_DEFINE_EI(EI_MAG1, 1, "magic number") \ -_ELF_DEFINE_EI(EI_MAG2, 2, "magic number") \ -_ELF_DEFINE_EI(EI_MAG3, 3, "magic number") \ -_ELF_DEFINE_EI(EI_CLASS, 4, "file class") \ -_ELF_DEFINE_EI(EI_DATA, 5, "data encoding") \ -_ELF_DEFINE_EI(EI_VERSION, 6, "file version") \ -_ELF_DEFINE_EI(EI_OSABI, 7, "OS ABI kind") \ -_ELF_DEFINE_EI(EI_ABIVERSION, 8, "OS ABI version") \ -_ELF_DEFINE_EI(EI_PAD, 9, "padding start") \ -_ELF_DEFINE_EI(EI_NIDENT, 16, "total size") - -#undef _ELF_DEFINE_EI -#define _ELF_DEFINE_EI(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_EI_OFFSETS() - EI__LAST__ -}; - -/* - * The ELF class of an object. - */ -#define _ELF_DEFINE_ELFCLASS() \ -_ELF_DEFINE_EC(ELFCLASSNONE, 0, "Unknown ELF class") \ -_ELF_DEFINE_EC(ELFCLASS32, 1, "32 bit objects") \ -_ELF_DEFINE_EC(ELFCLASS64, 2, "64 bit objects") - -#undef _ELF_DEFINE_EC -#define _ELF_DEFINE_EC(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELFCLASS() - EC__LAST__ -}; - -/* - * Endianness of data in an ELF object. - */ - -#define _ELF_DEFINE_ELF_DATA_ENDIANNESS() \ -_ELF_DEFINE_ED(ELFDATANONE, 0, "Unknown data endianness") \ -_ELF_DEFINE_ED(ELFDATA2LSB, 1, "little endian") \ -_ELF_DEFINE_ED(ELFDATA2MSB, 2, "big endian") - -#undef _ELF_DEFINE_ED -#define _ELF_DEFINE_ED(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_DATA_ENDIANNESS() - ED__LAST__ -}; - -/* - * Values of the magic numbers used in identification array. - */ -#define _ELF_DEFINE_ELF_MAGIC() \ -_ELF_DEFINE_EMAG(ELFMAG0, 0x7FU) \ -_ELF_DEFINE_EMAG(ELFMAG1, 'E') \ -_ELF_DEFINE_EMAG(ELFMAG2, 'L') \ -_ELF_DEFINE_EMAG(ELFMAG3, 'F') - -#undef _ELF_DEFINE_EMAG -#define _ELF_DEFINE_EMAG(N, V) N = V , -enum { - _ELF_DEFINE_ELF_MAGIC() - ELFMAG__LAST__ -}; - -/* - * ELF OS ABI field. - */ -#define _ELF_DEFINE_ELF_OSABI() \ -_ELF_DEFINE_EABI(ELFOSABI_NONE, 0, \ - "No extensions or unspecified") \ -_ELF_DEFINE_EABI(ELFOSABI_SYSV, 0, "SYSV") \ -_ELF_DEFINE_EABI(ELFOSABI_HPUX, 1, "Hewlett-Packard HP-UX") \ -_ELF_DEFINE_EABI(ELFOSABI_NETBSD, 2, "NetBSD") \ -_ELF_DEFINE_EABI(ELFOSABI_GNU, 3, "GNU") \ -_ELF_DEFINE_EABI(ELFOSABI_HURD, 4, "GNU/HURD") \ -_ELF_DEFINE_EABI(ELFOSABI_86OPEN, 5, "86Open Common ABI") \ -_ELF_DEFINE_EABI(ELFOSABI_SOLARIS, 6, "Sun Solaris") \ -_ELF_DEFINE_EABI(ELFOSABI_AIX, 7, "AIX") \ -_ELF_DEFINE_EABI(ELFOSABI_IRIX, 8, "IRIX") \ -_ELF_DEFINE_EABI(ELFOSABI_FREEBSD, 9, "FreeBSD") \ -_ELF_DEFINE_EABI(ELFOSABI_TRU64, 10, "Compaq TRU64 UNIX") \ -_ELF_DEFINE_EABI(ELFOSABI_MODESTO, 11, "Novell Modesto") \ -_ELF_DEFINE_EABI(ELFOSABI_OPENBSD, 12, "Open BSD") \ -_ELF_DEFINE_EABI(ELFOSABI_OPENVMS, 13, "Open VMS") \ -_ELF_DEFINE_EABI(ELFOSABI_NSK, 14, \ - "Hewlett-Packard Non-Stop Kernel") \ -_ELF_DEFINE_EABI(ELFOSABI_AROS, 15, "Amiga Research OS") \ -_ELF_DEFINE_EABI(ELFOSABI_FENIXOS, 16, \ - "The FenixOS highly scalable multi-core OS") \ -_ELF_DEFINE_EABI(ELFOSABI_ARM_AEABI, 64, \ - "ARM specific symbol versioning extensions") \ -_ELF_DEFINE_EABI(ELFOSABI_ARM, 97, "ARM ABI") \ -_ELF_DEFINE_EABI(ELFOSABI_STANDALONE, 255, \ - "Standalone (embedded) application") - -#undef _ELF_DEFINE_EABI -#define _ELF_DEFINE_EABI(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_OSABI() - ELFOSABI__LAST__ -}; - -#define ELFOSABI_LINUX ELFOSABI_GNU - -/* - * ELF Machine types: (EM_*). - */ -#define _ELF_DEFINE_ELF_MACHINES() \ -_ELF_DEFINE_EM(EM_NONE, 0, "No machine") \ -_ELF_DEFINE_EM(EM_M32, 1, "AT&T WE 32100") \ -_ELF_DEFINE_EM(EM_SPARC, 2, "SPARC") \ -_ELF_DEFINE_EM(EM_386, 3, "Intel 80386") \ -_ELF_DEFINE_EM(EM_68K, 4, "Motorola 68000") \ -_ELF_DEFINE_EM(EM_88K, 5, "Motorola 88000") \ -_ELF_DEFINE_EM(EM_860, 7, "Intel 80860") \ -_ELF_DEFINE_EM(EM_MIPS, 8, "MIPS I Architecture") \ -_ELF_DEFINE_EM(EM_S370, 9, "IBM System/370 Processor") \ -_ELF_DEFINE_EM(EM_MIPS_RS3_LE, 10, "MIPS RS3000 Little-endian") \ -_ELF_DEFINE_EM(EM_PARISC, 15, "Hewlett-Packard PA-RISC") \ -_ELF_DEFINE_EM(EM_VPP500, 17, "Fujitsu VPP500") \ -_ELF_DEFINE_EM(EM_SPARC32PLUS, 18, \ - "Enhanced instruction set SPARC") \ -_ELF_DEFINE_EM(EM_960, 19, "Intel 80960") \ -_ELF_DEFINE_EM(EM_PPC, 20, "PowerPC") \ -_ELF_DEFINE_EM(EM_PPC64, 21, "64-bit PowerPC") \ -_ELF_DEFINE_EM(EM_S390, 22, "IBM System/390 Processor") \ -_ELF_DEFINE_EM(EM_SPU, 23, "IBM SPU/SPC") \ -_ELF_DEFINE_EM(EM_V800, 36, "NEC V800") \ -_ELF_DEFINE_EM(EM_FR20, 37, "Fujitsu FR20") \ -_ELF_DEFINE_EM(EM_RH32, 38, "TRW RH-32") \ -_ELF_DEFINE_EM(EM_RCE, 39, "Motorola RCE") \ -_ELF_DEFINE_EM(EM_ARM, 40, "Advanced RISC Machines ARM") \ -_ELF_DEFINE_EM(EM_ALPHA, 41, "Digital Alpha") \ -_ELF_DEFINE_EM(EM_SH, 42, "Hitachi SH") \ -_ELF_DEFINE_EM(EM_SPARCV9, 43, "SPARC Version 9") \ -_ELF_DEFINE_EM(EM_TRICORE, 44, \ - "Siemens TriCore embedded processor") \ -_ELF_DEFINE_EM(EM_ARC, 45, \ - "Argonaut RISC Core, Argonaut Technologies Inc.") \ -_ELF_DEFINE_EM(EM_H8_300, 46, "Hitachi H8/300") \ -_ELF_DEFINE_EM(EM_H8_300H, 47, "Hitachi H8/300H") \ -_ELF_DEFINE_EM(EM_H8S, 48, "Hitachi H8S") \ -_ELF_DEFINE_EM(EM_H8_500, 49, "Hitachi H8/500") \ -_ELF_DEFINE_EM(EM_IA_64, 50, \ - "Intel IA-64 processor architecture") \ -_ELF_DEFINE_EM(EM_MIPS_X, 51, "Stanford MIPS-X") \ -_ELF_DEFINE_EM(EM_COLDFIRE, 52, "Motorola ColdFire") \ -_ELF_DEFINE_EM(EM_68HC12, 53, "Motorola M68HC12") \ -_ELF_DEFINE_EM(EM_MMA, 54, \ - "Fujitsu MMA Multimedia Accelerator") \ -_ELF_DEFINE_EM(EM_PCP, 55, "Siemens PCP") \ -_ELF_DEFINE_EM(EM_NCPU, 56, \ - "Sony nCPU embedded RISC processor") \ -_ELF_DEFINE_EM(EM_NDR1, 57, "Denso NDR1 microprocessor") \ -_ELF_DEFINE_EM(EM_STARCORE, 58, "Motorola Star*Core processor") \ -_ELF_DEFINE_EM(EM_ME16, 59, "Toyota ME16 processor") \ -_ELF_DEFINE_EM(EM_ST100, 60, \ - "STMicroelectronics ST100 processor") \ -_ELF_DEFINE_EM(EM_TINYJ, 61, \ - "Advanced Logic Corp. TinyJ embedded processor family") \ -_ELF_DEFINE_EM(EM_X86_64, 62, "AMD x86-64 architecture") \ -_ELF_DEFINE_EM(EM_PDSP, 63, "Sony DSP Processor") \ -_ELF_DEFINE_EM(EM_PDP10, 64, \ - "Digital Equipment Corp. PDP-10") \ -_ELF_DEFINE_EM(EM_PDP11, 65, \ - "Digital Equipment Corp. PDP-11") \ -_ELF_DEFINE_EM(EM_FX66, 66, "Siemens FX66 microcontroller") \ -_ELF_DEFINE_EM(EM_ST9PLUS, 67, \ - "STMicroelectronics ST9+ 8/16 bit microcontroller") \ -_ELF_DEFINE_EM(EM_ST7, 68, \ - "STMicroelectronics ST7 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_68HC16, 69, \ - "Motorola MC68HC16 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC11, 70, \ - "Motorola MC68HC11 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC08, 71, \ - "Motorola MC68HC08 Microcontroller") \ -_ELF_DEFINE_EM(EM_68HC05, 72, \ - "Motorola MC68HC05 Microcontroller") \ -_ELF_DEFINE_EM(EM_SVX, 73, "Silicon Graphics SVx") \ -_ELF_DEFINE_EM(EM_ST19, 74, \ - "STMicroelectronics ST19 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_VAX, 75, "Digital VAX") \ -_ELF_DEFINE_EM(EM_CRIS, 76, \ - "Axis Communications 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_JAVELIN, 77, \ - "Infineon Technologies 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_FIREPATH, 78, \ - "Element 14 64-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_ZSP, 79, \ - "LSI Logic 16-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_MMIX, 80, \ - "Donald Knuth's educational 64-bit processor") \ -_ELF_DEFINE_EM(EM_HUANY, 81, \ - "Harvard University machine-independent object files") \ -_ELF_DEFINE_EM(EM_PRISM, 82, "SiTera Prism") \ -_ELF_DEFINE_EM(EM_AVR, 83, \ - "Atmel AVR 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_FR30, 84, "Fujitsu FR30") \ -_ELF_DEFINE_EM(EM_D10V, 85, "Mitsubishi D10V") \ -_ELF_DEFINE_EM(EM_D30V, 86, "Mitsubishi D30V") \ -_ELF_DEFINE_EM(EM_V850, 87, "NEC v850") \ -_ELF_DEFINE_EM(EM_M32R, 88, "Mitsubishi M32R") \ -_ELF_DEFINE_EM(EM_MN10300, 89, "Matsushita MN10300") \ -_ELF_DEFINE_EM(EM_MN10200, 90, "Matsushita MN10200") \ -_ELF_DEFINE_EM(EM_PJ, 91, "picoJava") \ -_ELF_DEFINE_EM(EM_OPENRISC, 92, \ - "OpenRISC 32-bit embedded processor") \ -_ELF_DEFINE_EM(EM_ARC_COMPACT, 93, \ - "ARC International ARCompact processor") \ -_ELF_DEFINE_EM(EM_XTENSA, 94, \ - "Tensilica Xtensa Architecture") \ -_ELF_DEFINE_EM(EM_VIDEOCORE, 95, \ - "Alphamosaic VideoCore processor") \ -_ELF_DEFINE_EM(EM_TMM_GPP, 96, \ - "Thompson Multimedia General Purpose Processor") \ -_ELF_DEFINE_EM(EM_NS32K, 97, \ - "National Semiconductor 32000 series") \ -_ELF_DEFINE_EM(EM_TPC, 98, "Tenor Network TPC processor") \ -_ELF_DEFINE_EM(EM_SNP1K, 99, "Trebia SNP 1000 processor") \ -_ELF_DEFINE_EM(EM_ST200, 100, \ - "STMicroelectronics (www.st.com) ST200 microcontroller") \ -_ELF_DEFINE_EM(EM_IP2K, 101, \ - "Ubicom IP2xxx microcontroller family") \ -_ELF_DEFINE_EM(EM_MAX, 102, "MAX Processor") \ -_ELF_DEFINE_EM(EM_CR, 103, \ - "National Semiconductor CompactRISC microprocessor") \ -_ELF_DEFINE_EM(EM_F2MC16, 104, "Fujitsu F2MC16") \ -_ELF_DEFINE_EM(EM_MSP430, 105, \ - "Texas Instruments embedded microcontroller msp430") \ -_ELF_DEFINE_EM(EM_BLACKFIN, 106, \ - "Analog Devices Blackfin (DSP) processor") \ -_ELF_DEFINE_EM(EM_SE_C33, 107, \ - "S1C33 Family of Seiko Epson processors") \ -_ELF_DEFINE_EM(EM_SEP, 108, \ - "Sharp embedded microprocessor") \ -_ELF_DEFINE_EM(EM_ARCA, 109, "Arca RISC Microprocessor") \ -_ELF_DEFINE_EM(EM_UNICORE, 110, \ - "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University") \ -_ELF_DEFINE_EM(EM_EXCESS, 111, \ - "eXcess: 16/32/64-bit configurable embedded CPU") \ -_ELF_DEFINE_EM(EM_DXP, 112, \ - "Icera Semiconductor Inc. Deep Execution Processor") \ -_ELF_DEFINE_EM(EM_ALTERA_NIOS2, 113, \ - "Altera Nios II soft-core processor") \ -_ELF_DEFINE_EM(EM_CRX, 114, \ - "National Semiconductor CompactRISC CRX microprocessor") \ -_ELF_DEFINE_EM(EM_XGATE, 115, \ - "Motorola XGATE embedded processor") \ -_ELF_DEFINE_EM(EM_C166, 116, \ - "Infineon C16x/XC16x processor") \ -_ELF_DEFINE_EM(EM_M16C, 117, \ - "Renesas M16C series microprocessors") \ -_ELF_DEFINE_EM(EM_DSPIC30F, 118, \ - "Microchip Technology dsPIC30F Digital Signal Controller") \ -_ELF_DEFINE_EM(EM_CE, 119, \ - "Freescale Communication Engine RISC core") \ -_ELF_DEFINE_EM(EM_M32C, 120, \ - "Renesas M32C series microprocessors") \ -_ELF_DEFINE_EM(EM_TSK3000, 131, "Altium TSK3000 core") \ -_ELF_DEFINE_EM(EM_RS08, 132, \ - "Freescale RS08 embedded processor") \ -_ELF_DEFINE_EM(EM_SHARC, 133, \ - "Analog Devices SHARC family of 32-bit DSP processors") \ -_ELF_DEFINE_EM(EM_ECOG2, 134, \ - "Cyan Technology eCOG2 microprocessor") \ -_ELF_DEFINE_EM(EM_SCORE7, 135, \ - "Sunplus S+core7 RISC processor") \ -_ELF_DEFINE_EM(EM_DSP24, 136, \ - "New Japan Radio (NJR) 24-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_VIDEOCORE3, 137, \ - "Broadcom VideoCore III processor") \ -_ELF_DEFINE_EM(EM_LATTICEMICO32, 138, \ - "RISC processor for Lattice FPGA architecture") \ -_ELF_DEFINE_EM(EM_SE_C17, 139, "Seiko Epson C17 family") \ -_ELF_DEFINE_EM(EM_TI_C6000, 140, \ - "The Texas Instruments TMS320C6000 DSP family") \ -_ELF_DEFINE_EM(EM_TI_C2000, 141, \ - "The Texas Instruments TMS320C2000 DSP family") \ -_ELF_DEFINE_EM(EM_TI_C5500, 142, \ - "The Texas Instruments TMS320C55x DSP family") \ -_ELF_DEFINE_EM(EM_MMDSP_PLUS, 160, \ - "STMicroelectronics 64bit VLIW Data Signal Processor") \ -_ELF_DEFINE_EM(EM_CYPRESS_M8C, 161, "Cypress M8C microprocessor") \ -_ELF_DEFINE_EM(EM_R32C, 162, \ - "Renesas R32C series microprocessors") \ -_ELF_DEFINE_EM(EM_TRIMEDIA, 163, \ - "NXP Semiconductors TriMedia architecture family") \ -_ELF_DEFINE_EM(EM_QDSP6, 164, "QUALCOMM DSP6 Processor") \ -_ELF_DEFINE_EM(EM_8051, 165, "Intel 8051 and variants") \ -_ELF_DEFINE_EM(EM_STXP7X, 166, \ - "STMicroelectronics STxP7x family of configurable and extensible RISC processors") \ -_ELF_DEFINE_EM(EM_NDS32, 167, \ - "Andes Technology compact code size embedded RISC processor family") \ -_ELF_DEFINE_EM(EM_ECOG1, 168, \ - "Cyan Technology eCOG1X family") \ -_ELF_DEFINE_EM(EM_ECOG1X, 168, \ - "Cyan Technology eCOG1X family") \ -_ELF_DEFINE_EM(EM_MAXQ30, 169, \ - "Dallas Semiconductor MAXQ30 Core Micro-controllers") \ -_ELF_DEFINE_EM(EM_XIMO16, 170, \ - "New Japan Radio (NJR) 16-bit DSP Processor") \ -_ELF_DEFINE_EM(EM_MANIK, 171, \ - "M2000 Reconfigurable RISC Microprocessor") \ -_ELF_DEFINE_EM(EM_CRAYNV2, 172, \ - "Cray Inc. NV2 vector architecture") \ -_ELF_DEFINE_EM(EM_RX, 173, "Renesas RX family") \ -_ELF_DEFINE_EM(EM_METAG, 174, \ - "Imagination Technologies META processor architecture") \ -_ELF_DEFINE_EM(EM_MCST_ELBRUS, 175, \ - "MCST Elbrus general purpose hardware architecture") \ -_ELF_DEFINE_EM(EM_ECOG16, 176, \ - "Cyan Technology eCOG16 family") \ -_ELF_DEFINE_EM(EM_CR16, 177, \ - "National Semiconductor CompactRISC CR16 16-bit microprocessor") \ -_ELF_DEFINE_EM(EM_ETPU, 178, \ - "Freescale Extended Time Processing Unit") \ -_ELF_DEFINE_EM(EM_SLE9X, 179, \ - "Infineon Technologies SLE9X core") \ -_ELF_DEFINE_EM(EM_AVR32, 185, \ - "Atmel Corporation 32-bit microprocessor family") \ -_ELF_DEFINE_EM(EM_STM8, 186, \ - "STMicroeletronics STM8 8-bit microcontroller") \ -_ELF_DEFINE_EM(EM_TILE64, 187, \ - "Tilera TILE64 multicore architecture family") \ -_ELF_DEFINE_EM(EM_TILEPRO, 188, \ - "Tilera TILEPro multicore architecture family") \ -_ELF_DEFINE_EM(EM_MICROBLAZE, 189, \ - "Xilinx MicroBlaze 32-bit RISC soft processor core") \ -_ELF_DEFINE_EM(EM_CUDA, 190, "NVIDIA CUDA architecture") \ -_ELF_DEFINE_EM(EM_TILEGX, 191, \ - "Tilera TILE-Gx multicore architecture family") \ -_ELF_DEFINE_EM(EM_CLOUDSHIELD, 192, \ - "CloudShield architecture family") \ -_ELF_DEFINE_EM(EM_COREA_1ST, 193, \ - "KIPO-KAIST Core-A 1st generation processor family") \ -_ELF_DEFINE_EM(EM_COREA_2ND, 194, \ - "KIPO-KAIST Core-A 2nd generation processor family") \ -_ELF_DEFINE_EM(EM_ARC_COMPACT2, 195, "Synopsys ARCompact V2") \ -_ELF_DEFINE_EM(EM_OPEN8, 196, \ - "Open8 8-bit RISC soft processor core") \ -_ELF_DEFINE_EM(EM_RL78, 197, "Renesas RL78 family") \ -_ELF_DEFINE_EM(EM_VIDEOCORE5, 198, "Broadcom VideoCore V processor") \ -_ELF_DEFINE_EM(EM_78KOR, 199, "Renesas 78KOR family") - -#undef _ELF_DEFINE_EM -#define _ELF_DEFINE_EM(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_MACHINES() - EM__LAST__ -}; - -/* Older synonyms. */ -#define EM_ARC_A5 EM_ARC_COMPACT - -/* - * ELF file types: (ET_*). - */ -#define _ELF_DEFINE_ELF_TYPES() \ -_ELF_DEFINE_ET(ET_NONE, 0, "No file type") \ -_ELF_DEFINE_ET(ET_REL, 1, "Relocatable object") \ -_ELF_DEFINE_ET(ET_EXEC, 2, "Executable") \ -_ELF_DEFINE_ET(ET_DYN, 3, "Shared object") \ -_ELF_DEFINE_ET(ET_CORE, 4, "Core file") \ -_ELF_DEFINE_ET(ET_LOOS, 0xFE00U, "Begin OS-specific range") \ -_ELF_DEFINE_ET(ET_HIOS, 0xFEFFU, "End OS-specific range") \ -_ELF_DEFINE_ET(ET_LOPROC, 0xFF00U, "Begin processor-specific range") \ -_ELF_DEFINE_ET(ET_HIPROC, 0xFFFFU, "End processor-specific range") - -#undef _ELF_DEFINE_ET -#define _ELF_DEFINE_ET(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ELF_TYPES() - ET__LAST__ -}; - -/* ELF file format version numbers. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* - * Flags for section groups. - */ -#define GRP_COMDAT 0x1 /* COMDAT semantics */ -#define GRP_MASKOS 0x0ff00000 /* OS-specific flags */ -#define GRP_MASKPROC 0xf0000000 /* processor-specific flags */ - -/* - * Flags used by program header table entries. - */ - -#define _ELF_DEFINE_PHDR_FLAGS() \ -_ELF_DEFINE_PF(PF_X, 0x1, "Execute") \ -_ELF_DEFINE_PF(PF_W, 0x2, "Write") \ -_ELF_DEFINE_PF(PF_R, 0x4, "Read") \ -_ELF_DEFINE_PF(PF_MASKOS, 0x0ff00000, "OS-specific flags") \ -_ELF_DEFINE_PF(PF_MASKPROC, 0xf0000000, "Processor-specific flags") \ -_ELF_DEFINE_PF(PF_ARM_SB, 0x10000000, \ - "segment contains the location addressed by the static base") \ -_ELF_DEFINE_PF(PF_ARM_PI, 0x20000000, \ - "segment is position-independent") \ -_ELF_DEFINE_PF(PF_ARM_ABS, 0x40000000, \ - "segment must be loaded at its base address") - -#undef _ELF_DEFINE_PF -#define _ELF_DEFINE_PF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_PHDR_FLAGS() - PF__LAST__ -}; - -/* - * Types of program header table entries. - */ - -#define _ELF_DEFINE_PHDR_TYPES() \ -_ELF_DEFINE_PT(PT_NULL, 0, "ignored entry") \ -_ELF_DEFINE_PT(PT_LOAD, 1, "loadable segment") \ -_ELF_DEFINE_PT(PT_DYNAMIC, 2, \ - "contains dynamic linking information") \ -_ELF_DEFINE_PT(PT_INTERP, 3, "names an interpreter") \ -_ELF_DEFINE_PT(PT_NOTE, 4, "auxiliary information") \ -_ELF_DEFINE_PT(PT_SHLIB, 5, "reserved") \ -_ELF_DEFINE_PT(PT_PHDR, 6, \ - "describes the program header itself") \ -_ELF_DEFINE_PT(PT_TLS, 7, "thread local storage") \ -_ELF_DEFINE_PT(PT_LOOS, 0x60000000UL, \ - "start of OS-specific range") \ -_ELF_DEFINE_PT(PT_SUNW_UNWIND, 0x6464E550UL, \ - "Solaris/amd64 stack unwind tables") \ -_ELF_DEFINE_PT(PT_GNU_EH_FRAME, 0x6474E550UL, \ - "GCC generated .eh_frame_hdr segment") \ -_ELF_DEFINE_PT(PT_GNU_STACK, 0x6474E551UL, \ - "Stack flags") \ -_ELF_DEFINE_PT(PT_GNU_RELRO, 0x6474E552UL, \ - "Segment becomes read-only after relocation") \ -_ELF_DEFINE_PT(PT_SUNWBSS, 0x6FFFFFFAUL, \ - "A Solaris .SUNW_bss section") \ -_ELF_DEFINE_PT(PT_SUNWSTACK, 0x6FFFFFFBUL, \ - "A Solaris process stack") \ -_ELF_DEFINE_PT(PT_SUNWDTRACE, 0x6FFFFFFCUL, \ - "Used by dtrace(1)") \ -_ELF_DEFINE_PT(PT_SUNWCAP, 0x6FFFFFFDUL, \ - "Special hardware capability requirements") \ -_ELF_DEFINE_PT(PT_HIOS, 0x6FFFFFFFUL, \ - "end of OS-specific range") \ -_ELF_DEFINE_PT(PT_LOPROC, 0x70000000UL, \ - "start of processor-specific range") \ -_ELF_DEFINE_PT(PT_ARM_ARCHEXT, 0x70000000UL, \ - "platform architecture compatibility information") \ -_ELF_DEFINE_PT(PT_ARM_EXIDX, 0x70000001UL, \ - "exception unwind tables") \ -_ELF_DEFINE_PT(PT_MIPS_REGINFO, 0x70000000UL, \ - "register usage information") \ -_ELF_DEFINE_PT(PT_MIPS_RTPROC, 0x70000001UL, \ - "runtime procedure table") \ -_ELF_DEFINE_PT(PT_MIPS_OPTIONS, 0x70000002UL, \ - "options segment") \ -_ELF_DEFINE_PT(PT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific range") - -#undef _ELF_DEFINE_PT -#define _ELF_DEFINE_PT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_PHDR_TYPES() - PT__LAST__ = PT_HIPROC -}; - -/* synonyms. */ -#define PT_ARM_UNWIND PT_ARM_EXIDX -#define PT_HISUNW PT_HIOS -#define PT_LOSUNW PT_SUNWBSS - -/* - * Section flags. - */ - -#define _ELF_DEFINE_SECTION_FLAGS() \ -_ELF_DEFINE_SHF(SHF_WRITE, 0x1, \ - "writable during program execution") \ -_ELF_DEFINE_SHF(SHF_ALLOC, 0x2, \ - "occupies memory during program execution") \ -_ELF_DEFINE_SHF(SHF_EXECINSTR, 0x4, "executable instructions") \ -_ELF_DEFINE_SHF(SHF_MERGE, 0x10, \ - "may be merged to prevent duplication") \ -_ELF_DEFINE_SHF(SHF_STRINGS, 0x20, \ - "NUL-terminated character strings") \ -_ELF_DEFINE_SHF(SHF_INFO_LINK, 0x40, \ - "the sh_info field holds a link") \ -_ELF_DEFINE_SHF(SHF_LINK_ORDER, 0x80, \ - "special ordering requirements during linking") \ -_ELF_DEFINE_SHF(SHF_OS_NONCONFORMING, 0x100, \ - "requires OS-specific processing during linking") \ -_ELF_DEFINE_SHF(SHF_GROUP, 0x200, \ - "member of a section group") \ -_ELF_DEFINE_SHF(SHF_TLS, 0x400, \ - "holds thread-local storage") \ -_ELF_DEFINE_SHF(SHF_MASKOS, 0x0FF00000UL, \ - "bits reserved for OS-specific semantics") \ -_ELF_DEFINE_SHF(SHF_AMD64_LARGE, 0x10000000UL, \ - "section uses large code model") \ -_ELF_DEFINE_SHF(SHF_ENTRYSECT, 0x10000000UL, \ - "section contains an entry point (ARM)") \ -_ELF_DEFINE_SHF(SHF_COMDEF, 0x80000000UL, \ - "section may be multiply defined in input to link step (ARM)") \ -_ELF_DEFINE_SHF(SHF_MIPS_GPREL, 0x10000000UL, \ - "section must be part of global data area") \ -_ELF_DEFINE_SHF(SHF_MIPS_MERGE, 0x20000000UL, \ - "section data should be merged to eliminate duplication") \ -_ELF_DEFINE_SHF(SHF_MIPS_ADDR, 0x40000000UL, \ - "section data is addressed by default") \ -_ELF_DEFINE_SHF(SHF_MIPS_STRING, 0x80000000UL, \ - "section data is string data by default") \ -_ELF_DEFINE_SHF(SHF_MIPS_NOSTRIP, 0x08000000UL, \ - "section data may not be stripped") \ -_ELF_DEFINE_SHF(SHF_MIPS_LOCAL, 0x04000000UL, \ - "section data local to process") \ -_ELF_DEFINE_SHF(SHF_MIPS_NAMES, 0x02000000UL, \ - "linker must generate implicit hidden weak names") \ -_ELF_DEFINE_SHF(SHF_MIPS_NODUPE, 0x01000000UL, \ - "linker must retain only one copy") \ -_ELF_DEFINE_SHF(SHF_ORDERED, 0x40000000UL, \ - "section is ordered with respect to other sections") \ -_ELF_DEFINE_SHF(SHF_EXCLUDE, 0x80000000UL, \ - "section is excluded from executables and shared objects") \ -_ELF_DEFINE_SHF(SHF_MASKPROC, 0xF0000000UL, \ - "bits reserved for processor-specific semantics") - -#undef _ELF_DEFINE_SHF -#define _ELF_DEFINE_SHF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_FLAGS() - SHF__LAST__ -}; - -/* - * Special section indices. - */ -#define _ELF_DEFINE_SECTION_INDICES() \ -_ELF_DEFINE_SHN(SHN_UNDEF, 0, "undefined section") \ -_ELF_DEFINE_SHN(SHN_LORESERVE, 0xFF00U, "start of reserved area") \ -_ELF_DEFINE_SHN(SHN_LOPROC, 0xFF00U, \ - "start of processor-specific range") \ -_ELF_DEFINE_SHN(SHN_BEFORE, 0xFF00U, "used for section ordering") \ -_ELF_DEFINE_SHN(SHN_AFTER, 0xFF01U, "used for section ordering") \ -_ELF_DEFINE_SHN(SHN_AMD64_LCOMMON, 0xFF02U, "large common block label") \ -_ELF_DEFINE_SHN(SHN_MIPS_ACOMMON, 0xFF00U, \ - "allocated common symbols in a DSO") \ -_ELF_DEFINE_SHN(SHN_MIPS_TEXT, 0xFF01U, "Reserved (obsolete)") \ -_ELF_DEFINE_SHN(SHN_MIPS_DATA, 0xFF02U, "Reserved (obsolete)") \ -_ELF_DEFINE_SHN(SHN_MIPS_SCOMMON, 0xFF03U, \ - "gp-addressable common symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_SUNDEFINED, 0xFF04U, \ - "gp-addressable undefined symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_LCOMMON, 0xFF05U, "local common symbols") \ -_ELF_DEFINE_SHN(SHN_MIPS_LUNDEFINED, 0xFF06U, \ - "local undefined symbols") \ -_ELF_DEFINE_SHN(SHN_HIPROC, 0xFF1FU, \ - "end of processor-specific range") \ -_ELF_DEFINE_SHN(SHN_LOOS, 0xFF20U, \ - "start of OS-specific range") \ -_ELF_DEFINE_SHN(SHN_SUNW_IGNORE, 0xFF3FU, "used by dtrace") \ -_ELF_DEFINE_SHN(SHN_HIOS, 0xFF3FU, \ - "end of OS-specific range") \ -_ELF_DEFINE_SHN(SHN_ABS, 0xFFF1U, "absolute references") \ -_ELF_DEFINE_SHN(SHN_COMMON, 0xFFF2U, "references to COMMON areas") \ -_ELF_DEFINE_SHN(SHN_XINDEX, 0xFFFFU, "extended index") \ -_ELF_DEFINE_SHN(SHN_HIRESERVE, 0xFFFFU, "end of reserved area") - -#undef _ELF_DEFINE_SHN -#define _ELF_DEFINE_SHN(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_INDICES() - SHN__LAST__ -}; - -/* - * Section types. - */ - -#define _ELF_DEFINE_SECTION_TYPES() \ -_ELF_DEFINE_SHT(SHT_NULL, 0, "inactive header") \ -_ELF_DEFINE_SHT(SHT_PROGBITS, 1, "program defined information") \ -_ELF_DEFINE_SHT(SHT_SYMTAB, 2, "symbol table") \ -_ELF_DEFINE_SHT(SHT_STRTAB, 3, "string table") \ -_ELF_DEFINE_SHT(SHT_RELA, 4, \ - "relocation entries with addends") \ -_ELF_DEFINE_SHT(SHT_HASH, 5, "symbol hash table") \ -_ELF_DEFINE_SHT(SHT_DYNAMIC, 6, \ - "information for dynamic linking") \ -_ELF_DEFINE_SHT(SHT_NOTE, 7, "additional notes") \ -_ELF_DEFINE_SHT(SHT_NOBITS, 8, "section occupying no space") \ -_ELF_DEFINE_SHT(SHT_REL, 9, \ - "relocation entries without addends") \ -_ELF_DEFINE_SHT(SHT_SHLIB, 10, "reserved") \ -_ELF_DEFINE_SHT(SHT_DYNSYM, 11, "symbol table") \ -_ELF_DEFINE_SHT(SHT_INIT_ARRAY, 14, \ - "pointers to initialization functions") \ -_ELF_DEFINE_SHT(SHT_FINI_ARRAY, 15, \ - "pointers to termination functions") \ -_ELF_DEFINE_SHT(SHT_PREINIT_ARRAY, 16, \ - "pointers to functions called before initialization") \ -_ELF_DEFINE_SHT(SHT_GROUP, 17, "defines a section group") \ -_ELF_DEFINE_SHT(SHT_SYMTAB_SHNDX, 18, \ - "used for extended section numbering") \ -_ELF_DEFINE_SHT(SHT_LOOS, 0x60000000UL, \ - "start of OS-specific range") \ -_ELF_DEFINE_SHT(SHT_SUNW_dof, 0x6FFFFFF4UL, \ - "used by dtrace") \ -_ELF_DEFINE_SHT(SHT_SUNW_cap, 0x6FFFFFF5UL, \ - "capability requirements") \ -_ELF_DEFINE_SHT(SHT_GNU_ATTRIBUTES, 0x6FFFFFF5UL, \ - "object attributes") \ -_ELF_DEFINE_SHT(SHT_SUNW_SIGNATURE, 0x6FFFFFF6UL, \ - "module verification signature") \ -_ELF_DEFINE_SHT(SHT_GNU_HASH, 0x6FFFFFF6UL, \ - "GNU Hash sections") \ -_ELF_DEFINE_SHT(SHT_GNU_LIBLIST, 0x6FFFFFF7UL, \ - "List of libraries to be prelinked") \ -_ELF_DEFINE_SHT(SHT_SUNW_ANNOTATE, 0x6FFFFFF7UL, \ - "special section where unresolved references are allowed") \ -_ELF_DEFINE_SHT(SHT_SUNW_DEBUGSTR, 0x6FFFFFF8UL, \ - "debugging information") \ -_ELF_DEFINE_SHT(SHT_CHECKSUM, 0x6FFFFFF8UL, \ - "checksum for dynamic shared objects") \ -_ELF_DEFINE_SHT(SHT_SUNW_DEBUG, 0x6FFFFFF9UL, \ - "debugging information") \ -_ELF_DEFINE_SHT(SHT_SUNW_move, 0x6FFFFFFAUL, \ - "information to handle partially initialized symbols") \ -_ELF_DEFINE_SHT(SHT_SUNW_COMDAT, 0x6FFFFFFBUL, \ - "section supporting merging of multiple copies of data") \ -_ELF_DEFINE_SHT(SHT_SUNW_syminfo, 0x6FFFFFFCUL, \ - "additional symbol information") \ -_ELF_DEFINE_SHT(SHT_SUNW_verdef, 0x6FFFFFFDUL, \ - "symbol versioning information") \ -_ELF_DEFINE_SHT(SHT_SUNW_verneed, 0x6FFFFFFEUL, \ - "symbol versioning requirements") \ -_ELF_DEFINE_SHT(SHT_SUNW_versym, 0x6FFFFFFFUL, \ - "symbol versioning table") \ -_ELF_DEFINE_SHT(SHT_HIOS, 0x6FFFFFFFUL, \ - "end of OS-specific range") \ -_ELF_DEFINE_SHT(SHT_LOPROC, 0x70000000UL, \ - "start of processor-specific range") \ -_ELF_DEFINE_SHT(SHT_ARM_EXIDX, 0x70000001UL, \ - "exception index table") \ -_ELF_DEFINE_SHT(SHT_ARM_PREEMPTMAP, 0x70000002UL, \ - "BPABI DLL dynamic linking preemption map") \ -_ELF_DEFINE_SHT(SHT_ARM_ATTRIBUTES, 0x70000003UL, \ - "object file compatibility attributes") \ -_ELF_DEFINE_SHT(SHT_ARM_DEBUGOVERLAY, 0x70000004UL, \ - "overlay debug information") \ -_ELF_DEFINE_SHT(SHT_ARM_OVERLAYSECTION, 0x70000005UL, \ - "overlay debug information") \ -_ELF_DEFINE_SHT(SHT_MIPS_LIBLIST, 0x70000000UL, \ - "DSO library information used in link") \ -_ELF_DEFINE_SHT(SHT_MIPS_MSYM, 0x70000001UL, \ - "MIPS symbol table extension") \ -_ELF_DEFINE_SHT(SHT_MIPS_CONFLICT, 0x70000002UL, \ - "symbol conflicting with DSO-defined symbols ") \ -_ELF_DEFINE_SHT(SHT_MIPS_GPTAB, 0x70000003UL, \ - "global pointer table") \ -_ELF_DEFINE_SHT(SHT_MIPS_UCODE, 0x70000004UL, \ - "reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_DEBUG, 0x70000005UL, \ - "reserved (obsolete debug information)") \ -_ELF_DEFINE_SHT(SHT_MIPS_REGINFO, 0x70000006UL, \ - "register usage information") \ -_ELF_DEFINE_SHT(SHT_MIPS_PACKAGE, 0x70000007UL, \ - "OSF reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_PACKSYM, 0x70000008UL, \ - "OSF reserved") \ -_ELF_DEFINE_SHT(SHT_MIPS_RELD, 0x70000009UL, \ - "dynamic relocation") \ -_ELF_DEFINE_SHT(SHT_MIPS_IFACE, 0x7000000BUL, \ - "subprogram interface information") \ -_ELF_DEFINE_SHT(SHT_MIPS_CONTENT, 0x7000000CUL, \ - "section content classification") \ -_ELF_DEFINE_SHT(SHT_MIPS_OPTIONS, 0x7000000DUL, \ - "general options") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTASYM, 0x7000001BUL, \ - "Delta C++: symbol table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTAINST, 0x7000001CUL, \ - "Delta C++: instance table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTACLASS, 0x7000001DUL, \ - "Delta C++: class table") \ -_ELF_DEFINE_SHT(SHT_MIPS_DWARF, 0x7000001EUL, \ - "DWARF debug information") \ -_ELF_DEFINE_SHT(SHT_MIPS_DELTADECL, 0x7000001FUL, \ - "Delta C++: declarations") \ -_ELF_DEFINE_SHT(SHT_MIPS_SYMBOL_LIB, 0x70000020UL, \ - "symbol-to-library mapping") \ -_ELF_DEFINE_SHT(SHT_MIPS_EVENTS, 0x70000021UL, \ - "event locations") \ -_ELF_DEFINE_SHT(SHT_MIPS_TRANSLATE, 0x70000022UL, \ - "???") \ -_ELF_DEFINE_SHT(SHT_MIPS_PIXIE, 0x70000023UL, \ - "special pixie sections") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE, 0x70000024UL, \ - "address translation table") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE_DEBUG, 0x70000025UL, \ - "SGI internal address translation table") \ -_ELF_DEFINE_SHT(SHT_MIPS_WHIRL, 0x70000026UL, \ - "intermediate code") \ -_ELF_DEFINE_SHT(SHT_MIPS_EH_REGION, 0x70000027UL, \ - "C++ exception handling region info") \ -_ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD, 0x70000028UL, \ - "obsolete") \ -_ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, \ - "runtime procedure descriptor table exception information") \ -_ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ - "SPARC-specific data") \ -_ELF_DEFINE_SHT(SHT_AMD64_UNWIND, 0x70000001UL, \ - "unwind tables for the AMD64") \ -_ELF_DEFINE_SHT(SHT_ORDERED, 0x7FFFFFFFUL, \ - "sort entries in the section") \ -_ELF_DEFINE_SHT(SHT_HIPROC, 0x7FFFFFFFUL, \ - "end of processor-specific range") \ -_ELF_DEFINE_SHT(SHT_LOUSER, 0x80000000UL, \ - "start of application-specific range") \ -_ELF_DEFINE_SHT(SHT_HIUSER, 0xFFFFFFFFUL, \ - "end of application-specific range") - -#undef _ELF_DEFINE_SHT -#define _ELF_DEFINE_SHT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SECTION_TYPES() - SHT__LAST__ = SHT_HIUSER -}; - -/* Aliases for section types. */ -#define SHT_GNU_verdef SHT_SUNW_verdef -#define SHT_GNU_verneed SHT_SUNW_verneed -#define SHT_GNU_versym SHT_SUNW_versym - -/* - * Symbol binding information. - */ - -#define _ELF_DEFINE_SYMBOL_BINDING() \ -_ELF_DEFINE_STB(STB_LOCAL, 0, \ - "not visible outside defining object file") \ -_ELF_DEFINE_STB(STB_GLOBAL, 1, \ - "visible across all object files being combined") \ -_ELF_DEFINE_STB(STB_WEAK, 2, \ - "visible across all object files but with low precedence") \ -_ELF_DEFINE_STB(STB_LOOS, 10, "start of OS-specific range") \ -_ELF_DEFINE_STB(STB_HIOS, 12, "end of OS-specific range") \ -_ELF_DEFINE_STB(STB_LOPROC, 13, \ - "start of processor-specific range") \ -_ELF_DEFINE_STB(STB_HIPROC, 15, \ - "end of processor-specific range") - -#undef _ELF_DEFINE_STB -#define _ELF_DEFINE_STB(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_BINDING() - STB__LAST__ -}; - -/* - * Symbol types - */ - -#define _ELF_DEFINE_SYMBOL_TYPES() \ -_ELF_DEFINE_STT(STT_NOTYPE, 0, "unspecified type") \ -_ELF_DEFINE_STT(STT_OBJECT, 1, "data object") \ -_ELF_DEFINE_STT(STT_FUNC, 2, "executable code") \ -_ELF_DEFINE_STT(STT_SECTION, 3, "section") \ -_ELF_DEFINE_STT(STT_FILE, 4, "source file") \ -_ELF_DEFINE_STT(STT_COMMON, 5, "uninitialized common block") \ -_ELF_DEFINE_STT(STT_TLS, 6, "thread local storage") \ -_ELF_DEFINE_STT(STT_LOOS, 10, "start of OS-specific types") \ -_ELF_DEFINE_STT(STT_HIOS, 12, "end of OS-specific types") \ -_ELF_DEFINE_STT(STT_LOPROC, 13, \ - "start of processor-specific types") \ -_ELF_DEFINE_STT(STT_ARM_TFUNC, 13, "Thumb function (GNU)") \ -_ELF_DEFINE_STT(STT_ARM_16BIT, 15, "Thumb label (GNU)") \ -_ELF_DEFINE_STT(STT_HIPROC, 15, \ - "end of processor-specific types") - -#undef _ELF_DEFINE_STT -#define _ELF_DEFINE_STT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_TYPES() - STT__LAST__ -}; - -/* - * Symbol binding. - */ - -#define _ELF_DEFINE_SYMBOL_BINDING_KINDS() \ -_ELF_DEFINE_SYB(SYMINFO_BT_SELF, 0xFFFFU, \ - "bound to self") \ -_ELF_DEFINE_SYB(SYMINFO_BT_PARENT, 0xFFFEU, \ - "bound to parent") \ -_ELF_DEFINE_SYB(SYMINFO_BT_NONE, 0xFFFDU, \ - "no special binding") - -#undef _ELF_DEFINE_SYB -#define _ELF_DEFINE_SYB(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_BINDING_KINDS() - SYMINFO__LAST__ -}; - -/* - * Symbol visibility. - */ - -#define _ELF_DEFINE_SYMBOL_VISIBILITY() \ -_ELF_DEFINE_STV(STV_DEFAULT, 0, \ - "as specified by symbol type") \ -_ELF_DEFINE_STV(STV_INTERNAL, 1, \ - "as defined by processor semantics") \ -_ELF_DEFINE_STV(STV_HIDDEN, 2, \ - "hidden from other components") \ -_ELF_DEFINE_STV(STV_PROTECTED, 3, \ - "local references are not preemptable") - -#undef _ELF_DEFINE_STV -#define _ELF_DEFINE_STV(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_VISIBILITY() - STV__LAST__ -}; - -/* - * Symbol flags. - */ -#define _ELF_DEFINE_SYMBOL_FLAGS() \ -_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECT, 0x01, \ - "directly assocated reference") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_COPY, 0x04, \ - "definition by copy-relocation") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_LAZYLOAD, 0x08, \ - "object should be lazily loaded") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECTBIND, 0x10, \ - "reference should be directly bound") \ -_ELF_DEFINE_SYF(SYMINFO_FLG_NOEXTDIRECT, 0x20, \ - "external references not allowed to bind to definition") - -#undef _ELF_DEFINE_SYF -#define _ELF_DEFINE_SYF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_SYMBOL_FLAGS() - SYMINFO_FLG__LAST__ -}; - -/* - * Version dependencies. - */ -#define _ELF_DEFINE_VERSIONING_DEPENDENCIES() \ -_ELF_DEFINE_VERD(VER_NDX_LOCAL, 0, "local scope") \ -_ELF_DEFINE_VERD(VER_NDX_GLOBAL, 1, "global scope") -#undef _ELF_DEFINE_VERD -#define _ELF_DEFINE_VERD(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_DEPENDENCIES() - VER_NDX__LAST__ -}; - -/* - * Version flags. - */ -#define _ELF_DEFINE_VERSIONING_FLAGS() \ -_ELF_DEFINE_VERF(VER_FLG_BASE, 0x1, "file version") \ -_ELF_DEFINE_VERF(VER_FLG_WEAK, 0x2, "weak version") -#undef _ELF_DEFINE_VERF -#define _ELF_DEFINE_VERF(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_FLAGS() - VER_FLG__LAST__ -}; - -/* - * Version needs - */ -#define _ELF_DEFINE_VERSIONING_NEEDS() \ -_ELF_DEFINE_VRN(VER_NEED_NONE, 0, "invalid version") \ -_ELF_DEFINE_VRN(VER_NEED_CURRENT, 1, "current version") -#undef _ELF_DEFINE_VRN -#define _ELF_DEFINE_VRN(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_NEEDS() - VER_NEED__LAST__ -}; - -/* - * Version numbers. - */ -#define _ELF_DEFINE_VERSIONING_NUMBERS() \ -_ELF_DEFINE_VRNU(VER_DEF_NONE, 0, "invalid version") \ -_ELF_DEFINE_VRNU(VER_DEF_CURRENT, 1, "current version") -#undef _ELF_DEFINE_VRNU -#define _ELF_DEFINE_VRNU(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_VERSIONING_NUMBERS() - VER_DEF__LAST__ -}; - -/** - ** Relocation types. - **/ - -#define _ELF_DEFINE_386_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_386_NONE, 0) \ -_ELF_DEFINE_RELOC(R_386_32, 1) \ -_ELF_DEFINE_RELOC(R_386_PC32, 2) \ -_ELF_DEFINE_RELOC(R_386_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_386_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_386_COPY, 5) \ -_ELF_DEFINE_RELOC(R_386_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_386_JMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_386_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_386_GOTOFF, 9) \ -_ELF_DEFINE_RELOC(R_386_GOTPC, 10) \ -_ELF_DEFINE_RELOC(R_386_32PLT, 11) \ -_ELF_DEFINE_RELOC(R_386_16, 20) \ -_ELF_DEFINE_RELOC(R_386_PC16, 21) \ -_ELF_DEFINE_RELOC(R_386_8, 22) \ -_ELF_DEFINE_RELOC(R_386_PC8, 23) - -/* - * These are the symbols used in the Sun ``Linkers and Loaders - * Guide'', Document No: 817-1984-17. See the X86_64 relocations list - * below for the spellings used in the ELF specification. - */ -#define _ELF_DEFINE_AMD64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_AMD64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_AMD64_64, 1) \ -_ELF_DEFINE_RELOC(R_AMD64_PC32, 2) \ -_ELF_DEFINE_RELOC(R_AMD64_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_AMD64_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_AMD64_COPY, 5) \ -_ELF_DEFINE_RELOC(R_AMD64_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_AMD64_JUMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_AMD64_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTPCREL, 9) \ -_ELF_DEFINE_RELOC(R_AMD64_32, 10) \ -_ELF_DEFINE_RELOC(R_AMD64_32S, 11) \ -_ELF_DEFINE_RELOC(R_AMD64_16, 12) \ -_ELF_DEFINE_RELOC(R_AMD64_PC16, 13) \ -_ELF_DEFINE_RELOC(R_AMD64_8, 14) \ -_ELF_DEFINE_RELOC(R_AMD64_PC8, 15) \ -_ELF_DEFINE_RELOC(R_AMD64_PC64, 24) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTOFF64, 25) \ -_ELF_DEFINE_RELOC(R_AMD64_GOTPC32, 26) - -#define _ELF_DEFINE_ARM_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_ARM_NONE, 0) \ -_ELF_DEFINE_RELOC(R_ARM_PC24, 1) \ -_ELF_DEFINE_RELOC(R_ARM_ABS32, 2) \ -_ELF_DEFINE_RELOC(R_ARM_REL32, 3) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G0, 4) \ -_ELF_DEFINE_RELOC(R_ARM_ABS16, 5) \ -_ELF_DEFINE_RELOC(R_ARM_ABS12, 6) \ -_ELF_DEFINE_RELOC(R_ARM_THM_ABS5, 7) \ -_ELF_DEFINE_RELOC(R_ARM_ABS8, 8) \ -_ELF_DEFINE_RELOC(R_ARM_SBREL32, 9) \ -_ELF_DEFINE_RELOC(R_ARM_THM_CALL, 10) \ -_ELF_DEFINE_RELOC(R_ARM_THM_PC8, 11) \ -_ELF_DEFINE_RELOC(R_ARM_BREL_ADJ, 12) \ -_ELF_DEFINE_RELOC(R_ARM_SWI24, 13) \ -_ELF_DEFINE_RELOC(R_ARM_THM_SWI8, 14) \ -_ELF_DEFINE_RELOC(R_ARM_XPC25, 15) \ -_ELF_DEFINE_RELOC(R_ARM_THM_XPC22, 16) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DTPMOD32, 17) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DTPOFF32, 18) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_TPOFF32, 19) \ -_ELF_DEFINE_RELOC(R_ARM_COPY, 20) \ -_ELF_DEFINE_RELOC(R_ARM_GLOB_DAT, 21) \ -_ELF_DEFINE_RELOC(R_ARM_JUMP_SLOT, 22) \ -_ELF_DEFINE_RELOC(R_ARM_RELATIVE, 23) \ -_ELF_DEFINE_RELOC(R_ARM_GOTOFF32, 24) \ -_ELF_DEFINE_RELOC(R_ARM_BASE_PREL, 25) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_BREL, 26) \ -_ELF_DEFINE_RELOC(R_ARM_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_ARM_CALL, 28) \ -_ELF_DEFINE_RELOC(R_ARM_JUMP24, 29) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP24, 30) \ -_ELF_DEFINE_RELOC(R_ARM_BASE_ABS, 31) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL7_0, 32) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL15_8, 33) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL23_15, 34) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SBREL_11_0, 35) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_19_12, 36) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_27_20, 37) \ -_ELF_DEFINE_RELOC(R_ARM_TARGET1, 38) \ -_ELF_DEFINE_RELOC(R_ARM_SBREL31, 39) \ -_ELF_DEFINE_RELOC(R_ARM_V4BX, 40) \ -_ELF_DEFINE_RELOC(R_ARM_TARGET2, 41) \ -_ELF_DEFINE_RELOC(R_ARM_PREL31, 42) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_ABS_NC, 43) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_ABS, 44) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_PREL_NC, 45) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_PREL, 46) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_ABS_NC, 47) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_ABS, 48) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_PREL_NC, 49) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_PREL, 50) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP19, 51) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP6, 52) \ -_ELF_DEFINE_RELOC(R_ARM_THM_ALU_PREL_11_0, 53) \ -_ELF_DEFINE_RELOC(R_ARM_THM_PC12, 54) \ -_ELF_DEFINE_RELOC(R_ARM_ABS32_NOI, 55) \ -_ELF_DEFINE_RELOC(R_ARM_REL32_NOI, 56) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0_NC, 57) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0, 58) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1_NC, 59) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1, 60) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G2, 61) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G1, 62) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G2, 63) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G0, 64) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G1, 65) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G2, 66) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G0, 67) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G1, 68) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G2, 69) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0_NC, 70) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0, 71) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1_NC, 72) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1, 73) \ -_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G2, 74) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G0, 75) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G1, 76) \ -_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G2, 77) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G0, 78) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G1, 79) \ -_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G2, 80) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G0, 81) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G1, 82) \ -_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G2, 83) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL_NC, 84) \ -_ELF_DEFINE_RELOC(R_ARM_MOVT_BREL, 85) \ -_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL, 86) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL_NC, 87) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_BREL, 88) \ -_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL, 89) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_GOTDESC, 90) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_CALL, 91) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_DESCSEQ, 92) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_CALL, 93) \ -_ELF_DEFINE_RELOC(R_ARM_PLT32_ABS, 94) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_ABS, 95) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_PREL, 96) \ -_ELF_DEFINE_RELOC(R_ARM_GOT_BREL12, 97) \ -_ELF_DEFINE_RELOC(R_ARM_GOTOFF12, 98) \ -_ELF_DEFINE_RELOC(R_ARM_GOTRELAX, 99) \ -_ELF_DEFINE_RELOC(R_ARM_GNU_VTENTRY, 100) \ -_ELF_DEFINE_RELOC(R_ARM_GNU_VTINHERIT, 101) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP11, 102) \ -_ELF_DEFINE_RELOC(R_ARM_THM_JUMP8, 103) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_GD32, 104) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDM32, 105) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDO32, 106) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_IE32, 107) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LE32, 108) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LDO12, 109) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_LE12, 110) \ -_ELF_DEFINE_RELOC(R_ARM_TLS_IE12GP, 111) \ -_ELF_DEFINE_RELOC(R_ARM_ME_TOO, 128) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ16, 129) \ -_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ32, 130) - -#define _ELF_DEFINE_IA64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_IA_64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM14, 0x21) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM22, 0x22) \ -_ELF_DEFINE_RELOC(R_IA_64_IMM64, 0x23) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR32MSB, 0x24) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR32LSB, 0x25) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR64MSB, 0x26) \ -_ELF_DEFINE_RELOC(R_IA_64_DIR64LSB, 0x27) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL22, 0x2a) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64I, 0x2b) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL32MSB, 0x2c) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL32LSB, 0x2d) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64MSB, 0x2e) \ -_ELF_DEFINE_RELOC(R_IA_64_GPREL64LSB, 0x2f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF22, 0x32) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF64I, 0x33) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF22, 0x3a) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64I, 0x3b) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64MSB, 0x3e) \ -_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64LSB, 0x3f) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64I, 0x43) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR32MSB, 0x44) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR32LSB, 0x45) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64MSB, 0x46) \ -_ELF_DEFINE_RELOC(R_IA_64_FPTR64LSB, 0x47) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL60B, 0x48) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21B, 0x49) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21M, 0x4a) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21F, 0x4b) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL32MSB, 0x4c) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL32LSB, 0x4d) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64MSB, 0x4e) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64LSB, 0x4f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR22, 0x52) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64I, 0x53) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32MSB, 0x54) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32LSB, 0x55) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64MSB, 0x56) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64LSB, 0x57) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL32MSB, 0x5c) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL32LSB, 0x5d) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL64MSB, 0x5e) \ -_ELF_DEFINE_RELOC(R_IA_64_SEGREL64LSB, 0x5f) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL32MSB, 0x64) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL32LSB, 0x65) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL64MSB, 0x66) \ -_ELF_DEFINE_RELOC(R_IA_64_SECREL64LSB, 0x67) \ -_ELF_DEFINE_RELOC(R_IA_64_REL32MSB, 0x6c) \ -_ELF_DEFINE_RELOC(R_IA_64_REL32LSB, 0x6d) \ -_ELF_DEFINE_RELOC(R_IA_64_REL64MSB, 0x6e) \ -_ELF_DEFINE_RELOC(R_IA_64_REL64LSB, 0x6f) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV32MSB, 0x74) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV32LSB, 0x75) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV64MSB, 0x76) \ -_ELF_DEFINE_RELOC(R_IA_64_LTV64LSB, 0x77) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21BIa, 0x79) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL22, 0x7A) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL64I, 0x7B) \ -_ELF_DEFINE_RELOC(R_IA_64_IPLTMSB, 0x80) \ -_ELF_DEFINE_RELOC(R_IA_64_IPLTLSB, 0x81) \ -_ELF_DEFINE_RELOC(R_IA_64_SUB, 0x85) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF22X, 0x86) \ -_ELF_DEFINE_RELOC(R_IA_64_LDXMOV, 0x87) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL14, 0x91) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL22, 0x92) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64I, 0x93) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64MSB, 0x96) \ -_ELF_DEFINE_RELOC(R_IA_64_TPREL64LSB, 0x97) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_TPREL22, 0x9A) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64MSB, 0xA6) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64LSB, 0xA7) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPMOD22, 0xAA) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL14, 0xB1) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL22, 0xB2) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64I, 0xB3) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL32MSB, 0xB4) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL32LSB, 0xB5) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64MSB, 0xB6) \ -_ELF_DEFINE_RELOC(R_IA_64_DTPREL64LSB, 0xB7) \ -_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPREL22, 0xBA) - -#define _ELF_DEFINE_MIPS_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_MIPS_NONE, 0) \ -_ELF_DEFINE_RELOC(R_MIPS_16, 1) \ -_ELF_DEFINE_RELOC(R_MIPS_32, 2) \ -_ELF_DEFINE_RELOC(R_MIPS_REL32, 3) \ -_ELF_DEFINE_RELOC(R_MIPS_26, 4) \ -_ELF_DEFINE_RELOC(R_MIPS_HI16, 5) \ -_ELF_DEFINE_RELOC(R_MIPS_LO16, 6) \ -_ELF_DEFINE_RELOC(R_MIPS_GPREL16, 7) \ -_ELF_DEFINE_RELOC(R_MIPS_LITERAL, 8) \ -_ELF_DEFINE_RELOC(R_MIPS_GOT16, 9) \ -_ELF_DEFINE_RELOC(R_MIPS_PC16, 10) \ -_ELF_DEFINE_RELOC(R_MIPS_CALL16, 11) \ -_ELF_DEFINE_RELOC(R_MIPS_GPREL32, 12) \ -_ELF_DEFINE_RELOC(R_MIPS_64, 18) \ -_ELF_DEFINE_RELOC(R_MIPS_GOTHI16, 21) \ -_ELF_DEFINE_RELOC(R_MIPS_GOTLO16, 22) \ -_ELF_DEFINE_RELOC(R_MIPS_CALLHI16, 30) \ -_ELF_DEFINE_RELOC(R_MIPS_CALLLO16, 31) - -#define _ELF_DEFINE_PPC32_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_PPC_NONE, 0) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR32, 1) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR24, 2) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16, 3) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_LO, 4) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_HI, 5) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR16_HA, 6) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14, 7) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRTAKEN, 8) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRNTAKEN, 9) \ -_ELF_DEFINE_RELOC(R_PPC_REL24, 10) \ -_ELF_DEFINE_RELOC(R_PPC_REL14, 11) \ -_ELF_DEFINE_RELOC(R_PPC_REL14_BRTAKEN, 12) \ -_ELF_DEFINE_RELOC(R_PPC_REL14_BRNTAKEN, 13) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16, 14) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_LO, 15) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_HI, 16) \ -_ELF_DEFINE_RELOC(R_PPC_GOT16_HA, 17) \ -_ELF_DEFINE_RELOC(R_PPC_PLTREL24, 18) \ -_ELF_DEFINE_RELOC(R_PPC_COPY, 19) \ -_ELF_DEFINE_RELOC(R_PPC_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_PPC_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_PPC_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_PPC_LOCAL24PC, 23) \ -_ELF_DEFINE_RELOC(R_PPC_UADDR32, 24) \ -_ELF_DEFINE_RELOC(R_PPC_UADDR16, 25) \ -_ELF_DEFINE_RELOC(R_PPC_REL32, 26) \ -_ELF_DEFINE_RELOC(R_PPC_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_PPC_PLTREL32, 28) \ -_ELF_DEFINE_RELOC(R_PPC_PLT16_LO, 29) \ -_ELF_DEFINE_RELOC(R_PPL_PLT16_HI, 30) \ -_ELF_DEFINE_RELOC(R_PPC_PLT16_HA, 31) \ -_ELF_DEFINE_RELOC(R_PPC_SDAREL16, 32) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF, 33) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_LO, 34) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HI, 35) \ -_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HA, 36) \ -_ELF_DEFINE_RELOC(R_PPC_ADDR30, 37) \ -_ELF_DEFINE_RELOC(R_PPC_TLS, 67) \ -_ELF_DEFINE_RELOC(R_PPC_DTPMOD32, 68) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16, 69) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_LO, 70) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_HI, 71) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL16_HA, 72) \ -_ELF_DEFINE_RELOC(R_PPC_TPREL32, 73) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16, 74) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_LO, 75) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HI, 76) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HA, 77) \ -_ELF_DEFINE_RELOC(R_PPC_DTPREL32, 78) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16, 79) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_LO, 80) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HI, 81) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HA, 82) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16, 83) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_LO, 84) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HI, 85) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HA, 86) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16, 87) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_LO, 88) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HI, 89) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HA, 90) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16, 91) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_LO, 92) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HI, 93) \ -_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HA, 94) \ -_ELF_DEFINE_RELOC(R_PPC_TLSGD, 95) \ -_ELF_DEFINE_RELOC(R_PPC_TLSLD, 96) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR32, 101) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16, 102) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_LO, 103) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HI, 104) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HA, 105) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDAI16, 106) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2I16, 107) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2REL, 108) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_SDA21, 109) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_MRKREF, 110) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELSEC16, 111) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_LO, 112) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HI, 113) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HA, 114) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_BIT_FLD, 115) \ -_ELF_DEFINE_RELOC(R_PPC_EMB_RELSDA, 116) \ - -#define _ELF_DEFINE_PPC64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_PPC64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR32, 1) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR24, 2) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16, 3) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO, 4) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HI, 5) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HA, 6) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14, 7) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRTAKEN, 8) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRNTAKEN, 9) \ -_ELF_DEFINE_RELOC(R_PPC64_REL24, 10) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14, 11) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14_BRTAKEN, 12) \ -_ELF_DEFINE_RELOC(R_PPC64_REL14_BRNTAKEN, 13) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16, 14) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO, 15) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_HI, 16) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_HA, 17) \ -_ELF_DEFINE_RELOC(R_PPC64_COPY, 19) \ -_ELF_DEFINE_RELOC(R_PPC64_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_PPC64_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_PPC64_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR32, 24) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR16, 25) \ -_ELF_DEFINE_RELOC(R_PPC64_REL32, 26) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT32, 27) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTREL32, 28) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO, 29) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_HI, 30) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_HA, 31) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF, 33) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO, 34) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HI, 35) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HA, 36) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR30, 37) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR64, 38) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHER, 39) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHERA, 40) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHEST, 41) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHESTA, 42) \ -_ELF_DEFINE_RELOC(R_PPC64_UADDR64, 43) \ -_ELF_DEFINE_RELOC(R_PPC64_REL64, 44) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT64, 45) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTREL64, 46) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16, 47) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO, 48) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_HI, 49) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_HA, 50) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC, 51) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16, 52) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO, 53) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HI, 54) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HA, 55) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_DS, 56) \ -_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO_DS, 57) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_DS, 58) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO_DS, 59) \ -_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO_DS, 60) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_DS, 61) \ -_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO_DS, 62) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_DS, 63) \ -_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO_DS, 64) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_DS, 65) \ -_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO_DS, 66) \ -_ELF_DEFINE_RELOC(R_PPC64_TLS, 67) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPMOD64, 68) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16, 69) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO, 60) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HI, 71) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HA, 72) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL64, 73) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16, 74) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO, 75) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HI, 76) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HA, 77) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL64, 78) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16, 79) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_LO, 80) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HI, 81) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HA, 82) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16, 83) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_LO, 84) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HI, 85) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HA, 86) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_DS, 87) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_LO_DS, 88) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HI, 89) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HA, 90) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_DS, 91) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_LO_DS, 92) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HI, 93) \ -_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HA, 94) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_DS, 95) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO_DS, 96) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHER, 97) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHERA, 98) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHEST, 99) \ -_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHESTA, 100) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_DS, 101) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO_DS, 102) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHER, 103) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHERA, 104) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHEST, 105) \ -_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) \ -_ELF_DEFINE_RELOC(R_PPC64_TLSGD, 107) \ -_ELF_DEFINE_RELOC(R_PPC64_TLSLD, 108) - -#define _ELF_DEFINE_SPARC_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_SPARC_NONE, 0) \ -_ELF_DEFINE_RELOC(R_SPARC_8, 1) \ -_ELF_DEFINE_RELOC(R_SPARC_16, 2) \ -_ELF_DEFINE_RELOC(R_SPARC_32, 3) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP8, 4) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP16, 5) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP32, 6) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP30, 7) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP22, 8) \ -_ELF_DEFINE_RELOC(R_SPARC_HI22, 9) \ -_ELF_DEFINE_RELOC(R_SPARC_22, 10) \ -_ELF_DEFINE_RELOC(R_SPARC_13, 11) \ -_ELF_DEFINE_RELOC(R_SPARC_LO10, 12) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT10, 13) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT13, 14) \ -_ELF_DEFINE_RELOC(R_SPARC_GOT22, 15) \ -_ELF_DEFINE_RELOC(R_SPARC_PC10, 16) \ -_ELF_DEFINE_RELOC(R_SPARC_PC22, 17) \ -_ELF_DEFINE_RELOC(R_SPARC_WPLT30, 18) \ -_ELF_DEFINE_RELOC(R_SPARC_COPY, 19) \ -_ELF_DEFINE_RELOC(R_SPARC_GLOB_DAT, 20) \ -_ELF_DEFINE_RELOC(R_SPARC_JMP_SLOT, 21) \ -_ELF_DEFINE_RELOC(R_SPARC_RELATIVE, 22) \ -_ELF_DEFINE_RELOC(R_SPARC_UA32, 23) \ -_ELF_DEFINE_RELOC(R_SPARC_PLT32, 24) \ -_ELF_DEFINE_RELOC(R_SPARC_HIPLT22, 25) \ -_ELF_DEFINE_RELOC(R_SPARC_LOPLT10, 26) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT32, 27) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT22, 28) \ -_ELF_DEFINE_RELOC(R_SPARC_PCPLT10, 29) \ -_ELF_DEFINE_RELOC(R_SPARC_10, 30) \ -_ELF_DEFINE_RELOC(R_SPARC_11, 31) \ -_ELF_DEFINE_RELOC(R_SPARC_64, 32) \ -_ELF_DEFINE_RELOC(R_SPARC_OLO10, 33) \ -_ELF_DEFINE_RELOC(R_SPARC_HH22, 34) \ -_ELF_DEFINE_RELOC(R_SPARC_HM10, 35) \ -_ELF_DEFINE_RELOC(R_SPARC_LM22, 36) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_HH22, 37) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_HM10, 38) \ -_ELF_DEFINE_RELOC(R_SPARC_PC_LM22, 39) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP16, 40) \ -_ELF_DEFINE_RELOC(R_SPARC_WDISP19, 41) \ -_ELF_DEFINE_RELOC(R_SPARC_7, 43) \ -_ELF_DEFINE_RELOC(R_SPARC_5, 44) \ -_ELF_DEFINE_RELOC(R_SPARC_6, 45) \ -_ELF_DEFINE_RELOC(R_SPARC_DISP64, 46) \ -_ELF_DEFINE_RELOC(R_SPARC_PLT64, 47) \ -_ELF_DEFINE_RELOC(R_SPARC_HIX22, 48) \ -_ELF_DEFINE_RELOC(R_SPARC_LOX10, 49) \ -_ELF_DEFINE_RELOC(R_SPARC_H44, 50) \ -_ELF_DEFINE_RELOC(R_SPARC_M44, 51) \ -_ELF_DEFINE_RELOC(R_SPARC_L44, 52) \ -_ELF_DEFINE_RELOC(R_SPARC_REGISTER, 53) \ -_ELF_DEFINE_RELOC(R_SPARC_UA64, 54) \ -_ELF_DEFINE_RELOC(R_SPARC_UA16, 55) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_HIX22, 80) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_LOX10, 81) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83) \ -_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP, 84) \ -_ELF_DEFINE_RELOC(R_SPARC_H34, 85) - -#define _ELF_DEFINE_X86_64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_X86_64_NONE, 0) \ -_ELF_DEFINE_RELOC(R_X86_64_64, 1) \ -_ELF_DEFINE_RELOC(R_X86_64_PC32, 2) \ -_ELF_DEFINE_RELOC(R_X86_64_GOT32, 3) \ -_ELF_DEFINE_RELOC(R_X86_64_PLT32, 4) \ -_ELF_DEFINE_RELOC(R_X86_64_COPY, 5) \ -_ELF_DEFINE_RELOC(R_X86_64_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_X86_64_JUMP_SLOT, 7) \ -_ELF_DEFINE_RELOC(R_X86_64_RELATIVE, 8) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPCREL, 9) \ -_ELF_DEFINE_RELOC(R_X86_64_32, 10) \ -_ELF_DEFINE_RELOC(R_X86_64_32S, 11) \ -_ELF_DEFINE_RELOC(R_X86_64_16, 12) \ -_ELF_DEFINE_RELOC(R_X86_64_PC16, 13) \ -_ELF_DEFINE_RELOC(R_X86_64_8, 14) \ -_ELF_DEFINE_RELOC(R_X86_64_PC8, 15) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPMOD64, 16) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPOFF64, 17) \ -_ELF_DEFINE_RELOC(R_X86_64_TPOFF64, 18) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSGD, 19) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSLD, 20) \ -_ELF_DEFINE_RELOC(R_X86_64_DTPOFF32, 21) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTTPOFF, 22) \ -_ELF_DEFINE_RELOC(R_X86_64_TPOFF32, 23) \ -_ELF_DEFINE_RELOC(R_X86_64_PC64, 24) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTOFF64, 25) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPC32, 26) \ -_ELF_DEFINE_RELOC(R_X86_64_SIZE32, 32) \ -_ELF_DEFINE_RELOC(R_X86_64_SIZE64, 33) \ -_ELF_DEFINE_RELOC(R_X86_64_GOTPC32_TLSDESC, 34) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSDESC_CALL, 35) \ -_ELF_DEFINE_RELOC(R_X86_64_TLSDESC, 36) - -#define _ELF_DEFINE_RELOCATIONS() \ -_ELF_DEFINE_386_RELOCATIONS() \ -_ELF_DEFINE_AMD64_RELOCATIONS() \ -_ELF_DEFINE_IA64_RELOCATIONS() \ -_ELF_DEFINE_MIPS_RELOCATIONS() \ -_ELF_DEFINE_PPC32_RELOCATIONS() \ -_ELF_DEFINE_PPC64_RELOCATIONS() \ -_ELF_DEFINE_SPARC_RELOCATIONS() \ -_ELF_DEFINE_X86_64_RELOCATIONS() - -#undef _ELF_DEFINE_RELOC -#define _ELF_DEFINE_RELOC(N, V) N = V , -enum { - _ELF_DEFINE_RELOCATIONS() - R__LAST__ -}; - -#define PN_XNUM 0xFFFFU /* Use extended section numbering. */ - -/** - ** ELF Types. - **/ - -typedef uint32_t Elf32_Addr; /* Program address. */ -typedef uint8_t Elf32_Byte; /* Unsigned tiny integer. */ -typedef uint16_t Elf32_Half; /* Unsigned medium integer. */ -typedef uint32_t Elf32_Off; /* File offset. */ -typedef uint16_t Elf32_Section; /* Section index. */ -typedef int32_t Elf32_Sword; /* Signed integer. */ -typedef uint32_t Elf32_Word; /* Unsigned integer. */ -typedef uint64_t Elf32_Lword; /* Unsigned long integer. */ - -typedef uint64_t Elf64_Addr; /* Program address. */ -typedef uint8_t Elf64_Byte; /* Unsigned tiny integer. */ -typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ -typedef uint64_t Elf64_Off; /* File offset. */ -typedef uint16_t Elf64_Section; /* Section index. */ -typedef int32_t Elf64_Sword; /* Signed integer. */ -typedef uint32_t Elf64_Word; /* Unsigned integer. */ -typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ -typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ -typedef int64_t Elf64_Sxword; /* Signed long integer. */ - - -/* - * Capability descriptors. - */ - -/* 32-bit capability descriptor. */ -typedef struct { - Elf32_Word c_tag; /* Type of entry. */ - union { - Elf32_Word c_val; /* Integer value. */ - Elf32_Addr c_ptr; /* Pointer value. */ - } c_un; -} Elf32_Cap; - -/* 64-bit capability descriptor. */ -typedef struct { - Elf64_Xword c_tag; /* Type of entry. */ - union { - Elf64_Xword c_val; /* Integer value. */ - Elf64_Addr c_ptr; /* Pointer value. */ - } c_un; -} Elf64_Cap; - -/* - * MIPS .conflict section entries. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Addr c_index; -} Elf32_Conflict; - -/* 64-bit entry. */ -typedef struct { - Elf64_Addr c_index; -} Elf64_Conflict; - -/* - * Dynamic section entries. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Sword d_tag; /* Type of entry. */ - union { - Elf32_Word d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Pointer value. */ - } d_un; -} Elf32_Dyn; - -/* 64-bit entry. */ -typedef struct { - Elf64_Sxword d_tag; /* Type of entry. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Pointer value; */ - } d_un; -} Elf64_Dyn; - - -/* - * The executable header (EHDR). - */ - -/* 32 bit EHDR. */ -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ - Elf32_Half e_type; /* Object file type (ET_*). */ - Elf32_Half e_machine; /* Machine type (EM_*). */ - Elf32_Word e_version; /* File format version (EV_*). */ - Elf32_Addr e_entry; /* Start address. */ - Elf32_Off e_phoff; /* File offset to the PHDR table. */ - Elf32_Off e_shoff; /* File offset to the SHDRheader. */ - Elf32_Word e_flags; /* Flags (EF_*). */ - Elf32_Half e_ehsize; /* Elf header size in bytes. */ - Elf32_Half e_phentsize; /* PHDR table entry size in bytes. */ - Elf32_Half e_phnum; /* Number of PHDR entries. */ - Elf32_Half e_shentsize; /* SHDR table entry size in bytes. */ - Elf32_Half e_shnum; /* Number of SHDR entries. */ - Elf32_Half e_shstrndx; /* Index of section name string table. */ -} Elf32_Ehdr; - - -/* 64 bit EHDR. */ -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ - Elf64_Half e_type; /* Object file type (ET_*). */ - Elf64_Half e_machine; /* Machine type (EM_*). */ - Elf64_Word e_version; /* File format version (EV_*). */ - Elf64_Addr e_entry; /* Start address. */ - Elf64_Off e_phoff; /* File offset to the PHDR table. */ - Elf64_Off e_shoff; /* File offset to the SHDRheader. */ - Elf64_Word e_flags; /* Flags (EF_*). */ - Elf64_Half e_ehsize; /* Elf header size in bytes. */ - Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ - Elf64_Half e_phnum; /* Number of PHDR entries. */ - Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ - Elf64_Half e_shnum; /* Number of SHDR entries. */ - Elf64_Half e_shstrndx; /* Index of section name string table. */ -} Elf64_Ehdr; - - -/* - * Shared object information. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Word l_name; /* The name of a shared object. */ - Elf32_Word l_time_stamp; /* 32-bit timestamp. */ - Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ - Elf32_Word l_version; /* Interface version string index. */ - Elf32_Word l_flags; /* Flags (LL_*). */ -} Elf32_Lib; - -/* 64-bit entry. */ -typedef struct { - Elf64_Word l_name; - Elf64_Word l_time_stamp; - Elf64_Word l_checksum; - Elf64_Word l_version; - Elf64_Word l_flags; -} Elf64_Lib; - -#define _ELF_DEFINE_LL_FLAGS() \ -_ELF_DEFINE_LL(LL_NONE, 0, \ - "no flags") \ -_ELF_DEFINE_LL(LL_EXACT_MATCH, 0x1, \ - "require an exact match") \ -_ELF_DEFINE_LL(LL_IGNORE_INT_VER, 0x2, \ - "ignore version incompatibilities") \ -_ELF_DEFINE_LL(LL_REQUIRE_MINOR, 0x4, \ - "") \ -_ELF_DEFINE_LL(LL_EXPORTS, 0x8, \ - "") \ -_ELF_DEFINE_LL(LL_DELAY_LOAD, 0x10, \ - "") \ -_ELF_DEFINE_LL(LL_DELTA, 0x20, \ - "") - -#undef _ELF_DEFINE_LL -#define _ELF_DEFINE_LL(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_LL_FLAGS() - LL__LAST__ -}; - -/* - * Note tags - */ - -#define _ELF_DEFINE_NOTE_ENTRY_TYPES() \ -_ELF_DEFINE_NT(NT_ABI_TAG, 1, "Tag indicating the ABI") \ -_ELF_DEFINE_NT(NT_GNU_HWCAP, 2, "Hardware capabilities") \ -_ELF_DEFINE_NT(NT_GNU_BUILD_ID, 3, "Build id, set by ld(1)") \ -_ELF_DEFINE_NT(NT_GNU_GOLD_VERSION, 4, \ - "Version number of the GNU gold linker") \ -_ELF_DEFINE_NT(NT_PRSTATUS, 1, "Process status") \ -_ELF_DEFINE_NT(NT_FPREGSET, 2, "Floating point information") \ -_ELF_DEFINE_NT(NT_PRPSINFO, 3, "Process information") \ -_ELF_DEFINE_NT(NT_AUXV, 6, "Auxiliary vector") \ -_ELF_DEFINE_NT(NT_PRXFPREG, 0x46E62B7FUL, \ - "Linux user_xfpregs structure") \ -_ELF_DEFINE_NT(NT_PSTATUS, 10, "Linux process status") \ -_ELF_DEFINE_NT(NT_FPREGS, 12, "Linux floating point regset") \ -_ELF_DEFINE_NT(NT_PSINFO, 13, "Linux process information") \ -_ELF_DEFINE_NT(NT_LWPSTATUS, 16, "Linux lwpstatus_t type") \ -_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type") - -#undef _ELF_DEFINE_NT -#define _ELF_DEFINE_NT(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_NOTE_ENTRY_TYPES() - NT__LAST__ -}; - -/* Aliases for the ABI tag. */ -#define NT_FREEBSD_ABI_TAG NT_ABI_TAG -#define NT_GNU_ABI_TAG NT_ABI_TAG -#define NT_NETBSD_IDENT NT_ABI_TAG -#define NT_OPENBSD_IDENT NT_ABI_TAG - -/* - * Note descriptors. - */ - -typedef struct { - uint32_t n_namesz; /* Length of note's name. */ - uint32_t n_descsz; /* Length of note's value. */ - uint32_t n_type; /* Type of note. */ -} Elf_Note; - -typedef Elf_Note Elf32_Nhdr; /* 32-bit note header. */ -typedef Elf_Note Elf64_Nhdr; /* 64-bit note header. */ - -/* - * MIPS ELF options descriptor header. - */ - -typedef struct { - Elf64_Byte kind; /* Type of options. */ - Elf64_Byte size; /* Size of option descriptor. */ - Elf64_Half section; /* Index of section affected. */ - Elf64_Word info; /* Kind-specific information. */ -} Elf_Options; - -/* - * Option kinds. - */ - -#define _ELF_DEFINE_OPTION_KINDS() \ -_ELF_DEFINE_ODK(ODK_NULL, 0, "undefined") \ -_ELF_DEFINE_ODK(ODK_REGINFO, 1, "register usage info") \ -_ELF_DEFINE_ODK(ODK_EXCEPTIONS, 2, "exception processing info") \ -_ELF_DEFINE_ODK(ODK_PAD, 3, "section padding") \ -_ELF_DEFINE_ODK(ODK_HWPATCH, 4, "hardware patch applied") \ -_ELF_DEFINE_ODK(ODK_FILL, 5, "fill value used by linker") \ -_ELF_DEFINE_ODK(ODK_TAGS, 6, "reserved space for tools") \ -_ELF_DEFINE_ODK(ODK_HWAND, 7, "hardware AND patch applied") \ -_ELF_DEFINE_ODK(ODK_HWOR, 8, "hardware OR patch applied") \ -_ELF_DEFINE_ODK(ODK_GP_GROUP, 9, \ - "GP group to use for text/data sections") \ -_ELF_DEFINE_ODK(ODK_IDENT, 10, "ID information") \ -_ELF_DEFINE_ODK(ODK_PAGESIZE, 11, "page size infomation") - -#undef _ELF_DEFINE_ODK -#define _ELF_DEFINE_ODK(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_OPTION_KINDS() - ODK__LAST__ -}; - -/* - * ODK_EXCEPTIONS info field masks. - */ - -#define _ELF_DEFINE_ODK_EXCEPTIONS_MASK() \ -_ELF_DEFINE_OEX(OEX_FPU_MIN, 0x0000001FUL, \ - "minimum FPU exception which must be enabled") \ -_ELF_DEFINE_OEX(OEX_FPU_MAX, 0x00001F00UL, \ - "maximum FPU exception which can be enabled") \ -_ELF_DEFINE_OEX(OEX_PAGE0, 0x00010000UL, \ - "page zero must be mapped") \ -_ELF_DEFINE_OEX(OEX_SMM, 0x00020000UL, \ - "run in sequential memory mode") \ -_ELF_DEFINE_OEX(OEX_PRECISEFP, 0x00040000UL, \ - "run in precise FP exception mode") \ -_ELF_DEFINE_OEX(OEX_DISMISS, 0x00080000UL, \ - "dismiss invalid address traps") - -#undef _ELF_DEFINE_OEX -#define _ELF_DEFINE_OEX(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_EXCEPTIONS_MASK() - OEX__LAST__ -}; - -/* - * ODK_PAD info field masks. - */ - -#define _ELF_DEFINE_ODK_PAD_MASK() \ -_ELF_DEFINE_OPAD(OPAD_PREFIX, 0x0001) \ -_ELF_DEFINE_OPAD(OPAD_POSTFIX, 0x0002) \ -_ELF_DEFINE_OPAD(OPAD_SYMBOL, 0x0004) - -#undef _ELF_DEFINE_OPAD -#define _ELF_DEFINE_OPAD(N, V) N = V , -enum { - _ELF_DEFINE_ODK_PAD_MASK() - OPAD__LAST__ -}; - -/* - * ODK_HWPATCH info field masks. - */ - -#define _ELF_DEFINE_ODK_HWPATCH_MASK() \ -_ELF_DEFINE_OHW(OHW_R4KEOP, 0x00000001UL, \ - "patch for R4000 branch at end-of-page bug") \ -_ELF_DEFINE_OHW(OHW_R8KPFETCH, 0x00000002UL, \ - "R8000 prefetch bug may occur") \ -_ELF_DEFINE_OHW(OHW_R5KEOP, 0x00000004UL, \ - "patch for R5000 branch at end-of-page bug") \ -_ELF_DEFINE_OHW(OHW_R5KCVTL, 0x00000008UL, \ - "R5000 cvt.[ds].l bug: clean == 1") \ -_ELF_DEFINE_OHW(OHW_R10KLDL, 0x00000010UL, \ - "needd patch for R10000 misaligned load") - -#undef _ELF_DEFINE_OHW -#define _ELF_DEFINE_OHW(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_HWPATCH_MASK() - OHW__LAST__ -}; - -/* - * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks. - */ - -#define _ELF_DEFINE_ODK_HWP_MASK() \ -_ELF_DEFINE_HWP(OHWA0_R4KEOP_CHECKED, 0x00000001UL, \ - "object checked for R4000 end-of-page bug") \ -_ELF_DEFINE_HWP(OHWA0_R4KEOP_CLEAN, 0x00000002UL, \ - "object verified clean for R4000 end-of-page bug") \ -_ELF_DEFINE_HWP(OHWO0_FIXADE, 0x00000001UL, \ - "object requires call to fixade") - -#undef _ELF_DEFINE_HWP -#define _ELF_DEFINE_HWP(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_HWP_MASK() - OHWX0__LAST__ -}; - -/* - * ODK_IDENT/ODK_GP_GROUP info field masks. - */ - -#define _ELF_DEFINE_ODK_GP_MASK() \ -_ELF_DEFINE_OGP(OGP_GROUP, 0x0000FFFFUL, "GP group number") \ -_ELF_DEFINE_OGP(OGP_SELF, 0x00010000UL, \ - "GP group is self-contained") - -#undef _ELF_DEFINE_OGP -#define _ELF_DEFINE_OGP(N, V, DESCR) N = V , -enum { - _ELF_DEFINE_ODK_GP_MASK() - OGP__LAST__ -}; - -/* - * MIPS ELF register info descriptor. - */ - -/* 32 bit RegInfo entry. */ -typedef struct { - Elf32_Word ri_gprmask; /* Mask of general register used. */ - Elf32_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ - Elf32_Addr ri_gp_value; /* GP register value. */ -} Elf32_RegInfo; - -/* 64 bit RegInfo entry. */ -typedef struct { - Elf64_Word ri_gprmask; /* Mask of general register used. */ - Elf64_Word ri_pad; /* Padding. */ - Elf64_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ - Elf64_Addr ri_gp_value; /* GP register value. */ -} Elf64_RegInfo; - -/* - * Program Header Table (PHDR) entries. - */ - -/* 32 bit PHDR entry. */ -typedef struct { - Elf32_Word p_type; /* Type of segment. */ - Elf32_Off p_offset; /* File offset to segment. */ - Elf32_Addr p_vaddr; /* Virtual address in memory. */ - Elf32_Addr p_paddr; /* Physical address (if relevant). */ - Elf32_Word p_filesz; /* Size of segment in file. */ - Elf32_Word p_memsz; /* Size of segment in memory. */ - Elf32_Word p_flags; /* Segment flags. */ - Elf32_Word p_align; /* Alignment constraints. */ -} Elf32_Phdr; - -/* 64 bit PHDR entry. */ -typedef struct { - Elf64_Word p_type; /* Type of segment. */ - Elf64_Word p_flags; /* File offset to segment. */ - Elf64_Off p_offset; /* Virtual address in memory. */ - Elf64_Addr p_vaddr; /* Physical address (if relevant). */ - Elf64_Addr p_paddr; /* Size of segment in file. */ - Elf64_Xword p_filesz; /* Size of segment in memory. */ - Elf64_Xword p_memsz; /* Segment flags. */ - Elf64_Xword p_align; /* Alignment constraints. */ -} Elf64_Phdr; - - -/* - * Move entries, for describing data in COMMON blocks in a compact - * manner. - */ - -/* 32-bit move entry. */ -typedef struct { - Elf32_Lword m_value; /* Initialization value. */ - Elf32_Word m_info; /* Encoded size and index. */ - Elf32_Word m_poffset; /* Offset relative to symbol. */ - Elf32_Half m_repeat; /* Repeat count. */ - Elf32_Half m_stride; /* Number of units to skip. */ -} Elf32_Move; - -/* 64-bit move entry. */ -typedef struct { - Elf64_Lword m_value; /* Initialization value. */ - Elf64_Xword m_info; /* Encoded size and index. */ - Elf64_Xword m_poffset; /* Offset relative to symbol. */ - Elf64_Half m_repeat; /* Repeat count. */ - Elf64_Half m_stride; /* Number of units to skip. */ -} Elf64_Move; - -#define ELF32_M_SYM(I) ((I) >> 8) -#define ELF32_M_SIZE(I) ((unsigned char) (I)) -#define ELF32_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) - -#define ELF64_M_SYM(I) ((I) >> 8) -#define ELF64_M_SIZE(I) ((unsigned char) (I)) -#define ELF64_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) - -/* - * Section Header Table (SHDR) entries. - */ - -/* 32 bit SHDR */ -typedef struct { - Elf32_Word sh_name; /* index of section name */ - Elf32_Word sh_type; /* section type */ - Elf32_Word sh_flags; /* section flags */ - Elf32_Addr sh_addr; /* in-memory address of section */ - Elf32_Off sh_offset; /* file offset of section */ - Elf32_Word sh_size; /* section size in bytes */ - Elf32_Word sh_link; /* section header table link */ - Elf32_Word sh_info; /* extra information */ - Elf32_Word sh_addralign; /* alignment constraint */ - Elf32_Word sh_entsize; /* size for fixed-size entries */ -} Elf32_Shdr; - -/* 64 bit SHDR */ -typedef struct { - Elf64_Word sh_name; /* index of section name */ - Elf64_Word sh_type; /* section type */ - Elf64_Xword sh_flags; /* section flags */ - Elf64_Addr sh_addr; /* in-memory address of section */ - Elf64_Off sh_offset; /* file offset of section */ - Elf64_Xword sh_size; /* section size in bytes */ - Elf64_Word sh_link; /* section header table link */ - Elf64_Word sh_info; /* extra information */ - Elf64_Xword sh_addralign; /* alignment constraint */ - Elf64_Xword sh_entsize; /* size for fixed-size entries */ -} Elf64_Shdr; - - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* index of symbol's name */ - Elf32_Addr st_value; /* value for the symbol */ - Elf32_Word st_size; /* size of associated data */ - unsigned char st_info; /* type and binding attributes */ - unsigned char st_other; /* visibility */ - Elf32_Half st_shndx; /* index of related section */ -} Elf32_Sym; - -typedef struct { - Elf64_Word st_name; /* index of symbol's name */ - unsigned char st_info; /* value for the symbol */ - unsigned char st_other; /* size of associated data */ - Elf64_Half st_shndx; /* type and binding attributes */ - Elf64_Addr st_value; /* visibility */ - Elf64_Xword st_size; /* index of related section */ -} Elf64_Sym; - -#define ELF32_ST_BIND(I) ((I) >> 4) -#define ELF32_ST_TYPE(I) ((I) & 0xFU) -#define ELF32_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) - -#define ELF64_ST_BIND(I) ((I) >> 4) -#define ELF64_ST_TYPE(I) ((I) & 0xFU) -#define ELF64_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) - -#define ELF32_ST_VISIBILITY(O) ((O) & 0x3) -#define ELF64_ST_VISIBILITY(O) ((O) & 0x3) - -/* - * Syminfo descriptors, containing additional symbol information. - */ - -/* 32-bit entry. */ -typedef struct { - Elf32_Half si_boundto; /* Entry index with additional flags. */ - Elf32_Half si_flags; /* Flags. */ -} Elf32_Syminfo; - -/* 64-bit entry. */ -typedef struct { - Elf64_Half si_boundto; /* Entry index with additional flags. */ - Elf64_Half si_flags; /* Flags. */ -} Elf64_Syminfo; - -/* - * Relocation descriptors. - */ - -typedef struct { - Elf32_Addr r_offset; /* location to apply relocation to */ - Elf32_Word r_info; /* type+section for relocation */ -} Elf32_Rel; - -typedef struct { - Elf32_Addr r_offset; /* location to apply relocation to */ - Elf32_Word r_info; /* type+section for relocation */ - Elf32_Sword r_addend; /* constant addend */ -} Elf32_Rela; - -typedef struct { - Elf64_Addr r_offset; /* location to apply relocation to */ - Elf64_Xword r_info; /* type+section for relocation */ -} Elf64_Rel; - -typedef struct { - Elf64_Addr r_offset; /* location to apply relocation to */ - Elf64_Xword r_info; /* type+section for relocation */ - Elf64_Sxword r_addend; /* constant addend */ -} Elf64_Rela; - - -#define ELF32_R_SYM(I) ((I) >> 8) -#define ELF32_R_TYPE(I) ((unsigned char) (I)) -#define ELF32_R_INFO(S,T) (((S) << 8) + (unsigned char) (T)) - -#define ELF64_R_SYM(I) ((I) >> 32) -#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL) -#define ELF64_R_INFO(S,T) (((S) << 32) + ((T) & 0xFFFFFFFFUL)) - -/* - * Symbol versioning structures. - */ - -/* 32-bit structures. */ -typedef struct -{ - Elf32_Word vda_name; /* Index to name. */ - Elf32_Word vda_next; /* Offset to next entry. */ -} Elf32_Verdaux; - -typedef struct -{ - Elf32_Word vna_hash; /* Hash value of dependency name. */ - Elf32_Half vna_flags; /* Flags. */ - Elf32_Half vna_other; /* Unused. */ - Elf32_Word vna_name; /* Offset to dependency name. */ - Elf32_Word vna_next; /* Offset to next vernaux entry. */ -} Elf32_Vernaux; - -typedef struct -{ - Elf32_Half vd_version; /* Version information. */ - Elf32_Half vd_flags; /* Flags. */ - Elf32_Half vd_ndx; /* Index into the versym section. */ - Elf32_Half vd_cnt; /* Number of aux entries. */ - Elf32_Word vd_hash; /* Hash value of name. */ - Elf32_Word vd_aux; /* Offset to aux entries. */ - Elf32_Word vd_next; /* Offset to next version definition. */ -} Elf32_Verdef; - -typedef struct -{ - Elf32_Half vn_version; /* Version number. */ - Elf32_Half vn_cnt; /* Number of aux entries. */ - Elf32_Word vn_file; /* Offset of associated file name. */ - Elf32_Word vn_aux; /* Offset of vernaux array. */ - Elf32_Word vn_next; /* Offset of next verneed entry. */ -} Elf32_Verneed; - -typedef Elf32_Half Elf32_Versym; - -/* 64-bit structures. */ - -typedef struct { - Elf64_Word vda_name; /* Index to name. */ - Elf64_Word vda_next; /* Offset to next entry. */ -} Elf64_Verdaux; - -typedef struct { - Elf64_Word vna_hash; /* Hash value of dependency name. */ - Elf64_Half vna_flags; /* Flags. */ - Elf64_Half vna_other; /* Unused. */ - Elf64_Word vna_name; /* Offset to dependency name. */ - Elf64_Word vna_next; /* Offset to next vernaux entry. */ -} Elf64_Vernaux; - -typedef struct { - Elf64_Half vd_version; /* Version information. */ - Elf64_Half vd_flags; /* Flags. */ - Elf64_Half vd_ndx; /* Index into the versym section. */ - Elf64_Half vd_cnt; /* Number of aux entries. */ - Elf64_Word vd_hash; /* Hash value of name. */ - Elf64_Word vd_aux; /* Offset to aux entries. */ - Elf64_Word vd_next; /* Offset to next version definition. */ -} Elf64_Verdef; - -typedef struct { - Elf64_Half vn_version; /* Version number. */ - Elf64_Half vn_cnt; /* Number of aux entries. */ - Elf64_Word vn_file; /* Offset of associated file name. */ - Elf64_Word vn_aux; /* Offset of vernaux array. */ - Elf64_Word vn_next; /* Offset of next verneed entry. */ -} Elf64_Verneed; - -typedef Elf64_Half Elf64_Versym; - - -/* - * The header for GNU-style hash sections. - */ - -typedef struct { - uint32_t gh_nbuckets; /* Number of hash buckets. */ - uint32_t gh_symndx; /* First visible symbol in .dynsym. */ - uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ - uint32_t gh_shift2; /* Bloom filter shift count. */ -} Elf_GNU_Hash_Header; - -#endif /* _ELFDEFINITIONS_H_ */ diff --git a/linkers/elftoolchain/common/native-elf-format b/linkers/elftoolchain/common/native-elf-format deleted file mode 100755 index af70759..0000000 --- a/linkers/elftoolchain/common/native-elf-format +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# $Id: native-elf-format 2064 2011-10-26 15:12:32Z jkoshy $ -# -# Find the native ELF format for a host platform by compiling a -# test object and examining the resulting object. -# -# This script is used if there is no easy way to determine this -# information statically at compile time. - -program=`basename $0` -tmp_c=`mktemp -u nefXXXXXX`.c -tmp_o=`echo ${tmp_c} | sed -e 's/.c$/.o/'` - -trap "rm -f ${tmp_c} ${tmp_o}" 0 1 2 3 15 - -touch ${tmp_c} - -echo "/* Generated by ${program} on `date` */" - -cc -c ${tmp_c} -o ${tmp_o} -readelf -h ${tmp_o} | awk ' -$1 ~ "Class:" { - sub("ELF","",$2); elfclass = $2; - } -$1 ~ "Data:" { - if (match($0, "little")) { - elfdata = "LSB"; - } else { - elfdata = "MSB"; - } - } -$1 ~ "Machine:" { - if (match($0, "Intel.*386")) { - elfarch = "EM_386"; - } else if (match($0, ".*X86-64")) { - elfarch = "EM_X86_64"; - } else { - elfarch = "unknown"; - } - } -END { - printf("#define ELFTC_CLASS ELFCLASS%s\n", elfclass); - printf("#define ELFTC_ARCH %s\n", elfarch); - printf("#define ELFTC_BYTEORDER ELFDATA2%s\n", elfdata); -}' - diff --git a/linkers/elftoolchain/common/os.Linux.mk b/linkers/elftoolchain/common/os.Linux.mk deleted file mode 100644 index 2339e2a..0000000 --- a/linkers/elftoolchain/common/os.Linux.mk +++ /dev/null @@ -1,13 +0,0 @@ -# -# Build recipes for Linux based operating systems. -# -# $Id: os.Linux.mk 2064 2011-10-26 15:12:32Z jkoshy $ - -_NATIVE_ELF_FORMAT = native-elf-format - -.BEGIN: ${_NATIVE_ELF_FORMAT}.h - -${_NATIVE_ELF_FORMAT}.h: - ${.CURDIR}/${_NATIVE_ELF_FORMAT} > ${.TARGET} || rm ${.TARGET} - -CLEANFILES += ${_NATIVE_ELF_FORMAT}.h diff --git a/linkers/elftoolchain/common/uthash.h b/linkers/elftoolchain/common/uthash.h deleted file mode 100644 index 8428b9c..0000000 --- a/linkers/elftoolchain/common/uthash.h +++ /dev/null @@ -1,906 +0,0 @@ -/* -Copyright (c) 2003-2011, Troy D. Hanson http://uthash.sourceforge.net -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* $Id: uthash.h 2064 2011-10-26 15:12:32Z jkoshy $ */ - -#ifndef UTHASH_H -#define UTHASH_H - -#include /* memcmp,strlen */ -#include /* ptrdiff_t */ -#include /* exit() */ - -/* These macros use decltype or the earlier __typeof GNU extension. - As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ source) this code uses whatever method is needed - or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define DECLTYPE(x) (decltype(x)) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#define DECLTYPE(x) -#endif -#else /* GNU, Sun and other compilers */ -#define DECLTYPE(x) (__typeof(x)) -#endif - -#ifdef NO_DECLTYPE -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - char **_da_dst = (char**)(&(dst)); \ - *_da_dst = (char*)(src); \ -} while(0) -#else -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - (dst) = DECLTYPE(dst)(src); \ -} while(0) -#endif - -/* a number of the hash function use uint32_t which isn't defined on win32 */ -#ifdef _MSC_VER -typedef unsigned int uint32_t; -typedef unsigned char uint8_t; -#else -#include /* uint32_t */ -#endif - -#define UTHASH_VERSION 1.9.4 - -#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ -#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ -#define uthash_free(ptr,sz) free(ptr) /* free fcn */ - -#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ -#define uthash_expand_fyi(tbl) /* can be defined to log expands */ - -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ - -/* calculate the element whose hash handle address is hhe */ -#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) - -#define HASH_FIND(hh,head,keyptr,keylen,out) \ -do { \ - unsigned _hf_bkt,_hf_hashv; \ - out=NULL; \ - if (head) { \ - HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ - if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ - HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ - keyptr,keylen,out); \ - } \ - } \ -} while (0) - -#ifdef HASH_BLOOM -#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) -#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) -#define HASH_BLOOM_MAKE(tbl) \ -do { \ - (tbl)->bloom_nbits = HASH_BLOOM; \ - (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ - if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ - memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ - (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ -} while (0); - -#define HASH_BLOOM_FREE(tbl) \ -do { \ - uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ -} while (0); - -#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) - -#define HASH_BLOOM_ADD(tbl,hashv) \ - HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) - -#define HASH_BLOOM_TEST(tbl,hashv) \ - HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) - -#else -#define HASH_BLOOM_MAKE(tbl) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) -#define HASH_BLOOM_TEST(tbl,hashv) (1) -#endif - -#define HASH_MAKE_TABLE(hh,head) \ -do { \ - (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ - sizeof(UT_hash_table)); \ - if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ - (head)->hh.tbl->tail = &((head)->hh); \ - (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ - (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ - (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ - (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ - memset((head)->hh.tbl->buckets, 0, \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - HASH_BLOOM_MAKE((head)->hh.tbl); \ - (head)->hh.tbl->signature = HASH_SIGNATURE; \ -} while(0) - -#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ - HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) - -#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ -do { \ - unsigned _ha_bkt; \ - (add)->hh.next = NULL; \ - (add)->hh.key = (char*)keyptr; \ - (add)->hh.keylen = keylen_in; \ - if (!(head)) { \ - head = (add); \ - (head)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh,head); \ - } else { \ - (head)->hh.tbl->tail->next = (add); \ - (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ - (head)->hh.tbl->tail = &((add)->hh); \ - } \ - (head)->hh.tbl->num_items++; \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ - (add)->hh.hashv, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ - HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ - HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ - HASH_FSCK(hh,head); \ -} while(0) - -#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ -do { \ - bkt = ((hashv) & ((num_bkts) - 1)); \ -} while(0) - -/* delete "delptr" from the hash table. - * "the usual" patch-up process for the app-order doubly-linked-list. - * The use of _hd_hh_del below deserves special explanation. - * These used to be expressed using (delptr) but that led to a bug - * if someone used the same symbol for the head and deletee, like - * HASH_DELETE(hh,users,users); - * We want that to work, but by changing the head (users) below - * we were forfeiting our ability to further refer to the deletee (users) - * in the patch-up process. Solution: use scratch space to - * copy the deletee pointer, then the latter references are via that - * scratch pointer rather than through the repointed (users) symbol. - */ -#define HASH_DELETE(hh,head,delptr) \ -do { \ - unsigned _hd_bkt; \ - struct UT_hash_handle *_hd_hh_del; \ - if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - head = NULL; \ - } else { \ - _hd_hh_del = &((delptr)->hh); \ - if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ - (head)->hh.tbl->tail = \ - (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho); \ - } \ - if ((delptr)->hh.prev) { \ - ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ - (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ - } else { \ - DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ - } \ - if (_hd_hh_del->next) { \ - ((UT_hash_handle*)((char*)_hd_hh_del->next + \ - (head)->hh.tbl->hho))->prev = \ - _hd_hh_del->prev; \ - } \ - HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ - (head)->hh.tbl->num_items--; \ - } \ - HASH_FSCK(hh,head); \ -} while (0) - - -/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ -#define HASH_FIND_STR(head,findstr,out) \ - HASH_FIND(hh,head,findstr,strlen(findstr),out) -#define HASH_ADD_STR(head,strfield,add) \ - HASH_ADD(hh,head,strfield,strlen(add->strfield),add) -#define HASH_FIND_INT(head,findint,out) \ - HASH_FIND(hh,head,findint,sizeof(int),out) -#define HASH_ADD_INT(head,intfield,add) \ - HASH_ADD(hh,head,intfield,sizeof(int),add) -#define HASH_FIND_PTR(head,findptr,out) \ - HASH_FIND(hh,head,findptr,sizeof(void *),out) -#define HASH_ADD_PTR(head,ptrfield,add) \ - HASH_ADD(hh,head,ptrfield,sizeof(void *),add) -#define HASH_DEL(head,delptr) \ - HASH_DELETE(hh,head,delptr) - -/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. - * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. - */ -#ifdef HASH_DEBUG -#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head) \ -do { \ - unsigned _bkt_i; \ - unsigned _count, _bkt_count; \ - char *_prev; \ - struct UT_hash_handle *_thh; \ - if (head) { \ - _count = 0; \ - for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ - _bkt_count = 0; \ - _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ - _prev = NULL; \ - while (_thh) { \ - if (_prev != (char*)(_thh->hh_prev)) { \ - HASH_OOPS("invalid hh_prev %p, actual %p\n", \ - _thh->hh_prev, _prev ); \ - } \ - _bkt_count++; \ - _prev = (char*)(_thh); \ - _thh = _thh->hh_next; \ - } \ - _count += _bkt_count; \ - if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("invalid bucket count %d, actual %d\n", \ - (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ - } \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid hh item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ - } \ - /* traverse hh in app order; check next/prev integrity, count */ \ - _count = 0; \ - _prev = NULL; \ - _thh = &(head)->hh; \ - while (_thh) { \ - _count++; \ - if (_prev !=(char*)(_thh->prev)) { \ - HASH_OOPS("invalid prev %p, actual %p\n", \ - _thh->prev, _prev ); \ - } \ - _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ - _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ - (head)->hh.tbl->hho) : NULL ); \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid app item count %d, actual %d\n", \ - (head)->hh.tbl->num_items, _count ); \ - } \ - } \ -} while (0) -#else -#define HASH_FSCK(hh,head) -#endif - -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to - * the descriptor to which this macro is defined for tuning the hash function. - * The app can #include to get the prototype for write(2). */ -#ifdef HASH_EMIT_KEYS -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ -do { \ - unsigned _klen = fieldlen; \ - write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ - write(HASH_EMIT_KEYS, keyptr, fieldlen); \ -} while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) -#endif - -/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION -#define HASH_FCN HASH_FUNCTION -#else -#define HASH_FCN HASH_JEN -#endif - -/* The Bernstein hash function, used in Perl prior to v5.6 */ -#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _hb_keylen=keylen; \ - char *_hb_key=(char*)(key); \ - (hashv) = 0; \ - while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ - bkt = (hashv) & (num_bkts-1); \ -} while (0) - - -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _sx_i; \ - char *_hs_key=(char*)(key); \ - hashv = 0; \ - for(_sx_i=0; _sx_i < keylen; _sx_i++) \ - hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ - bkt = hashv & (num_bkts-1); \ -} while (0) - -#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _fn_i; \ - char *_hf_key=(char*)(key); \ - hashv = 2166136261UL; \ - for(_fn_i=0; _fn_i < keylen; _fn_i++) \ - hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ - bkt = hashv & (num_bkts-1); \ -} while(0); - -#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _ho_i; \ - char *_ho_key=(char*)(key); \ - hashv = 0; \ - for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ - hashv += _ho_key[_ho_i]; \ - hashv += (hashv << 10); \ - hashv ^= (hashv >> 6); \ - } \ - hashv += (hashv << 3); \ - hashv ^= (hashv >> 11); \ - hashv += (hashv << 15); \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -#define HASH_JEN_MIX(a,b,c) \ -do { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ -} while (0) - -#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ -do { \ - unsigned _hj_i,_hj_j,_hj_k; \ - char *_hj_key=(char*)(key); \ - hashv = 0xfeedbeef; \ - _hj_i = _hj_j = 0x9e3779b9; \ - _hj_k = keylen; \ - while (_hj_k >= 12) { \ - _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ - + ( (unsigned)_hj_key[2] << 16 ) \ - + ( (unsigned)_hj_key[3] << 24 ) ); \ - _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ - + ( (unsigned)_hj_key[6] << 16 ) \ - + ( (unsigned)_hj_key[7] << 24 ) ); \ - hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ - + ( (unsigned)_hj_key[10] << 16 ) \ - + ( (unsigned)_hj_key[11] << 24 ) ); \ - \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - \ - _hj_key += 12; \ - _hj_k -= 12; \ - } \ - hashv += keylen; \ - switch ( _hj_k ) { \ - case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ - case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ - case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ - case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ - case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ - case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ - case 5: _hj_j += _hj_key[4]; \ - case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ - case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ - case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ - case 1: _hj_i += _hj_key[0]; \ - } \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - bkt = hashv & (num_bkts-1); \ -} while(0) - -/* The Paul Hsieh hash function */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif -#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ -do { \ - char *_sfh_key=(char*)(key); \ - uint32_t _sfh_tmp, _sfh_len = keylen; \ - \ - int _sfh_rem = _sfh_len & 3; \ - _sfh_len >>= 2; \ - hashv = 0xcafebabe; \ - \ - /* Main loop */ \ - for (;_sfh_len > 0; _sfh_len--) { \ - hashv += get16bits (_sfh_key); \ - _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ - hashv = (hashv << 16) ^ _sfh_tmp; \ - _sfh_key += 2*sizeof (uint16_t); \ - hashv += hashv >> 11; \ - } \ - \ - /* Handle end cases */ \ - switch (_sfh_rem) { \ - case 3: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 16; \ - hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ - hashv += hashv >> 11; \ - break; \ - case 2: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 11; \ - hashv += hashv >> 17; \ - break; \ - case 1: hashv += *_sfh_key; \ - hashv ^= hashv << 10; \ - hashv += hashv >> 1; \ - } \ - \ - /* Force "avalanching" of final 127 bits */ \ - hashv ^= hashv << 3; \ - hashv += hashv >> 5; \ - hashv ^= hashv << 4; \ - hashv += hashv >> 17; \ - hashv ^= hashv << 25; \ - hashv += hashv >> 6; \ - bkt = hashv & (num_bkts-1); \ -} while(0); - -#ifdef HASH_USING_NO_STRICT_ALIASING -/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. - * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. - * MurmurHash uses the faster approach only on CPU's where we know it's safe. - * - * Note the preprocessor built-in defines can be emitted using: - * - * gcc -m64 -dM -E - < /dev/null (on gcc) - * cc -## a.c (where a.c is a simple test file) (Sun Studio) - */ -#if (defined(__i386__) || defined(__x86_64__)) -#define MUR_GETBLOCK(p,i) p[i] -#else /* non intel */ -#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) -#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) -#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) -#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) -#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) -#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) -#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) -#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) -#else /* assume little endian non-intel */ -#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) -#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) -#endif -#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ - (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ - (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ - MUR_ONE_THREE(p)))) -#endif -#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) -#define MUR_FMIX(_h) \ -do { \ - _h ^= _h >> 16; \ - _h *= 0x85ebca6b; \ - _h ^= _h >> 13; \ - _h *= 0xc2b2ae35l; \ - _h ^= _h >> 16; \ -} while(0) - -#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ -do { \ - const uint8_t *_mur_data = (const uint8_t*)(key); \ - const int _mur_nblocks = (keylen) / 4; \ - uint32_t _mur_h1 = 0xf88D5353; \ - uint32_t _mur_c1 = 0xcc9e2d51; \ - uint32_t _mur_c2 = 0x1b873593; \ - const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ - int _mur_i; \ - for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ - uint32_t _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ - _mur_k1 *= _mur_c1; \ - _mur_k1 = MUR_ROTL32(_mur_k1,15); \ - _mur_k1 *= _mur_c2; \ - \ - _mur_h1 ^= _mur_k1; \ - _mur_h1 = MUR_ROTL32(_mur_h1,13); \ - _mur_h1 = _mur_h1*5+0xe6546b64; \ - } \ - const uint8_t *_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ - uint32_t _mur_k1=0; \ - switch((keylen) & 3) { \ - case 3: _mur_k1 ^= _mur_tail[2] << 16; \ - case 2: _mur_k1 ^= _mur_tail[1] << 8; \ - case 1: _mur_k1 ^= _mur_tail[0]; \ - _mur_k1 *= _mur_c1; \ - _mur_k1 = MUR_ROTL32(_mur_k1,15); \ - _mur_k1 *= _mur_c2; \ - _mur_h1 ^= _mur_k1; \ - } \ - _mur_h1 ^= (keylen); \ - MUR_FMIX(_mur_h1); \ - hashv = _mur_h1; \ - bkt = hashv & (num_bkts-1); \ -} while(0) -#endif /* HASH_USING_NO_STRICT_ALIASING */ - -/* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) - -/* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ -do { \ - if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ - else out=NULL; \ - while (out) { \ - if (out->hh.keylen == keylen_in) { \ - if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ - } \ - if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \ - else out = NULL; \ - } \ -} while(0) - -/* add an item to a bucket */ -#define HASH_ADD_TO_BKT(head,addhh) \ -do { \ - head.count++; \ - (addhh)->hh_next = head.hh_head; \ - (addhh)->hh_prev = NULL; \ - if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ - (head).hh_head=addhh; \ - if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ - && (addhh)->tbl->noexpand != 1) { \ - HASH_EXPAND_BUCKETS((addhh)->tbl); \ - } \ -} while(0) - -/* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(hh,head,hh_del) \ - (head).count--; \ - if ((head).hh_head == hh_del) { \ - (head).hh_head = hh_del->hh_next; \ - } \ - if (hh_del->hh_prev) { \ - hh_del->hh_prev->hh_next = hh_del->hh_next; \ - } \ - if (hh_del->hh_next) { \ - hh_del->hh_next->hh_prev = hh_del->hh_prev; \ - } - -/* Bucket expansion has the effect of doubling the number of buckets - * and redistributing the items into the new buckets. Ideally the - * items will distribute more or less evenly into the new buckets - * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * - * With the items distributed into more buckets, the chain length - * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain - * length is the essence of how a hash provides constant time lookup. - * - * The calculation of tbl->ideal_chain_maxlen below deserves some - * explanation. First, keep in mind that we're calculating the ideal - * maximum chain length based on the *new* (doubled) bucket count. - * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate - * ceil(n/b). We don't depend on floating point arithmetic in this - * hash, so to calculate ceil(n/b) with integers we could write - * - * ceil(n/b) = (n/b) + ((n%b)?1:0) - * - * and in fact a previous version of this hash did just that. - * But now we have improved things a bit by recognizing that b is - * always a power of two. We keep its base 2 log handy (call it lb), - * so now we can write this with a bit shift and logical AND: - * - * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * - */ -#define HASH_EXPAND_BUCKETS(tbl) \ -do { \ - unsigned _he_bkt; \ - unsigned _he_bkt_i; \ - struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ - UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ - _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ - memset(_he_new_buckets, 0, \ - 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - tbl->ideal_chain_maxlen = \ - (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ - ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ - tbl->nonideal_items = 0; \ - for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ - { \ - _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ - while (_he_thh) { \ - _he_hh_nxt = _he_thh->hh_next; \ - HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ - _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ - if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ - tbl->nonideal_items++; \ - _he_newbkt->expand_mult = _he_newbkt->count / \ - tbl->ideal_chain_maxlen; \ - } \ - _he_thh->hh_prev = NULL; \ - _he_thh->hh_next = _he_newbkt->hh_head; \ - if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ - _he_thh; \ - _he_newbkt->hh_head = _he_thh; \ - _he_thh = _he_hh_nxt; \ - } \ - } \ - uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ - tbl->num_buckets *= 2; \ - tbl->log2_num_buckets++; \ - tbl->buckets = _he_new_buckets; \ - tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ - (tbl->ineff_expands+1) : 0; \ - if (tbl->ineff_expands > 1) { \ - tbl->noexpand=1; \ - uthash_noexpand_fyi(tbl); \ - } \ - uthash_expand_fyi(tbl); \ -} while(0) - - -/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. - * HASH_SRT was added to allow the hash handle name to be passed in. */ -#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) -#define HASH_SRT(hh,head,cmpfcn) \ -do { \ - unsigned _hs_i; \ - unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ - struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ - if (head) { \ - _hs_insize = 1; \ - _hs_looping = 1; \ - _hs_list = &((head)->hh); \ - while (_hs_looping) { \ - _hs_p = _hs_list; \ - _hs_list = NULL; \ - _hs_tail = NULL; \ - _hs_nmerges = 0; \ - while (_hs_p) { \ - _hs_nmerges++; \ - _hs_q = _hs_p; \ - _hs_psize = 0; \ - for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ - _hs_psize++; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - if (! (_hs_q) ) break; \ - } \ - _hs_qsize = _hs_insize; \ - while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ - if (_hs_psize == 0) { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else if (( \ - cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ - ) <= 0) { \ - _hs_e = _hs_p; \ - _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ - ((void*)((char*)(_hs_p->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_psize--; \ - } else { \ - _hs_e = _hs_q; \ - _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ - ((void*)((char*)(_hs_q->next) + \ - (head)->hh.tbl->hho)) : NULL); \ - _hs_qsize--; \ - } \ - if ( _hs_tail ) { \ - _hs_tail->next = ((_hs_e) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ - } else { \ - _hs_list = _hs_e; \ - } \ - _hs_e->prev = ((_hs_tail) ? \ - ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ - _hs_tail = _hs_e; \ - } \ - _hs_p = _hs_q; \ - } \ - _hs_tail->next = NULL; \ - if ( _hs_nmerges <= 1 ) { \ - _hs_looping=0; \ - (head)->hh.tbl->tail = _hs_tail; \ - DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ - } \ - _hs_insize *= 2; \ - } \ - HASH_FSCK(hh,head); \ - } \ -} while (0) - -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash - * hash handle that must be present in the structure. */ -#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ -do { \ - unsigned _src_bkt, _dst_bkt; \ - void *_last_elt=NULL, *_elt; \ - UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ - ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ - if (src) { \ - for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ - for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ - _src_hh; \ - _src_hh = _src_hh->hh_next) { \ - _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ - if (cond(_elt)) { \ - _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ - _dst_hh->key = _src_hh->key; \ - _dst_hh->keylen = _src_hh->keylen; \ - _dst_hh->hashv = _src_hh->hashv; \ - _dst_hh->prev = _last_elt; \ - _dst_hh->next = NULL; \ - if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ - if (!dst) { \ - DECLTYPE_ASSIGN(dst,_elt); \ - HASH_MAKE_TABLE(hh_dst,dst); \ - } else { \ - _dst_hh->tbl = (dst)->hh_dst.tbl; \ - } \ - HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ - HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ - (dst)->hh_dst.tbl->num_items++; \ - _last_elt = _elt; \ - _last_elt_hh = _dst_hh; \ - } \ - } \ - } \ - } \ - HASH_FSCK(hh_dst,dst); \ -} while (0) - -#define HASH_CLEAR(hh,head) \ -do { \ - if (head) { \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head)=NULL; \ - } \ -} while(0) - -#ifdef NO_DECLTYPE -#define HASH_ITER(hh,head,el,tmp) \ -for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) -#else -#define HASH_ITER(hh,head,el,tmp) \ -for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) -#endif - -/* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) -#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) - -typedef struct UT_hash_bucket { - struct UT_hash_handle *hh_head; - unsigned count; - - /* expand_mult is normally set to 0. In this situation, the max chain length - * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). - * However, setting expand_mult to a non-zero value delays bucket expansion - * (that would be triggered by additions to this particular bucket) - * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. - * (The multiplier is simply expand_mult+1). The whole idea of this - * multiplier is to reduce bucket expansions, since they are expensive, in - * situations where we know that a particular bucket tends to be overused. - * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. - */ - unsigned expand_mult; - -} UT_hash_bucket; - -/* random signature used only to find hash tables in external analysis */ -#define HASH_SIGNATURE 0xa0111fe1 -#define HASH_BLOOM_SIGNATURE 0xb12220f2 - -typedef struct UT_hash_table { - UT_hash_bucket *buckets; - unsigned num_buckets, log2_num_buckets; - unsigned num_items; - struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ - ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ - - /* in an ideal situation (all buckets used equally), no bucket would have - * more than ceil(#items/#buckets) items. that's the ideal chain length. */ - unsigned ideal_chain_maxlen; - - /* nonideal_items is the number of items in the hash whose chain position - * exceeds the ideal chain maxlen. these items pay the penalty for an uneven - * hash distribution; reaching them in a chain traversal takes >ideal steps */ - unsigned nonideal_items; - - /* ineffective expands occur when a bucket doubling was performed, but - * afterward, more than half the items in the hash had nonideal chain - * positions. If this happens on two consecutive expansions we inhibit any - * further expansion, as it's not helping; this happens when the hash - * function isn't a good fit for the key domain. When expansion is inhibited - * the hash will still work, albeit no longer in constant time. */ - unsigned ineff_expands, noexpand; - - uint32_t signature; /* used only to find hash tables in external analysis */ -#ifdef HASH_BLOOM - uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ - uint8_t *bloom_bv; - char bloom_nbits; -#endif - -} UT_hash_table; - -typedef struct UT_hash_handle { - struct UT_hash_table *tbl; - void *prev; /* prev element in app order */ - void *next; /* next element in app order */ - struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ - struct UT_hash_handle *hh_next; /* next hh in bucket order */ - void *key; /* ptr to enclosing struct's key */ - unsigned keylen; /* enclosing struct's key len */ - unsigned hashv; /* result of hash-fcn(key) */ -} UT_hash_handle; - -#endif /* UTHASH_H */ diff --git a/linkers/elftoolchain/libelf/Makefile b/linkers/elftoolchain/libelf/Makefile deleted file mode 100644 index 41e902a..0000000 --- a/linkers/elftoolchain/libelf/Makefile +++ /dev/null @@ -1,158 +0,0 @@ -# $Id: Makefile 1345 2011-01-01 11:17:52Z jkoshy $ - -TOP= ${.CURDIR}/.. - -LIB= elf - -SRCS= elf.c \ - elf_begin.c \ - elf_cntl.c \ - elf_end.c elf_errmsg.c elf_errno.c \ - elf_data.c \ - elf_fill.c \ - elf_flag.c \ - elf_getarhdr.c \ - elf_getarsym.c \ - elf_getbase.c \ - elf_getident.c \ - elf_hash.c \ - elf_kind.c \ - elf_memory.c \ - elf_next.c \ - elf_rand.c \ - elf_rawfile.c \ - elf_phnum.c \ - elf_shnum.c \ - elf_shstrndx.c \ - elf_scn.c \ - elf_strptr.c \ - elf_update.c \ - elf_version.c \ - gelf_cap.c \ - gelf_checksum.c \ - gelf_dyn.c \ - gelf_ehdr.c \ - gelf_getclass.c \ - gelf_fsize.c \ - gelf_move.c \ - gelf_phdr.c \ - gelf_rel.c \ - gelf_rela.c \ - gelf_shdr.c \ - gelf_sym.c \ - gelf_syminfo.c \ - gelf_symshndx.c \ - gelf_xlate.c \ - libelf_align.c \ - libelf_allocate.c \ - libelf_ar.c \ - libelf_ar_util.c \ - libelf_checksum.c \ - libelf_data.c \ - libelf_ehdr.c \ - libelf_extended.c \ - libelf_phdr.c \ - libelf_shdr.c \ - libelf_xlate.c \ - ${GENSRCS} -INCS= libelf.h gelf.h - -GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c -CLEANFILES= ${GENSRCS} - -SHLIB_MAJOR= 1 - -WARNS?= 6 - -MAN= elf.3 \ - elf_begin.3 \ - elf_cntl.3 \ - elf_end.3 \ - elf_errmsg.3 \ - elf_fill.3 \ - elf_flagdata.3 \ - elf_getarhdr.3 \ - elf_getarsym.3 \ - elf_getbase.3 \ - elf_getdata.3 \ - elf_getident.3 \ - elf_getscn.3 \ - elf_getphdrnum.3 \ - elf_getphnum.3 \ - elf_getshdrnum.3 \ - elf_getshnum.3 \ - elf_getshdrstrndx.3 \ - elf_getshstrndx.3 \ - elf_hash.3 \ - elf_kind.3 \ - elf_memory.3 \ - elf_next.3 \ - elf_rawfile.3 \ - elf_rand.3 \ - elf_strptr.3 \ - elf_update.3 \ - elf_version.3 \ - gelf.3 \ - gelf_checksum.3 \ - gelf_fsize.3 \ - gelf_getcap.3 \ - gelf_getclass.3 \ - gelf_getdyn.3 \ - gelf_getehdr.3 \ - gelf_getmove.3 \ - gelf_getphdr.3 \ - gelf_getrel.3 \ - gelf_getrela.3 \ - gelf_getshdr.3 \ - gelf_getsym.3 \ - gelf_getsyminfo.3 \ - gelf_getsymshndx.3 \ - gelf_newehdr.3 \ - gelf_newphdr.3 \ - gelf_update_ehdr.3 \ - gelf_xlatetof.3 - -MLINKS+= \ - elf_errmsg.3 elf_errno.3 \ - elf_flagdata.3 elf_flagarhdr.3 \ - elf_flagdata.3 elf_flagehdr.3 \ - elf_flagdata.3 elf_flagelf.3 \ - elf_flagdata.3 elf_flagphdr.3 \ - elf_flagdata.3 elf_flagscn.3 \ - elf_flagdata.3 elf_flagshdr.3 \ - elf_getdata.3 elf_newdata.3 \ - elf_getdata.3 elf_rawdata.3 \ - elf_getscn.3 elf_ndxscn.3 \ - elf_getscn.3 elf_newscn.3 \ - elf_getscn.3 elf_nextscn.3 \ - elf_getshstrndx.3 elf_setshstrndx.3 \ - gelf_getcap.3 gelf_update_cap.3 \ - gelf_getdyn.3 gelf_update_dyn.3 \ - gelf_getmove.3 gelf_update_move.3 \ - gelf_getrel.3 gelf_update_rel.3 \ - gelf_getrela.3 gelf_update_rela.3 \ - gelf_getsym.3 gelf_update_sym.3 \ - gelf_getsyminfo.3 gelf_update_syminfo.3 \ - gelf_getsymshndx.3 gelf_update_symshndx.3 \ - gelf_update_ehdr.3 gelf_update_phdr.3 \ - gelf_update_ehdr.3 gelf_update_shdr.3 \ - gelf_xlatetof.3 gelf_xlatetom.3 - -.for E in 32 64 -MLINKS+= \ - gelf_checksum.3 elf${E}_checksum.3 \ - gelf_fsize.3 elf${E}_fsize.3 \ - gelf_getehdr.3 elf${E}_getehdr.3 \ - gelf_getphdr.3 elf${E}_getphdr.3 \ - gelf_getshdr.3 elf${E}_getshdr.3 \ - gelf_newehdr.3 elf${E}_newehdr.3 \ - gelf_newphdr.3 elf${E}_newphdr.3 \ - gelf_xlatetof.3 elf${E}_xlatetof.3 \ - gelf_xlatetof.3 elf${E}_xlatetom.3 -.endfor - -libelf_convert.c: elf_types.m4 libelf_convert.m4 -libelf_fsize.c: elf_types.m4 libelf_fsize.m4 -libelf_msize.c: elf_types.m4 libelf_msize.m4 - -.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/linkers/elftoolchain/libelf/Version.map b/linkers/elftoolchain/libelf/Version.map deleted file mode 100644 index 2c595ea..0000000 --- a/linkers/elftoolchain/libelf/Version.map +++ /dev/null @@ -1,97 +0,0 @@ -/* - * $Id: Version.map 2033 2011-10-23 09:21:13Z jkoshy $ - * - * $FreeBSD: src/lib/libelf/Version.map,v 1.3 2007/04/29 14:05:22 deischen Exp $ - */ -FBSD_1.0 { -global: - elf32_checksum; - elf32_fsize; - elf32_getehdr; - elf32_getphdr; - elf32_getshdr; - elf32_newehdr; - elf32_newphdr; - elf32_xlatetof; - elf32_xlatetom; - elf64_checksum; - elf64_fsize; - elf64_getehdr; - elf64_getphdr; - elf64_getshdr; - elf64_newehdr; - elf64_newphdr; - elf64_xlatetof; - elf64_xlatetom; - elf_begin; - elf_cntl; - elf_end; - elf_errmsg; - elf_errno; - elf_fill; - elf_flagarhdr; - elf_flagdata; - elf_flagehdr; - elf_flagelf; - elf_flagphdr; - elf_flagscn; - elf_flagshdr; - elf_getarhdr; - elf_getarsym; - elf_getbase; - elf_getdata; - elf_getident; - elf_getscn; - elf_getphdrnum; - elf_getphnum; - elf_getshdrnum; - elf_getshnum; - elf_getshdrstrndx; - elf_getshstrndx; - elf_hash; - elf_kind; - elf_memory; - elf_ndxscn; - elf_newdata; - elf_newscn; - elf_next; - elf_nextscn; - elf_rand; - elf_rawdata; - elf_rawfile; - elf_setshstrndx; - elf_strptr; - elf_update; - elf_version; - gelf_checksum; - gelf_fsize; - gelf_getcap; - gelf_getclass; - gelf_getdyn; - gelf_getehdr; - gelf_getmove; - gelf_getphdr; - gelf_getrel; - gelf_getrela; - gelf_getshdr; - gelf_getsym; - gelf_getsyminfo; - gelf_getsymshndx; - gelf_newehdr; - gelf_newphdr; - gelf_update_cap; - gelf_update_dyn; - gelf_update_ehdr; - gelf_update_move; - gelf_update_phdr; - gelf_update_rel; - gelf_update_rela; - gelf_update_shdr; - gelf_update_sym; - gelf_update_syminfo; - gelf_update_symshndx; - gelf_xlatetof; - gelf_xlatetom; -local: - *; -}; diff --git a/linkers/elftoolchain/libelf/_libelf.h b/linkers/elftoolchain/libelf/_libelf.h deleted file mode 100644 index ef15642..0000000 --- a/linkers/elftoolchain/libelf/_libelf.h +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf.h 1921 2011-09-23 08:04:02Z jkoshy $ - */ - -#ifndef __LIBELF_H_ -#define __LIBELF_H_ - -#include - -#include "_libelf_config.h" - -#include "_elftc.h" - -/* - * Library-private data structures. - */ - -#define LIBELF_MSG_SIZE 256 - -struct _libelf_globals { - int libelf_arch; - unsigned int libelf_byteorder; - int libelf_class; - int libelf_error; - int libelf_fillchar; - unsigned int libelf_version; - char libelf_msg[LIBELF_MSG_SIZE]; -}; - -extern struct _libelf_globals _libelf; - -#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) - -#define LIBELF_ELF_ERROR_MASK 0xFF -#define LIBELF_OS_ERROR_SHIFT 8 - -#define LIBELF_SET_ERROR(E, O) do { \ - LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \ - ((O) << LIBELF_OS_ERROR_SHIFT)); \ - } while (0) - -#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) - -/* - * Flags for library internal use. These use the upper 16 bits of the - * `e_flags' field. - */ -#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */ -#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */ -#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */ -#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */ -#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */ -#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */ -#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */ -#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */ - -struct _Elf { - int e_activations; /* activation count */ - unsigned int e_byteorder; /* ELFDATA* */ - int e_class; /* ELFCLASS* */ - Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ - int e_fd; /* associated file descriptor */ - unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ - Elf_Kind e_kind; /* ELF_K_* */ - Elf *e_parent; /* non-NULL for archive members */ - char *e_rawfile; /* uninterpreted bytes */ - size_t e_rawsize; /* size of uninterpreted bytes */ - unsigned int e_version; /* file version */ - - /* - * Header information for archive members. See the - * LIBELF_F_AR_HEADER flag. - */ - union { - Elf_Arhdr *e_arhdr; /* translated header */ - char *e_rawhdr; /* untranslated header */ - } e_hdr; - - union { - struct { /* ar(1) archives */ - off_t e_next; /* set by elf_rand()/elf_next() */ - int e_nchildren; - char *e_rawstrtab; /* file name strings */ - size_t e_rawstrtabsz; - char *e_rawsymtab; /* symbol table */ - size_t e_rawsymtabsz; - Elf_Arsym *e_symtab; - size_t e_symtabsz; - } e_ar; - struct { /* regular ELF files */ - union { - Elf32_Ehdr *e_ehdr32; - Elf64_Ehdr *e_ehdr64; - } e_ehdr; - union { - Elf32_Phdr *e_phdr32; - Elf64_Phdr *e_phdr64; - } e_phdr; - STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ - size_t e_nphdr; /* number of Phdr entries */ - size_t e_nscn; /* number of sections */ - size_t e_strndx; /* string table section index */ - } e_elf; - } e_u; -}; - -struct _Elf_Scn { - union { - Elf32_Shdr s_shdr32; - Elf64_Shdr s_shdr64; - } s_shdr; - STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ - STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ - STAILQ_ENTRY(_Elf_Scn) s_next; - struct _Elf *s_elf; /* parent ELF descriptor */ - unsigned int s_flags; /* flags for the section as a whole */ - size_t s_ndx; /* index# for this section */ - uint64_t s_offset; /* managed by elf_update() */ - uint64_t s_rawoff; /* original offset in the file */ - uint64_t s_size; /* managed by elf_update() */ -}; - - -enum { - ELF_TOFILE, - ELF_TOMEMORY -}; - -#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > UINT_MAX) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - -#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > INT_MAX || \ - (SRC)->NAME < INT_MIN) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ - } while (0) - - -/* - * Function Prototypes. - */ - -__BEGIN_DECLS -Elf_Data *_libelf_allocate_data(Elf_Scn *_s); -Elf *_libelf_allocate_elf(void); -Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); -Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); -Elf *_libelf_ar_open(Elf *_e); -Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); -int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); -Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); -Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); -unsigned long _libelf_checksum(Elf *_e, int _elfclass); -void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); -int _libelf_falign(Elf_Type _t, int _elfclass); -size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, - size_t count); -int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); -void *_libelf_getphdr(Elf *_e, int _elfclass); -void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); -void _libelf_init_elf(Elf *_e, Elf_Kind _kind); -int _libelf_load_section_headers(Elf *e, void *ehdr); -int _libelf_malign(Elf_Type _t, int _elfclass); -size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); -void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); -Elf_Data *_libelf_release_data(Elf_Data *_d); -Elf *_libelf_release_elf(Elf *_e); -Elf_Scn *_libelf_release_scn(Elf_Scn *_s); -int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); -int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); -int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, - size_t _shstrndx); -Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, - unsigned int _encoding, int _elfclass, int _direction); -int _libelf_xlate_shtype(uint32_t _sht); -__END_DECLS - -#endif /* __LIBELF_H_ */ diff --git a/linkers/elftoolchain/libelf/_libelf_ar.h b/linkers/elftoolchain/libelf/_libelf_ar.h deleted file mode 100644 index d6b15a7..0000000 --- a/linkers/elftoolchain/libelf/_libelf_ar.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $ - */ - -#ifndef __LIBELF_AR_H_ -#define __LIBELF_AR_H_ - -/* - * Prototypes and declarations needed by libelf's ar(1) archive - * handling code. - */ - -#include - -#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX "#1/" -#define LIBELF_AR_BSD_SYMTAB_NAME "__.SYMDEF" -#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE \ - (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) - -#define IS_EXTENDED_BSD_NAME(NAME) \ - (strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0) - - -char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname, - int _svr4names); -char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh); -char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar); -int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base, - size_t *_ret); - -#endif /* __LIBELF_AR_H_ */ diff --git a/linkers/elftoolchain/libelf/_libelf_config.h b/linkers/elftoolchain/libelf/_libelf_config.h deleted file mode 100644 index a318e70..0000000 --- a/linkers/elftoolchain/libelf/_libelf_config.h +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: _libelf_config.h 2032 2011-10-23 09:07:00Z jkoshy $ - */ - -#ifdef __FreeBSD__ - -#define LIBELF_VCSID(ID) __FBSDID(ID) - -/* - * Define LIBELF_{ARCH,BYTEORDER,CLASS} based on the machine architecture. - * See also: . - */ - -#if defined(__amd64__) - -#define LIBELF_ARCH EM_X86_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__arm__) - -#define LIBELF_ARCH EM_ARM -#if defined(__ARMEB__) /* Big-endian ARM. */ -#define LIBELF_BYTEORDER ELFDATA2MSB -#else -#define LIBELF_BYTEORDER ELFDATA2LSB -#endif -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__i386__) - -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__ia64__) - -#define LIBELF_ARCH EM_IA_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__mips__) - -#define LIBELF_ARCH EM_MIPS -#if defined(__MIPSEB__) -#define LIBELF_BYTEORDER ELFDATA2MSB -#else -#define LIBELF_BYTEORDER ELFDATA2LSB -#endif -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__powerpc__) - -#define LIBELF_ARCH EM_PPC -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS32 - -#elif defined(__sparc__) - -#define LIBELF_ARCH EM_SPARCV9 -#define LIBELF_BYTEORDER ELFDATA2MSB -#define LIBELF_CLASS ELFCLASS64 - -#else -#error Unknown FreeBSD architecture. -#endif -#endif /* __FreeBSD__ */ - - -#ifdef __NetBSD__ - -#include - -#define LIBELF_VCSID(ID) __RCSID(ID) - -#if !defined(ARCH_ELFSIZE) -#error ARCH_ELFSIZE is not defined. -#endif - -#if ARCH_ELFSIZE == 32 -#define LIBELF_ARCH ELF32_MACHDEP_ID -#define LIBELF_BYTEORDER ELF32_MACHDEP_ENDIANNESS -#define LIBELF_CLASS ELFCLASS32 -#define Elf_Note Elf32_Nhdr -#else -#define LIBELF_ARCH ELF64_MACHDEP_ID -#define LIBELF_BYTEORDER ELF64_MACHDEP_ENDIANNESS -#define LIBELF_CLASS ELFCLASS64 -#define Elf_Note Elf64_Nhdr -#endif - -#endif /* __NetBSD__ */ - -#ifdef __APPLE__ - -#define LIBELF_VCSID(ID) - -#if defined(__amd64__) - -#define LIBELF_ARCH EM_X86_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__i386__) - -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 - -#else -#error Unknown Apple architecture. -#endif - -#define roundup2 roundup - -#endif /* __APPLE__ */ - -/* - * GNU & Linux compatibility. - * - * `__linux__' is defined in an environment runs the Linux kernel and glibc. - * `__GNU__' is defined in an environment runs a GNU kernel (Hurd) and glibc. - * `__GLIBC__' is defined for an environment that runs glibc over a non-GNU - * kernel such as GNU/kFreeBSD. - */ - -#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) - -#if defined(__linux__) - -#include "native-elf-format.h" - -#define LIBELF_CLASS ELFTC_CLASS -#define LIBELF_ARCH ELFTC_ARCH -#define LIBELF_BYTEORDER ELFTC_BYTEORDER - -#endif /* defined(__linux__) */ - -#define LIBELF_VCSID(ID) - -#if LIBELF_CLASS == ELFCLASS32 -#define Elf_Note Elf32_Nhdr -#elif LIBELF_CLASS == ELFCLASS64 -#define Elf_Note Elf64_Nhdr -#else -#error LIBELF_CLASS needs to be one of ELFCLASS32 or ELFCLASS64 -#endif - -#define roundup2 roundup - -#endif /* defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) */ - -#ifdef __WIN32__ - -#define LIBELF_VCSID(ID) - -#if defined(__amd64__) - -#define LIBELF_ARCH EM_X86_64 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS64 - -#elif defined(__i386__) - -#define LIBELF_ARCH EM_386 -#define LIBELF_BYTEORDER ELFDATA2LSB -#define LIBELF_CLASS ELFCLASS32 - -#else -#error Unknown Apple architecture. -#endif - -#endif /* __APPLE__ */ diff --git a/linkers/elftoolchain/libelf/elf.3 b/linkers/elftoolchain/libelf/elf.3 deleted file mode 100644 index 5d86f60..0000000 --- a/linkers/elftoolchain/libelf/elf.3 +++ /dev/null @@ -1,589 +0,0 @@ -.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf.3 1730 2011-08-14 10:03:34Z jkoshy $ -.\" -.Dd August 14, 2011 -.Os -.Dt ELF 3 -.Sh NAME -.Nm elf -.Nd API for manipulating ELF objects -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Sh DESCRIPTION -The -.Lb libelf -provides functions that allow an application to read and manipulate -ELF object files, and to read -.Xr ar 1 -archives. -The library allows the manipulation of ELF objects in a byte ordering -and word-size independent way, allowing an application to read and -create ELF objects for 32 and 64 bit architectures and for little- -and big-endian machines. -The library is capable of processing ELF objects that use extended -section numbering. -.Pp -This manual page serves to provide an overview of the functionality in -the ELF library. -Further information may found in the manual pages for individual -.Xr ELF 3 -functions that comprise the library. -.Ss ELF Concepts -As described in -.Xr elf 5 , -ELF files contain several data structures that are laid out in a -specific way. -ELF files begin with an -.Dq Executable Header , -and may contain an optional -.Dq Program Header Table , -and optional data in the form of ELF -.Dq sections . -A -.Dq Section Header Table -describes the content of the data in these sections. -.Pp -ELF objects have an associated -.Dq "ELF class" -which denotes the natural machine word size for the architecture -the object is associated with. -Objects for 32 bit architectures have an ELF class of -.Dv ELFCLASS32 . -Objects for 64 bit architectures have an ELF class of -.Dv ELFCLASS64 . -.Pp -ELF objects also have an associated -.Dq endianness -which denotes the endianness of the machine architecture associated -with the object. -This may be -.Dv ELFDATA2LSB -for little-endian architectures and -.Dv ELFDATA2MSB -for big-endian architectures. -.Pp -ELF objects are also associated with an API version number. -This version number determines the layout of the individual components -of an ELF file and the semantics associated with these. -.Ss Data Representation And Translation -The -.Xr ELF 3 -library distinguishes between -.Dq native -representations of ELF data structures and their -.Dq file -representations. -.Pp -An application would work with ELF data in its -.Dq native -representation, i.e., using the native byteorder and alignment mandated -by the processor the application is running on. -The -.Dq file -representation of the same data could use a different byte ordering -and follow different constraints on object alignment than these native -constraints. -.Pp -Accordingly, the -.Xr ELF 3 -library offers translation facilities -.Xr ( elf32_xlatetof 3 , -.Xr elf32_xlatetom 3 , -.Xr elf64_xlatetof 3 -and -.Xr elf64_xlatetom 3 ) -to and from these -representations and also provides higher-level APIs that retrieve and store -data from the ELF object in a transparent manner. -.Ss Library Working Version -Conceptually, there are three version numbers associated with an -application using the ELF library to manipulate ELF objects: -.Bl -bullet -compact -offset indent -.It -The ELF version that the application was compiled against. -This version determines the ABI expected by the application. -.It -The ELF version of the ELF object being manipulated by the -application through the ELF library. -.It -The ELF version (or set of versions) supported by the ELF library itself. -.El -.Pp -In order to facilitate working with ELF objects of differing versions, -the ELF library requires the application to call the -.Fn elf_version -function before invoking many of its operations, in order to inform -the library of the application's desired working version. -.Pp -In the current implementation, all three versions have to be -.Dv EV_CURRENT . -.Ss Namespace use -The ELF library uses the following prefixes: -.Bl -tag -width "ELF_F_*" -.It Dv elf_ -Used for class-independent functions. -.It Dv elf32_ -Used for functions working with 32 bit ELF objects. -.It Dv elf64_ -Used for functions working with 64 bit ELF objects. -.It Dv Elf_ -Used for class-independent data types. -.It Dv ELF_C_ -Used for command values used in a few functions. -These symbols are defined as members of the -.Vt Dv Elf_Cmd -enumeration. -.It Dv ELF_E_ -Used for error numbers. -.It Dv ELF_F_ -Used for flags. -.It Dv ELF_K_ -These constants define the kind of file associated with an ELF -descriptor. -See -.Xr elf_kind 3 . -The symbols are defined by the -.Vt Elf_Kind -enumeration. -.It Dv ELF_T_ -These values are defined by the -.Vt Elf_Type -enumeration, and denote the types of ELF data structures -that can be present in an ELF object. -.El -.Pp -In addition, the library uses symbols with prefixes -.Dv _ELF -and -.Dv _libelf -for its internal use. -.Ss Descriptors -Applications communicate with the library using descriptors. -These are: -.Bl -tag -width ".Vt Elf_Data" -.It Vt Elf -An -.Vt Elf -descriptor represents an ELF object or an -.Xr ar 1 -archive. -It is allocated using one of the -.Fn elf_begin -or -.Fn elf_memory -functions. -An -.Vt Elf -descriptor can be used to read and write data to an ELF file. -An -.Vt Elf -descriptor can be associated with zero or more -.Vt Elf_Scn -section descriptors. -.Pp -Given an ELF descriptor, the application may retrieve the ELF -object's class-dependent -.Dq "Executable Header" -structures using the -.Fn elf32_getehdr -or -.Fn elf64_getehdr -functions. -A new Ehdr structure may be allocated using the -.Fn elf64_newehdr -or -.Fn elf64_newehdr -functions. -.Pp -The -.Dq "Program Header Table" -associated with an ELF descriptor may be allocated using the -.Fn elf32_getphdr -or -.Fn elf64_getphdr -functions. -A new program header table may be allocated or an existing table -resized using the -.Fn elf32_newphdr -or -.Fn elf64_newphdr -functions. -.Pp -The -.Vt Elf -structure is opaque and has no members visible to the -application. -.\" TODO describe the Elf_Arhdr and Elf_Arsym structures. -.It Vt Elf_Data -An -.Vt Elf_Data -data structure describes an individual chunk of a ELF file as -represented in memory. -It has the following application-visible members: -.Bl -tag -width ".Vt unsigned int d_version" -compact -.It Vt "uint64_t d_align" -The in-file alignment of the data buffer within its containing ELF section. -This value must be non-zero and a power of two. -.It Vt "void *d_buf" -A pointer to data in memory. -.It Vt "uint64_t d_off" -The offset with the containing section where this descriptors data -would be placed. -This field will be computed by the library unless the application -requests full control of the ELF object's layout. -.It Vt "uint64_t d_size" -The number of bytes of data in this descriptor. -.It Vt "Elf_Type d_type" -The ELF type (see below) of the data in this descriptor. -.It Vt "unsigned int d_version" -The operating version for the data in this buffer. -.El -.Pp -.Vt Elf_Data -descriptors are usually associated with -.Vt Elf_Scn -descriptors. -Existing data descriptors associated with an ELF section may be -structures are retrieved using the -.Fn elf_getdata -and -.Fn elf_rawdata -functions. -The -.Fn elf_newdata -function may be used to attach new data descriptors to an ELF section. -.It Vt Elf_Scn -.Vt Elf_Scn -descriptors represent a section in an ELF object. -.Pp -They are retrieved using the -.Fn elf_getscn -function. -An application may iterate through the existing sections of an ELF -object using the -.Fn elf_nextscn -function. -New sections may be allocated using the -.Fn elf_newscn -function. -.Pp -The -.Vt Elf_Scn -descriptor is opaque and contains no application modifiable fields. -.El -.Ss Supported Elf Types -The following ELF datatypes are supported by the library. -.Pp -.Bl -tag -width ".Dv ELF_T_SYMINFO" -compact -.It Dv ELF_T_ADDR -Machine addresses. -.It Dv ELF_T_BYTE -Byte data. -The library will not attempt to translate byte data. -.It Dv ELF_T_CAP -Software and hardware capability records. -.It Dv ELF_T_DYN -Records used in a section of type -.Dv SHT_DYNAMIC . -.It Dv ELF_T_EHDR -ELF executable header. -.It Dv ELF_T_GNUHASH -GNU-style hash tables. -.It Dv ELF_T_HALF -16-bit unsigned words. -.It Dv ELF_T_LWORD -64 bit unsigned words. -.It Dv ELF_T_MOVE -ELF Move records. -.\".It Dv ELF_T_MOVEP -.\" As yet unsupported. -.It Dv ELF_T_NOTE -ELF Note structures. -.It Dv ELF_T_OFF -File offsets. -.It Dv ELF_T_PHDR -ELF program header table entries. -.It Dv ELF_T_REL -ELF relocation entries. -.It Dv ELF_T_RELA -ELF relocation entries with addends. -.It Dv ELF_T_SHDR -ELF section header entries. -.It Dv ELF_T_SWORD -Signed 32-bit words. -.It Dv ELF_T_SXWORD -Signed 64-bit words. -.It Dv ELF_T_SYMINFO -ELF symbol information. -.It Dv ELF_T_SYM -ELF symbol table entries. -.It Dv ELF_T_VDEF -Symbol version definition records. -.It Dv ELF_T_VNEED -Symbol version requirement records. -.It Dv ELF_T_WORD -Unsigned 32-bit words. -.It Dv ELF_T_XWORD -Unsigned 64-bit words. -.El -.Pp -The symbol -.Dv ELF_T_NUM -denotes the number of Elf types known to the library. -.Pp -The following table shows the mapping between ELF section types -defined in -.Xr elf 5 -and the types supported by the library. -.Bl -column ".Dv SHT_PREINIT_ARRAY" ".Dv ELF_T_SYMINFO" -.It Em Section Type Ta Em "Library Type" Ta Em Description -.It Dv SHT_DYNAMIC Ta Dv ELF_T_DYN Ta Xo -.Sq .dynamic -section entries. -.Xc -.It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. -.It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. -.It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. -.It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. -.It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. -.It Dv SHT_NOBITS Ta Dv ELF_T_BYTE Ta Xo -Empty sections. -See -.Xr elf 5 . -.Xc -.It Dv SHT_NOTE Ta Dv ELF_T_NOTE Ta ELF note records. -.It Dv SHT_PREINIT_ARRAY Ta Dv ELF_T_ADDR Ta Pre-initialization function pointers. -.It Dv SHT_PROGBITS Ta Dv ELF_T_BYTE Ta Machine code. -.It Dv SHT_REL Ta Dv ELF_T_REL Ta ELF relocation records. -.It Dv SHT_RELA Ta Dv ELF_T_RELA Ta Relocation records with addends. -.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. -.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. -.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. -.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. -.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. -.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. -.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. -.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. -.El -.TE -.Ss Functional Grouping -This section contains a brief overview of the available functionality -in the ELF library. -Each function listed here is described further in its own manual page. -.Bl -tag -width indent -.It "Archive Access" -.Bl -tag -compact -.It Fn elf_getarsym -Retrieve the archive symbol table. -.It Fn elf_getarhdr -Retrieve the archive header for an object. -.It Fn elf_getbase -Retrieve the offset of a member inside an archive. -.It Fn elf_next -Iterate through an -.Xr ar 1 -archive. -.It Fn elf_rand -Random access inside an -.Xr ar 1 -archive. -.El -.It "Data Structures" -.Bl -tag -compact -.It Fn elf_getdata -Retrieve translated data for an ELF section. -.It Fn elf_getscn -Retrieve the section descriptor for a named section. -.It Fn elf_ndxscn -Retrieve the index for a section. -.It Fn elf_newdata -Add a new -.Vt Elf_Data -descriptor to an ELF section. -.It Fn elf_newscn -Add a new section descriptor to an ELF descriptor. -.It Fn elf_nextscn -Iterate through the sections in an ELF object. -.It Fn elf_rawdata -Retrieve untranslated data for an ELF sectino. -.It Fn elf_rawfile -Return a pointer to the untranslated file contents for an ELF object. -.It Fn elf32_getehdr , Fn elf64_getehdr -Retrieve the Executable Header in an ELF object. -.It Fn elf32_getphdr , Fn elf64_getphdr -Retrieve the Program Header Table in an ELF object. -.It Fn elf32_getshdr , Fn elf64_getshdr -Retrieve the ELF section header associated with an -.Vt Elf_Scn -descriptor. -.It Fn elf32_newehdr , Fn elf64_newehdr -Allocate an Executable Header in an ELF object. -.It Fn elf32_newphdr , Fn elf64_newphdr -Allocate or resize the Program Header Table in an ELF object. -.El -.It "Data Translation" -.Bl -tag -compact -.It Fn elf32_xlatetof , Fn elf64_xlatetof -Translate an ELF data structure from its native representation to its -file representation. -.It Fn elf32_xlatetom , Fn elf64_xlatetom -Translate an ELF data structure from its file representation to a -native representation. -.El -.It "Error Reporting" -.Bl -tag -compact -.It Fn elf_errno -Retrieve the current error. -.It Fn elf_errmsg -Retrieve a human readable description of the current error. -.El -.It "Initialization" -.Bl -tag -compact -.It Fn elf_begin -Opens an -.Xr ar 1 -archive or ELF object given a file descriptor. -.It Fn elf_end -Close an ELF descriptor and release all its resources. -.It Fn elf_memory -Opens an -.Xr ar 1 -archive or ELF object present in a memory arena. -.It Fn elf_version -Sets the operating version. -.El -.It "IO Control" -.Bl -tag -width ".Fn elf_setshstrndx" -compact -.It Fn elf_cntl -Manage the association between and ELF descriptor and its underlying file. -.It Fn elf_flagdata -Mark an -.Vt Elf_Data -descriptor as dirty. -.It Fn elf_flagehdr -Mark the ELF Executable Header in an ELF descriptor as dirty. -.It Fn elf_flagphdr -Mark the ELF Program Header Table in an ELF descriptor as dirty. -.It Fn elf_flagscn -Mark an -.Vt Elf_Scn -descriptor as dirty. -.It Fn elf_flagshdr -Mark an ELF Section Header as dirty. -.It Fn elf_setshstrndx -Set the index of the section name string table for the ELF object. -.It Fn elf_update -Recompute ELF object layout and optionally write the modified object -back to the underlying file. -.El -.It "Queries" -.Bl -tag -width ".Fn elf_getshstrndx" -compact -.It Fn elf32_checksum , Fn elf64_checkum -Compute checksum of an ELF object. -.It Fn elf_getident -Retrieve the identification bytes for an ELF object. -.It Fn elf_getshnum -Retrieve the number of sections in an ELF object. -.It Fn elf_getshstrndx -Retrieve the section index of the section name string table in -an ELF object. -.It Fn elf_hash -Compute the ELF hash value of a string. -.It Fn elf_kind -Query the kind of object associated with an ELF descriptor. -.It Fn elf32_fsize , Fn elf64_fsize -Return the size of the file representation of an ELF type. -.El -.El -.Ss Controlling ELF Object Layout -In the usual mode of operation, library will compute section -offsets and alignments based on the contents of an ELF descriptor's -sections without need for further intervention by the -application. -.Pp -However, if the application wishes to take complete charge of the -layout of the ELF file, it may set the -.Dv ELF_F_LAYOUT -flag on an ELF descriptor using -.Xr elf_flagelf 3 , -following which the library will use the data offsets and alignments -specified by the application when laying out the file. -Application control of file layout is described further in the -.Xr elf_update 3 -manual page. -.Pp -Gaps in between sections will be filled with the fill character -set by function -.Fn elf_fill . -.Ss Error Handling -In case an error is encountered, these library functions set an -internal error number and signal the presence of the error by -returning an special return value. -The application can check the -current error number by calling -.Xr elf_errno 3 . -A human readable description of the recorded error is available by -calling -.Xr elf_errmsg 3 . -.Ss Memory Management Rules -The library keeps track of all -.Vt Elf_Scn -and -.Vt Elf_Data -descriptors associated with an ELF descriptor and recovers them -when the descriptor is closed using -.Xr elf_end 3 . -Thus the application must not call -.Xr free 3 -on data structures allocated by the ELF library. -.Pp -Conversely the library will not -free data that it has not allocated. -As an example, an application may call -.Xr elf_newdata 3 -to allocate a new -.Vt Elf_Data -descriptor and can set the -.Va d_off -member of the descriptor to point to a region of memory allocated -using -.Xr malloc 3 . -It is the applications responsibility to free this arena, though the -library will reclaim the space used by the -.Vt Elf_Data -descriptor itself. -.Sh SEE ALSO -.Xr gelf 3 , -.Xr elf 5 -.Sh HISTORY -The original ELF(3) API was developed for Unix System V. -The current implementation of the ELF(3) API appeared in -.Fx 7.0 . -.Sh AUTHORS -The ELF library was written by -.An "Joseph Koshy" -.Aq jkoshy@FreeBSD.org . diff --git a/linkers/elftoolchain/libelf/elf.c b/linkers/elftoolchain/libelf/elf.c deleted file mode 100644 index e3ef7f3..0000000 --- a/linkers/elftoolchain/libelf/elf.c +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf.c 1345 2011-01-01 11:17:52Z jkoshy $"); - -struct _libelf_globals _libelf = { - .libelf_arch = LIBELF_ARCH, - .libelf_byteorder = LIBELF_BYTEORDER, - .libelf_class = LIBELF_CLASS, - .libelf_error = 0, - .libelf_fillchar = 0, - .libelf_version = EV_NONE -}; diff --git a/linkers/elftoolchain/libelf/elf_begin.3 b/linkers/elftoolchain/libelf/elf_begin.3 deleted file mode 100644 index 5a013a4..0000000 --- a/linkers/elftoolchain/libelf/elf_begin.3 +++ /dev/null @@ -1,311 +0,0 @@ -.\" Copyright (c) 2006,2008-2011 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_begin.3 1925 2011-09-23 09:34:05Z jkoshy $ -.\" -.Dd September 23, 2011 -.Os -.Dt ELF_BEGIN 3 -.Sh NAME -.Nm elf_begin -.Nd open an ELF file or ar(1) archive -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf *" -.Fn elf_begin "int fd" "Elf_Cmd cmd" "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_begin -is used to open ELF files and -.Xr ar 1 -archives for further processing by other APIs in the -.Xr elf 3 -library. -It is also used to access individual ELF members of an -.Xr ar 1 -archive in combination with the -.Xr elf_next 3 -and -.Xr elf_rand 3 -APIs. -.Pp -Argument -.Ar fd -is an open file descriptor returned from an -.Xr open 2 -system call. -Function -.Fn elf_begin -uses argument -.Ar fd -for reading or writing depending on the value of argument -.Ar cmd . -Argument -.Ar elf -is primarily used for iterating through archives. -.Pp -The argument -.Ar cmd -can have the following values: -.Bl -tag -width "ELF_C_WRITE" -.It ELF_C_NULL -Causes -.Fn elf_begin -to return NULL. -Arguments -.Ar fd -and -.Ar elf -are ignored, and no additional error is signalled. -.It ELF_C_READ -This value is to be when the application wishes to examine (but not -modify) the contents of the file specified by the arguments -.Ar fd -and -.Ar elf . -It can be used for both -.Xr ar 1 -archives and for ELF objects. -.Pp -If argument -.Ar elf -is NULL, the library will allocate a new ELF descriptor for the file -being processed. -The argument -.Ar fd -should have been opened for reading. -.Pp -If argument -.Ar elf -is not NULL, and references a regular ELF file previously opened with -.Fn elf_begin , -then the activation count for the descriptor referenced by argument -.Ar elf -is incremented. -The value in argument -.Ar fd -should match that used to open the descriptor argument -.Ar elf . -.Pp -If argument -.Ar elf -is not NULL, and references a descriptor for an -.Xr ar 1 -archive opened earlier with -.Fn elf_begin , -a descriptor for an element in the archive is returned as -described in the section -.Sx "Processing ar(1) archives" -below. -The value for argument -.Ar fd -should match that used to open the archive earlier. -.Pp -If argument -.Ar elf -is not NULL, and references an -.Xr ar 1 -archive opened earlier with -.Fn elf_memory , -then the value of the argument -.Ar fd -is ignored. -.It Dv ELF_C_RDWR -This command is used to prepare an ELF file for reading and writing. -This command is not supported for -.Xr ar 1 -archives. -.Pp -Argument -.Ar fd -should have been opened for reading and writing. -If argument -.Ar elf -is NULL, the library will allocate a new ELF descriptor for -the file being processed. -If the argument -.Ar elf -is non-null, it should point to a descriptor previously -allocated with -.Fn elf_begin -with the same values for arguments -.Ar fd -and -.Ar cmd ; -in this case the library will increment the activation count for descriptor -.Ar elf -and return the same descriptor. -.Pp -Changes to the in-memory image of the ELF file may be written back to -disk using the -.Xr elf_update 3 -function. -.It Dv ELF_C_WRITE -This command is used when the application wishes to create a new ELF -file. -Argument -.Ar fd -should have been opened for writing. -Argument -.Ar elf -is ignored, and the previous contents of file referenced by argument -.Ar fd -are overwritten. -.El -.Ss Processing ar(1) archives -An -.Xr ar 1 -archive may be opened in read mode (with argument -.Ar cmd -set to -.Dv ELF_C_READ ) -using -.Fn elf_begin -or -.Fn elf_memory . -The returned ELF descriptor can be passed into to -subsequent calls to -.Fn elf_begin -to access individual members of the archive. -.Pp -Random access within an opened archive is possible using -the -.Xr elf_next 3 -and -.Xr elf_rand 3 -functions. -.Pp -The symbol table of the archive may be retrieved -using -.Xr elf_getarsym 3 . -.Sh RETURN VALUES -The function returns a pointer to a ELF descriptor if successful, or NULL -if an error occurred. -.Sh EXAMPLES -To iterate through the members of an -.Xr ar 1 -archive, use: -.Bd -literal -offset indent -Elf_Cmd c; -Elf *ar_e, *elf_e; -\&... -c = ELF_C_READ; -if ((ar_e = elf_begin(fd, c, (Elf *) 0)) == 0) { - \&... handle error in opening the archive ... -} -while ((elf_e = elf_begin(fd, c, ar_e)) != 0) { - \&... process member referenced by elf_e here ... - c = elf_next(elf_e); - elf_end(elf_e); -} -.Ed -.Pp -To create a new ELF file, use: -.Bd -literal -offset indent -int fd; -Elf *e; -\&... -if ((fd = open("filename", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) { - \&... handle the error from open(2) ... -} -if ((e = elf_begin(fd, ELF_C_WRITE, (Elf *) 0)) == 0) { - \&... handle the error from elf_begin() ... -} -\&... create the ELF image using other elf(3) APIs ... -elf_update(e, ELF_C_WRITE); -elf_end(e); -.Ed -.Sh ERRORS -Function -.Fn elf_begin -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARCHIVE -The archive denoted by argument -.Ar elf -could not be parsed. -.It Bq Er ELF_E_ARGUMENT -The value in argument -.Ar cmd -was unrecognized. -.It Bq Er ELF_E_ARGUMENT -A non-null value for argument -.Ar elf -was specified when -.Ar cmd -was set to -.Dv ELF_C_RDWR . -.It Bq Er ELF_E_ARGUMENT -The value of argument -.Ar fd -differs from the one the ELF descriptor -.Ar elf -was created with. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -differs from the value specified when ELF descriptor -.Ar elf -was created. -.It Bq Er ELF_E_ARGUMENT -An -.Xr ar 1 -archive was opened with with -.Ar cmd -set to -.Dv ELF_C_RDWR . -.It Bq Er ELF_E_ARGUMENT -The file referenced by argument -.Ar fd -was empty. -.It Bq Er ELF_E_ARGUMENT -The underlying file for argument -.Ar fd -was of an unsupported type. -.It Bq Er ELF_E_IO -The file descriptor in argument -.Ar fd -was invalid. -.It Bq Er ELF_E_IO -The file descriptor in argument -.Ar fd -could not be read or written to. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was encountered. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_begin -was called before a working version was established with -.Xr elf_version 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_end 3 , -.Xr elf_errno 3 , -.Xr elf_memory 3 , -.Xr elf_next 3 , -.Xr elf_rand 3 , -.Xr elf_update 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_begin.c b/linkers/elftoolchain/libelf/elf_begin.c deleted file mode 100644 index a6c9e4a..0000000 --- a/linkers/elftoolchain/libelf/elf_begin.c +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_begin.c 1923 2011-09-23 09:01:13Z jkoshy $"); - -#define _LIBELF_INITSIZE (64*1024) - -/* - * Read from a device file, pipe or socket. - */ -static void * -_libelf_read_special_file(int fd, size_t *fsz) -{ - ssize_t readsz; - size_t bufsz, datasz; - unsigned char *buf, *t; - - datasz = 0; - readsz = 0; - bufsz = _LIBELF_INITSIZE; - if ((buf = malloc(bufsz)) == NULL) - goto resourceerror; - - /* - * Read data from the file descriptor till we reach EOF, or - * till an error is encountered. - */ - do { - /* Check if we need to expand the data buffer. */ - if (datasz == bufsz) { - bufsz *= 2; - if ((t = realloc(buf, bufsz)) == NULL) - goto resourceerror; - buf = t; - } - - do { - readsz = bufsz - datasz; - t = buf + datasz; - if ((readsz = read(fd, t, readsz)) <= 0) - break; - datasz += readsz; - } while (datasz < bufsz); - - } while (readsz > 0); - - if (readsz < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - assert(readsz == 0); - - /* - * Free up extra buffer space. - */ - if (bufsz > datasz) { - if (datasz > 0) { - if ((t = realloc(buf, datasz)) == NULL) - goto resourceerror; - buf = t; - } else { /* Zero bytes read. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - free(buf); - buf = NULL; - } - } - - *fsz = datasz; - return (buf); - -resourceerror: - LIBELF_SET_ERROR(RESOURCE, 0); -error: - if (buf != NULL) - free(buf); - return (NULL); -} - - -static Elf * -_libelf_open_object(int fd, Elf_Cmd c) -{ - Elf *e; - void *m; - mode_t mode; - size_t fsize; - struct stat sb; - unsigned int flags; - - assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); - - if (fstat(fd, &sb) < 0) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - mode = sb.st_mode; - fsize = (size_t) sb.st_size; - - /* - * Reject unsupported file types. - */ - if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && - !S_ISSOCK(mode)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - /* - * For ELF_C_WRITE mode, allocate and return a descriptor. - */ - if (c == ELF_C_WRITE) { - if ((e = _libelf_allocate_elf()) != NULL) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_byteorder = LIBELF_PRIVATE(byteorder); - e->e_fd = fd; - e->e_cmd = c; - if (!S_ISREG(mode)) - e->e_flags |= LIBELF_F_SPECIAL_FILE; - } - - return (e); - } - - - /* - * ELF_C_READ and ELF_C_RDWR mode. - */ - m = NULL; - flags = 0; - if (S_ISREG(mode)) { - /* - * Always map regular files in with 'PROT_READ' - * permissions. - * - * For objects opened in ELF_C_RDWR mode, when - * elf_update(3) is called, we remove this mapping, - * write file data out using write(2), and map the new - * contents back. - */ - if ((m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, - (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); - } - - flags = LIBELF_F_RAWFILE_MMAP; - } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) - flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; - else - return (NULL); - - if ((e = elf_memory(m, fsize)) == NULL) { - assert((flags & LIBELF_F_RAWFILE_MALLOC) || - (flags & LIBELF_F_RAWFILE_MMAP)); - if (flags & LIBELF_F_RAWFILE_MMAP) - (void) munmap(m, fsize); - else - free(m); - return (NULL); - } - - /* ar(1) archives aren't supported in RDWR mode. */ - if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { - (void) elf_end(e); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - e->e_flags |= flags; - e->e_fd = fd; - e->e_cmd = c; - - return (e); -} - -Elf * -elf_begin(int fd, Elf_Cmd c, Elf *a) -{ - Elf *e; - - e = NULL; - - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - switch (c) { - case ELF_C_NULL: - return (NULL); - - case ELF_C_WRITE: - /* - * The ELF_C_WRITE command is required to ignore the - * descriptor passed in. - */ - a = NULL; - break; - - case ELF_C_RDWR: - if (a != NULL) { /* not allowed for ar(1) archives. */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - /*FALLTHROUGH*/ - case ELF_C_READ: - /* - * Descriptor `a' could be for a regular ELF file, or - * for an ar(1) archive. If descriptor `a' was opened - * using a valid file descriptor, we need to check if - * the passed in `fd' value matches the original one. - */ - if (a && - ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - break; - - default: - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - - } - - if (a == NULL) - e = _libelf_open_object(fd, c); - else if (a->e_kind == ELF_K_AR) - e = _libelf_ar_open_member(a->e_fd, c, a); - else - (e = a)->e_activations++; - - return (e); -} diff --git a/linkers/elftoolchain/libelf/elf_cntl.3 b/linkers/elftoolchain/libelf/elf_cntl.3 deleted file mode 100644 index 32649d1..0000000 --- a/linkers/elftoolchain/libelf/elf_cntl.3 +++ /dev/null @@ -1,111 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_cntl.3 289 2009-01-08 08:26:08Z jkoshy $ -.\" -.Dd August 9, 2006 -.Os -.Dt ELF_CNTL 3 -.Sh NAME -.Nm elf_cntl -.Nd control an elf file descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_cntl "Elf *elf" "Elf_Cmd cmd" -.Sh DESCRIPTION -Function -.Fn elf_cntl -controls the ELF library's subsequent use of the file descriptor -used to create ELF descriptor -.Ar elf . -.Pp -Argument -.Ar cmd -informs the library of the action to be taken: -.Bl -tag -width "ELF_C_FDDONE" -.It Dv ELF_C_FDDONE -This value instructs the ELF library not to perform any further -I/O on the file descriptor associated with argument -.Ar elf . -For ELF descriptors opened with mode -.Ar ELF_C_WRITE -or -.Ar ELF_C_RDWR -subsequent -.Fn elf_update -operations on the descriptor will fail. -.It Dv ELF_C_FDREAD -This value instructs the ELF library to read in all necessary -data associated with ELF descriptor -.Ar elf -into memory so that the underlying file descriptor can be -safely closed with command -.Dv ELF_C_FDDONE . -.El -.Pp -Argument -.Ar elf -must be an ELF descriptor associated with a file system object -(e.g., an -.Xr ar 1 -archive, an ELF file, or other data file). -.Sh IMPLEMENTATION NOTES -Due to use of -.Xr mmap 2 -internally, this function is a no-op for ELF objects opened in -.Dv ELF_C_READ -mode. -.Sh RETURN VALUES -Function -.Fn elf_cntl -returns 0 on success, or -1 if an error was detected. -.Sh ERRORS -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARCHIVE -Argument -.Ar elf -is a descriptor for an archive member. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -was not recognized. -.It Bq Er ELF_E_MODE -An -.Dv ELF_C_FDREAD -operation was requested on an ELF descriptor opened -for writing. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_next 3 , -.Xr elf_update 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_cntl.c b/linkers/elftoolchain/libelf/elf_cntl.c deleted file mode 100644 index 2021917..0000000 --- a/linkers/elftoolchain/libelf/elf_cntl.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_cntl.c 189 2008-07-20 10:38:08Z jkoshy $"); - -int -elf_cntl(Elf *e, Elf_Cmd c) -{ - if (e == NULL || - (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if (e->e_parent) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (-1); - } - - if (c == ELF_C_FDREAD) { - if (e->e_cmd == ELF_C_WRITE) { - LIBELF_SET_ERROR(MODE, 0); - return (-1); - } - else - return (0); - } - - e->e_fd = -1; - return 0; -} diff --git a/linkers/elftoolchain/libelf/elf_data.c b/linkers/elftoolchain/libelf/elf_data.c deleted file mode 100644 index 5ac6453..0000000 --- a/linkers/elftoolchain/libelf/elf_data.c +++ /dev/null @@ -1,247 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_data.c 1765 2011-08-22 05:59:05Z jkoshy $"); - -Elf_Data * -elf_getdata(Elf_Scn *s, Elf_Data *d) -{ - Elf *e; - size_t fsz, msz, count; - int elfclass, elftype; - unsigned int sh_type; - uint64_t sh_align, sh_offset, sh_size; - int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - if (s == NULL || (e = s->s_elf) == NULL || - (d != NULL && s != d->d_scn)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) - return (d); - - if (d != NULL) - return (STAILQ_NEXT(d, d_next)); - - if (e->e_rawfile == NULL) { - /* - * In the ELF_C_WRITE case, there is no source that - * can provide data for the section. - */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - elfclass = e->e_class; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - - if (elfclass == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || - elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && - sh_offset + sh_size > (uint64_t) e->e_rawsize)) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (elftype, (size_t) 1, e->e_version)) == 0) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (sh_size % fsz) { - LIBELF_SET_ERROR(SECTION, 0); - return (NULL); - } - - count = sh_size / fsz; - - msz = _libelf_msize(elftype, elfclass, e->e_version); - - assert(msz > 0); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_buf = NULL; - d->d_off = 0; - d->d_align = sh_align; - d->d_size = msz * count; - d->d_type = elftype; - d->d_version = e->e_version; - - if (sh_type == SHT_NOBITS || sh_size == 0) { - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - return (d); - } - - if ((d->d_buf = malloc(msz*count)) == NULL) { - (void) _libelf_release_data(d); - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_flags |= LIBELF_F_DATA_MALLOCED; - - xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); - if (!(*xlate)(d->d_buf, d->d_size, e->e_rawfile + sh_offset, count, - e->e_byteorder != LIBELF_PRIVATE(byteorder))) { - _libelf_release_data(d); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - return (d); -} - -Elf_Data * -elf_newdata(Elf_Scn *s) -{ - Elf *e; - Elf_Data *d; - - if (s == NULL || (e = s->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - /* - * elf_newdata() has to append a data descriptor, so - * bring in existing section data if not already present. - */ - if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) - if (elf_getdata(s, NULL) == NULL) - return (NULL); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - STAILQ_INSERT_TAIL(&s->s_data, d, d_next); - - d->d_align = 1; - d->d_buf = NULL; - d->d_off = (uint64_t) ~0; - d->d_size = 0; - d->d_type = ELF_T_BYTE; - d->d_version = LIBELF_PRIVATE(version); - - (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); - - return (d); -} - -/* - * Retrieve a data descriptor for raw (untranslated) data for section - * `s'. - */ - -Elf_Data * -elf_rawdata(Elf_Scn *s, Elf_Data *d) -{ - Elf *e; - int elf_class; - uint32_t sh_type; - uint64_t sh_align, sh_offset, sh_size; - - if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(e->e_kind == ELF_K_ELF); - - if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) - return (d); - - if (d != NULL) - return (STAILQ_NEXT(d, d_next)); - - elf_class = e->e_class; - - assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); - - if (elf_class == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_offset = s->s_shdr.s_shdr64.sh_offset; - sh_size = s->s_shdr.s_shdr64.sh_size; - sh_align = s->s_shdr.s_shdr64.sh_addralign; - } - - if (sh_type == SHT_NULL) - return (NULL); - - if ((d = _libelf_allocate_data(s)) == NULL) - return (NULL); - - d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : - e->e_rawfile + sh_offset; - d->d_off = 0; - d->d_align = sh_align; - d->d_size = sh_size; - d->d_type = ELF_T_BYTE; - d->d_version = e->e_version; - - STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); - - return (d); -} diff --git a/linkers/elftoolchain/libelf/elf_end.3 b/linkers/elftoolchain/libelf/elf_end.3 deleted file mode 100644 index 8649faa..0000000 --- a/linkers/elftoolchain/libelf/elf_end.3 +++ /dev/null @@ -1,76 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_end.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 29, 2006 -.Os -.Dt ELF_END 3 -.Sh NAME -.Nm elf_end -.Nd release an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_end "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_end -is used to release the resources associated with an ELF descriptor -pointed to by argument -.Ar elf . -This descriptor must have been allocated by a previous call to -.Xr elf_begin 3 -or -.Xr elf_memory 3 . -For programming convenience, a NULL value is permitted for argument -.Ar elf . -.Pp -A call to -.Fn elf_end -decrements the activation count for descriptor -.Ar elf -by one. -The resources associated with the descriptor are only released -with its activation count goes to zero. -.Pp -Once function -.Fn elf_end -returns zero, the ELF descriptor -.Ar elf -will no longer be valid and should not be used further. -.Sh RETURN VALUES -Function -.Fn elf_end -returns the current value of the ELF descriptor -.Ar elf Ap s -activation count, or zero if argument -.Ar elf -was NULL. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_memory 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_end.c b/linkers/elftoolchain/libelf/elf_end.c deleted file mode 100644 index 136ed9a..0000000 --- a/linkers/elftoolchain/libelf/elf_end.c +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2009,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_end.c 1922 2011-09-23 08:04:33Z jkoshy $"); - -int -elf_end(Elf *e) -{ - Elf *sv; - Elf_Scn *scn, *tscn; - - if (e == NULL || e->e_activations == 0) - return (0); - - if (--e->e_activations > 0) - return (e->e_activations); - - assert(e->e_activations == 0); - - while (e && e->e_activations == 0) { - switch (e->e_kind) { - case ELF_K_AR: - /* - * If we still have open child descriptors, we - * need to defer reclaiming resources till all - * the child descriptors for the archive are - * closed. - */ - if (e->e_u.e_ar.e_nchildren > 0) - return (0); - break; - case ELF_K_ELF: - /* - * Reclaim all section descriptors. - */ - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, - tscn) - scn = _libelf_release_scn(scn); - break; - case ELF_K_NUM: - assert(0); - default: - break; - } - - if (e->e_rawfile) { - if (e->e_flags & LIBELF_F_RAWFILE_MMAP) - (void) munmap(e->e_rawfile, e->e_rawsize); - else if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) - free(e->e_rawfile); - } - - sv = e; - if ((e = e->e_parent) != NULL) - e->e_u.e_ar.e_nchildren--; - sv = _libelf_release_elf(sv); - } - - return (0); -} diff --git a/linkers/elftoolchain/libelf/elf_errmsg.3 b/linkers/elftoolchain/libelf/elf_errmsg.3 deleted file mode 100644 index 822ba6a..0000000 --- a/linkers/elftoolchain/libelf/elf_errmsg.3 +++ /dev/null @@ -1,107 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_errmsg.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 11, 2006 -.Os -.Dt ELF_ERRMSG 3 -.Sh NAME -.Nm elf_errmsg , -.Nm elf_errno -.Nd ELF library error message handling -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_errno "void" -.Ft "const char *" -.Fn elf_errmsg "int error" -.Sh DESCRIPTION -When an error occurs during an ELF library API call, the library -encodes the error using an error number and stores the error number -internally for retrieval by the application at a later point of time. -Error numbers may contain an OS supplied error code in addition to -an ELF API specific error code. -An error number value of zero indicates no error. -.Pp -Function -.Fn elf_errno -is used to retrieve the last error recorded by the ELF library. -Invoking this function has the side-effect of resetting the -ELF library's recorded error number to zero. -.Pp -The function -.Fn elf_errmsg -returns a null-terminated string with a human readable -description of the error specified in argument -.Ar error . -A zero value for argument -.Ar error -retrieves the most recent error encountered by the ELF -library. -An argument value of -1 behaves identically, except that -it guarantees a non-NULL return from -.Fn elf_errmsg . -.Sh RETURN VALUES -Function -.Fn elf_errno -returns a non-zero value encoding the last error encountered -by the ELF library, or zero if no error was encountered. -.Pp -Function -.Fn elf_errmsg -returns a pointer to library local storage for non-zero values -of argument -.Ar error . -With a zero argument, the function will return a NULL pointer if no -error had been encountered by the library, or will return a pointer to -library local storage containing an appropriate message otherwise. -.Sh EXAMPLES -Clearing the ELF library's recorded error number can be accomplished -by invoking -.Fn elf_errno -and discarding its return value. -.Bd -literal -offset indent -/* clear error */ -(void) elf_errno(); -.Ed -.Pp -Retrieving a human-readable description of the current error number -can be done with the following snippet: -.Bd -literal -offset indent -int err; -const char *errmsg; -\&... -err = elf_errno(); -if (err != 0) - errmsg = elf_errmsg(err); -.Ed -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 -.Sh BUGS -Function -.Fn elf_errmsg -is not localized. diff --git a/linkers/elftoolchain/libelf/elf_errmsg.c b/linkers/elftoolchain/libelf/elf_errmsg.c deleted file mode 100644 index 7a6e552..0000000 --- a/linkers/elftoolchain/libelf/elf_errmsg.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_errmsg.c 1345 2011-01-01 11:17:52Z jkoshy $"); - -/* - * Retrieve a human readable translation for an error message. - */ - -const char *_libelf_errors[] = { -#define DEFINE_ERROR(N,S) [ELF_E_##N] = S - DEFINE_ERROR(NONE, "No Error"), - DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), - DEFINE_ERROR(ARGUMENT, "Invalid argument"), - DEFINE_ERROR(CLASS, "ELF class mismatch"), - DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), - DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), - DEFINE_ERROR(IO, "I/O error"), - DEFINE_ERROR(LAYOUT, "Layout constraint violation"), - DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), - DEFINE_ERROR(RANGE, "Value out of range of target"), - DEFINE_ERROR(RESOURCE, "Resource exhaustion"), - DEFINE_ERROR(SECTION, "Invalid section descriptor"), - DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), - DEFINE_ERROR(UNIMPL, "Unimplemented feature"), - DEFINE_ERROR(VERSION, "Unknown ELF API version"), - DEFINE_ERROR(NUM, "Unknown error") -#undef DEFINE_ERROR -}; - -const char * -elf_errmsg(int error) -{ - int oserr; - - if (error == ELF_E_NONE && - (error = LIBELF_PRIVATE(error)) == 0) - return NULL; - else if (error == -1) - error = LIBELF_PRIVATE(error); - - oserr = error >> LIBELF_OS_ERROR_SHIFT; - error &= LIBELF_ELF_ERROR_MASK; - - if (error < ELF_E_NONE || error >= ELF_E_NUM) - return _libelf_errors[ELF_E_NUM]; - if (oserr) { - (void) snprintf(LIBELF_PRIVATE(msg), - sizeof(LIBELF_PRIVATE(msg)), "%s: %s", - _libelf_errors[error], strerror(oserr)); - return (const char *)&LIBELF_PRIVATE(msg); - } - return _libelf_errors[error]; -} diff --git a/linkers/elftoolchain/libelf/elf_errno.c b/linkers/elftoolchain/libelf/elf_errno.c deleted file mode 100644 index 95e91b9..0000000 --- a/linkers/elftoolchain/libelf/elf_errno.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_errno.c 1345 2011-01-01 11:17:52Z jkoshy $"); - -int -elf_errno(void) -{ - int old; - - old = LIBELF_PRIVATE(error); - LIBELF_PRIVATE(error) = 0; - return (old & LIBELF_ELF_ERROR_MASK); -} diff --git a/linkers/elftoolchain/libelf/elf_fill.3 b/linkers/elftoolchain/libelf/elf_fill.3 deleted file mode 100644 index ab42a42..0000000 --- a/linkers/elftoolchain/libelf/elf_fill.3 +++ /dev/null @@ -1,52 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_fill.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 11, 2006 -.Os -.Dt ELF_FILL 3 -.Sh NAME -.Nm elf_fill -.Nd set fill byte for inter-section padding -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft void -.Fn elf_fill "int fill" -.Sh DESCRIPTION -Function -.Fn elf_fill -allows an application to specify a fill value for the padding inserted -between two sections of an ELF file to meet section alignment -constraints. -By default the ELF library uses zero bytes for padding. -.Pp -The ELF library will only pad bytes if the -.Dv ELF_F_LAYOUT -flag is not set for the ELF file. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagelf 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_fill.c b/linkers/elftoolchain/libelf/elf_fill.c deleted file mode 100644 index ac9e02e..0000000 --- a/linkers/elftoolchain/libelf/elf_fill.c +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_fill.c 189 2008-07-20 10:38:08Z jkoshy $"); - -void -elf_fill(int fill) -{ - LIBELF_PRIVATE(fillchar) = fill; -} diff --git a/linkers/elftoolchain/libelf/elf_flag.c b/linkers/elftoolchain/libelf/elf_flag.c deleted file mode 100644 index 9d31719..0000000 --- a/linkers/elftoolchain/libelf/elf_flag.c +++ /dev/null @@ -1,195 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2009,2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_flag.c 1918 2011-09-22 10:42:06Z jkoshy $"); - -unsigned int -elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) -{ - unsigned int r; - - if (a == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = a->ar_flags |= flags; - else - r = a->ar_flags &= ~flags; - - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) -{ - unsigned int r; - - if (d == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = d->d_flags |= flags; - else - r = d->d_flags &= ~flags; - - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *ehdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || - (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV | - ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if (c == ELF_C_SET) - r = e->e_flags |= flags; - else - r = e->e_flags &= ~flags; - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) -{ - int ec; - void *phdr; - - if (e == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) - phdr = e->e_u.e_elf.e_phdr.e_phdr32; - else - phdr = e->e_u.e_elf.e_phdr.e_phdr64; - - if (phdr == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (0); - } - - return (elf_flagelf(e, c, flags)); -} - -unsigned int -elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - int r; - - if (s == NULL) - return (0); - - if ((c != ELF_C_SET && c != ELF_C_CLR) || - (flags & ~ELF_F_DIRTY) != 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (c == ELF_C_SET) - r = s->s_flags |= flags; - else - r = s->s_flags &= ~flags; - return (r & LIBELF_F_API_MASK); -} - -unsigned int -elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) -{ - return (elf_flagscn(s, c, flags)); -} diff --git a/linkers/elftoolchain/libelf/elf_flagdata.3 b/linkers/elftoolchain/libelf/elf_flagdata.3 deleted file mode 100644 index d4fd420..0000000 --- a/linkers/elftoolchain/libelf/elf_flagdata.3 +++ /dev/null @@ -1,194 +0,0 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_flagdata.3 221 2008-08-10 04:56:27Z jkoshy $ -.\" -.Dd October 22, 2007 -.Os -.Dt ELF_FLAGDATA 3 -.Sh NAME -.Nm elf_flagarhdr , -.Nm elf_flagdata , -.Nm elf_flagehdr , -.Nm elf_flagelf , -.Nm elf_flagphdr , -.Nm elf_flagscn , -.Nm elf_flagshdr -.Nd manipulate flags associated with ELF(3) data structures -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "unsigned int" -.Fn elf_flagarhdr "Elf_Arhdr *arhdr" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagdata "Elf_Data *data" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagehdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagelf "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagphdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagscn "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" -.Ft "unsigned int" -.Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" -.Sh DESCRIPTION -These functions are used to query, set or reset flags on data -structures associated with an ELF file. -.Pp -Arguments -.Ar arhdr , -.Ar data , -.Ar elf -and -.Ar scn -denote the data structures whose flags need to be changed. -These values are allowed to be NULL to simplify error handling in -application code. -.Pp -Argument -.Ar cmd -may have the following values: -.Bl -tag -width ELF_C_SET -.It Dv ELF_C_CLR -The argument -.Ar flags -specifies the flags to be cleared. -.It Dv ELF_C_SET -The argument -.Ar flags -specifies the flags to be set. -.El -.Pp -The argument -.Ar flags -is allowed to have the following flags set: -.Bl -tag -width ELF_F_ARCHIVE_SYSV -.It Dv ELF_F_ARCHIVE -This flag is only valid with the -.Fn elf_flagelf -API. -It informs the library that the application desires to create an -.Xr ar 1 -archive. -Argument -.Ar elf -should have been opened for writing using the -.Dv ELF_C_WRITE -command to function -.Fn elf_begin . -.It Dv ELF_F_ARCHIVE_SYSV -This flag is used in conjunction with the -.Dv ELF_F_ARCHIVE -flag to indicate that library should create archives that conform -to System V layout rules. -The default is to create BSD style archives. -.It Dv ELF_F_DIRTY -Mark the associated data structure as needing to be written back -to the underlying file. -A subsequent call to -.Xr elf_update 3 -will resynchronize the library's internal data structures. -.It Dv ELF_F_LAYOUT -This flag is only valid with the -.Fn elf_flagelf -API. -It informs the library that the application will take -responsibility for the layout of the file and that the library is -not to insert any padding in between sections. -.El -.Pp -Marking a given data structure as -.Dq dirty -affects all of its contained elements. -Thus marking an ELF descriptor -.Ar elf -with -.Fn elf_flagelf "elf" "ELF_C_SET" "ELF_F_DIRTY" -means that the entire contents of the descriptor are -.Dq dirty . -.Pp -Using a value of zero for argument -.Ar flags -will return the current set of flags for the data structure being -queried. -.Sh RETURN VALUES -These functions return the updated flags is successful, and zero if -an error is detected. -.Sh COMPATIBILITY -The -.Fn elf_flagarhdr -function and the -.Dv ELF_F_ARCHIVE -and -.Dv ELF_F_ARCHIVE_SYSV -flags are an extension to the ELF(3) API. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -An unsupported value was used for the -.Ar cmd -argument. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar flags -had unsupported flags set. -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_MODE -The -.Dv ELF_F_ARCHIVE -flag was used with an ELF descriptor that had not been opened for writing. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_flagehdr -was called without an executable header being allocated. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_flagphdr -was called without a program header being allocated. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_newehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf32_newshdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf64_newshdr 3 , -.Xr elf_newdata 3 , -.Xr elf_update 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr gelf_newphdr 3 , -.Xr gelf_newshdr 3 , -.Xr gelf_update_dyn 3 , -.Xr gelf_update_move 3 , -.Xr gelf_update_rel 3 , -.Xr gelf_update_rela 3 , -.Xr gelf_update_sym 3 , -.Xr gelf_update_syminfo 3 diff --git a/linkers/elftoolchain/libelf/elf_getarhdr.3 b/linkers/elftoolchain/libelf/elf_getarhdr.3 deleted file mode 100644 index 1aab71c..0000000 --- a/linkers/elftoolchain/libelf/elf_getarhdr.3 +++ /dev/null @@ -1,97 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getarhdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 15, 2006 -.Os -.Dt ELF_GETARHDR 3 -.Sh NAME -.Nm elf_getarhdr -.Nd retrieve ar(1) header for an archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Arhdr *" -.Fn elf_getarhdr "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_getarhdr -function returns a pointer to an archive member header for -a descriptor -.Ar elf . -This descriptor must have been returned by a prior call to -.Xr elf_begin 3 , -and must be a descriptor for a member inside an -.Xr ar 1 -archive. -.Pp -Structure -.Vt Elf_Arhdr -includes the following members: -.Bl -tag -width indent -.It Vt "char *" Va ar_name -A pointer to a null terminated string containing the translated -name of the archive member. -.It Vt "char *" Va ar_rawname -A pointer to a null terminated string containing the untranslated -name for the archive member, including all -.Xr ar 1 -formatting characters and trailing white space. -.It Vt time_t Va ar_date -The timestamp associated with the member. -.It Vt uid_t Va ar_uid -The uid of the creator of the member. -.It Vt gid_t Va ar_gid -The gid of the creator of the member. -.It Vt mode_t Va ar_mode -The file mode of the member. -.It Vt size_t Va ar_size -The size of the member in bytes. -.El -.Sh RETURN VALUES -This function returns a valid pointer to an -.Vt Elf_Arhdr -structure if successful, or NULL if an error is encountered. -.Sh ERRORS -Function -.Fn elf_getarhdr -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for a member of an -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getarsym 3 , -.Xr elf_memory 3 diff --git a/linkers/elftoolchain/libelf/elf_getarhdr.c b/linkers/elftoolchain/libelf/elf_getarhdr.c deleted file mode 100644 index 43ceafd..0000000 --- a/linkers/elftoolchain/libelf/elf_getarhdr.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_getarhdr.c 1341 2011-01-01 04:28:29Z jkoshy $"); - -Elf_Arhdr * -elf_getarhdr(Elf *e) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (e->e_flags & LIBELF_F_AR_HEADER) - return (e->e_hdr.e_arhdr); - - return (_libelf_ar_gethdr(e)); -} diff --git a/linkers/elftoolchain/libelf/elf_getarsym.3 b/linkers/elftoolchain/libelf/elf_getarsym.3 deleted file mode 100644 index cda0511..0000000 --- a/linkers/elftoolchain/libelf/elf_getarsym.3 +++ /dev/null @@ -1,130 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getarsym.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 15, 2006 -.Os -.Dt ELF_GETARSYM 3 -.Sh NAME -.Nm elf_getarsym -.Nd retrieve the symbol table of an archive -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Arsym *" -.Fn elf_getarsym "Elf *elf" "size_t *ptr" -.Sh DESCRIPTION -The function -.Fn elf_getarsym -retrieves the symbol table for an -.Xr ar 1 -archive, if one is available. -.Pp -Argument -.Ar elf -should be a descriptor for an -.Xr ar 1 -archive opened using -.Fn elf_begin -or -.Fn elf_memory . -.Pp -If the archive -.Ar elf -contains a symbol table with n entries, this function returns a -pointer to an array of n+1 -.Vt Elf_Arsym -structures. -An -.Vt Elf_Arsym -structure has the following elements: -.Bl -tag -width indent -compact -.It Vt "char *" Va as_name -This structure member is a pointer to a null-terminated symbol name. -.It Vt "off_t" Va as_off -This structure member contains the byte offset from the beginning of the archive to -the header for the archive member. -This value is suitable for use with -.Xr elf_rand 3 . -.It Vt "unsigned long" Va as_hash -This structure member contains a portable hash value for the symbol -name, as computed by -.Xr elf_hash 3 . -.El -.Pp -The last entry of the returned array will have a NULL value for member -.Va as_name , -a zero value for member -.Va as_off -and an illegal value of ~0UL for -.Va as_hash . -.Pp -If argument -.Ar ptr -is non-null, the -.Fn elf_getarsym -function will store the number of table entries returned (including the -sentinel entry at the end) into the location it points to. -.Sh RETURN VALUES -Function -.Fn elf_getarsym -returns a pointer to an array of -.Vt Elf_Arsym -structures if successful, or a NULL -pointer if an error was encountered. -.Pp -If argument -.Ar ptr -is non-null and there was no error, the library will store the -number of archive symbol entries returned into the location it -points to. -If argument -.Ar ptr -is non-null and an error was encountered, the library will -set the location pointed to by it to zero. -.Sh ERRORS -Function -.Fn elf_getarsym -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getarhdr 3 , -.Xr elf_hash 3 , -.Xr elf_memory 3 , -.Xr elf_next 3 , -.Xr elf_rand 3 diff --git a/linkers/elftoolchain/libelf/elf_getarsym.c b/linkers/elftoolchain/libelf/elf_getarsym.c deleted file mode 100644 index 1852262..0000000 --- a/linkers/elftoolchain/libelf/elf_getarsym.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_getarsym.c 1360 2011-01-08 08:27:41Z jkoshy $"); - -Elf_Arsym * -elf_getarsym(Elf *ar, size_t *ptr) -{ - size_t n; - Elf_Arsym *symtab; - - n = 0; - symtab = NULL; - - if (ar == NULL || ar->e_kind != ELF_K_AR) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) - n = ar->e_u.e_ar.e_symtabsz; - else if (ar->e_u.e_ar.e_rawsymtab) - symtab = (ar->e_flags & LIBELF_F_AR_VARIANT_SVR4) ? - _libelf_ar_process_svr4_symtab(ar, &n) : - _libelf_ar_process_bsd_symtab(ar, &n); - else - LIBELF_SET_ERROR(ARCHIVE, 0); - - if (ptr) - *ptr = n; - return (symtab); -} diff --git a/linkers/elftoolchain/libelf/elf_getbase.3 b/linkers/elftoolchain/libelf/elf_getbase.3 deleted file mode 100644 index fa17353..0000000 --- a/linkers/elftoolchain/libelf/elf_getbase.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getbase.3 978 2010-06-06 12:40:19Z jkoshy $ -.\" -.Dd June 6, 2010 -.Os -.Dt ELF_GETBASE 3 -.Sh NAME -.Nm elf_getbase -.Nd get the base offset for an object file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_getbase "Elf *elf" -.Sh DESCRIPTION -Function -.Fn elf_getbase -returns the file offset to the first byte of the object referenced by ELF -descriptor -.Ar elf . -.Pp -For descriptors referencing members of archives, the returned offset is -the file offset of the member in its containing archive. -For descriptors to regular objects, the returned offset is (vacuously) -zero. -.Sh RETURN VALUES -Function -.Fn elf_getbase -returns a valid file offset if successful, or -.Pq Vt off_t -.Li -1 -in case of an error. -.Sh ERRORS -Function -.Fn elf_getbase -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getarhdr 3 , -.Xr elf_getident 3 , -.Xr elf_rawfile 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_getbase.c b/linkers/elftoolchain/libelf/elf_getbase.c deleted file mode 100644 index 30058ca..0000000 --- a/linkers/elftoolchain/libelf/elf_getbase.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_getbase.c 977 2010-06-06 11:50:31Z jkoshy $"); - -off_t -elf_getbase(Elf *e) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return ((off_t) -1); - } - - if (e->e_parent == NULL) - return ((off_t) 0); - - return ((off_t) ((uintptr_t) e->e_rawfile - - (uintptr_t) e->e_parent->e_rawfile)); -} diff --git a/linkers/elftoolchain/libelf/elf_getdata.3 b/linkers/elftoolchain/libelf/elf_getdata.3 deleted file mode 100644 index 8816a5a..0000000 --- a/linkers/elftoolchain/libelf/elf_getdata.3 +++ /dev/null @@ -1,229 +0,0 @@ -.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getdata.3 1766 2011-08-22 06:01:03Z jkoshy $ -.\" -.Dd January 26, 2011 -.Os -.Dt ELF_GETDATA 3 -.Sh NAME -.Nm elf_getdata , -.Nm elf_newdata , -.Nm elf_rawdata -.Nd iterate through or allocate section data -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Data *" -.Fn elf_getdata "Elf_Scn *scn" "Elf_Data *data" -.Ft "Elf_Data *" -.Fn elf_newdata "Elf_Scn *scn" -.Ft "Elf_Data *" -.Fn elf_rawdata "Elf_Scn *scn" "Elf_Data *data" -.Sh DESCRIPTION -These functions are used to access and manipulate data descriptors -associated with section descriptors. -Data descriptors used by the ELF library are described in -.Xr elf 3 . -.Pp -Function -.Fn elf_getdata -will return the next data descriptor associated with section descriptor -.Ar scn . -The returned data descriptor will be setup to contain translated data. -Argument -.Ar data -may be NULL, in which case the function returns the first data descriptor -associated with section -.Ar scn . -If argument -.Ar data -is not NULL, it must be a pointer to a data descriptor associated with -section descriptor -.Ar scn , -and function -.Fn elf_getdata -will return a pointer to the next data descriptor for the section, -or NULL when the end of the section's descriptor list is reached. -.Pp -Function -.Fn elf_newdata -will allocate a new data descriptor and append it to the list of data -descriptors associated with section descriptor -.Ar scn . -The new data descriptor will be initialized as follows: -.Bl -tag -width "d_version" -compact -offset indent -.It Va d_align -Set to 1. -.It Va d_buf -Initialized to NULL. -.It Va d_off -Set to (off_t) -1. -This field is under application control if the -.Dv ELF_F_LAYOUT -flag was set on the ELF descriptor. -.It Va d_size -Set to zero. -.It Va d_type -Initialized to -.Dv ELF_T_BYTE . -.It Va d_version -Set to the current working version of the library, as set by -.Xr elf_version 3 . -.El -The application must set these values as appropriate before -calling -.Xr elf_update 3 . -Section -.Ar scn -must be associated with an ELF file opened for writing. -If the application has not requested full control of layout by -setting the -.Dv ELF_F_LAYOUT -flag on descriptor -.Ar elf , -then the data referenced by the returned descriptor will be positioned -after the existing content of the section, honoring the file alignment -specified in member -.Va d_align . -On successful completion of a call to -.Fn elf_newdata , -the ELF library will mark the section -.Ar scn -as -.Dq dirty . -.Pp -Function -.Fn elf_rawdata -is used to step through the data descriptors associated with -section -.Ar scn . -In contrast to function -.Fn elf_getdata , -this function returns untranslated data. -If argument -.Ar data -is NULL, the first data descriptor associated with section -.Ar scn -is returned. -If argument -.Ar data -is not NULL, is must be a data descriptor associated with -section -.Ar scn , -and function -.Fn elf_rawdata -will return the next data descriptor in the list, or NULL -if no further descriptors are present. -Function -.Fn elf_rawdata -always returns -.Vt Elf_Data -structures of type -.Dv ELF_T_BYTE . -.Ss Special handling of zero-sized and SHT_NOBITS sections -For sections of type -.Dv SHT_NOBITS, -and for zero-sized sections, -the functions -.Fn elf_getdata -and -.Fn elf_rawdata -return a pointer to a valid -.Vt Elf_Data -structure that has its -.Va d_buf -member set to NULL and its -.Va d_size -member set to the size of the section. -.Pp -If an application wishes to create a section of type -.Dv SHT_NOBITS , -it should add a data buffer to the section using function -.Fn elf_newdata . -It should then set the -.Va d_buf -and -.Va d_size -members of the returned -.Vt Elf_Data -structure to NULL and the desired size of the section respectively. -.Sh RETURN VALUES -These functions return a valid pointer to a data descriptor if successful, or -NULL if an error occurs. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Either of the arguments -.Ar scn -or -.Ar data -was NULL. -.It Bq Er ELF_E_ARGUMENT -The data descriptor referenced by argument -.Ar data -is not associated with section descriptor -.Ar scn . -.It Bq Er ELF_E_ARGUMENT -The section denoted by argument -.Ar scn -had no data associated with it. -.It Bq Er ELF_E_DATA -Retrieval of data from the underlying object failed. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -Section -.Ar scn -had type -.Dv SHT_NULL . -.It Bq Er ELF_E_SECTION -The type of the section -.Ar scn -was not recognized by the library. -.It Bq Er ELF_E_SECTION -The size of the section -.Ar scn -is not a multiple of the file size for its section type. -.It Bq Er ELF_E_SECTION -The file offset for section -.Ar scn -is incorrect. -.It Bq Er ELF_E_UNIMPL -The section type associated with section -.Ar scn -is currently unsupported by the library. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagdata 3 , -.Xr elf_flagscn 3 , -.Xr elf_getscn 3 , -.Xr elf_getshdr 3 , -.Xr elf_newscn 3 , -.Xr elf_rawfile 3 , -.Xr elf_update 3 , -.Xr elf_version 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_getident.3 b/linkers/elftoolchain/libelf/elf_getident.3 deleted file mode 100644 index 01d7f97..0000000 --- a/linkers/elftoolchain/libelf/elf_getident.3 +++ /dev/null @@ -1,83 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getident.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd July 3, 2006 -.Os -.Dt ELF_GETIDENT 3 -.Sh NAME -.Nm elf_getident -.Nd return the initial bytes of a file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft char * -.Fn elf_getident "Elf *elf" "size_t *sz" -.Sh DESCRIPTION -Function -.Fn elf_getident -returns a pointer to the initial bytes of the file for descriptor -.Ar elf . -.Pp -If argument -.Ar sz -is non-null, the size of the identification area returned is written -to the location pointed to by -.Ar sz . -This location is set to zero on errors. -.Sh RETURN VALUES -Function -.Fn elf_getident -will return a non-NULL pointer to the initial bytes of the file if -successful, or NULL if an error condition is detected. -.Sh ERRORS -Function -.Fn elf_getident -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_SEQUENCE -ELF descriptor -.Ar elf -was opened for writing and function -.Fn elf_getident -was called before a call to -.Xr elf_update 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getarhdr 3 , -.Xr elf_getbase 3 , -.Xr elf_getflags 3 , -.Xr elf_kind 3 , -.Xr elf_rawfile 3 , -.Xr elf_update 3 , -.Xr gelf 3 , -.Xr gelf_getclass 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getident.c b/linkers/elftoolchain/libelf/elf_getident.c deleted file mode 100644 index c17f3a5..0000000 --- a/linkers/elftoolchain/libelf/elf_getident.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_getident.c 189 2008-07-20 10:38:08Z jkoshy $"); - -char * -elf_getident(Elf *e, size_t *sz) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - goto error; - } - - if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - goto error; - } - - assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); - - if (sz) { - if (e->e_kind == ELF_K_AR) - *sz = SARMAG; - else if (e->e_kind == ELF_K_ELF) - *sz = EI_NIDENT; - else - *sz = e->e_rawsize; - } - - return ((char *) e->e_rawfile); - - error: - if (sz) - *sz = 0; - return (NULL); -} diff --git a/linkers/elftoolchain/libelf/elf_getphdrnum.3 b/linkers/elftoolchain/libelf/elf_getphdrnum.3 deleted file mode 100644 index f0fae5e..0000000 --- a/linkers/elftoolchain/libelf/elf_getphdrnum.3 +++ /dev/null @@ -1,86 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getphdrnum.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 5, 2009 -.Os -.Dt ELF_GETPHDRNUM 3 -.Sh NAME -.Nm elf_getphdrnum -.Nd return the number of program headers in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getphdrnum "Elf *elf" "size_t *phnum" -.Sh DESCRIPTION -Function -.Fn elf_getphdrnum -retrieves the number of ELF program headers associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar phnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects and ELF objects that use extended numbering. -.Pp -.Sh RETURN VALUES -Function -.Fn elf_getphdrnum -returns a zero value if successful, or -1 in case of an error. -.Sh ERRORS -Function -.Fn elf_getphnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable Header. -.It Bq Er ELF_E_HEADER -The ELF Executable Header associated with argument -.Ar elf -was corrupt. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -was corrupt. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getshdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getphnum.3 b/linkers/elftoolchain/libelf/elf_getphnum.3 deleted file mode 100644 index 95c7540..0000000 --- a/linkers/elftoolchain/libelf/elf_getphnum.3 +++ /dev/null @@ -1,93 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getphnum.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 5, 2009 -.Os -.Dt ELF_GETPHNUM 3 -.Sh NAME -.Nm elf_getphnum -.Nd return the number of program headers in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getphnum "Elf *elf" "size_t *phnum" -.Sh DESCRIPTION -This function is deprecated. -Please use function -.Xr elf_getphdrnum 3 -instead. -.Pp -Function -.Fn elf_getphnum -retrieves the number of ELF program headers associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar phnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects and ELF objects that use extended numbering. -.Pp -.Sh RETURN VALUES -Function -.Fn elf_getphnum -returns a non-zero value if successful, or zero in case of an -error. -.Sh ERRORS -Function -.Fn elf_getphnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable Header. -.It Bq Er ELF_E_HEADER -The ELF Executable Header associated with argument -.Ar elf -was corrupt. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -was corrupt. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getscn.3 b/linkers/elftoolchain/libelf/elf_getscn.3 deleted file mode 100644 index 0afe443..0000000 --- a/linkers/elftoolchain/libelf/elf_getscn.3 +++ /dev/null @@ -1,151 +0,0 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getscn.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd October 22, 2007 -.Os -.Dt ELF_GETSCN 3 -.Sh NAME -.Nm elf_getscn , -.Nm elf_ndxscn , -.Nm elf_newscn , -.Nm elf_nextscn -.Nd get/allocate section information for an ELF object -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Scn *" -.Fn elf_getscn "Elf *elf" "size_t index" -.Ft size_t -.Fn elf_ndxscn "Elf_Scn *scn" -.Ft "Elf_Scn *" -.Fn elf_newscn "Elf *elf" -.Ft "Elf_Scn *" -.Fn elf_nextscn "Elf *elf" "Elf_Scn *scn" -.Sh DESCRIPTION -These functions are used to iterate through the sections associated -with an ELF descriptor. -.Pp -Function -.Fn elf_getscn -will return a section descriptor for the section at index -.Ar index -in the object denoted by ELF descriptor -.Ar elf . -An error will be signalled if the specified section does not -exist. -.Pp -Function -.Fn elf_ndxscn -returns the section table index associated with section descriptor -.Ar scn . -.Pp -Function -.Fn elf_newscn -creates a new section and appends it to the list of sections -associated with descriptor -.Ar elf . -The library will automatically increment the -.Va e_shnum -field of the ELF header associated with descriptor -.Ar elf , -and will set the -.Dv ELF_F_DIRTY -flag on the returned section descriptor. -For ELF descriptors opened for writing, the ELF library will -automatically create an empty section at index zero -.Dv ( SHN_UNDEF ) -on the first call to -.Fn elf_newscn . -.Pp -Function -.Fn elf_nextscn -takes a section descriptor -.Ar scn -and returns a pointer to the section descriptor at the next higher -index. -Argument -.Ar scn -is allowed to be NULL, in which case this function will return a -pointer to the section descriptor at index 1. -If no further sections are present, function -.Fn elf_nextscn -will return a NULL pointer. -.Sh RETURN VALUES -Functions -.Fn elf_getscn , -.Fn elf_newscn -and -.Fn elf_nextscn -return a valid pointer to a section descriptor if successful, or -NULL if an error occurs. -.Pp -Function -.Fn elf_ndxscn -returns a valid section table index if successful, or -.Dv SHN_UNDEF -if an error occurs. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar elf -or -.Ar scn -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar index -exceeded the current number of sections in the ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Section descriptor -.Ar scn -was not associated with ELF descriptor -.Ar elf . -.It Bq Er ELF_E_CLASS -Descriptor -.Ar elf -was of an unknown ELF class. -.It Bq Er ELF_E_SECTION -Argument -.Ar elf -specified extended section numbering in the ELF header with the section header at -index -.Dv SHN_UNDEF -not being of type -.Dv SHT_NULL . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagdata 3 , -.Xr elf_flagscn 3 , -.Xr elf_getdata 3 , -.Xr elf_getshdr 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_getshdrnum.3 b/linkers/elftoolchain/libelf/elf_getshdrnum.3 deleted file mode 100644 index e2bf354..0000000 --- a/linkers/elftoolchain/libelf/elf_getshdrnum.3 +++ /dev/null @@ -1,78 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getshdrnum.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 4, 2009 -.Os -.Dt ELF_GETSHDRNUM 3 -.Sh NAME -.Nm elf_getshdrnum -.Nd return the number of sections in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshdrnum "Elf *elf" "size_t *shnum" -.Sh DESCRIPTION -Function -.Fn elf_getshdrnum -retrieves the number of ELF sections associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar shnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects, and ELF objects that use extended section numbering. -.Pp -.Sh RETURN VALUES -Function -.Fn elf_getshdrnum -returns zero value if successful, or -1 in case of an error. -.Sh ERRORS -Function -.Fn elf_getshdrnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getshdrstrndx.3 b/linkers/elftoolchain/libelf/elf_getshdrstrndx.3 deleted file mode 100644 index b02e715..0000000 --- a/linkers/elftoolchain/libelf/elf_getshdrstrndx.3 +++ /dev/null @@ -1,79 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getshdrstrndx.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 5, 2009 -.Os -.Dt ELF_GETSHDRSTRNDX 3 -.Sh NAME -.Nm elf_getshdrstrndx -.Nd retrieve the index of the section name string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshdrstrndx "Elf *elf" "size_t *ndxptr" -.Sh DESCRIPTION -Function -.Fn elf_getshdrstrndx -retrieves the section index of the string table containing section -names from descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar ndxptr . -.Pp -This function allow applications to process both normal ELF -objects and ELF objects that use extended section numbering uniformly. -.Pp -.Sh RETURN VALUES -These functions return zero if successful, or -1 in case of an error. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -contained a value in the reserved range of section indices. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getshnum.3 b/linkers/elftoolchain/libelf/elf_getshnum.3 deleted file mode 100644 index 615aa71..0000000 --- a/linkers/elftoolchain/libelf/elf_getshnum.3 +++ /dev/null @@ -1,84 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getshnum.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 5, 2009 -.Os -.Dt ELF_GETSHNUM 3 -.Sh NAME -.Nm elf_getshnum -.Nd return the number of sections in an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshnum "Elf *elf" "size_t *shnum" -.Sh DESCRIPTION -This function is deprecated. -Please use -.Xr elf_getshdrnum 3 -instead. -.Pp -Function -.Fn elf_getshnum -retrieves the number of ELF sections associated with descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar shnum . -.Pp -This routine allows applications to uniformly process both normal ELF -objects, and ELF objects that use extended section numbering. -.Pp -.Sh RETURN VALUES -Function -.Fn elf_getshnum -returns a non-zero value if successful, or zero in case of an -error. -.Sh ERRORS -Function -.Fn elf_getshnum -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrstrndx 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_getshstrndx.3 b/linkers/elftoolchain/libelf/elf_getshstrndx.3 deleted file mode 100644 index 71c6f95..0000000 --- a/linkers/elftoolchain/libelf/elf_getshstrndx.3 +++ /dev/null @@ -1,94 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_getshstrndx.3 467 2009-08-05 18:18:49Z jkoshy $ -.\" -.Dd August 5, 2009 -.Os -.Dt ELF_GETSHSTRNDX 3 -.Sh NAME -.Nm elf_getshstrndx , -.Nm elf_setshstrndx -.Nd retrieve/update the index of the section name string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft int -.Fn elf_getshstrndx "Elf *elf" "size_t *ndxptr" -.Ft int -.Fn elf_setshstrndx "Elf *elf" "size_t ndx" -.Sh DESCRIPTION -Function -.Fn elf_getshstrndx -retrieves the section index of the string table containing section -names from descriptor -.Ar elf -and stores it into the location pointed to by argument -.Ar ndxptr . -Function -.Fn elf_getshstrndx -is deprecated. -Please use -.Xr elf_getshdrstrndx 3 -instead. -.Pp -Function -.Fn elf_setshstrndx -sets the index of the section name string table to argument -.Ar ndx . -.Pp -These routines allow applications to process both normal ELF -objects and ELF objects that use extended section numbering uniformly. -.Pp -.Sh RETURN VALUES -These functions return a non-zero value if successful, or zero in case -of an error. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was passed in for argument -.Ar elf . -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not for an ELF file. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -lacks an ELF Executable header. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -contained a value in the reserved range of section indices. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_getident 3 , -.Xr elf_getphdrnum 3 , -.Xr elf_getshdrnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 diff --git a/linkers/elftoolchain/libelf/elf_hash.3 b/linkers/elftoolchain/libelf/elf_hash.3 deleted file mode 100644 index f099558..0000000 --- a/linkers/elftoolchain/libelf/elf_hash.3 +++ /dev/null @@ -1,57 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_hash.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 15, 2006 -.Os -.Dt ELF_HASH 3 -.Sh NAME -.Nm elf_hash -.Nd compute a hash value for a string -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "unsigned long" -.Fn elf_hash "const char *name" -.Sh DESCRIPTION -Function -.Fn elf_hash -computes a portable hash value for the null terminated string -pointed to by argument -.Ar name . -.Pp -The hash value returned is will be identical across -machines of different architectures. -This allows hash tables to be built on one machine and -correctly used on another of a different architecture. -The hash value returned is also guaranteed -.Em not -to be the bit pattern of all ones (~0UL). -.Sh IMPLEMENTATION NOTES -The library internally uses unsigned 32 bit arithmetic to compute -the hash value. -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_hash.c b/linkers/elftoolchain/libelf/elf_hash.c deleted file mode 100644 index 12c764d..0000000 --- a/linkers/elftoolchain/libelf/elf_hash.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf_config.h" - -LIBELF_VCSID("$Id: elf_hash.c 189 2008-07-20 10:38:08Z jkoshy $"); - -/* - * This elf_hash function is defined by the System V ABI. - */ - -unsigned long -elf_hash(const char *name) -{ - unsigned long h, t; - const unsigned char *s; - - s = (const unsigned char *) name; - h = t = 0; - - for (; *s != '\0'; h = h & ~t) { - h = (h << 4) + *s++; - t = h & 0xF0000000UL; - if (t) - h ^= t >> 24; - } - - return (h); -} diff --git a/linkers/elftoolchain/libelf/elf_kind.3 b/linkers/elftoolchain/libelf/elf_kind.3 deleted file mode 100644 index a5bbf9d..0000000 --- a/linkers/elftoolchain/libelf/elf_kind.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_kind.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 1, 2006 -.Os -.Dt ELF_KIND 3 -.Sh NAME -.Nm elf_kind -.Nd determine ELF file type -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft Elf_Kind -.Fn elf_kind "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_kind -function identifies the kind of file associated with its argument -.Ar elf . -The argument -.Ar elf -is allowed to be NULL. -.Sh RETURN VALUES -The -.Fn elf_kind -function returns one of the following values: -.Bl -tag -width indent -.It Dv ELF_K_AR -The file associated with argument -.Ar elf -is an archive. -.It Dv ELF_K_ELF -The file associated with argument -.Ar elf -is an ELF file. -.It Dv ELF_K_NONE -The argument -.Ar elf -was NULL, or the ELF library could not determine the type of the file -associated with argument -.Ar elf , -or an error occurred when processing. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_getident 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_kind.c b/linkers/elftoolchain/libelf/elf_kind.c deleted file mode 100644 index 0b4251a..0000000 --- a/linkers/elftoolchain/libelf/elf_kind.c +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_kind.c 189 2008-07-20 10:38:08Z jkoshy $"); - -Elf_Kind -elf_kind(Elf *e) -{ - if (e == NULL) - return (ELF_K_NONE); - if (e->e_kind == ELF_K_AR || - e->e_kind == ELF_K_ELF) - return (e->e_kind); - return (ELF_K_NONE); -} diff --git a/linkers/elftoolchain/libelf/elf_memory.3 b/linkers/elftoolchain/libelf/elf_memory.3 deleted file mode 100644 index 2f9da44..0000000 --- a/linkers/elftoolchain/libelf/elf_memory.3 +++ /dev/null @@ -1,122 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_memory.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 28, 2006 -.Os -.Dt ELF_MEMORY 3 -.Sh NAME -.Nm elf_memory -.Nd process an ELF or ar(1) archive mapped into memory -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf *" -.Fn elf_memory "char *image" "size_t size" -.Sh DESCRIPTION -Function -.Fn elf_memory -is used to process an ELF file or -.Xr ar 1 -archive whose image is present in memory. -.Pp -Argument -.Ar image -points to the start of the memory image of the file or archive. -Argument -.Ar size -contains the size in bytes of the memory image. -.Pp -The ELF descriptor is created for reading (i.e., analogous to the -use of -.Xr elf_begin 3 -with a command argument value of -.Dv ELF_C_READ Ns ). -.Sh RETURN VALUES -Function -.Fn elf_memory -returns a pointer to a new ELF descriptor if successful, or NULL if an -error occurred. -.Pp -The return value may be queried for the file type using -.Xr elf_kind 3 . -.Sh EXAMPLES -To read parse an elf file, use: -.Bd -literal -offset indent -int fd; -void *p; -struct stat sb; -Elf *e; -\&... -if ((fd = open("./elf-file", O_RDONLY)) < 0 || - fstat(fd, &sb) < 0 || - (p = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == - MAP_FAILED) { - ... handle system error ... -} - -if ((e = elf_memory(p, sb.st_size)) == NULL) { - ... handle elf(3) error ... -} -\&... use ELF descriptor "e" here ... -.Ed -.Sh ERRORS -Function -.Fn elf_memory -can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -A NULL value was used for argument -.Ar image -or the value of argument -.Ar sz -was zero. -.It Bq Er ELF_E_HEADER -The header of the ELF object contained an unsupported value in its -.Va e_ident[EI_CLASS] -field. -.It Bq Er ELF_E_HEADER -The header of the ELF object contained an unsupported value in its -.Va e_ident[EI_DATA] -field. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SEQUENCE -Function -.Fn elf_memory -was called before a working version was set using -.Xr elf_version 3 . -.It Bq Er ELF_E_VERSION -The argument -.Ar image -corresponds to an ELF file with an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_errno 3 , -.Xr elf_kind 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_memory.c b/linkers/elftoolchain/libelf/elf_memory.c deleted file mode 100644 index 691beaf..0000000 --- a/linkers/elftoolchain/libelf/elf_memory.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_memory.c 189 2008-07-20 10:38:08Z jkoshy $"); - -Elf * -elf_memory(char *image, size_t sz) -{ - Elf *e; - - if (LIBELF_PRIVATE(version) == EV_NONE) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - if (image == NULL || sz == 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((e = _libelf_allocate_elf()) == NULL) - return (NULL); - - e->e_cmd = ELF_C_READ; - e->e_rawfile = image; - e->e_rawsize = sz; - -#undef LIBELF_IS_ELF -#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ - (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ - (P)[EI_MAG3] == ELFMAG3) - - if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { - _libelf_init_elf(e, ELF_K_ELF); - e->e_class = image[EI_CLASS]; - e->e_byteorder = image[EI_DATA]; - e->e_version = image[EI_VERSION]; - - if (e->e_version > EV_CURRENT) { - e = _libelf_release_elf(e); - LIBELF_SET_ERROR(VERSION, 0); - return (NULL); - } - - if ((e->e_byteorder != ELFDATA2LSB && e->e_byteorder != - ELFDATA2MSB) || (e->e_class != ELFCLASS32 && e->e_class != - ELFCLASS64)) { - e = _libelf_release_elf(e); - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - } else if (sz >= SARMAG && - strncmp(image, ARMAG, (size_t) SARMAG) == 0) { - _libelf_init_elf(e, ELF_K_AR); - e = _libelf_ar_open(e); - } else - _libelf_init_elf(e, ELF_K_NONE); - - return (e); -} diff --git a/linkers/elftoolchain/libelf/elf_next.3 b/linkers/elftoolchain/libelf/elf_next.3 deleted file mode 100644 index 859d06c..0000000 --- a/linkers/elftoolchain/libelf/elf_next.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_next.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 17, 2006 -.Os -.Dt ELF_NEXT 3 -.Sh NAME -.Nm elf_next -.Nd provide sequential access to the next archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft Elf_Cmd -.Fn elf_next "Elf *elf" -.Sh DESCRIPTION -The -.Fn elf_next -function causes the ELF archive descriptor corresponding to argument -.Ar elf -to be adjusted to provide access to the next member in -the archive on a subsequent call to -.Fn elf_begin . -.Pp -The return value of -.Fn elf_next -is suitable for use in a loop invoking -.Fn elf_begin . -.Sh RETURN VALUES -If successful, function -.Fn elf_next -returns the value -.Dv ELF_C_READ . -Otherwise, if argument -.Ar elf -was not associated with an archive, or if it was -.Dv NULL , -or if any other error occurred, the value -.Dv ELF_C_NULL -is returned. -.Sh EXAMPLES -To process all the members of an archive use: -.Bd -literal -offset indent -Elf_Cmd cmd; -Elf *archive, *e; -\&... -cmd = ELF_C_READ; -archive = elf_begin(fd, cmd, NULL); -while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) -{ - ... process `e' here ... - - cmd = elf_next(e); - elf_end(e); -} -elf_end(archive); -.Ed -.Sh ERRORS -Function -.Fn elf_next -may fail with the following error: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not associated with a containing -.Xr ar 1 -archive. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_rand 3 diff --git a/linkers/elftoolchain/libelf/elf_next.c b/linkers/elftoolchain/libelf/elf_next.c deleted file mode 100644 index d6ca552..0000000 --- a/linkers/elftoolchain/libelf/elf_next.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_next.c 1678 2011-07-28 04:36:34Z jkoshy $"); - -Elf_Cmd -elf_next(Elf *e) -{ - off_t next; - Elf *parent; - - if (e == NULL) - return (ELF_C_NULL); - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (ELF_C_NULL); - } - - assert (parent->e_kind == ELF_K_AR); - assert (parent->e_cmd == ELF_C_READ); - assert(e->e_rawfile > parent->e_rawfile); - - next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; - next = (next + 1) & ~1; /* round up to an even boundary */ - - parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? - (off_t) 0 : next; - - return (ELF_C_READ); -} diff --git a/linkers/elftoolchain/libelf/elf_phnum.c b/linkers/elftoolchain/libelf/elf_phnum.c deleted file mode 100644 index d63c490..0000000 --- a/linkers/elftoolchain/libelf/elf_phnum.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_phnum.c 466 2009-08-04 17:17:42Z jkoshy $"); - -static int -_libelf_getphdrnum(Elf *e, size_t *phnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *phnum = e->e_u.e_elf.e_nphdr; - - return (0); -} - -int -elf_getphdrnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum)); -} - -/* Deprecated API */ -int -elf_getphnum(Elf *e, size_t *phnum) -{ - return (_libelf_getphdrnum(e, phnum) >= 0); -} diff --git a/linkers/elftoolchain/libelf/elf_rand.3 b/linkers/elftoolchain/libelf/elf_rand.3 deleted file mode 100644 index e5affd6..0000000 --- a/linkers/elftoolchain/libelf/elf_rand.3 +++ /dev/null @@ -1,118 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_rand.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd June 17, 2006 -.Os -.Dt ELF_RAND 3 -.Sh NAME -.Nm elf_rand -.Nd provide sequential access to the next archive member -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_rand "Elf *archive" "off_t offset" -.Sh DESCRIPTION -The -.Fn elf_rand -function causes the ELF descriptor -.Ar archive -to be adjusted so that the next call to -.Xr elf_begin 3 -will provide access to the archive member at byte offset -.Ar offset -in the archive. -Argument -.Ar offset -is the byte offset from the start of the archive to the beginning of -the archive header for the desired member. -.Pp -Archive member offsets may be retrieved using the -.Xr elf_getarsym 3 -function. -.Sh RETURN VALUES -Function -.Fn elf_rand -returns -.Ar offset -if successful or zero in case of an error. -.Sh EXAMPLES -To process all the members of an archive use: -.Bd -literal -offset indent -off_t off; -Elf *archive, *e; -\&... -cmd = ELF_C_READ; -archive = elf_begin(fd, cmd, NULL); -while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) -{ - ... process `e' here ... - elf_end(e); - - off = ...new value...; - if (elf_rand(archive, off) != off) { - ... process error ... - } -} -elf_end(archive); -.Ed -.Pp -To rewind an archive, use: -.Bd -literal -offset indent -Elf *archive; -\&... -if (elf_rand(archive, SARMAG) != SARMAG) { - ... error ... -} -.Ed -.Sh ERRORS -Function -.Fn elf_rand -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar archive -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar archive -was not a descriptor for an -.Xr ar 1 -archive. -.It Bq Er ELF_E_ARCHIVE -Argument -.Ar offset -did not correspond to the start of an archive member header. -.El -.Sh SEE ALSO -.Xr ar 1 , -.Xr elf 3 , -.Xr elf_begin 3 , -.Xr elf_end 3 , -.Xr elf_getarsym 3 , -.Xr elf_next 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_rand.c b/linkers/elftoolchain/libelf/elf_rand.c deleted file mode 100644 index 2e7328a..0000000 --- a/linkers/elftoolchain/libelf/elf_rand.c +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_rand.c 189 2008-07-20 10:38:08Z jkoshy $"); - -off_t -elf_rand(Elf *ar, off_t offset) -{ - struct ar_hdr *arh; - - if (ar == NULL || ar->e_kind != ELF_K_AR || - (offset & 1) || offset < SARMAG || - offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return 0; - } - - arh = (struct ar_hdr *) (ar->e_rawfile + offset); - - /* a too simple sanity check */ - if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { - LIBELF_SET_ERROR(ARCHIVE, 0); - return 0; - } - - ar->e_u.e_ar.e_next = offset; - - return (offset); -} diff --git a/linkers/elftoolchain/libelf/elf_rawfile.3 b/linkers/elftoolchain/libelf/elf_rawfile.3 deleted file mode 100644 index a713b42..0000000 --- a/linkers/elftoolchain/libelf/elf_rawfile.3 +++ /dev/null @@ -1,76 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_rawfile.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd July 3, 2006 -.Os -.Dt ELF_RAWFILE 3 -.Sh NAME -.Nm elf_rawfile -.Nd return uninterpreted contents of an ELF file -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft char * -.Fn elf_rawfile "Elf *elf" "size_t *sz" -.Sh DESCRIPTION -Function -.Fn elf_rawfile -returns the uninterpreted contents of the file referenced by ELF descriptor -.Ar elf . -.Pp -If argument -.Ar sz -is non-null, the function stores the file's size in bytes -in the location to which it points. -A value of zero is written to this location if an error is -encountered. -.Sh RETURN VALUES -Function -.Fn elf_rawfile -returns a valid pointer if successful or NULL if an error occurs. -.Sh ERRORS -Function -.Fn elf_rawfile -may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_SEQUENCE -Argument -.Ar elf -was opened for writing and function -.Fn elf_rawfile -was invoked before -.Xr elf_update 3 . -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getident 3 , -.Xr elf_kind 3 , -.Xr elf_update 3 diff --git a/linkers/elftoolchain/libelf/elf_rawfile.c b/linkers/elftoolchain/libelf/elf_rawfile.c deleted file mode 100644 index 22a9f95..0000000 --- a/linkers/elftoolchain/libelf/elf_rawfile.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_rawfile.c 189 2008-07-20 10:38:08Z jkoshy $"); - -char * -elf_rawfile(Elf *e, size_t *sz) -{ - char *ptr; - size_t size; - - size = e ? e->e_rawsize : 0; - ptr = NULL; - - if (e == NULL) - LIBELF_SET_ERROR(ARGUMENT, 0); - else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) - LIBELF_SET_ERROR(SEQUENCE, 0); - - if (sz) - *sz = size; - - return (ptr); -} diff --git a/linkers/elftoolchain/libelf/elf_scn.c b/linkers/elftoolchain/libelf/elf_scn.c deleted file mode 100644 index 80444fd..0000000 --- a/linkers/elftoolchain/libelf/elf_scn.c +++ /dev/null @@ -1,232 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_scn.c 1077 2010-08-09 15:37:40Z jkoshy $"); - -/* - * Load an ELF section table and create a list of Elf_Scn structures. - */ -int -_libelf_load_section_headers(Elf *e, void *ehdr) -{ - int ec, swapbytes; - size_t fsz, i, shnum; - uint64_t shoff; - char *src; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf_Scn *scn; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(e != NULL); - assert(ehdr != NULL); - assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); - -#define CHECK_EHDR(E,EH) do { \ - if (fsz != (EH)->e_shentsize || \ - shoff + fsz * shnum > e->e_rawsize) { \ - LIBELF_SET_ERROR(HEADER, 0); \ - return (0); \ - } \ - } while (0) - - ec = e->e_class; - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - shnum = e->e_u.e_elf.e_nscn; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - shoff = (uint64_t) eh32->e_shoff; - CHECK_EHDR(e, eh32); - } else { - eh64 = (Elf64_Ehdr *) ehdr; - shoff = eh64->e_shoff; - CHECK_EHDR(e, eh64); - } - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - - swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); - src = e->e_rawfile + shoff; - - /* - * If the file is using extended numbering then section #0 - * would have already been read in. - */ - - i = 0; - if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == - STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); - - i = 1; - src += fsz; - } - - for (; i < shnum; i++, src += fsz) { - if ((scn = _libelf_allocate_scn(e, i)) == NULL) - return (0); - - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, - (size_t) 1, swapbytes); - - if (ec == ELFCLASS32) { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr32.sh_offset; - scn->s_size = scn->s_shdr.s_shdr32.sh_size; - } else { - scn->s_offset = scn->s_rawoff = - scn->s_shdr.s_shdr64.sh_offset; - scn->s_size = scn->s_shdr.s_shdr64.sh_size; - } - } - - e->e_flags |= LIBELF_F_SHDRS_LOADED; - - return (1); -} - - -Elf_Scn * -elf_getscn(Elf *e, size_t index) -{ - int ec; - void *ehdr; - Elf_Scn *s; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return (NULL); - - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) - if (s->s_ndx == index) - return (s); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -size_t -elf_ndxscn(Elf_Scn *s) -{ - if (s == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (SHN_UNDEF); - } - return (s->s_ndx); -} - -Elf_Scn * -elf_newscn(Elf *e) -{ - int ec; - void *ehdr; - Elf_Scn *scn; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - /* - * The application may be asking for a new section descriptor - * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We - * need to bring in the existing section information before - * appending a new one to the list. - * - * Per the ELF(3) API, an application is allowed to open a - * file using ELF_C_READ, mess with its internal structure and - * use elf_update(...,ELF_C_NULL) to compute its new layout. - */ - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return (NULL); - - if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { - assert(e->e_u.e_elf.e_nscn == 0); - if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == - NULL) - return (NULL); - e->e_u.e_elf.e_nscn++; - } - - assert(e->e_u.e_elf.e_nscn > 0); - - if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) - return (NULL); - - e->e_u.e_elf.e_nscn++; - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - return (scn); -} - -Elf_Scn * -elf_nextscn(Elf *e, Elf_Scn *s) -{ - if (e == NULL || (e->e_kind != ELF_K_ELF) || - (s && s->s_elf != e)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - return (s == NULL ? elf_getscn(e, (size_t) 1) : - STAILQ_NEXT(s, s_next)); -} diff --git a/linkers/elftoolchain/libelf/elf_shnum.c b/linkers/elftoolchain/libelf/elf_shnum.c deleted file mode 100644 index 515027a..0000000 --- a/linkers/elftoolchain/libelf/elf_shnum.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_shnum.c 466 2009-08-04 17:17:42Z jkoshy $"); - -static int -_libelf_getshdrnum(Elf *e, size_t *shnum) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *shnum = e->e_u.e_elf.e_nscn; - - return (0); -} - -int -elf_getshdrnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum)); -} - -/* Deprecated API. */ -int -elf_getshnum(Elf *e, size_t *shnum) -{ - return (_libelf_getshdrnum(e, shnum) >= 0); -} diff --git a/linkers/elftoolchain/libelf/elf_shstrndx.c b/linkers/elftoolchain/libelf/elf_shstrndx.c deleted file mode 100644 index bac14b4..0000000 --- a/linkers/elftoolchain/libelf/elf_shstrndx.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_shstrndx.c 466 2009-08-04 17:17:42Z jkoshy $"); - -static int -_libelf_getshdrstrndx(Elf *e, size_t *strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (-1); - } - - if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) - return (-1); - - *strndx = e->e_u.e_elf.e_strndx; - - return (0); -} - -int -elf_getshdrstrndx(Elf *e, size_t *strndx) -{ - return (_libelf_getshdrstrndx(e, strndx)); -} - -int -elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ -{ - return (_libelf_getshdrstrndx(e, strndx) >= 0); -} - -int -elf_setshstrndx(Elf *e, size_t strndx) -{ - void *eh; - int ec; - - if (e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - return (_libelf_setshstrndx(e, eh, ec, strndx)); -} diff --git a/linkers/elftoolchain/libelf/elf_strptr.3 b/linkers/elftoolchain/libelf/elf_strptr.3 deleted file mode 100644 index 31e0f83..0000000 --- a/linkers/elftoolchain/libelf/elf_strptr.3 +++ /dev/null @@ -1,116 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_strptr.3 1081 2010-08-14 02:23:48Z jkoshy $ -.\" -.Dd December 16, 2006 -.Os -.Dt ELF_STRPTR 3 -.Sh NAME -.Nm elf_strptr -.Nd retrieve a string pointer in a string table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "char *" -.Fn elf_strptr "Elf *elf" "size_t scndx" "size_t stroffset" -.Sh DESCRIPTION -Function -.Fn elf_strptr -allows an application to convert a string table offset to a string -pointer, correctly translating the offset in the presence -of multiple -.Vt Elf_Data -descriptors covering the contents of the section. -.Pp -Argument -.Ar elf -is a descriptor for an ELF object. -Argument -.Ar scndx -is the section index for an ELF string table. -Argument -.Ar stroffset -is the index of the desired string in the string -table. -.Sh RETURN VALUES -Function -.Fn elf_strptr -returns a valid pointer on success or NULL in case an error was -encountered. -.Sh ERRORS -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar scndx -was not the section index for a string table. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar stroffset -exceeded the size of the string table. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar stroffset -index an unallocated region of the string table. -.It Bq Er ELF_E_DATA -Offset -.Ar stroffset -indexed a region that was not covered by any Elf_Data -descriptor. -.It Bq Er ELF_E_DATA -An erroneous -.Vt Elf_Data -descriptor was part of the section specified by argument -.Ar scndx . -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -contained an invalid section header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -Section -.Ar scndx -contained a malformed section header. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getshdr 3 , -.Xr elf64_getshdr 3 , -.Xr elf_getdata 3 , -.Xr elf_rawdata 3 , -.Xr gelf 3 , -.Xr gelf_getshdr 3 diff --git a/linkers/elftoolchain/libelf/elf_strptr.c b/linkers/elftoolchain/libelf/elf_strptr.c deleted file mode 100644 index bfa39de..0000000 --- a/linkers/elftoolchain/libelf/elf_strptr.c +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_strptr.c 189 2008-07-20 10:38:08Z jkoshy $"); - -/* - * Convert an ELF section#,offset pair to a string pointer. - */ - -char * -elf_strptr(Elf *e, size_t scndx, size_t offset) -{ - Elf_Scn *s; - Elf_Data *d; - size_t alignment, count; - GElf_Shdr shdr; - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((s = elf_getscn(e, scndx)) == NULL || - gelf_getshdr(s, &shdr) == NULL) - return (NULL); - - if (shdr.sh_type != SHT_STRTAB || - offset >= shdr.sh_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - d = NULL; - if (e->e_flags & ELF_F_LAYOUT) { - - /* - * The application is taking responsibility for the - * ELF object's layout, so we can directly translate - * an offset to a `char *' address using the `d_off' - * members of Elf_Data descriptors. - */ - while ((d = elf_getdata(s, d)) != NULL) { - - if (d->d_buf == 0 || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if (offset >= d->d_off && - offset < d->d_off + d->d_size) - return ((char *) d->d_buf + offset - d->d_off); - } - } else { - /* - * Otherwise, the `d_off' members are not useable and - * we need to compute offsets ourselves, taking into - * account 'holes' in coverage of the section introduced - * by alignment requirements. - */ - count = (size_t) 0; /* cumulative count of bytes seen */ - while ((d = elf_getdata(s, d)) != NULL && count <= offset) { - - if (d->d_buf == NULL || d->d_size == 0) - continue; - - if (d->d_type != ELF_T_BYTE) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((alignment = d->d_align) > 1) { - if ((alignment & (alignment - 1)) != 0) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - count = roundup2(count, alignment); - } - - if (offset < count) { - /* offset starts in the 'hole' */ - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (offset < count + d->d_size) { - if (d->d_buf != NULL) - return ((char *) d->d_buf + - offset - count); - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - count += d->d_size; - } - } - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/linkers/elftoolchain/libelf/elf_types.m4 b/linkers/elftoolchain/libelf/elf_types.m4 deleted file mode 100644 index 9e9680d..0000000 --- a/linkers/elftoolchain/libelf/elf_types.m4 +++ /dev/null @@ -1,309 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ - */ - -/* - * ELF types, defined in the "enum Elf_Type" API. - * - * The members of the list form a 2-tuple: (name, C-type-suffix). - * + `name' is an Elf_Type symbol without the `ELF_T_' prefix. - * + `C-type-suffix' is the suffix for Elf32_ and Elf64_ type names. - */ - -define(`ELF_TYPE_LIST', - ``ADDR, Addr', - `BYTE, Byte', - `CAP, Cap', - `DYN, Dyn', - `EHDR, Ehdr', - `GNUHASH, -', - `HALF, Half', - `LWORD, Lword', - `MOVE, Move', - `MOVEP, MoveP', - `NOTE, Note', - `OFF, Off', - `PHDR, Phdr', - `REL, Rel', - `RELA, Rela', - `SHDR, Shdr', - `SWORD, Sword', - `SXWORD, Sxword', - `SYMINFO, Syminfo', - `SYM, Sym', - `VDEF, Verdef', - `VNEED, Verneed', - `WORD, Word', - `XWORD, Xword', - `NUM, _'') - -/* - * DEFINE_STRUCT(NAME,MEMBERLIST...) - * - * Map a type name to its members. - * - * Each member-list element comprises of pairs of (field name, type), - * in the sequence used in the file representation of `NAME'. - * - * Each member list element comprises a pair containing a field name - * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, - * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. - * - * The last element of a member list is the null element: `_,_'. - */ - -define(`DEFINE_STRUCT',`define(`$1_DEF',shift($@))dnl') - -DEFINE_STRUCT(`Elf32_Cap', - ``c_tag, WORD', - `c_un.c_val, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Cap', - ``c_tag, XWORD', - `c_un.c_val, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Dyn', - ``d_tag, SWORD', - `d_un.d_ptr, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Dyn', - ``d_tag, SXWORD', - `d_un.d_ptr, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Ehdr', - ``e_ident, IDENT', - `e_type, HALF', - `e_machine, HALF', - `e_version, WORD', - `e_entry, ADDR', - `e_phoff, OFF', - `e_shoff, OFF', - `e_flags, WORD', - `e_ehsize, HALF', - `e_phentsize, HALF', - `e_phnum, HALF', - `e_shentsize, HALF', - `e_shnum, HALF', - `e_shstrndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Ehdr', - ``e_ident, IDENT', - `e_type, HALF', - `e_machine, HALF', - `e_version, WORD', - `e_entry, ADDR', - `e_phoff, OFF', - `e_shoff, OFF', - `e_flags, WORD', - `e_ehsize, HALF', - `e_phentsize, HALF', - `e_phnum, HALF', - `e_shentsize, HALF', - `e_shnum, HALF', - `e_shstrndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Move', - ``m_value, LWORD', - `m_info, WORD', - `m_poffset, WORD', - `m_repeat, HALF', - `m_stride, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Move', - ``m_value, LWORD', - `m_info, XWORD', - `m_poffset, XWORD', - `m_repeat, HALF', - `m_stride, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Phdr', - ``p_type, WORD', - `p_offset, OFF', - `p_vaddr, ADDR', - `p_paddr, ADDR', - `p_filesz, WORD', - `p_memsz, WORD', - `p_flags, WORD', - `p_align, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Phdr', - ``p_type, WORD', - `p_flags, WORD', - `p_offset, OFF', - `p_vaddr, ADDR', - `p_paddr, ADDR', - `p_filesz, XWORD', - `p_memsz, XWORD', - `p_align, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Rel', - ``r_offset, ADDR', - `r_info, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Rel', - ``r_offset, ADDR', - `r_info, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Rela', - ``r_offset, ADDR', - `r_info, WORD', - `r_addend, SWORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Rela', - ``r_offset, ADDR', - `r_info, XWORD', - `r_addend, SXWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Shdr', - ``sh_name, WORD', - `sh_type, WORD', - `sh_flags, WORD', - `sh_addr, ADDR', - `sh_offset, OFF', - `sh_size, WORD', - `sh_link, WORD', - `sh_info, WORD', - `sh_addralign, WORD', - `sh_entsize, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Shdr', - ``sh_name, WORD', - `sh_type, WORD', - `sh_flags, XWORD', - `sh_addr, ADDR', - `sh_offset, OFF', - `sh_size, XWORD', - `sh_link, WORD', - `sh_info, WORD', - `sh_addralign, XWORD', - `sh_entsize, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Sym', - ``st_name, WORD', - `st_value, ADDR', - `st_size, WORD', - `st_info, BYTE', - `st_other, BYTE', - `st_shndx, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Sym', - ``st_name, WORD', - `st_info, BYTE', - `st_other, BYTE', - `st_shndx, HALF', - `st_value, ADDR', - `st_size, XWORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Syminfo', - ``si_boundto, HALF', - `si_flags, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf64_Syminfo', - ``si_boundto, HALF', - `si_flags, HALF', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verdaux', - ``vda_name, WORD', - `vda_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verdaux', - ``vda_name, WORD', - `vda_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verdef', - ``vd_version, HALF', - `vd_flags, HALF', - `vd_ndx, HALF', - `vd_cnt, HALF', - `vd_hash, WORD', - `vd_aux, WORD', - `vd_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verdef', - ``vd_version, HALF', - `vd_flags, HALF', - `vd_ndx, HALF', - `vd_cnt, HALF', - `vd_hash, WORD', - `vd_aux, WORD', - `vd_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Verneed', - ``vn_version, HALF', - `vn_cnt, HALF', - `vn_file, WORD', - `vn_aux, WORD', - `vn_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Verneed', - ``vn_version, HALF', - `vn_cnt, HALF', - `vn_file, WORD', - `vn_aux, WORD', - `vn_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf32_Vernaux', - ``vna_hash, WORD', - `vna_flags, HALF', - `vna_other, HALF', - `vna_name, WORD', - `vna_next, WORD', - `_,_'') - -DEFINE_STRUCT(`Elf64_Vernaux', - ``vna_hash, WORD', - `vna_flags, HALF', - `vna_other, HALF', - `vna_name, WORD', - `vna_next, WORD', - `_,_'') diff --git a/linkers/elftoolchain/libelf/elf_update.3 b/linkers/elftoolchain/libelf/elf_update.3 deleted file mode 100644 index 40a1e40..0000000 --- a/linkers/elftoolchain/libelf/elf_update.3 +++ /dev/null @@ -1,378 +0,0 @@ -.\" Copyright (c) 2006-2011 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_update.3 1729 2011-08-14 09:13:00Z jkoshy $ -.\" -.Dd August 14, 2011 -.Os -.Dt ELF_UPDATE 3 -.Sh NAME -.Nm elf_update -.Nd update an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft off_t -.Fn elf_update "Elf *elf" "Elf_Cmd cmd" -.Sh DESCRIPTION -Function -.Fn elf_update -causes the library to recalculate the structure of an ELF -object and optionally write out the image of the object -to file. -.Pp -Argument -.Ar elf -should reference a valid ELF descriptor. -.Pp -Argument -.Ar cmd -can be one of the following values: -.Bl -tag -width "Dv ELF_C_WRITE" -.It Dv ELF_C_NULL -The library will recalculate structural information flagging -modified structures with the -.Dv ELF_F_DIRTY -flag, but will not write data to the underlying file image. -.It Dv ELF_C_WRITE -The library will recalculate structural information and will -also write the new image to the underlying file. -The ELF descriptor referenced by argument -.Ar elf -should permit the underlying ELF object to be written or updated -(see -.Xr elf_begin 3 ) . -.El -.Pp -All pointers to -.Vt Elf_Scn -and -.Vt Elf_Data -descriptors associated with descriptor -.Ar elf -should be considered invalid after a call to -.Fn elf_update . -.Ss Specifying Object Layout -The -.Lb libelf -supports two layout modes. -.Bl -tag -width indent -.It "Library Layout" -If the -.Dv ELF_F_LAYOUT -flag is not set on the ELF descriptor, the ELF library will lay out -the ELF object according to the following scheme: -.Bl -tag -compact -width "Section Data" -.It Em EHDR -The ELF executable header will be placed at the start of the object. -.It Em PHDR -If the ELF descriptor contains a program header table, it will be -placed after the Executable Header. -.It Em Section Data -ELF section data, if any, will be placed next, keeping each section's -alignment requirements in mind. -.It Em SHDR -The ELF section header table, if any, will be placed last. -.El -.It "Application Controlled Layout" -The application can take full control of the layout of the ELF object -by setting the -.Dv ELF_F_LAYOUT -flag on the ELF descriptor (see -.Xr elf_flagelf 3 ) . -In this case the library will lay out the ELF object using -application-supplied information as below: -.Pp -.Bl -tag -compact -width "Section Data" -.It Em EHDR -The ELF executable header will be placed at the start of the object. -.It Em PHDR -The ELF program header table, if any, it will be placed at the offset -specified in the -.Va e_phoff -field of the ELF executable header. -.It Em Section Data -The data for each ELF section will be placed at the offset specified -by the -.Va sh_offset -field of the section's header. -The size of the section will be taken from the -.Va sh_size -field of the section header. -.It Em SHDR -The ELF section header table, if any, will be placed at the offset -specified by the -.Va e_shoff -field of the executable header. -.El -.El -.Pp -Gaps in the coverage of the file's contents will be set to the fill value -specified by -.Xr elf_fill 3 . -.Ss Application Supplied Information -The application needs to set the following fields in the data -structures associated with the ELF descriptor prior to calling -.Fn elf_update . -.Bl -tag -width indent -.It "Executable Header" -The fields of the ELF executable header that need to be set by the -application are: -.Pp -.Bl -tag -width "e_ident[EI_OSABI]" -compact -.It Va e_entry -To be set to the desired entry address for executables. -.It Va e_flags -To be set to the desired processor specific flags. -.It Va "e_ident[EI_DATA]" -Must be set to one of -.Dv ELFDATA2LSB -or -.Dv ELFDATA2MSB . -.It Va "e_ident[EI_OSABI]" -To be set to the OS ABI desired. -For example, for -.Fx -executables, this field should be set to -.Dv ELFOSABI_FREEBSD . -.It Va e_machine -To be set to the desired machine architecture, one of the -.Dv EM_* -values in the header file -.In elfdefinitions.h . -.It Va e_phoff -If the application is managing the object's layout, it must -set this field to the file offset of the ELF program header table. -.It Va e_shoff -If the application is managing the object's layout, it must -set this field to the file offset of the ELF section header table. -.It Va e_shstrndx -To be set to the index of the string table containing -section names. -.It Va e_type -To be set to the type of the ELF object, one of the -.Dv ET_* -values in the header file -.In elfdefinitions.h . -.It Va e_version -To be set to the desired version of the ELF object. -.El -.It "Program Header" -All fields of the entries in the program header table need to be -set by the application. -.It "Section Header" -The fields of ELF section headers that need to be set by the -application are: -.Pp -.Bl -tag -width "sh_addralign" -compact -.It Va sh_addr -To be set to the memory address where the section should reside. -.It Va sh_addralign -If the application is managing the file layout, it must set this -field to the desired alignment for the section's contents. -This value must be a power of two and must be at least as large as the -largest alignment needed by any -.Vt Elf_Data -descriptor associated with the section. -.It Va sh_entsize -To be set to the size of each entry, for sections containing fixed size -elements, or set to zero for sections without fixed size elements. -If the application is not managing file layout, it may leave this -field as zero for those sections whose types are known to the library. -.It Va sh_flags -To be set to the desired section flags. -.It Va sh_info -To be set as described in -.Xr elf 5 . -.It Va sh_link -To be set as described in -.Xr elf 5 . -.It Va sh_name -To be set to the index of the section's name in the string table -containing section names. -.It Va sh_offset -If the application is managing the file layout, it must set this -field to the file offset of the section's contents. -.It Va sh_size -If the application is managing the file layout, it must set this -field to the file size of the section's contents. -.It Va sh_type -To be set to the type of the section. -.El -.It "Section Data" -The -.Vt Elf_Data -descriptors associated with each section specify its contents -(see -.Xr elf_getdata 3 ) . -While all the fields in these descriptors are under application -control, the following fields influence object layout: -.Bl -tag -width "Va d_align" -compact -.It Va d_align -To be set to the desired alignment, within the containing section, of -the descriptor's data. -.It Va d_off -If the application is managing object layout, it must set this field -to the file offset, within the section, at which the descriptor's data -should be placed. -.It Va d_size -To be set to the size in bytes of the memory representation of the -descriptor's data. -.El -.El -.Sh RETURN VALUES -Function -.Fn elf_update -returns the total size of the file image if successful, or -1 if an -error occurred. -.Sh ERRORS -This function may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar cmd -was not recognized. -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -The -.Va e_ident[EI_CLASS] -field of the executable header of argument -.Ar elf -did not match the class of the file. -.It Bq Er ELF_E_DATA -An -.Vt Elf_Data -descriptor contained in argument -.Ar elf -specified an unsupported type. -.It Bq Er ELF_E_DATA -An -.Vt Elf_Data -descriptor specified an alignment that was zero or was not a power of -two. -.It Bq Er ELF_E_HEADER -The ELF header in argument -.Ar elf -requested a different byte order from the byte order already -associated with the file. -.It Bq Er ELF_E_IO -An I/O error was encountered. -.It Bq Er ELF_E_LAYOUT -An -.Vt Elf_Data -descriptor contained in argument -.Ar elf -specified an alignment incompatible with its containing section. -.It Bq Er ELF_E_LAYOUT -Argument -.Ar elf -contained section descriptors that overlapped in extent. -.It Bq Er ELF_E_LAYOUT -Argument -.Ar elf -contained section descriptors that were incorrectly aligned or were -too small for their data. -.It Bq Er ELF_E_LAYOUT -The flag -.Dv ELF_F_LAYOUT -was set on the Elf descriptor and the executable header overlapped -with the program header table. -.It Bq Er ELF_E_LAYOUT -The flag -.Dv ELF_F_LAYOUT -was set on the Elf descriptor and the program header table was placed -at a misaligned file offset. -.It Bq Er ELF_E_LAYOUT -The flag -.Dv ELF_F_LAYOUT -was set on the Elf descriptor and the section header table overlapped -an extent mapped by a section descriptor. -.It Bq Er ELF_E_LAYOUT -The -.Dv ELF_F_LAYOUT -flag was set on the Elf descriptor, and the -.Va d_offset -field in an -.Vt Elf_Data -descriptor contained a value that was not a multiple of the -descriptor's specified alignment. -.It Bq Er ELF_E_MODE -An -.Dv ELF_C_WRITE -operation was requested with an ELF descriptor that was not opened for -writing or updating. -.It Bq Er ELF_E_SECTION -Argument -.Ar elf -contained a section with an unrecognized type. -.It Bq Er ELF_E_SECTION -The section header at index -.Dv SHN_UNDEF -had an illegal section type. -.It Bq Er ELF_E_SEQUENCE -An -.Dv ELF_C_WRITE -operation was requested after a prior call to -.Fn elf_cntl elf ELF_C_FDDONE -disassociated the ELF descriptor -.Ar elf -from its underlying file. -.It Bq Er ELF_E_VERSION -Argument -.Ar elf -had an unsupported version or contained an -.Vt Elf_Data -descriptor with an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf32_getphdr 3 , -.Xr elf32_newehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf64_getphdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf_begin 3 , -.Xr elf_cntl 3 , -.Xr elf_fill 3 , -.Xr elf_flagehdr 3 , -.Xr elf_flagelf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr elf_newdata 3 , -.Xr elf_newscn 3 , -.Xr elf_rawdata 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr gelf_newphdr 3 , -.Xr elf 5 diff --git a/linkers/elftoolchain/libelf/elf_update.c b/linkers/elftoolchain/libelf/elf_update.c deleted file mode 100644 index 9806131..0000000 --- a/linkers/elftoolchain/libelf/elf_update.c +++ /dev/null @@ -1,1184 +0,0 @@ -/*- - * Copyright (c) 2006-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_update.c 1922 2011-09-23 08:04:33Z jkoshy $"); - -/* - * Layout strategy: - * - * - Case 1: ELF_F_LAYOUT is asserted - * In this case the application has full control over where the - * section header table, program header table, and section data - * will reside. The library only perform error checks. - * - * - Case 2: ELF_F_LAYOUT is not asserted - * - * The library will do the object layout using the following - * ordering: - * - The executable header is placed first, are required by the - * ELF specification. - * - The program header table is placed immediately following the - * executable header. - * - Section data, if any, is placed after the program header - * table, aligned appropriately. - * - The section header table, if needed, is placed last. - * - * There are two sub-cases to be taken care of: - * - * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR - * - * In this sub-case, the underlying ELF object may already have - * content in it, which the application may have modified. The - * library will retrieve content from the existing object as - * needed. - * - * - Case 2b: e->e_cmd == ELF_C_WRITE - * - * The ELF object is being created afresh in this sub-case; - * there is no pre-existing content in the underlying ELF - * object. - */ - -/* - * The types of extents in an ELF object. - */ -enum elf_extent { - ELF_EXTENT_EHDR, - ELF_EXTENT_PHDR, - ELF_EXTENT_SECTION, - ELF_EXTENT_SHDR -}; - -/* - * A extent descriptor, used when laying out an ELF object. - */ -struct _Elf_Extent { - SLIST_ENTRY(_Elf_Extent) ex_next; - uint64_t ex_start; /* Start of the region. */ - uint64_t ex_size; /* The size of the region. */ - enum elf_extent ex_type; /* Type of region. */ - void *ex_desc; /* Associated descriptor. */ -}; - -SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); - -/* - * Compute the extents of a section, by looking at the data - * descriptors associated with it. The function returns 1 - * if successful, or zero if an error was detected. - */ -static int -_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) -{ - int ec; - size_t fsz, msz; - Elf_Data *d; - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - uint32_t sh_type; - uint64_t d_align; - unsigned int elftype; - uint64_t scn_size, scn_alignment; - uint64_t sh_align, sh_entsize, sh_offset, sh_size; - - ec = e->e_class; - - shdr32 = &s->s_shdr.s_shdr32; - shdr64 = &s->s_shdr.s_shdr64; - if (ec == ELFCLASS32) { - sh_type = shdr32->sh_type; - sh_align = (uint64_t) shdr32->sh_addralign; - sh_entsize = (uint64_t) shdr32->sh_entsize; - sh_offset = (uint64_t) shdr32->sh_offset; - sh_size = (uint64_t) shdr32->sh_size; - } else { - sh_type = shdr64->sh_type; - sh_align = shdr64->sh_addralign; - sh_entsize = shdr64->sh_entsize; - sh_offset = shdr64->sh_offset; - sh_size = shdr64->sh_size; - } - - assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); - - elftype = _libelf_xlate_shtype(sh_type); - if (elftype > ELF_T_LAST) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - if (sh_align == 0) - sh_align = _libelf_falign(elftype, ec); - - /* - * Compute the section's size and alignment using the data - * descriptors associated with the section. - */ - if (STAILQ_EMPTY(&s->s_data)) { - /* - * The section's content (if any) has not been read in - * yet. If section is not dirty marked dirty, we can - * reuse the values in the 'sh_size' and 'sh_offset' - * fields of the section header. - */ - if ((s->s_flags & ELF_F_DIRTY) == 0) { - /* - * If the library is doing the layout, then we - * compute the new start offset for the - * section based on the current offset and the - * section's alignment needs. - * - * If the application is doing the layout, we - * can use the value in the 'sh_offset' field - * in the section header directly. - */ - if (e->e_flags & ELF_F_LAYOUT) - goto updatedescriptor; - else - goto computeoffset; - } - - /* - * Otherwise, we need to bring in the section's data - * from the underlying ELF object. - */ - if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) - return (0); - } - - /* - * Loop through the section's data descriptors. - */ - scn_size = 0L; - scn_alignment = 0; - STAILQ_FOREACH(d, &s->s_data, d_next) { - - /* - * The data buffer's type is known. - */ - if (d->d_type >= ELF_T_NUM) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * The data buffer's version is supported. - */ - if (d->d_version != e->e_version) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - - /* - * The buffer's alignment is non-zero and a power of - * two. - */ - if ((d_align = d->d_align) == 0 || - (d_align & (d_align - 1))) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * The buffer's size should be a multiple of the - * memory size of the underlying type. - */ - msz = _libelf_msize(d->d_type, ec, e->e_version); - if (d->d_size % msz) { - LIBELF_SET_ERROR(DATA, 0); - return (0); - } - - /* - * If the application is controlling layout, then the - * d_offset field should be compatible with the - * buffer's specified alignment. - */ - if ((e->e_flags & ELF_F_LAYOUT) && - (d->d_off & (d_align - 1))) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - - /* - * Compute the section's size. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if ((uint64_t) d->d_off + d->d_size > scn_size) - scn_size = d->d_off + d->d_size; - } else { - scn_size = roundup2(scn_size, d->d_align); - d->d_off = scn_size; - fsz = _libelf_fsize(d->d_type, ec, d->d_version, - d->d_size / msz); - scn_size += fsz; - } - - /* - * The section's alignment is the maximum alignment - * needed for its data buffers. - */ - if (d_align > scn_alignment) - scn_alignment = d_align; - } - - - /* - * If the application is requesting full control over the - * layout of the section, check the section's specified size, - * offsets and alignment for sanity. - */ - if (e->e_flags & ELF_F_LAYOUT) { - if (scn_alignment > sh_align || sh_offset % sh_align || - sh_size < scn_size) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - goto updatedescriptor; - } - - /* - * Otherwise, compute the values in the section header. - * - * The section alignment is the maximum alignment for any of - * its contained data descriptors. - */ - if (scn_alignment > sh_align) - sh_align = scn_alignment; - - /* - * If the section entry size is zero, try and fill in an - * appropriate entry size. Per the elf(5) manual page - * sections without fixed-size entries should have their - * 'sh_entsize' field set to zero. - */ - if (sh_entsize == 0 && - (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, - (size_t) 1)) == 1) - sh_entsize = 0; - - sh_size = scn_size; - -computeoffset: - /* - * Compute the new offset for the section based on - * the section's alignment needs. - */ - sh_offset = roundup(rc, sh_align); - - /* - * Update the section header. - */ - if (ec == ELFCLASS32) { - shdr32->sh_addralign = (uint32_t) sh_align; - shdr32->sh_entsize = (uint32_t) sh_entsize; - shdr32->sh_offset = (uint32_t) sh_offset; - shdr32->sh_size = (uint32_t) sh_size; - } else { - shdr64->sh_addralign = sh_align; - shdr64->sh_entsize = sh_entsize; - shdr64->sh_offset = sh_offset; - shdr64->sh_size = sh_size; - } - -updatedescriptor: - /* - * Update the section descriptor. - */ - s->s_size = sh_size; - s->s_offset = sh_offset; - - return (1); -} - -/* - * Free a list of extent descriptors. - */ - -static void -_libelf_release_extents(struct _Elf_Extent_List *extents) -{ - struct _Elf_Extent *ex; - - while ((ex = SLIST_FIRST(extents)) != NULL) { - SLIST_REMOVE_HEAD(extents, ex_next); - free(ex); - } -} - -/* - * Check if an extent 's' defined by [start..start+size) is free. - * This routine assumes that the given extent list is sorted in order - * of ascending extent offsets. - */ - -static int -_libelf_extent_is_unused(struct _Elf_Extent_List *extents, - const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt) -{ - uint64_t tmax, tmin; - struct _Elf_Extent *t, *pt; - const uint64_t smax = start + size; - - /* First, look for overlaps with existing extents. */ - pt = NULL; - SLIST_FOREACH(t, extents, ex_next) { - tmin = t->ex_start; - tmax = tmin + t->ex_size; - - if (tmax <= start) { - /* - * 't' lies entirely before 's': ...| t |...| s |... - */ - pt = t; - continue; - } else if (smax <= tmin) { - /* - * 's' lies entirely before 't', and after 'pt': - * ...| pt |...| s |...| t |... - */ - assert(pt == NULL || - pt->ex_start + pt->ex_size <= start); - break; - } else - /* 's' and 't' overlap. */ - return (0); - } - - if (prevt) - *prevt = pt; - return (1); -} - -/* - * Insert an extent into the list of extents. - */ - -static int -_libelf_insert_extent(struct _Elf_Extent_List *extents, int type, - uint64_t start, uint64_t size, void *desc) -{ - struct _Elf_Extent *ex, *prevt; - - assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR); - - prevt = NULL; - - /* - * If the requested range overlaps with an existing extent, - * signal an error. - */ - if (!_libelf_extent_is_unused(extents, start, size, &prevt)) { - LIBELF_SET_ERROR(LAYOUT, 0); - return (0); - } - - /* Allocate and fill in a new extent descriptor. */ - if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return (0); - } - ex->ex_start = start; - ex->ex_size = size; - ex->ex_desc = desc; - ex->ex_type = type; - - /* Insert the region descriptor into the list. */ - if (prevt) - SLIST_INSERT_AFTER(prevt, ex, ex_next); - else - SLIST_INSERT_HEAD(extents, ex, ex_next); - return (1); -} - -/* - * Recompute section layout. - */ - -static off_t -_libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) -{ - int ec; - Elf_Scn *s; - size_t sh_type; - - ec = e->e_class; - - /* - * Make a pass through sections, computing the extent of each - * section. - */ - STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - sh_type = s->s_shdr.s_shdr32.sh_type; - else - sh_type = s->s_shdr.s_shdr64.sh_type; - - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) - continue; - - if (_libelf_compute_section_extents(e, s, rc) == 0) - return ((off_t) -1); - - if (s->s_size == 0) - continue; - - if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION, - s->s_offset, s->s_size, s)) - return ((off_t) -1); - - if ((size_t) rc < s->s_offset + s->s_size) - rc = s->s_offset + s->s_size; - } - - return (rc); -} - -/* - * Recompute the layout of the ELF object and update the internal data - * structures associated with the ELF descriptor. - * - * Returns the size in bytes the ELF object would occupy in its file - * representation. - * - * After a successful call to this function, the following structures - * are updated: - * - * - The ELF header is updated. - * - All extents in the ELF object are sorted in order of ascending - * addresses. Sections have their section header table entries - * updated. An error is signalled if an overlap was detected among - * extents. - * - Data descriptors associated with sections are checked for valid - * types, offsets and alignment. - * - * After a resync_elf() successfully returns, the ELF descriptor is - * ready for being handed over to _libelf_write_elf(). - */ - -static off_t -_libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) -{ - int ec, eh_class, eh_type; - unsigned int eh_byteorder, eh_version; - size_t align, fsz; - size_t phnum, shnum; - off_t rc, phoff, shoff; - void *ehdr, *phdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - rc = 0; - - ec = e->e_class; - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - /* - * Prepare the EHDR. - */ - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return ((off_t) -1); - - eh32 = ehdr; - eh64 = ehdr; - - if (ec == ELFCLASS32) { - eh_byteorder = eh32->e_ident[EI_DATA]; - eh_class = eh32->e_ident[EI_CLASS]; - phoff = (uint64_t) eh32->e_phoff; - shoff = (uint64_t) eh32->e_shoff; - eh_type = eh32->e_type; - eh_version = eh32->e_version; - } else { - eh_byteorder = eh64->e_ident[EI_DATA]; - eh_class = eh64->e_ident[EI_CLASS]; - phoff = eh64->e_phoff; - shoff = eh64->e_shoff; - eh_type = eh64->e_type; - eh_version = eh64->e_version; - } - - if (eh_version == EV_NONE) - eh_version = EV_CURRENT; - - if (eh_version != e->e_version) { /* always EV_CURRENT */ - LIBELF_SET_ERROR(VERSION, 0); - return ((off_t) -1); - } - - if (eh_class != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return ((off_t) -1); - } - - if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { - LIBELF_SET_ERROR(HEADER, 0); - return ((off_t) -1); - } - - shnum = e->e_u.e_elf.e_nscn; - phnum = e->e_u.e_elf.e_nphdr; - - e->e_byteorder = eh_byteorder; - -#define INITIALIZE_EHDR(E,EC,V) do { \ - (E)->e_ident[EI_MAG0] = ELFMAG0; \ - (E)->e_ident[EI_MAG1] = ELFMAG1; \ - (E)->e_ident[EI_MAG2] = ELFMAG2; \ - (E)->e_ident[EI_MAG3] = ELFMAG3; \ - (E)->e_ident[EI_CLASS] = (EC); \ - (E)->e_ident[EI_VERSION] = (V); \ - (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ - (size_t) 1); \ - (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ - ELF_T_PHDR, (EC), (V), (size_t) 1); \ - (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ - (size_t) 1); \ - } while (0) - - if (ec == ELFCLASS32) - INITIALIZE_EHDR(eh32, ec, eh_version); - else - INITIALIZE_EHDR(eh64, ec, eh_version); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); - - if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) - return ((off_t) -1); - - /* - * Compute the layout the program header table, if one is - * present. The program header table needs to be aligned to a - * `natural' boundary. - */ - if (phnum) { - fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); - align = _libelf_falign(ELF_T_PHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - /* - * Check offsets for sanity. - */ - if (rc > phoff) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - - if (phoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - - } else - phoff = roundup(rc, align); - - rc = phoff + fsz; - - phdr = _libelf_getphdr(e, ec); - - if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, - fsz, phdr)) - return ((off_t) -1); - } else - phoff = 0; - - /* - * Compute the layout of the sections associated with the - * file. - */ - - if (e->e_cmd != ELF_C_WRITE && - (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && - _libelf_load_section_headers(e, ehdr) == 0) - return ((off_t) -1); - - if ((rc = _libelf_resync_sections(e, rc, extents)) < 0) - return ((off_t) -1); - - /* - * Compute the space taken up by the section header table, if - * one is needed. - * - * If ELF_F_LAYOUT has been asserted, the application may have - * placed the section header table in between existing - * sections, so the net size of the file need not increase due - * to the presence of the section header table. - * - * If the library is responsible for laying out the object, - * the section header table is placed after section data. - */ - if (shnum) { - fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum); - align = _libelf_falign(ELF_T_SHDR, ec); - - if (e->e_flags & ELF_F_LAYOUT) { - if (shoff % align) { - LIBELF_SET_ERROR(LAYOUT, 0); - return ((off_t) -1); - } - } else - shoff = roundup(rc, align); - - if (shoff + fsz > (size_t) rc) - rc = shoff + fsz; - - if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, - fsz, NULL)) - return ((off_t) -1); - } else - shoff = 0; - - /* - * Set the fields of the Executable Header that could potentially use - * extended numbering. - */ - _libelf_setphnum(e, ehdr, ec, phnum); - _libelf_setshnum(e, ehdr, ec, shnum); - - /* - * Update the `e_phoff' and `e_shoff' fields if the library is - * doing the layout. - */ - if ((e->e_flags & ELF_F_LAYOUT) == 0) { - if (ec == ELFCLASS32) { - eh32->e_phoff = (uint32_t) phoff; - eh32->e_shoff = (uint32_t) shoff; - } else { - eh64->e_phoff = (uint64_t) phoff; - eh64->e_shoff = (uint64_t) shoff; - } - } - - return (rc); -} - -/* - * Write out the contents of an ELF section. - */ - -static size_t -_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - size_t fsz, msz, nobjects, rc; - uint32_t sh_type; - uint64_t sh_off, sh_size; - int elftype; - Elf_Scn *s; - Elf_Data *d, dst; - - assert(ex->ex_type == ELF_EXTENT_SECTION); - - s = ex->ex_desc; - rc = ex->ex_start; - - if ((ec = e->e_class) == ELFCLASS32) { - sh_type = s->s_shdr.s_shdr32.sh_type; - sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; - } else { - sh_type = s->s_shdr.s_shdr64.sh_type; - sh_size = s->s_shdr.s_shdr64.sh_size; - } - - /* - * Ignore sections that do not allocate space in the file. - */ - if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) - return (rc); - - elftype = _libelf_xlate_shtype(sh_type); - assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); - - sh_off = s->s_offset; - assert(sh_off % _libelf_falign(elftype, ec) == 0); - - /* - * If the section has a `rawdata' descriptor, and the section - * contents have not been modified, use its contents directly. - * The `s_rawoff' member contains the offset into the original - * file, while `s_offset' contains its new location in the - * destination. - */ - - if (STAILQ_EMPTY(&s->s_data)) { - - if ((d = elf_rawdata(s, NULL)) == NULL) - return ((off_t) -1); - - STAILQ_FOREACH(d, &s->s_rawdata, d_next) { - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + - d->d_off - rc); - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_type == ELF_T_BYTE); - assert(d->d_version == e->e_version); - - (void) memcpy(nf + rc, - e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); - - rc += d->d_size; - } - - return (rc); - } - - /* - * Iterate over the set of data descriptors for this section. - * The prior call to _libelf_resync_elf() would have setup the - * descriptors for this step. - */ - - dst.d_version = e->e_version; - - STAILQ_FOREACH(d, &s->s_data, d_next) { - - msz = _libelf_msize(d->d_type, ec, e->e_version); - - if ((uint64_t) rc < sh_off + d->d_off) - (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); - - rc = sh_off + d->d_off; - - assert(d->d_buf != NULL); - assert(d->d_version == e->e_version); - assert(d->d_size % msz == 0); - - nobjects = d->d_size / msz; - - fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); - - dst.d_buf = nf + rc; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - rc += fsz; - } - - return ((off_t) rc); -} - -/* - * Write out an ELF Executable Header. - */ - -static off_t -_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - size_t fsz, msz; - Elf_Data dst, src; - - assert(ex->ex_type == ELF_EXTENT_EHDR); - assert(ex->ex_start == 0); /* Ehdr always comes first. */ - - ec = e->e_class; - - ehdr = _libelf_ehdr(e, ec, 0); - assert(ehdr != NULL); - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - src.d_buf = ehdr; - src.d_size = msz; - src.d_type = ELF_T_EHDR; - src.d_version = dst.d_version = e->e_version; - - dst.d_buf = nf; - dst.d_size = fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - return ((off_t) fsz); -} - -/* - * Write out an ELF program header table. - */ - -static off_t -_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf_Data dst, src; - size_t fsz, phnum; - uint64_t phoff; - - assert(ex->ex_type == ELF_EXTENT_PHDR); - - ec = e->e_class; - ehdr = _libelf_ehdr(e, ec, 0); - phnum = e->e_u.e_elf.e_nphdr; - - assert(phnum > 0); - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - phoff = (uint64_t) eh32->e_phoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - phoff = eh64->e_phoff; - } - - assert(phoff > 0); - assert(ex->ex_start == phoff); - assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); - assert(fsz > 0); - - src.d_buf = _libelf_getphdr(e, ec); - src.d_version = dst.d_version = e->e_version; - src.d_type = ELF_T_PHDR; - src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, - e->e_version); - - dst.d_size = fsz; - dst.d_buf = nf + ex->ex_start; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == - NULL) - return ((off_t) -1); - - return (phoff + fsz); -} - -/* - * Write out an ELF section header table. - */ - -static off_t -_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) -{ - int ec; - void *ehdr; - Elf_Scn *scn; - uint64_t shoff; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - size_t fsz, nscn; - Elf_Data dst, src; - - assert(ex->ex_type == ELF_EXTENT_SHDR); - - ec = e->e_class; - ehdr = _libelf_ehdr(e, ec, 0); - nscn = e->e_u.e_elf.e_nscn; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - shoff = (uint64_t) eh32->e_shoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - shoff = eh64->e_shoff; - } - - assert(nscn > 0); - assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0); - assert(ex->ex_start == shoff); - - (void) memset(&dst, 0, sizeof(dst)); - (void) memset(&src, 0, sizeof(src)); - - src.d_type = ELF_T_SHDR; - src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); - src.d_version = dst.d_version = e->e_version; - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); - - STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { - if (ec == ELFCLASS32) - src.d_buf = &scn->s_shdr.s_shdr32; - else - src.d_buf = &scn->s_shdr.s_shdr64; - - dst.d_size = fsz; - dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz; - - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, - ELF_TOFILE) == NULL) - return ((off_t) -1); - } - - return (ex->ex_start + nscn * fsz); -} - -/* - * Write out the file image. - * - * The original file could have been mapped in with an ELF_C_RDWR - * command and the application could have added new content or - * re-arranged its sections before calling elf_update(). Consequently - * its not safe to work `in place' on the original file. So we - * malloc() the required space for the updated ELF object and build - * the object there and write it out to the underlying file at the - * end. Note that the application may have opened the underlying file - * in ELF_C_RDWR and only retrieved/modified a few sections. We take - * care to avoid translating file sections unnecessarily. - * - * Gaps in the coverage of the file by the file's sections will be - * filled with the fill character set by elf_fill(3). - */ - -static off_t -_libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) -{ - off_t nrc, rc; - char *newfile; - Elf_Scn *scn, *tscn; - struct _Elf_Extent *ex; - - assert(e->e_kind == ELF_K_ELF); - assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); - assert(e->e_fd >= 0); - - if ((newfile = malloc((size_t) newsize)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return ((off_t) -1); - } - - nrc = rc = 0; - SLIST_FOREACH(ex, extents, ex_next) { - - /* Fill inter-extent gaps. */ - if (ex->ex_start > (size_t) rc) - (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), - ex->ex_start - rc); - - switch (ex->ex_type) { - case ELF_EXTENT_EHDR: - if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_PHDR: - if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_SECTION: - if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0) - goto error; - break; - - case ELF_EXTENT_SHDR: - if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0) - goto error; - break; - - default: - assert(0); - break; - } - - assert(ex->ex_start + ex->ex_size == (size_t) nrc); - assert(rc < nrc); - - rc = nrc; - } - - assert(rc == newsize); - - /* - * For regular files, throw away existing file content and - * unmap any existing mappings. - */ - if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) { - if (ftruncate(e->e_fd, (off_t) 0) < 0 || - lseek(e->e_fd, (off_t) 0, SEEK_SET)) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { - assert(e->e_rawfile != NULL); - assert(e->e_cmd == ELF_C_RDWR); - if (munmap(e->e_rawfile, e->e_rawsize) < 0) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - } - } - - /* - * Write out the new contents. - */ - if (write(e->e_fd, newfile, (size_t) newsize) != newsize) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - - /* - * For files opened in ELF_C_RDWR mode, set up the new 'raw' - * contents. - */ - if (e->e_cmd == ELF_C_RDWR) { - assert(e->e_rawfile != NULL); - if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { - if ((e->e_rawfile = mmap(NULL, (size_t) newsize, - PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == - MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - goto error; - } - } else if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { - free(e->e_rawfile); - e->e_rawfile = newfile; - newfile = NULL; - } - - /* Record the new size of the file. */ - e->e_rawsize = newsize; - } else { - /* File opened in ELF_C_WRITE mode. */ - assert(e->e_rawfile == NULL); - } - - /* - * Reset flags, remove existing section descriptors and - * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() - * and elf_getscn() will function correctly. - */ - - e->e_flags &= ~ELF_F_DIRTY; - - STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) - _libelf_release_scn(scn); - - if (e->e_class == ELFCLASS32) { - free(e->e_u.e_elf.e_ehdr.e_ehdr32); - if (e->e_u.e_elf.e_phdr.e_phdr32) - free(e->e_u.e_elf.e_phdr.e_phdr32); - - e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; - e->e_u.e_elf.e_phdr.e_phdr32 = NULL; - } else { - free(e->e_u.e_elf.e_ehdr.e_ehdr64); - if (e->e_u.e_elf.e_phdr.e_phdr64) - free(e->e_u.e_elf.e_phdr.e_phdr64); - - e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; - e->e_u.e_elf.e_phdr.e_phdr64 = NULL; - } - - /* Free the temporary buffer. */ - if (newfile) - free(newfile); - - return (rc); - - error: - free(newfile); - - return ((off_t) -1); -} - -/* - * Update an ELF object. - */ - -off_t -elf_update(Elf *e, Elf_Cmd c) -{ - int ec; - off_t rc; - struct _Elf_Extent_List extents; - - rc = (off_t) -1; - - if (e == NULL || e->e_kind != ELF_K_ELF || - (c != ELF_C_NULL && c != ELF_C_WRITE)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (rc); - } - - if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (rc); - } - - if (e->e_version == EV_NONE) - e->e_version = EV_CURRENT; - - if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (rc); - } - - SLIST_INIT(&extents); - - if ((rc = _libelf_resync_elf(e, &extents)) < 0) - goto done; - - if (c == ELF_C_NULL) - goto done; - - if (e->e_fd < 0) { - rc = (off_t) -1; - LIBELF_SET_ERROR(SEQUENCE, 0); - goto done; - } - - return (_libelf_write_elf(e, rc, &extents)); - -done: - _libelf_release_extents(&extents); - return (rc); -} diff --git a/linkers/elftoolchain/libelf/elf_version.3 b/linkers/elftoolchain/libelf/elf_version.3 deleted file mode 100644 index b09fb47..0000000 --- a/linkers/elftoolchain/libelf/elf_version.3 +++ /dev/null @@ -1,95 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elf_version.3 2123 2011-11-09 15:40:09Z jkoshy $ -.\" -.Dd November 9, 2011 -.Os -.Dt ELF_VERSION 3 -.Sh NAME -.Nm elf_version -.Nd retrieve or set ELF library operating version -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft unsigned int -.Fn elf_version "unsigned int version" -.Sh DESCRIPTION -The -.Fn elf_version -function is used to query the current operating version of the ELF -library, and to inform the ELF library about the application's desired -operating version. -.Pp -If the argument -.Ar version -is -.Dv EV_NONE , -the -.Fn elf_version -function returns the currently configured operating version for the -ELF library. -.Pp -If the argument -.Ar version -is not -.Dv EV_NONE , -and if argument -.Ar version -is supported by the ELF library, function -.Fn elf_version -sets the library's operating version to -.Ar version , -and returns the previous value of the operating version. -If argument -.Ar version -cannot be supported, then the -.Fn elf_version -function returns -.Dv EV_NONE . -.Sh RETURN VALUES -The -.Fn elf_version -function returns the currently configured ELF library version, or -.Dv EV_NONE -if an unsupported version is requested. -.Sh EXAMPLES -An application program would inform the ELF library about its desired -operating version and check for an error using the following code -snippet: -.Bd -literal -offset indent -if (elf_version(EV_CURRENT) == EV_NONE) - err(EXIT_FAILURE, "ELF library too old"); -.Ed -.Sh ERRORS -Function -.Fn elf_version -may fail with the following error: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er "ELF_E_VERSION" -An unsupported library version number was requested. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/elf_version.c b/linkers/elftoolchain/libelf/elf_version.c deleted file mode 100644 index 48950f4..0000000 --- a/linkers/elftoolchain/libelf/elf_version.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: elf_version.c 189 2008-07-20 10:38:08Z jkoshy $"); - -unsigned int -elf_version(unsigned int v) -{ - unsigned int old; - - if ((old = LIBELF_PRIVATE(version)) == EV_NONE) - old = EV_CURRENT; - - if (v == EV_NONE) - return old; - if (v > EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return EV_NONE; - } - - LIBELF_PRIVATE(version) = v; - return (old); -} diff --git a/linkers/elftoolchain/libelf/gelf.3 b/linkers/elftoolchain/libelf/gelf.3 deleted file mode 100644 index a5d68ce..0000000 --- a/linkers/elftoolchain/libelf/gelf.3 +++ /dev/null @@ -1,201 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd September 1, 2006 -.Os -.Dt GELF 3 -.Sh NAME -.Nm GElf -.Nd class-independent API for ELF manipulation -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Sh DESCRIPTION -This manual page describes a class independent API for manipulating -ELF objects. -This API allows an application to operate on ELF descriptors without -needing to the know the ELF class of the descriptor. -.Pp -The GElf API may be used alongside the ELF API without restriction. -.Ss GElf Data Structures -The GElf API defines the following class-independent data structures: -.Bl -tag -width GElf_Sxword -.It Vt GElf_Addr -A representation of ELF addresses. -.It Vt GElf_Dyn -A class-independent representation of ELF -.Sy .dynamic -section entries. -.It Vt GElf_Ehdr -A class-independent representation of an ELF Executable Header. -.It Vt GElf_Half -An unsigned 16 bit quantity. -.It Vt GElf_Off -A class-independent representation of a ELF offset. -.It Vt GElf_Phdr -A class-independent representation of an ELF Program Header Table -entry. -.It Vt GElf_Rel -A class-independent representation of an ELF relocation entry. -.It Vt GElf_Rela -A class-independent representation of an ELF relocation entry with -addend. -.It Vt GElf_Shdr -A class-independent representation of an ELF Section Header Table -entry. -.It Vt GElf_Sword -A signed 32 bit quantity. -.It Vt GElf_Sxword -A signed 64 bit quantity. -.It Vt GElf_Sym -A class-independent representation of an ELF symbol table entry. -.It Vt GElf_Word -An unsigned 32 bit quantity. -.It Vt GElf_Xword -An unsigned 64 bit quantity. -.El -.Pp -These data structures are sized to be compatible with the -corresponding 64 bit ELF structures, and have the same internal -structure as their 64 bit class-dependent counterparts. -Class-dependent ELF structures are described in -.Xr elf 5 . -.Ss GElf Programming Model -GElf functions always return a -.Em copy -of the underlying (class-dependent) ELF data structure. -The programming model with GElf is as follows: -.Bl -enum -.It -An application will retrieve data from an ELF descriptor using a -.Fn gelf_get_* -function. -This will copy out data into a private -.Vt GElf_* -data structure. -.It -The application will work with its private copy of the GElf -structure. -.It -Once done, the application copies the new values back to the -underlying ELF data structure using the -.Fn gelf_update_* -functions. -.It -The application will then use the -.Fn elf_flag* -APIs to indicate to the ELF library that an ELF data structure is dirty. -.El -.Pp -When updating an underlying 32 bit ELF data structure, the GElf -routines will signal an error if a GElf value is out of range -for the underlying ELF data type. -.Ss Namespace use -The GElf interface uses the following symbols: -.Bl -tag -.It GElf_* -Class-independent data types. -.It gelf_* -For functions defined in the API set. -.El -.Ss GElf Programming APIs -This section provides an overview of the GElf programming APIs. -Further information is provided in the manual page of each function -listed here. -.Bl -tag -.It "Allocating ELF Data Structures" -.Bl -tag -compact -.It Fn gelf_newehdr -Allocate a new ELF Executable Header. -.It Fn gelf_newphdr -Allocate a new ELF Program Header Table. -.El -.It "Data Translation" -.Bl -tag -compact -.It Fn gelf_xlatetof -Translate the native representation of an ELF data structure to its -file representation. -.It Fn gelf_xlatetom -Translate from the file representation of an ELF data structure to a -native representation. -.El -.It "Retrieving ELF Data" -.Bl -tag -compact -.It Fn gelf_getdyn -Retrieve an ELF -.Sy .dynamic -table entry. -.It Fn gelf_getehdr -Retrieve an ELF Executable Header from the underlying ELF descriptor. -.It Fn gelf_getphdr -Retrieve an ELF Program Header Table entry from the underlying ELF descriptor. -.It Fn gelf_getrel -Retrieve an ELF relocation entry. -.It Fn gelf_getrela -Retrieve an ELF relocation entry with addend. -.It Fn gelf_getshdr -Retrieve an ELF Section Header Table entry from the underlying ELF descriptor. -.It Fn gelf_getsym -Retrieve an ELF symbol table entry. -.El -.It Queries -.Bl -tag -compact -.It Fn gelf_checksum -Retrieves the ELF checksum for an ELF descriptor. -.It Fn gelf_fsize -Retrieves the size of the file representation of an ELF type. -.It Fn gelf_getclass -Retrieves the ELF class of an ELF descriptor. -.El -.It "Updating ELF Data" -.Bl -tag -compact -width ".Fn gelf_update_shdr" -.It Fn gelf_update_dyn -Copy back an ELF -.Sy .dynamic -Table entry. -.It Fn gelf_update_phdr -Copy back an ELF Program Header Table entry. -.It Fn gelf_update_rel -Copy back an ELF relocation entry. -.It Fn gelf_update_rela -Copy back an ELF relocation with addend entry. -.It Fn gelf_update_shdr -Copy back an ELF Section Header Table entry. -.It Fn gelf_update_sym -Copy back an ELF symbol table entry. -.El -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf 5 -.Sh HISTORY -The GELF(3) API first appeared in System V Release 4. -This implementation of the API first appeared in -.Fx 7.0 . -.Sh AUTHORS -The GElf API was implemented by -.An "Joseph Koshy" -.Aq jkoshy@FreeBSD.org . diff --git a/linkers/elftoolchain/libelf/gelf.h b/linkers/elftoolchain/libelf/gelf.h deleted file mode 100644 index 0a7dc24..0000000 --- a/linkers/elftoolchain/libelf/gelf.h +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: gelf.h 1168 2010-09-04 01:03:25Z jkoshy $ - */ - -#ifndef _GELF_H_ -#define _GELF_H_ - -#include - -#include - -typedef Elf64_Addr GElf_Addr; /* Addresses */ -typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ -typedef Elf64_Off GElf_Off; /* Offsets */ -typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ -typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ -typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ -typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ - -typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ -typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ -typedef Elf64_Phdr GElf_Phdr; /* Program header */ -typedef Elf64_Shdr GElf_Shdr; /* Section header */ -typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ -typedef Elf64_Rel GElf_Rel; /* Relocation entries */ -typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ - -typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ -typedef Elf64_Move GElf_Move; /* Move entries */ -typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ - -#define GELF_M_INFO ELF64_M_INFO -#define GELF_M_SIZE ELF64_M_SIZE -#define GELF_M_SYM ELF64_M_SYM - -#define GELF_R_INFO ELF64_R_INFO -#define GELF_R_SYM ELF64_R_SYM -#define GELF_R_TYPE ELF64_R_TYPE -#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA -#define GELF_R_TYPE_ID ELF64_R_TYPE_ID -#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO - -#define GELF_ST_BIND ELF64_ST_BIND -#define GELF_ST_INFO ELF64_ST_INFO -#define GELF_ST_TYPE ELF64_ST_TYPE -#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY - -__BEGIN_DECLS -long gelf_checksum(Elf *_elf); -size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, - unsigned int _version); -int gelf_getclass(Elf *_elf); -GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); -GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); -GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); -GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); -GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); -GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); -GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); -GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, - int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); -void * gelf_newehdr(Elf *_elf, int _class); -void * gelf_newphdr(Elf *_elf, size_t _phnum); -int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); -int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); -int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); -int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); -int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); -int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); -int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); -int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, - int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); -Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); -Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); - -GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); -GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); -GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); -int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); -int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); -int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); -__END_DECLS - -#endif /* _GELF_H_ */ diff --git a/linkers/elftoolchain/libelf/gelf_cap.c b/linkers/elftoolchain/libelf/gelf_cap.c deleted file mode 100644 index af0b388..0000000 --- a/linkers/elftoolchain/libelf/gelf_cap.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_cap.c 1166 2010-09-04 00:54:36Z jkoshy $"); - -GElf_Cap * -gelf_getcap(Elf_Data *d, int ndx, GElf_Cap *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - cap32 = (Elf32_Cap *) d->d_buf + ndx; - - dst->c_tag = cap32->c_tag; - dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; - - } else { - - cap64 = (Elf64_Cap *) d->d_buf + ndx; - - *dst = *cap64; - } - - return (dst); -} - -int -gelf_update_cap(Elf_Data *d, int ndx, GElf_Cap *gc) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Cap *cap32; - Elf64_Cap *cap64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gc == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - cap32 = (Elf32_Cap *) d->d_buf + ndx; - - LIBELF_COPY_U32(cap32, gc, c_tag); - LIBELF_COPY_U32(cap32, gc, c_un.c_val); - } else { - cap64 = (Elf64_Cap *) d->d_buf + ndx; - - *cap64 = *gc; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_checksum.3 b/linkers/elftoolchain/libelf/gelf_checksum.3 deleted file mode 100644 index e5f845f..0000000 --- a/linkers/elftoolchain/libelf/gelf_checksum.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_checksum.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_CHECKSUM 3 -.Sh NAME -.Nm elf32_checksum , -.Nm elf64_checksum , -.Nm gelf_checksum -.Nd return the checksum of an ELF object -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft long -.Fn elf32_checksum "Elf *elf" -.Ft long -.Fn elf64_checksum "Elf *elf" -.In gelf.h -.Ft long -.Fn gelf_checksum "Elf *elf" -.Sh DESCRIPTION -These functions return a simple checksum of the ELF object described -by their argument -.Ar elf . -The checksum is computed in way that allows its value to remain -unchanged in presence of modifications to the ELF object by utilities -like -.Xr strip 1 . -.Pp -Function -.Fn elf32_checksum -returns a checksum for an ELF descriptor -.Ar elf -of class -.Dv ELFCLASS32 . -.Pp -Function -.Fn elf64_checksum -returns a checksum for an ELF descriptor -.Ar elf -of class -.Dv ELFCLASS64 . -.Pp -Function -.Fn gelf_checksum -provides a class-independent way retrieving the checksum -for ELF object -.Ar elf . -.Sh RETURN VALUES -These functions return the checksum of the ELF object, or zero in case -an error was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -The ELF descriptor -.Ar elf -was not opened for reading or updating. -.It Bq Er ELF_E_CLASS -For functions -.Fn elf32_checksum -and -.Fn elf64_checksum , -ELF descriptor -.Ar elf -did not match the class of the called function. -.It Bq Er ELF_E_HEADER -The ELF object specified by argument -.Ar elf -had a malformed executable header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during processing. -.It Bq Er ELF_E_SECTION -The ELF object specified by argument -.Ar elf -contained a section with a malformed section header. -.It Bq Er ELF_E_VERSION -The ELF object was of an unsupported version. -.El -.Sh SEE ALSO -.Xr strip 1 , -.Xr elf 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_checksum.c b/linkers/elftoolchain/libelf/gelf_checksum.c deleted file mode 100644 index 30fbb97..0000000 --- a/linkers/elftoolchain/libelf/gelf_checksum.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_checksum.c 189 2008-07-20 10:38:08Z jkoshy $"); - -long -elf32_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS32)); -} - -long -elf64_checksum(Elf *e) -{ - return (_libelf_checksum(e, ELFCLASS64)); -} - -long -gelf_checksum(Elf *e) -{ - int ec; - if (e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - return (_libelf_checksum(e, ec)); -} diff --git a/linkers/elftoolchain/libelf/gelf_dyn.c b/linkers/elftoolchain/libelf/gelf_dyn.c deleted file mode 100644 index 6a2885c..0000000 --- a/linkers/elftoolchain/libelf/gelf_dyn.c +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_dyn.c 189 2008-07-20 10:38:08Z jkoshy $"); - -GElf_Dyn * -gelf_getdyn(Elf_Data *d, int ndx, GElf_Dyn *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_buf + ndx; - - dst->d_tag = dyn32->d_tag; - dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; - - } else { - - dyn64 = (Elf64_Dyn *) d->d_buf + ndx; - - *dst = *dyn64; - } - - return (dst); -} - -int -gelf_update_dyn(Elf_Data *d, int ndx, GElf_Dyn *ds) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Dyn *dyn32; - Elf64_Dyn *dyn64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || ds == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - dyn32 = (Elf32_Dyn *) d->d_buf + ndx; - - LIBELF_COPY_S32(dyn32, ds, d_tag); - LIBELF_COPY_U32(dyn32, ds, d_un.d_val); - } else { - dyn64 = (Elf64_Dyn *) d->d_buf + ndx; - - *dyn64 = *ds; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_ehdr.c b/linkers/elftoolchain/libelf/gelf_ehdr.c deleted file mode 100644 index 37ccce8..0000000 --- a/linkers/elftoolchain/libelf/gelf_ehdr.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_ehdr.c 1678 2011-07-28 04:36:34Z jkoshy $"); - -Elf32_Ehdr * -elf32_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 0)); -} - -Elf64_Ehdr * -elf64_getehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 0)); -} - -GElf_Ehdr * -gelf_getehdr(Elf *e, GElf_Ehdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) - return (NULL); - - (void) memcpy(d->e_ident, eh32->e_ident, - sizeof(eh32->e_ident)); - d->e_type = eh32->e_type; - d->e_machine = eh32->e_machine; - d->e_version = eh32->e_version; - d->e_entry = eh32->e_entry; - d->e_phoff = eh32->e_phoff; - d->e_shoff = eh32->e_shoff; - d->e_flags = eh32->e_flags; - d->e_ehsize = eh32->e_ehsize; - d->e_phentsize = eh32->e_phentsize; - d->e_phnum = eh32->e_phnum; - d->e_shentsize = eh32->e_shentsize; - d->e_shnum = eh32->e_shnum; - d->e_shstrndx = eh32->e_shstrndx; - - return (d); - } - - assert(ec == ELFCLASS64); - - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) - return (NULL); - *d = *eh64; - - return (d); -} - -Elf32_Ehdr * -elf32_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS32, 1)); -} - -Elf64_Ehdr * -elf64_newehdr(Elf *e) -{ - return (_libelf_ehdr(e, ELFCLASS64, 1)); -} - -void * -gelf_newehdr(Elf *e, int ec) -{ - if (e != NULL && - (ec == ELFCLASS32 || ec == ELFCLASS64)) - return (_libelf_ehdr(e, ec, 1)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -int -gelf_update_ehdr(Elf *e, GElf_Ehdr *s) -{ - int ec; - void *ehdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - - if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - eh64 = (Elf64_Ehdr *) ehdr; - *eh64 = *s; - return (1); - } - - eh32 = (Elf32_Ehdr *) ehdr; - - (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); - - eh32->e_type = s->e_type; - eh32->e_machine = s->e_machine; - eh32->e_version = s->e_version; - LIBELF_COPY_U32(eh32, s, e_entry); - LIBELF_COPY_U32(eh32, s, e_phoff); - LIBELF_COPY_U32(eh32, s, e_shoff); - eh32->e_flags = s->e_flags; - eh32->e_ehsize = s->e_ehsize; - eh32->e_phentsize = s->e_phentsize; - eh32->e_phnum = s->e_phnum; - eh32->e_shentsize = s->e_shentsize; - eh32->e_shnum = s->e_shnum; - eh32->e_shstrndx = s->e_shstrndx; - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_fsize.3 b/linkers/elftoolchain/libelf/gelf_fsize.3 deleted file mode 100644 index ac7996f..0000000 --- a/linkers/elftoolchain/libelf/gelf_fsize.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_fsize.3 317 2009-03-06 17:29:22Z jkoshy $ -.\" -.Dd February 5, 2008 -.Os -.Dt GELF_FSIZE 3 -.Sh NAME -.Nm gelf_fsize , -.Nm elf32_fsize , -.Nm elf64_fsize -.Nd return the size of a file type -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft size_t -.Fn elf32_fsize "Elf_Type type" "size_t count" "unsigned int version" -.Ft size_t -.Fn elf64_fsize "Elf_Type type" "size_t count" "unsigned int version" -.In gelf.h -.Ft size_t -.Fn gelf_fsize "Elf *elf" "Elf_Type type" "size_t count" "unsigned int version" -.Sh DESCRIPTION -These functions return the size in bytes of the file representation of -.Ar count -numbers of objects of ELF type -.Ar type . -For ELF types that are of variable length, these functions return a -size of one byte. -.Pp -Functions -.Fn elf32_fsize -and -.Fn elf64_fsize -return sizes for files of class -.Dv ELFCLASS32 -and -.Dv ELFCLASS64 -respectively. -Function -.Fn gelf_fsize -returns the size for the class of ELF descriptor -.Ar elf . -.Sh RETURN VALUES -These functions return a non-zero value in case of success, or zero in -case of an error. -.Sh ERRORS -These functions may fail with: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL in a call to -.Fn gelf_fsize . -.It Bq Er ELF_E_ARGUMENT -ELF descriptor -.Ar elf -had an unknown ELF class. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar type -contained an illegal value. -.It Bq Er ELF_E_UNIMPL -Support for ELF type -.Ar type -has not been implemented. -.It Bq Er ELF_E_VERSION -Argument -.Ar version -is not a supported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_fsize.c b/linkers/elftoolchain/libelf/gelf_fsize.c deleted file mode 100644 index 0e38d14..0000000 --- a/linkers/elftoolchain/libelf/gelf_fsize.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_fsize.c 189 2008-07-20 10:38:08Z jkoshy $"); - -size_t -elf32_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS32, v, c)); -} - -size_t -elf64_fsize(Elf_Type t, size_t c, unsigned int v) -{ - return (_libelf_fsize(t, ELFCLASS64, v, c)); -} - -size_t -gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) -{ - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) - return (_libelf_fsize(t, e->e_class, v, c)); - - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); -} diff --git a/linkers/elftoolchain/libelf/gelf_getcap.3 b/linkers/elftoolchain/libelf/gelf_getcap.3 deleted file mode 100644 index ed8eb02..0000000 --- a/linkers/elftoolchain/libelf/gelf_getcap.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getcap.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETCAP 3 -.Sh NAME -.Nm gelf_getcap , -.Nm gelf_update_cap -.Nd read and update ELF capability information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Cap *" -.Fn gelf_getcap "Elf_Data *data" "int ndx" "GElf_Cap *cap" -.Ft int -.Fn gelf_update_cap "Elf_Data *data" "int ndx" "GElf_Cap *cap" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Cap -or -.Vt Elf64_Cap -information. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_cap . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Cap -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getcap -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar cap -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_cap -converts the class-independent entry pointed to -by argument -.Ar cap -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_cap -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getcap -returns the value of argument -.Ar cap -if successful, or NULL in case of an error. -Function -.Fn gelf_update_cap -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar cap -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_SUNW_cap . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getclass.3 b/linkers/elftoolchain/libelf/gelf_getclass.3 deleted file mode 100644 index 3504569..0000000 --- a/linkers/elftoolchain/libelf/gelf_getclass.3 +++ /dev/null @@ -1,61 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getclass.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd July 3, 2006 -.Os -.Dt GELF_GETCLASS 3 -.Sh NAME -.Nm gelf_getclass -.Nd retrieve the class of an ELF descriptor -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft int -.Fn gelf_getclass "Elf *elf" -.Sh DESCRIPTION -Function -.Fn gelf_getclass -returns the ELF class of the descriptor supplied in argument -.Ar elf . -.Sh RETURN VALUES -Function -.Fn gelf_getclass -will return one of -.Dv ELFCLASS32 -or -.Dv ELFCLASS64 -if the argument -.Ar elf -is a descriptor for an ELF file. -The value -.Dv ELFCLASSNONE -is returned if argument -.Ar elf -was null, or if it was not a descriptor for an ELF file. -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_kind 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getclass.c b/linkers/elftoolchain/libelf/gelf_getclass.c deleted file mode 100644 index 349a9cd..0000000 --- a/linkers/elftoolchain/libelf/gelf_getclass.c +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_getclass.c 189 2008-07-20 10:38:08Z jkoshy $"); - -int -gelf_getclass(Elf *e) -{ - return (e != NULL ? e->e_class : ELFCLASSNONE); -} diff --git a/linkers/elftoolchain/libelf/gelf_getdyn.3 b/linkers/elftoolchain/libelf/gelf_getdyn.3 deleted file mode 100644 index f8c1778..0000000 --- a/linkers/elftoolchain/libelf/gelf_getdyn.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getdyn.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETDYN 3 -.Sh NAME -.Nm gelf_getdyn , -.Nm gelf_update_dyn -.Nd read and update ELF dynamic entries -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Dyn *" -.Fn gelf_getdyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" -.Ft int -.Fn gelf_update_dyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Dyn -or -.Vt Elf64_Dyn -information in the -.Sy dynamic -table of an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_DYNAMIC . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Dyn -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getdyn -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar dyn -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_dyn -converts the class-independent entry pointed to -by argument -.Ar dyn -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_dyn -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getdyn -returns the value of argument -.Ar dyn -if successful, or NULL in case of an error. -Function -.Fn gelf_update_dyn -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar dyn -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_DYNAMIC . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getehdr.3 b/linkers/elftoolchain/libelf/gelf_getehdr.3 deleted file mode 100644 index 56bdcd4..0000000 --- a/linkers/elftoolchain/libelf/gelf_getehdr.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getehdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd December 16, 2006 -.Os -.Dt GELF_GETEHDR 3 -.Sh NAME -.Nm elf32_getehdr , -.Nm elf64_getehdr , -.Nm gelf_getehdr -.Nd retrieve the object file header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Ehdr *" -.Fn elf32_getehdr "Elf *elf" -.Ft "Elf64_Ehdr *" -.Fn elf64_getehdr "Elf *elf" -.In gelf.h -.Ft "GElf_Ehdr *" -.Fn gelf_getehdr "Elf *elf" "GElf_Ehdr *dst" -.Sh DESCRIPTION -These functions retrieve the ELF object file -header from the ELF descriptor -.Ar elf -and return a translated header descriptor to their callers. -.Pp -Functions -.Fn elf32_getehdr -and -.Fn elf64_getehdr -return a pointer to the appropriate class-specific header descriptor -if it exists in the file referenced by descriptor -.Ar elf . -These functions return -.Dv NULL -if an ELF header was not found in file -.Ar elf . -.Pp -Function -.Fn gelf_getehdr -stores a translated copy of the header for ELF file -.Ar elf -into the descriptor pointed to by argument -.Ar dst . -It returns argument -.Ar dst -if successful or -.Dv NULL -in case of failure. -.Sh RETURN VALUES -These functions return a pointer to a translated header descriptor -if successful, or NULL on failure. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF file. -.It Bq Er ELF_E_ARGUMENT -The elf class of descriptor -.Ar elf -was not recognized. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar dst -was null. -.It Bq Er ELF_E_CLASS -The ELF class of descriptor -.Ar elf -did not match that of the API function being called. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -does not have an associated header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during execution. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_E_VERSION -The ELF descriptor -.Ar elf -had an unsupported ELF version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_newehdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf_flagehdr 3 , -.Xr elf_getident 3 , -.Xr gelf 3 , -.Xr gelf_newehdr 3 , -.Xr elf 5 diff --git a/linkers/elftoolchain/libelf/gelf_getmove.3 b/linkers/elftoolchain/libelf/gelf_getmove.3 deleted file mode 100644 index 871a040..0000000 --- a/linkers/elftoolchain/libelf/gelf_getmove.3 +++ /dev/null @@ -1,120 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getmove.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETMOVE 3 -.Sh NAME -.Nm gelf_getmove , -.Nm gelf_update_move -.Nd read and update Elf Move information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Move *" -.Fn gelf_getmove "Elf_Data *data" "int ndx" "GElf_Move *move" -.Ft int -.Fn gelf_update_move "Elf_Data *data" "int ndx" "GElf_Move *move" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Move -and -.Vt Elf64_Move -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_move . -Argument -.Ar ndx -is the index of the move record being retrieved or updated. -The class-independent -.Vt GElf_Move -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getmove -retrieves class-dependent move record at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar move -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_move -converts the class-independent move information pointed to -by argument -.Ar move -to class-dependent form, and writes it to the move record at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_move -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getmove -returns the value of argument -.Ar move -if successful, or NULL in case of an error. -Function -.Fn gelf_update_move -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar move -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of records in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing move information. -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getphdr.3 b/linkers/elftoolchain/libelf/gelf_getphdr.3 deleted file mode 100644 index f2d38aa..0000000 --- a/linkers/elftoolchain/libelf/gelf_getphdr.3 +++ /dev/null @@ -1,141 +0,0 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getphdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd October 21, 2007 -.Os -.Dt GELF_GETPHDR 3 -.Sh NAME -.Nm elf32_getphdr , -.Nm elf64_getphdr , -.Nm gelf_getphdr -.Nd retrieve an ELF program header table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Phdr *" -.Fn elf32_getphdr "Elf *elf" -.Ft "Elf64_Phdr *" -.Fn elf64_getphdr "Elf *elf" -.In gelf.h -.Ft "GElf_Phdr *" -.Fn gelf_getphdr "Elf *elf" "int index" "GElf_Phdr *dst" -.Sh DESCRIPTION -These functions retrieve and translate ELF program header information -from an ELF descriptor, if this information exists. -.Pp -Functions -.Fn elf32_getphdr -and -.Fn elf64_getphdr -return a pointer to an array of translated -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors respectively. -These descriptors are described in -.Xr elf 5 . -The number of entries in this array may be determined using the -.Xr elf_getphnum 3 -function. -.Pp -Function -.Fn gelf_getphdr -will retrieve the program header table entry at index -.Ar index -from ELF descriptor -.Ar elf. -The translated program header table entry will be written to the -address pointed to be argument -.Ar dst . -.Pp -Applications may inform the library of modifications to a program header table entry -by using the -.Xr elf_flagphdr 3 -API. -Applications using the -.Xr gelf 3 -interface need to use the -.Xr gelf_update_phdr 3 -API to copy modifications to a program header entry back to the underlying -ELF descriptor. -.Sh RETURN VALUES -The functions a valid pointer if successful, or NULL in case an error -was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar dst -was NULL. -.It Bq Er ELF_E_ARGUMENT -Index -.Ar index -was out of range. -.It Bq Er ELF_E_CLASS -The class of ELF descriptor -.Ar elf -did not match the expected class of the function being called. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -did not possess an executable header. -.It Bq Er ELF_E_HEADER -ELF descriptor -.Ar elf -had a corrupt executable header. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_VERSION -ELF descriptor -.Ar elf -was of an unsupported version. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf32_newphdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf64_newphdr 3 , -.Xr elf_flagphdr 3 , -.Xr elf_getphnum 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr gelf_newphdr 3 , -.Xr gelf_update_phdr 3 , -.Xr elf 5 diff --git a/linkers/elftoolchain/libelf/gelf_getrel.3 b/linkers/elftoolchain/libelf/gelf_getrel.3 deleted file mode 100644 index c7566e6..0000000 --- a/linkers/elftoolchain/libelf/gelf_getrel.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getrel.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETREL 3 -.Sh NAME -.Nm gelf_getrel , -.Nm gelf_update_rel -.Nd read and update ELF relocation entries -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Rel *" -.Fn gelf_getrel "Elf_Data *data" "int ndx" "GElf_Rel *rel" -.Ft int -.Fn gelf_update_rel "Elf_Data *data" "int ndx" "GElf_Rel *rel" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Rel -or -.Vt Elf64_Rel -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_REL . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Rel -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getrel -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar rel -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_rel -converts the class-independent entry pointed to -by argument -.Ar rel -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_rel -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getrel -returns the value of argument -.Ar rel -if successful, or NULL in case of an error. -Function -.Fn gelf_update_rel -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar rel -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_REL . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getrela.3 b/linkers/elftoolchain/libelf/gelf_getrela.3 deleted file mode 100644 index c77d52a..0000000 --- a/linkers/elftoolchain/libelf/gelf_getrela.3 +++ /dev/null @@ -1,121 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getrela.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETRELA 3 -.Sh NAME -.Nm gelf_getrela , -.Nm gelf_update_rela -.Nd read and update ELF relocation entries with addends -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Rela *" -.Fn gelf_getrela "Elf_Data *data" "int ndx" "GElf_Rela *rela" -.Ft int -.Fn gelf_update_rela "Elf_Data *data" "int ndx" "GElf_Rela *rela" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Rela -or -.Vt Elf64_Rela -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_RELA . -Argument -.Ar ndx -is the index of the entry being retrieved or updated. -The class-independent -.Vt GElf_Rela -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getrela -retrieves the class-dependent entry at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar rela -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_rela -converts the class-independent entry pointed to -by argument -.Ar rela -to class-dependent form, and writes it to the entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_rela -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getrela -returns the value of argument -.Ar rela -if successful, or NULL in case of an error. -Function -.Fn gelf_update_rela -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar rela -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of entries in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section of type -.Dv SHT_RELA . -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/gelf_getshdr.3 b/linkers/elftoolchain/libelf/gelf_getshdr.3 deleted file mode 100644 index e92d414..0000000 --- a/linkers/elftoolchain/libelf/gelf_getshdr.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getshdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 27, 2006 -.Os -.Dt GELF_GETSHDR 3 -.Sh NAME -.Nm elf32_getshdr , -.Nm elf64_getshdr , -.Nm gelf_getshdr -.Nd retrieve the class-dependent section header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Shdr *" -.Fn elf32_getshdr "Elf_Scn *scn" -.Ft "Elf64_Shdr *" -.Fn elf64_getshdr "Elf_Scn *scn" -.In gelf.h -.Ft "GElf_Shdr *" -.Fn gelf_getshdr "Elf_Scn *scn" "GElf_Shdr *shdr" -.Sh DESCRIPTION -These functions return a pointer to the ELF Section Header data -structure associated with section descriptor -.Ar scn . -.Pp -Function -.Fn elf32_getshdr -retrieves a pointer to an -.Vt Elf32_Shdr -structure. -Section descriptor -.Ar scn -must be associated with an ELF descriptor of class -.Dv ELFCLASS32 . -.Pp -Function -.Fn elf64_getshdr -retrieves a pointer to an -.Vt Elf64_Shdr -structure. -Section descriptor -.Ar scn -must be associated with an ELF descriptor of class -.Dv ELFCLASS64 . -.Pp -Function -.Fn gelf_getshdr -copies the values in the section header associated with argument -.Ar scn -to the structure pointed to be argument -.Ar dst . -The -.Vt GElf_Shdr -data structure is described in -.Xr gelf 3 . -.Sh RETURN VALUES -Functions -.Fn elf32_getshdr -and -.Fn elf64_getshdr -return a valid pointer to the appropriate section header on success -or NULL if an error was encountered. -.Pp -Function -.Fn gelf_getshdr -returns argument -.Ar dst -if successful, or NULL if an error was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar scn -or -.Ar shdr -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar scn -was not associated a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -The ELF class associated with the section descriptor -.Ar scn -did not match the class expected by the API. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_update_shdr 3 diff --git a/linkers/elftoolchain/libelf/gelf_getsym.3 b/linkers/elftoolchain/libelf/gelf_getsym.3 deleted file mode 100644 index 98d886f..0000000 --- a/linkers/elftoolchain/libelf/gelf_getsym.3 +++ /dev/null @@ -1,125 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getsym.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETSYM 3 -.Sh NAME -.Nm gelf_getsym , -.Nm gelf_update_sym -.Nd read and update symbol information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Sym *" -.Fn gelf_getsym "Elf_Data *data" "int ndx" "GElf_Sym *sym" -.Ft int -.Fn gelf_update_sym "Elf_Data *data" "int ndx" "GElf_Sym *sym" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Sym -and -.Vt Elf64_Sym -structures in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB , -.Dv SHT_DYNSYM -or -.Dv SHT_GNU_versym . -Argument -.Ar ndx -is the index of the symbol being retrieved or updated. -The class-independent -.Vt GElf_Sym -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsym -retrieves class-dependent symbol information at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar sym -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_sym -converts the class-independent symbol information pointed to -by argument -.Ar sym -to class-dependent form, and writes it to the symbol entry at index -.Ar ndx -in the data buffer described by argument -.Ar data . -Function -.Fn gelf_update_sym -signals an error if any of the values in the class-independent -representation exceeds the representable limits of the target -type. -.Sh RETURN VALUES -Function -.Fn gelf_getsym -returns the value of argument -.Ar sym -if successful, or NULL in case of an error. -Function -.Fn gelf_update_sym -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar sym -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of symbols in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing symbol information. -.It Bq Er ELF_E_RANGE -A value was not representable in the target type. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsyminfo 3 , -.Xr gelf_update_syminfo 3 diff --git a/linkers/elftoolchain/libelf/gelf_getsyminfo.3 b/linkers/elftoolchain/libelf/gelf_getsyminfo.3 deleted file mode 100644 index a1169f8..0000000 --- a/linkers/elftoolchain/libelf/gelf_getsyminfo.3 +++ /dev/null @@ -1,115 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getsyminfo.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 29, 2006 -.Os -.Dt GELF_GETSYMINFO 3 -.Sh NAME -.Nm gelf_getsyminfo , -.Nm gelf_update_syminfo -.Nd read and update symbol information -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Syminfo *" -.Fn gelf_getsyminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" -.Ft int -.Fn gelf_update_syminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" -.Sh DESCRIPTION -These convenience functions are used to retrieve and update class-dependent -.Vt Elf32_Syminfo -and -.Vt Elf64_Syminfo -records in an ELF object. -.Pp -Argument -.Ar data -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SUNW_syminfo . -Argument -.Ar ndx -is the index of the record being retrieved or updated. -The class-independent -.Vt GElf_Syminfo -structure is described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsyminfo -retrieves class-dependent record at index -.Ar ndx -in data buffer -.Ar data -and copies it to the destination pointed to by argument -.Ar syminfo -after translation to class-independent form. -.Pp -Function -.Fn gelf_update_syminfo -converts the class-independent record pointed to -by argument -.Ar syminfo -to class-dependent form, and writes it to the record at index -.Ar ndx -in the data buffer described by argument -.Ar data . -.Sh RETURN VALUES -Function -.Fn gelf_getsyminfo -returns the value of argument -.Ar syminfo -if successful, or NULL in case of an error. -Function -.Fn gelf_update_syminfo -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar data -or -.Ar syminfo -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero or larger than the number of symbols in the data -descriptor. -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar data -was not associated with a section containing symbol information. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsym 3 , -.Xr gelf_update_sym 3 diff --git a/linkers/elftoolchain/libelf/gelf_getsymshndx.3 b/linkers/elftoolchain/libelf/gelf_getsymshndx.3 deleted file mode 100644 index b635aac..0000000 --- a/linkers/elftoolchain/libelf/gelf_getsymshndx.3 +++ /dev/null @@ -1,162 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_getsymshndx.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd November 5, 2006 -.Os -.Dt GELF_GETSYMSHNDX 3 -.Sh NAME -.Nm gelf_getsymshndx , -.Nm gelf_update_symshndx -.Nd read and update symbol information using extended section indices -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft "GElf_Sym *" -.Fo gelf_getsymshndx -.Fa "Elf_Data *symdata" -.Fa "Elf_Data *xndxdata" -.Fa "int ndx" -.Fa "GElf_Sym *sym" -.Fa "Elf32_Word *xndxptr" -.Fc -.Ft int -.Fo gelf_update_symshndx -.Fa "Elf_Data *symdata" -.Fa "Elf_Data *xndxdata" -.Fa "int ndx" -.Fa "GElf_Sym *sym" -.Fa "Elf32_Word xndx" -.Fc -.Sh DESCRIPTION -These functions are analogous to -.Fn gelf_getsym -and -.Fn gelf_update_sym -respectively, but are capable of handling symbol tables using extended -section numbering. -.Pp -Argument -.Ar symdata -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB . -Argument -.Ar xndxdata -is an -.Vt Elf_Data -descriptor associated with a section of type -.Dv SHT_SYMTAB_SHNDX . -Argument -.Ar ndx -is the index of the symbol table entry being retrieved or updated. -Argument -.Ar sym -is a pointer to a class-independent -.Vt GElf_Sym -structure. -.Vt GElf_Sym -structures are described in detail in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_getsymshndx -retrieves symbol information at index -.Ar ndx -from the data descriptor specified by argument -.Ar symdata -and stores in class-independent form in argument -.Ar sym . -In addition it retrieves the extended section index for the -symbol from data buffer -.Ar xndxdata -and stores it into the location pointed to by argument -.Ar xndxptr . -.Pp -Function -.Fn gelf_update_symshndx -updates the underlying symbol table entry in data -descriptor -.Ar symdata -with the information in argument -.Ar sym . -In addition it sets the extended section index in -data buffer -.Ar xndxdata -to the value of argument -.Ar xndx . -.Sh RETURN VALUES -Function -.Fn gelf_getsymshndx -returns the value of argument -.Ar sym -if successful, or NULL in case of an error. -.Pp -Function -.Fn gelf_update_symshndx -returns a non-zero value if successful, or zero in case of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar symdata , -.Ar xndxdata , -.Ar xndxptr -or -.Ar sym -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -was less than zero, or too large for either of descriptors -.Ar symdata -or -.Ar xndxdata . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar symdata -was not associated with a section of type -.Dv SHT_SYMTAB . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar xndxdata -was not associated with a section of type -.Dv SHT_SYMTAB_SHNDX . -.It Bq Er ELF_E_ARGUMENT -Data descriptor -.Ar symdata -and -.Ar xndxdata -were associated with different ELF objects. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr elf_getscn 3 , -.Xr gelf 3 , -.Xr gelf_getsym 3 , -.Xr gelf_update_sym 3 diff --git a/linkers/elftoolchain/libelf/gelf_move.c b/linkers/elftoolchain/libelf/gelf_move.c deleted file mode 100644 index 753aba9..0000000 --- a/linkers/elftoolchain/libelf/gelf_move.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_move.c 1166 2010-09-04 00:54:36Z jkoshy $"); - -GElf_Move * -gelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Move *move32; - Elf64_Move *move64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - move32 = (Elf32_Move *) d->d_buf + ndx; - - dst->m_value = move32->m_value; - dst->m_info = (Elf64_Xword) move32->m_info; - dst->m_poffset = (Elf64_Xword) move32->m_poffset; - dst->m_repeat = move32->m_repeat; - dst->m_stride = move32->m_stride; - } else { - - move64 = (Elf64_Move *) d->d_buf + ndx; - - *dst = *move64; - } - - return (dst); -} - -int -gelf_update_move(Elf_Data *d, int ndx, GElf_Move *gm) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Move *move32; - Elf64_Move *move64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gm == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - move32 = (Elf32_Move *) d->d_buf + ndx; - - move32->m_value = gm->m_value; - LIBELF_COPY_U32(move32, gm, m_info); - LIBELF_COPY_U32(move32, gm, m_poffset); - move32->m_repeat = gm->m_repeat; - move32->m_stride = gm->m_stride; - - } else { - move64 = (Elf64_Move *) d->d_buf + ndx; - - *move64 = *gm; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_newehdr.3 b/linkers/elftoolchain/libelf/gelf_newehdr.3 deleted file mode 100644 index 180fea9..0000000 --- a/linkers/elftoolchain/libelf/gelf_newehdr.3 +++ /dev/null @@ -1,185 +0,0 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_newehdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd October 22, 2007 -.Os -.Dt GELF_NEWEHDR 3 -.Sh NAME -.Nm elf32_newehdr , -.Nm elf64_newehdr , -.Nm gelf_newehdr -.Nd retrieve or allocate the object file header -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Ehdr *" -.Fn elf32_newehdr "Elf *elf" -.Ft "Elf64_Ehdr *" -.Fn elf64_newehdr "Elf *elf" -.In gelf.h -.Ft "void *" -.Fn gelf_newehdr "Elf *elf" "int elfclass" -.Sh DESCRIPTION -These functions retrieve the ELF header from the ELF descriptor -.Ar elf , -allocating a new header if needed. -File data structures are translated to their in-memory representations -as described in -.Xr elf 3 . -.Pp -Function -.Fn elf32_newehdr -returns a pointer to a 32 bit -.Vt Elf32_Ehdr -structure. -Function -.Fn elf64_newehdr -returns a pointer to a 64 bit -.Vt Elf64_Ehdr structure. -.Pp -When argument -.Ar elfclass -has value -.Dv ELFCLASS32 , -function -.Fn gelf_newehdr -returns the value returned by -.Fn elf32_newehdr "elf" . -When argument -.Ar elfclass -has value -.Dv ELFCLASS64 -it returns the value returned by -.Fn elf64_newehdr "elf" . -.Pp -If a fresh header structure is allocated, the members of the -structure are initialized as follows: -.Bl -tag -width indent -.It Va "e_ident[EI_MAG0..EI_MAG3]" -Identification bytes at offsets -.Dv EI_MAG0 , -.Dv EI_MAG1 , -.Dv EI_MAG2 -and -.Dv EI_MAG3 -are set to the ELF signature. -.It Va "e_ident[EI_CLASS]" -The identification byte at offset -.Dv EI_CLASS -is set to the ELF class associated with the function being called -or to argument -.Ar elfclass -for function -.Fn gelf_newehdr . -.It Va "e_ident[EI_DATA]" -The identification byte at offset -.Dv EI_DATA -is set to -.Dv ELFDATANONE . -.It Va "e_ident[EI_VERSION]" -The identification byte at offset -.Dv EI_VERSION -is set to the ELF library's operating version set by a prior call to -.Xr elf_version 3 . -.It Va e_machine -is set to -.Dv EM_NONE . -.It Va e_type -is set to -.Dv ELF_K_NONE . -.It Va e_version -is set to the ELF library's operating version set by a prior call to -.Xr elf_version 3 . -.El -.Pp -Other members of the header are set to zero. -The application is responsible for changing these values -as needed before calling -.Fn elf_update . -.Pp -If successful, these three functions set the -.Dv ELF_F_DIRTY -flag on ELF descriptor -.Ar elf . -.Sh RETURN VALUES -These functions return a pointer to a translated header descriptor -if successful, or NULL on failure. -.Sh ERRORS -These functions can fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -The argument -.Ar elf -was null. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elfclass -had an unsupported value. -.It Bq Er ELF_E_ARGUMENT -The class of the ELF descriptor -.Ar elf -did not match that of the requested operation. -.It Bq Er ELF_E_ARGUMENT -For function -.Fn gelf_newehdr , -the class of argument -.Ar elf -was not -.Dv ELFCLASSNONE -and did not match the argument -.Ar elfclass . -.It Bq Er ELF_E_CLASS -The ELF class of descriptor -.Ar elf -did not match that of the API function being called. -.It Bq Er ELF_E_HEADER -A malformed ELF header was detected. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected during execution. -.It Bq Er ELF_E_SECTION -The ELF descriptor in argument -.Ar elf -did not adhere to the conventions used for extended numbering. -.It Bq Er ELF_E_VERSION -The ELF descriptor -.Ar elf -had an unsupported ELF version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getehdr 3 , -.Xr elf64_getehdr 3 , -.Xr elf_flagdata 3 , -.Xr elf_getident 3 , -.Xr elf_update 3 , -.Xr elf_version 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr elf 5 diff --git a/linkers/elftoolchain/libelf/gelf_newphdr.3 b/linkers/elftoolchain/libelf/gelf_newphdr.3 deleted file mode 100644 index 931385e..0000000 --- a/linkers/elftoolchain/libelf/gelf_newphdr.3 +++ /dev/null @@ -1,133 +0,0 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_newphdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd October 22, 2007 -.Os -.Dt GELF_NEWPHDR 3 -.Sh NAME -.Nm elf32_newphdr , -.Nm elf64_newphdr , -.Nm gelf_newphdr -.Nd allocate an ELF program header table -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf32_Phdr *" -.Fn elf32_newphdr "Elf *elf" "size_t count" -.Ft "Elf64_Phdr *" -.Fn elf64_newphdr "Elf *elf" "size_t count" -.In gelf.h -.Ft "void *" -.Fn gelf_newphdr "Elf *elf" "size_t count" -.Sh DESCRIPTION -These functions allocate an ELF Program Header table -for an ELF descriptor. -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors are described further in -.Xr elf 5 . -.Pp -Functions -.Fn elf32_newphdr -and -.Fn elf64_newphdr -allocate a table of -.Ar count -.Vt Elf32_Phdr -and -.Vt Elf64_Phdr -descriptors respectively, -discarding any existing program header table -already present in the ELF descriptor -.Ar elf . -A value of zero for argument -.Ar count -may be used to delete an existing program header table -from an ELF descriptor. -.Pp -Function -.Fn gelf_newphdr -will return a table of -.Vt Elf32_Phdr -or -.Vt Elf64_Phdr -with -.Ar count -elements depending on the ELF class of ELF descriptor -.Ar elf . -.Pp -The functions set the -.Dv ELF_F_DIRTY -flag on the program header table. -All members of the returned array of Phdr structures -will be initialized to zero. -.Pp -After a successful call to these functions, the pointer returned -by a prior call to -.Fn elf32_getphdr -or -.Fn elf64_getphdr -on the same descriptor -.Ar elf -will no longer be valid. -.Sh RETURN VALUES -The functions a valid pointer if successful, or NULL in case an error -was encountered. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_CLASS -ELF descriptor -.Ar elf -was of an unrecognized class. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.It Bq Er ELF_E_SEQUENCE -An executable header was not allocated for ELF descriptor -.Ar elf -before using these APIs. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf32_getphdr 3 , -.Xr elf32_newehdr 3 , -.Xr elf64_getphdr 3 , -.Xr elf64_newehdr 3 , -.Xr elf_flagphdr 3 , -.Xr elf_getphnum 3 , -.Xr gelf 3 , -.Xr gelf_getphdr 3 , -.Xr gelf_newehdr 3 , -.Xr elf 5 diff --git a/linkers/elftoolchain/libelf/gelf_phdr.c b/linkers/elftoolchain/libelf/gelf_phdr.c deleted file mode 100644 index 47000d8..0000000 --- a/linkers/elftoolchain/libelf/gelf_phdr.c +++ /dev/null @@ -1,177 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_phdr.c 189 2008-07-20 10:38:08Z jkoshy $"); - -Elf32_Phdr * -elf32_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS32)); -} - -Elf64_Phdr * -elf64_getphdr(Elf *e) -{ - return (_libelf_getphdr(e, ELFCLASS64)); -} - -GElf_Phdr * -gelf_getphdr(Elf *e, int index, GElf_Phdr *d) -{ - int ec; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - Elf32_Phdr *ep32; - Elf64_Phdr *ep64; - - if (d == NULL || e == NULL || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || - (e->e_kind != ELF_K_ELF) || index < 0) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || - ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) - return (NULL); - - if (index >= eh32->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep32 += index; - - d->p_type = ep32->p_type; - d->p_offset = ep32->p_offset; - d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; - d->p_paddr = (Elf64_Addr) ep32->p_paddr; - d->p_filesz = (Elf64_Xword) ep32->p_filesz; - d->p_memsz = (Elf64_Xword) ep32->p_memsz; - d->p_flags = ep32->p_flags; - d->p_align = (Elf64_Xword) ep32->p_align; - - } else { - if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || - (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) - return (NULL); - - if (index >= eh64->e_phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ep64 += index; - - *d = *ep64; - } - - return (d); -} - -Elf32_Phdr * -elf32_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS32, count)); -} - -Elf64_Phdr * -elf64_newphdr(Elf *e, size_t count) -{ - return (_libelf_newphdr(e, ELFCLASS64, count)); -} - -void * -gelf_newphdr(Elf *e, size_t count) -{ - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - return (_libelf_newphdr(e, e->e_class, count)); -} - -int -gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) -{ - int ec, phnum; - void *ehdr; - Elf32_Phdr *ph32; - Elf64_Phdr *ph64; - - if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (0); - - if (ec == ELFCLASS32) - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - else - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - - if (ndx < 0 || ndx > phnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; - *ph64 = *s; - return (1); - } - - ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; - - ph32->p_type = s->p_type; - ph32->p_flags = s->p_flags; - LIBELF_COPY_U32(ph32, s, p_offset); - LIBELF_COPY_U32(ph32, s, p_vaddr); - LIBELF_COPY_U32(ph32, s, p_paddr); - LIBELF_COPY_U32(ph32, s, p_filesz); - LIBELF_COPY_U32(ph32, s, p_memsz); - LIBELF_COPY_U32(ph32, s, p_align); - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_rel.c b/linkers/elftoolchain/libelf/gelf_rel.c deleted file mode 100644 index 7d0b6af..0000000 --- a/linkers/elftoolchain/libelf/gelf_rel.c +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_rel.c 189 2008-07-20 10:38:08Z jkoshy $"); - -GElf_Rel * -gelf_getrel(Elf_Data *d, int ndx, GElf_Rel *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rel32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rel32->r_info), - ELF32_R_TYPE(rel32->r_info)); - - } else { - - rel64 = (Elf64_Rel *) d->d_buf + ndx; - - *dst = *rel64; - } - - return (dst); -} - -int -gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rel *rel32; - Elf64_Rel *rel64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_REL, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rel32 = (Elf32_Rel *) d->d_buf + ndx; - - LIBELF_COPY_U32(rel32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - } else { - rel64 = (Elf64_Rel *) d->d_buf + ndx; - - *rel64 = *dr; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_rela.c b/linkers/elftoolchain/libelf/gelf_rela.c deleted file mode 100644 index 722c1ad..0000000 --- a/linkers/elftoolchain/libelf/gelf_rela.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_rela.c 189 2008-07-20 10:38:08Z jkoshy $"); - -GElf_Rela * -gelf_getrela(Elf_Data *d, int ndx, GElf_Rela *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_buf + ndx; - - dst->r_offset = (Elf64_Addr) rela32->r_offset; - dst->r_info = ELF64_R_INFO( - (Elf64_Xword) ELF32_R_SYM(rela32->r_info), - ELF32_R_TYPE(rela32->r_info)); - dst->r_addend = (Elf64_Sxword) rela32->r_addend; - - } else { - - rela64 = (Elf64_Rela *) d->d_buf + ndx; - - *dst = *rela64; - } - - return (dst); -} - -int -gelf_update_rela(Elf_Data *d, int ndx, GElf_Rela *dr) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Rela *rela32; - Elf64_Rela *rela64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dr == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - rela32 = (Elf32_Rela *) d->d_buf + ndx; - - LIBELF_COPY_U32(rela32, dr, r_offset); - - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || - ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { - LIBELF_SET_ERROR(RANGE, 0); - return (0); - } - rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); - - LIBELF_COPY_S32(rela32, dr, r_addend); - } else { - rela64 = (Elf64_Rela *) d->d_buf + ndx; - - *rela64 = *dr; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_shdr.c b/linkers/elftoolchain/libelf/gelf_shdr.c deleted file mode 100644 index 47e56e9..0000000 --- a/linkers/elftoolchain/libelf/gelf_shdr.c +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_shdr.c 189 2008-07-20 10:38:08Z jkoshy $"); - -Elf32_Shdr * -elf32_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS32)); -} - -Elf64_Shdr * -elf64_getshdr(Elf_Scn *s) -{ - return (_libelf_getshdr(s, ELFCLASS64)); -} - -GElf_Shdr * -gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) -{ - int ec; - void *sh; - Elf32_Shdr *sh32; - Elf64_Shdr *sh64; - - if (d == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) - return (NULL); - - ec = s->s_elf->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) { - sh32 = (Elf32_Shdr *) sh; - - d->sh_name = sh32->sh_name; - d->sh_type = sh32->sh_type; - d->sh_flags = (Elf64_Xword) sh32->sh_flags; - d->sh_addr = (Elf64_Addr) sh32->sh_addr; - d->sh_offset = (Elf64_Off) sh32->sh_offset; - d->sh_size = (Elf64_Xword) sh32->sh_size; - d->sh_link = sh32->sh_link; - d->sh_info = sh32->sh_info; - d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; - d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; - } else { - sh64 = (Elf64_Shdr *) sh; - *d = *sh64; - } - - return (d); -} - -int -gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) -{ - int ec; - Elf *e; - Elf32_Shdr *sh32; - - - if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || - e->e_kind != ELF_K_ELF || - ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (e->e_cmd == ELF_C_READ) { - LIBELF_SET_ERROR(MODE, 0); - return (0); - } - - (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); - - if (ec == ELFCLASS64) { - scn->s_shdr.s_shdr64 = *s; - return (1); - } - - sh32 = &scn->s_shdr.s_shdr32; - - sh32->sh_name = s->sh_name; - sh32->sh_type = s->sh_type; - LIBELF_COPY_U32(sh32, s, sh_flags); - LIBELF_COPY_U32(sh32, s, sh_addr); - LIBELF_COPY_U32(sh32, s, sh_offset); - LIBELF_COPY_U32(sh32, s, sh_size); - sh32->sh_link = s->sh_link; - sh32->sh_info = s->sh_info; - LIBELF_COPY_U32(sh32, s, sh_addralign); - LIBELF_COPY_U32(sh32, s, sh_entsize); - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_sym.c b/linkers/elftoolchain/libelf/gelf_sym.c deleted file mode 100644 index 3f84a17..0000000 --- a/linkers/elftoolchain/libelf/gelf_sym.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_sym.c 189 2008-07-20 10:38:08Z jkoshy $"); - -GElf_Sym * -gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - sym32 = (Elf32_Sym *) d->d_buf + ndx; - - dst->st_name = sym32->st_name; - dst->st_value = (Elf64_Addr) sym32->st_value; - dst->st_size = (Elf64_Xword) sym32->st_size; - dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), - ELF32_ST_TYPE(sym32->st_info)); - dst->st_other = sym32->st_other; - dst->st_shndx = sym32->st_shndx; - } else { - - sym64 = (Elf64_Sym *) d->d_buf + ndx; - - *dst = *sym64; - } - - return (dst); -} - -int -gelf_update_sym(Elf_Data *d, int ndx, GElf_Sym *gs) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Sym *sym32; - Elf64_Sym *sym64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - sym32 = (Elf32_Sym *) d->d_buf + ndx; - - sym32->st_name = gs->st_name; - sym32->st_info = gs->st_info; - sym32->st_other = gs->st_other; - sym32->st_shndx = gs->st_shndx; - - LIBELF_COPY_U32(sym32, gs, st_value); - LIBELF_COPY_U32(sym32, gs, st_size); - } else { - sym64 = (Elf64_Sym *) d->d_buf + ndx; - - *sym64 = *gs; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_syminfo.c b/linkers/elftoolchain/libelf/gelf_syminfo.c deleted file mode 100644 index 2e8d9d8..0000000 --- a/linkers/elftoolchain/libelf/gelf_syminfo.c +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_syminfo.c 1166 2010-09-04 00:54:36Z jkoshy $"); - -GElf_Syminfo * -gelf_getsyminfo(Elf_Data *d, int ndx, GElf_Syminfo *dst) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || dst == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - - syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; - - dst->si_boundto = syminfo32->si_boundto; - dst->si_flags = syminfo32->si_flags; - - } else { - - syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; - - *dst = *syminfo64; - } - - return (dst); -} - -int -gelf_update_syminfo(Elf_Data *d, int ndx, GElf_Syminfo *gs) -{ - int ec; - Elf *e; - Elf_Scn *scn; - Elf32_Syminfo *syminfo32; - Elf64_Syminfo *syminfo64; - size_t msz; - uint32_t sh_type; - - if (d == NULL || ndx < 0 || gs == NULL || - (scn = d->d_scn) == NULL || - (e = scn->s_elf) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= d->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - if (ec == ELFCLASS32) { - syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx; - - syminfo32->si_boundto = gs->si_boundto; - syminfo32->si_flags = gs->si_flags; - - } else { - syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx; - - *syminfo64 = *gs; - } - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_symshndx.c b/linkers/elftoolchain/libelf/gelf_symshndx.c deleted file mode 100644 index ab3549c..0000000 --- a/linkers/elftoolchain/libelf/gelf_symshndx.c +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_symshndx.c 189 2008-07-20 10:38:08Z jkoshy $"); - -GElf_Sym * -gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, - Elf32_Word *shindex) -{ - int ec; - Elf *e; - Elf_Scn *scn; - size_t msz; - uint32_t sh_type; - - if (gelf_getsym(d, ndx, dst) == 0) - return (NULL); - - if (id == NULL || (scn = id->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf) || - shindex == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - id->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - *shindex = ((Elf32_Word *) id->d_buf)[ndx]; - - return (dst); -} - -int -gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, - Elf32_Word xindex) -{ - int ec; - Elf *e; - Elf_Scn *scn; - size_t msz; - uint32_t sh_type; - - if (gelf_update_sym(d, ndx, gs) == 0) - return (0); - - if (id == NULL || (scn = id->d_scn) == NULL || - (e = scn->s_elf) == NULL || (e != d->d_scn->s_elf)) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - ec = e->e_class; - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec == ELFCLASS32) - sh_type = scn->s_shdr.s_shdr32.sh_type; - else - sh_type = scn->s_shdr.s_shdr64.sh_type; - - if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || - d->d_type != ELF_T_WORD) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); - assert(msz > 0); - - if (msz * ndx >= id->d_size) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0); - } - - *(((Elf32_Word *) id->d_buf) + ndx) = xindex; - - return (1); -} diff --git a/linkers/elftoolchain/libelf/gelf_update_ehdr.3 b/linkers/elftoolchain/libelf/gelf_update_ehdr.3 deleted file mode 100644 index f5e041d..0000000 --- a/linkers/elftoolchain/libelf/gelf_update_ehdr.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_update_ehdr.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd August 27, 2006 -.Os -.Dt GELF_UPDATE_EHDR 3 -.Sh NAME -.Nm gelf_update_ehdr , -.Nm gelf_update_phdr , -.Nm gelf_update_shdr -.Nd update underlying ELF data structures -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In gelf.h -.Ft int -.Fn gelf_update_ehdr "Elf *elf" "GElf_Ehdr *ehdr" -.Ft int -.Fn gelf_update_phdr "Elf *elf" "int ndx" "GElf_Phdr *phdr" -.Ft int -.Fn gelf_update_shdr "Elf_Scn *scn" "GElf_Shdr *shdr" -.Sh DESCRIPTION -These functions are used to update ELF data structures on the underlying -ELF descriptor. -Class-dependent data structures in the underlying ELF descriptor -are updated using the data in the class-independent GElf descriptors -and the underlying ELF data structures are marked -.Dq dirty . -The conversion process signals an error if the values being copied -to the target ELF data structure would exceed representation -limits. -GElf descriptors are described in -.Xr gelf 3 . -.Pp -Function -.Fn gelf_update_ehdr -updates the ELF Executable Header with the values in the -class-independent executable header -.Ar ehdr . -.Pp -Function -.Fn gelf_update_phdr -updates the ELF Program Header structure at index -.Ar ndx -with the values in the class-independent program header -.Ar phdr . -.Pp -Function -.Fn gelf_update_shdr -updates the ELF Section Header structure associated with section -descriptor -.Ar scn -with the values in argument -.Ar shdr . -.Sh RETURN VALUES -These functions return a non-zero integer on success, or zero in case -of an error. -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar elf , -.Ar ehdr , -.Ar phdr , -.Ar scn , -or -.Ar shdr -were NULL. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -was not a descriptor for an ELF object. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar elf -had an unsupported ELF class. -.It Bq Er ELF_E_ARGUMENT -Argument -.Ar ndx -exceeded the number of entries in the program header table. -.It Bq Er ELF_E_ARGUMENT -Section descriptor -.Ar scn -was not associated with an ELF descriptor. -.It Bq Er ELF_E_MODE -ELF descriptor -.Ar elf -was not opened for writing or updating. -.It Bq Er ELF_E_RESOURCE -An out of memory condition was detected. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_flagelf 3 , -.Xr elf_flagphdr 3 , -.Xr elf_flagshdr 3 , -.Xr gelf 3 , -.Xr gelf_getehdr 3 , -.Xr gelf_getphdr 3 , -.Xr gelf_getshdr 3 diff --git a/linkers/elftoolchain/libelf/gelf_xlate.c b/linkers/elftoolchain/libelf/gelf_xlate.c deleted file mode 100644 index 6cdf705..0000000 --- a/linkers/elftoolchain/libelf/gelf_xlate.c +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: gelf_xlate.c 1678 2011-07-28 04:36:34Z jkoshy $"); - -Elf_Data * -elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); -} - -Elf_Data * -elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE); -} - -Elf_Data * -elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY); -} - -Elf_Data * -elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) -{ - return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY); -} - -Elf_Data * -gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, - unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOMEMORY)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} - -Elf_Data * -gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, - unsigned int encoding) -{ - if (e != NULL) - return (_libelf_xlate(dst, src, encoding, e->e_class, - ELF_TOFILE)); - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); -} diff --git a/linkers/elftoolchain/libelf/gelf_xlatetof.3 b/linkers/elftoolchain/libelf/gelf_xlatetof.3 deleted file mode 100644 index ca90002..0000000 --- a/linkers/elftoolchain/libelf/gelf_xlatetof.3 +++ /dev/null @@ -1,247 +0,0 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: gelf_xlatetof.3 189 2008-07-20 10:38:08Z jkoshy $ -.\" -.Dd July 24, 2006 -.Os -.Dt GELF_XLATETOF 3 -.Sh NAME -.Nm elf32_xlate , -.Nm elf64_xlate , -.Nm gelf_xlate -.Nd translate data between files and memory -.Sh LIBRARY -.Lb libelf -.Sh SYNOPSIS -.In libelf.h -.Ft "Elf_Data *" -.Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.Ft "Elf_Data *" -.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" -.In gelf.h -.Ft "Elf_Data *" -.Fo gelf_xlatetof -.Fa "Elf *elf" -.Fa "Elf_Data *dst" -.Fa "Elf_Data *src" -.Fa "unsigned int encode" -.Fc -.Ft "Elf_Data *" -.Fo gelf_xlatetom -.Fa "Elf *elf" -.Fa "Elf_Data *dst" -.Fa "Elf_Data *src" -.Fa "unsigned int encode" -.Fc -.Sh DESCRIPTION -These functions translate between the file and memory representations -of ELF data structures. -The in-memory representation of an ELF data structure would confirm to -the byte ordering and data alignment restrictions dictated by the host -processor. -A file representation of the same data structure could use a non-native byte -ordering and in addition may be laid out differently with the file. -.Pp -Functions -.Fn elf32_xlatetom , -.Fn elf64_xlatetom , -and -.Fn gelf_xlatetom -translate data from file representations to native, in-memory representations. -Functions -.Fn elf32_xlatetof , -.Fn elf64_xlatetof , -and -.Fn gelf_xlatetof -translate data from in-memory representations to file representations. -.Pp -Argument -.Ar src -denotes an -.Vt Elf_Data -descriptor describing the source to be translated. -The following elements of the descriptor need to be set before -invoking these functions: -.Bl -hang -offset indent -.It Va d_buf -Set to a valid pointer value denoting the beginning of the data area -to be translated. -.It Va d_size -Set to the total size in bytes of the source data area to be -translated. -.It Va d_type -Set to the type of the source data being translated. -This value is one of the values defined in the -.Vt Elf_Type -enumeration. -The -.Vt Elf_Type -enumeration is described in -.Xr elf 3 . -.It Va d_version -Set to the version number of the ELF data structures being -translated. -Currently only version -.Dv EV_CURRENT -is supported. -.El -.Pp -Argument -.Ar dst -describes the destination buffer. -The following elements of the -.Vt Elf_Data -descriptor need to be set before invoking these functions: -.Bl -hang -offset indent -.It Va d_buf -Set to a valid pointer value that denotes the start of the destination -buffer that will hold translated data. -This value may be the same as that of the source buffer, in which case -an in-place conversion will be attempted. -.It Va d_size -Set to the size of the destination buffer in bytes. -This value will be modified if the function call succeeds. -.It Va d_version -Set to the desired version number of the destination. -Currently only version -.Dv EV_CURRENT -is supported. -.El -.Pp -These translations routines allow the source and destination buffers -to coincide, in which case an in-place translation will be done -if the destination is large enough to hold the translated data. -Other kinds of overlap between the source and destination buffers -are not permitted. -.Pp -On successful completion of the translation request the following -fields of the -.Ar dst -descriptor would be modified: -.Bl -hang -offset indent -.It Va d_size -Set to the size in bytes of the translated data. -.It Va d_type -Set to the -.Va d_type -value of the source data descriptor. -.El -.Pp -Argument -.Ar encode -specifies the encoding in which the file objects are represented. -It must be one of: -.Bl -hang -offset indent -.It Dv ELFDATANONE -File objects use the library's native byte ordering. -.It Dv ELFDATA2LSB -File objects use a little-endian ordering. -.It Dv ELFDATA2MSB -File objects use a big-endian ordering. -.El -.Pp -The functions -.Fn gelf_xlatetof -and -.Fn gelf_xlatetom -select the appropriate 32 or 64 bit translations based on the class of argument -.Ar elf . -.Sh RETURN VALUES -These functions return argument -.Ar dst -if successful, or NULL in case of an error. -.Sh EXAMPLES -TODO -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width "[ELF_E_RESOURCE]" -.It Bq Er ELF_E_ARGUMENT -One of arguments -.Ar src , -.Ar dst -or -.Ar elf -was NULL. -.It Bq Er ELF_E_ARGUMENT -Arguments -.Ar src -and -.Ar dst -were equal. -.It Bq Er ELF_E_ARGUMENT -The desired encoding parameter was not one of -.Dv ELFDATANONE , -.Dv ELFDATA2LSB -or -.Dv ELFDATA2MSB . -.It Bq Er ELF_E_ARGUMENT -The -.Ar d_type -field of argument -.Ar src -specified an unsupported type. -.It Bq Er ELF_E_DATA -The -.Ar src -argument specified a buffer size that was not an integral multiple of -its underlying type. -.It Bq Er ELF_E_DATA -The -.Ar dst -argument specified a buffer size that was too small. -.It Bq Er ELF_E_DATA -Argument -.Ar dst -specified a destination buffer that overlaps with the source -buffer. -.It Bq Er ELF_E_DATA -The destination buffer for a conversion to memory had an alignment -inappropriate for the underlying ELF type. -.It Bq Er ELF_E_DATA -The source buffer for a conversion to file had an alignment -inappropriate for the underlying ELF type. -.It Bq Er ELF_E_UNIMPL -The version numbers for arguments -.Ar dst -and -.Ar src -were not identical. -.It Bq Er ELF_E_UNIMPL -The argument -.Ar src -requested conversion for a type which is not currently -supported. -.It Bq Er ELF_E_VERSION -Argument -.Ar src -specified an unsupported version number. -.El -.Sh SEE ALSO -.Xr elf 3 , -.Xr elf_getdata 3 , -.Xr gelf 3 diff --git a/linkers/elftoolchain/libelf/libelf.h b/linkers/elftoolchain/libelf/libelf.h deleted file mode 100644 index 60b0f1c..0000000 --- a/linkers/elftoolchain/libelf/libelf.h +++ /dev/null @@ -1,258 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: libelf.h 1345 2011-01-01 11:17:52Z jkoshy $ - */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ - -#include -#include - -#include - -/* Library private data structures */ -typedef struct _Elf Elf; -typedef struct _Elf_Scn Elf_Scn; - -/* File types */ -typedef enum { - ELF_K_NONE = 0, - ELF_K_AR, /* `ar' archives */ - ELF_K_COFF, /* COFF files (unsupported) */ - ELF_K_ELF, /* ELF files */ - ELF_K_NUM -} Elf_Kind; - -#define ELF_K_FIRST ELF_K_NONE -#define ELF_K_LAST ELF_K_NUM - -/* Data types */ -typedef enum { - ELF_T_ADDR, - ELF_T_BYTE, - ELF_T_CAP, - ELF_T_DYN, - ELF_T_EHDR, - ELF_T_HALF, - ELF_T_LWORD, - ELF_T_MOVE, - ELF_T_MOVEP, - ELF_T_NOTE, - ELF_T_OFF, - ELF_T_PHDR, - ELF_T_REL, - ELF_T_RELA, - ELF_T_SHDR, - ELF_T_SWORD, - ELF_T_SXWORD, - ELF_T_SYMINFO, - ELF_T_SYM, - ELF_T_VDEF, - ELF_T_VNEED, - ELF_T_WORD, - ELF_T_XWORD, - ELF_T_GNUHASH, /* GNU style hash tables. */ - ELF_T_NUM -} Elf_Type; - -#define ELF_T_FIRST ELF_T_ADDR -#define ELF_T_LAST ELF_T_GNUHASH - -/* Commands */ -typedef enum { - ELF_C_NULL = 0, - ELF_C_CLR, - ELF_C_FDDONE, - ELF_C_FDREAD, - ELF_C_RDWR, - ELF_C_READ, - ELF_C_SET, - ELF_C_WRITE, - ELF_C_NUM -} Elf_Cmd; - -#define ELF_C_FIRST ELF_C_NULL -#define ELF_C_LAST ELF_C_NUM - -/* - * An `Elf_Data' structure describes data in an - * ELF section. - */ -typedef struct _Elf_Data { - /* - * `Public' members that are part of the ELF(3) API. - */ - uint64_t d_align; - void *d_buf; - uint64_t d_off; - uint64_t d_size; - Elf_Type d_type; - unsigned int d_version; - - /* - * Members that are not part of the public API. - */ - Elf_Scn *d_scn; /* containing section */ - unsigned int d_flags; - STAILQ_ENTRY(_Elf_Data) d_next; -} Elf_Data; - -/* - * An `Elf_Arhdr' structure describes an archive - * header. - */ -typedef struct { - time_t ar_date; - char *ar_name; /* archive member name */ - gid_t ar_gid; - mode_t ar_mode; - char *ar_rawname; /* 'raw' member name */ - size_t ar_size; - uid_t ar_uid; - - /* - * Members that are not part of the public API. - */ - int ar_flags; -} Elf_Arhdr; - -/* - * An `Elf_Arsym' describes an entry in the archive - * symbol table. - */ -typedef struct { - off_t as_off; /* byte offset to member's header */ - unsigned long as_hash; /* elf_hash() value for name */ - char *as_name; /* null terminated symbol name */ -} Elf_Arsym; - -/* - * Error numbers. - */ - -enum Elf_Error { - ELF_E_NONE, /* No error */ - ELF_E_ARCHIVE, /* Malformed ar(1) archive */ - ELF_E_ARGUMENT, /* Invalid argument */ - ELF_E_CLASS, /* Mismatched ELF class */ - ELF_E_DATA, /* Invalid data descriptor */ - ELF_E_HEADER, /* Missing or malformed ELF header */ - ELF_E_IO, /* I/O error */ - ELF_E_LAYOUT, /* Layout constraint violation */ - ELF_E_MODE, /* Wrong mode for ELF descriptor */ - ELF_E_RANGE, /* Value out of range */ - ELF_E_RESOURCE, /* Resource exhaustion */ - ELF_E_SECTION, /* Invalid section descriptor */ - ELF_E_SEQUENCE, /* API calls out of sequence */ - ELF_E_UNIMPL, /* Feature is unimplemented */ - ELF_E_VERSION, /* Unknown API version */ - ELF_E_NUM /* Max error number */ -}; - -/* - * Flags defined by the API. - */ - -#define ELF_F_LAYOUT 0x001U /* application will layout the file */ -#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ - -/* ELF(3) API extensions. */ -#define ELF_F_ARCHIVE 0x100U /* archive creation */ -#define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */ - -__BEGIN_DECLS -Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); -int elf_cntl(Elf *_elf, Elf_Cmd _cmd); -int elf_end(Elf *_elf); -const char *elf_errmsg(int _error); -int elf_errno(void); -void elf_fill(int _fill); -unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd, - unsigned int _flags); -unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, - unsigned int _flags); -unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); -Elf_Arhdr *elf_getarhdr(Elf *_elf); -Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); -off_t elf_getbase(Elf *_elf); -Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); -char *elf_getident(Elf *_elf, size_t *_ptr); -int elf_getphdrnum(Elf *_elf, size_t *_dst); -int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ -Elf_Scn *elf_getscn(Elf *_elf, size_t _index); -int elf_getshdrnum(Elf *_elf, size_t *_dst); -int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ -int elf_getshdrstrndx(Elf *_elf, size_t *_dst); -int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ -unsigned long elf_hash(const char *_name); -Elf_Kind elf_kind(Elf *_elf); -Elf *elf_memory(char *_image, size_t _size); -size_t elf_ndxscn(Elf_Scn *_scn); -Elf_Data *elf_newdata(Elf_Scn *_scn); -Elf_Scn *elf_newscn(Elf *_elf); -Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); -Elf_Cmd elf_next(Elf *_elf); -off_t elf_rand(Elf *_elf, off_t _off); -Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); -char *elf_rawfile(Elf *_elf, size_t *_size); -int elf_setshstrndx(Elf *_elf, size_t _shnum); -char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); -off_t elf_update(Elf *_elf, Elf_Cmd _cmd); -unsigned int elf_version(unsigned int _version); - -long elf32_checksum(Elf *_elf); -size_t elf32_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf32_Ehdr *elf32_getehdr(Elf *_elf); -Elf32_Phdr *elf32_getphdr(Elf *_elf); -Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); -Elf32_Ehdr *elf32_newehdr(Elf *_elf); -Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); - -long elf64_checksum(Elf *_elf); -size_t elf64_fsize(Elf_Type _type, size_t _count, - unsigned int _version); -Elf64_Ehdr *elf64_getehdr(Elf *_elf); -Elf64_Phdr *elf64_getphdr(Elf *_elf); -Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); -Elf64_Ehdr *elf64_newehdr(Elf *_elf); -Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); -Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, - unsigned int _enc); -__END_DECLS - -#endif /* _LIBELF_H_ */ diff --git a/linkers/elftoolchain/libelf/libelf_align.c b/linkers/elftoolchain/libelf/libelf_align.c deleted file mode 100644 index 55a65f9..0000000 --- a/linkers/elftoolchain/libelf/libelf_align.c +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_align.c 1169 2010-09-04 01:06:31Z jkoshy $"); - -struct align { - int a32; - int a64; -}; - -#ifdef __GNUC__ -#define MALIGN(N) { \ - .a32 = __alignof__(Elf32_##N), \ - .a64 = __alignof__(Elf64_##N) \ - } -#define MALIGN64(V) { \ - .a32 = 0, \ - .a64 = __alignof__(Elf64_##V) \ - } -#define MALIGN_WORD() { \ - .a32 = __alignof__(int32_t), \ - .a64 = __alignof__(int64_t) \ - } -#else -#error Need the __alignof__ builtin. -#endif -#define UNSUPPORTED() { \ - .a32 = 0, \ - .a64 = 0 \ - } - -static struct align malign[ELF_T_NUM] = { - [ELF_T_ADDR] = MALIGN(Addr), - [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, - [ELF_T_CAP] = MALIGN(Cap), - [ELF_T_DYN] = MALIGN(Dyn), - [ELF_T_EHDR] = MALIGN(Ehdr), - [ELF_T_HALF] = MALIGN(Half), - [ELF_T_LWORD] = MALIGN(Lword), - [ELF_T_MOVE] = MALIGN(Move), - [ELF_T_MOVEP] = UNSUPPORTED(), - [ELF_T_NOTE] = MALIGN(Nhdr), - [ELF_T_OFF] = MALIGN(Off), - [ELF_T_PHDR] = MALIGN(Phdr), - [ELF_T_REL] = MALIGN(Rel), - [ELF_T_RELA] = MALIGN(Rela), - [ELF_T_SHDR] = MALIGN(Shdr), - [ELF_T_SWORD] = MALIGN(Sword), - [ELF_T_SXWORD] = MALIGN64(Sxword), - [ELF_T_SYM] = MALIGN(Sym), - [ELF_T_SYMINFO] = MALIGN(Syminfo), - [ELF_T_VDEF] = MALIGN(Verdef), - [ELF_T_VNEED] = MALIGN(Verneed), - [ELF_T_WORD] = MALIGN(Word), - [ELF_T_XWORD] = MALIGN64(Xword), - [ELF_T_GNUHASH] = MALIGN_WORD() -}; - -int -_libelf_malign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? malign[t].a32 : - malign[t].a64); -} - -#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } - -static struct align falign[ELF_T_NUM] = { - [ELF_T_ADDR] = FALIGN(4,8), - [ELF_T_BYTE] = FALIGN(1,1), - [ELF_T_CAP] = FALIGN(4,8), - [ELF_T_DYN] = FALIGN(4,8), - [ELF_T_EHDR] = FALIGN(4,8), - [ELF_T_HALF] = FALIGN(2,2), - [ELF_T_LWORD] = FALIGN(8,8), - [ELF_T_MOVE] = FALIGN(8,8), - [ELF_T_MOVEP] = UNSUPPORTED(), - [ELF_T_NOTE] = FALIGN(4,4), - [ELF_T_OFF] = FALIGN(4,8), - [ELF_T_PHDR] = FALIGN(4,8), - [ELF_T_REL] = FALIGN(4,8), - [ELF_T_RELA] = FALIGN(4,8), - [ELF_T_SHDR] = FALIGN(4,8), - [ELF_T_SWORD] = FALIGN(4,4), - [ELF_T_SXWORD] = FALIGN(0,8), - [ELF_T_SYM] = FALIGN(4,8), - [ELF_T_SYMINFO] = FALIGN(2,2), - [ELF_T_VDEF] = FALIGN(4,4), - [ELF_T_VNEED] = FALIGN(4,4), - [ELF_T_WORD] = FALIGN(4,4), - [ELF_T_XWORD] = FALIGN(0,8), - [ELF_T_GNUHASH] = FALIGN(4,8) -}; - -int -_libelf_falign(Elf_Type t, int elfclass) -{ - if (t >= ELF_T_NUM || (int) t < 0) - return (0); - - return (elfclass == ELFCLASS32 ? falign[t].a32 : - falign[t].a64); -} diff --git a/linkers/elftoolchain/libelf/libelf_allocate.c b/linkers/elftoolchain/libelf/libelf_allocate.c deleted file mode 100644 index a753e8e..0000000 --- a/linkers/elftoolchain/libelf/libelf_allocate.c +++ /dev/null @@ -1,214 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Internal APIs - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_allocate.c 1341 2011-01-01 04:28:29Z jkoshy $"); - -Elf * -_libelf_allocate_elf(void) -{ - Elf *e; - - if ((e = malloc(sizeof(*e))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return NULL; - } - - e->e_activations = 1; - e->e_hdr.e_rawhdr = NULL; - e->e_byteorder = ELFDATANONE; - e->e_class = ELFCLASSNONE; - e->e_cmd = ELF_C_NULL; - e->e_fd = -1; - e->e_flags = 0; - e->e_kind = ELF_K_NONE; - e->e_parent = NULL; - e->e_rawfile = NULL; - e->e_rawsize = 0; - e->e_version = LIBELF_PRIVATE(version); - - (void) memset(&e->e_u, 0, sizeof(e->e_u)); - - return (e); -} - -void -_libelf_init_elf(Elf *e, Elf_Kind kind) -{ - assert(e != NULL); - assert(e->e_kind == ELF_K_NONE); - - e->e_kind = kind; - - switch (kind) { - case ELF_K_ELF: - STAILQ_INIT(&e->e_u.e_elf.e_scn); - break; - default: - break; - } -} - -#define FREE(P) do { \ - if (P) \ - free(P); \ - } while (0) - - -Elf * -_libelf_release_elf(Elf *e) -{ - Elf_Arhdr *arh; - - switch (e->e_kind) { - case ELF_K_AR: - FREE(e->e_u.e_ar.e_symtab); - break; - - case ELF_K_ELF: - switch (e->e_class) { - case ELFCLASS32: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); - FREE(e->e_u.e_elf.e_phdr.e_phdr32); - break; - case ELFCLASS64: - FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); - FREE(e->e_u.e_elf.e_phdr.e_phdr64); - break; - } - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - if (e->e_flags & LIBELF_F_AR_HEADER) { - arh = e->e_hdr.e_arhdr; - FREE(arh->ar_name); - FREE(arh->ar_rawname); - free(arh); - } - - break; - - default: - break; - } - - free(e); - - return (NULL); -} - -Elf_Data * -_libelf_allocate_data(Elf_Scn *s) -{ - Elf_Data *d; - - if ((d = calloc((size_t) 1, sizeof(Elf_Data))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - d->d_scn = s; - - return (d); -} - -Elf_Data * -_libelf_release_data(Elf_Data *d) -{ - - if (d->d_flags & LIBELF_F_DATA_MALLOCED) - free(d->d_buf); - - free(d); - - return (NULL); -} - -Elf_Scn * -_libelf_allocate_scn(Elf *e, size_t ndx) -{ - Elf_Scn *s; - - if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, errno); - return (NULL); - } - - s->s_elf = e; - s->s_ndx = ndx; - - STAILQ_INIT(&s->s_data); - STAILQ_INIT(&s->s_rawdata); - - STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); - - return (s); -} - -Elf_Scn * -_libelf_release_scn(Elf_Scn *s) -{ - Elf *e; - Elf_Data *d, *td; - - assert(s != NULL); - - STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { - STAILQ_REMOVE(&s->s_data, d, _Elf_Data, d_next); - d = _libelf_release_data(d); - } - - STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { - assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); - STAILQ_REMOVE(&s->s_rawdata, d, _Elf_Data, d_next); - d = _libelf_release_data(d); - } - - e = s->s_elf; - - assert(e != NULL); - - STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); - - free(s); - - return (NULL); -} diff --git a/linkers/elftoolchain/libelf/libelf_ar.c b/linkers/elftoolchain/libelf/libelf_ar.c deleted file mode 100644 index 14b383d..0000000 --- a/linkers/elftoolchain/libelf/libelf_ar.c +++ /dev/null @@ -1,461 +0,0 @@ -/*- - * Copyright (c) 2006,2008,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "_libelf.h" -#include "_libelf_ar.h" - -LIBELF_VCSID("$Id: libelf_ar.c 1341 2011-01-01 04:28:29Z jkoshy $"); - -#define LIBELF_NALLOC_SIZE 16 - -/* - * `ar' archive handling. - * - * `ar' archives start with signature `ARMAG'. Each archive member is - * preceded by a header containing meta-data for the member. This - * header is described in (struct ar_hdr). The header always - * starts on an even address. File data is padded with "\n" - * characters to keep this invariant. - * - * Special considerations for `ar' archives: - * - * There are two variants of the `ar' archive format: traditional BSD - * and SVR4. These differ in the way long file names are treated, and - * in the layout of the archive symbol table. - * - * The `ar' header only has space for a 16 character file name. - * - * In the SVR4 format, file names are terminated with a '/', so this - * effectively leaves 15 characters for the actual file name. Longer - * file names stored in a separate 'string table' and referenced - * indirectly from the name field. The string table itself appears as - * an archive member with name "// ". An `indirect' file name in an - * `ar' header matches the pattern "/[0-9]*". The digits form a - * decimal number that corresponds to a byte offset into the string - * table where the actual file name of the object starts. Strings in - * the string table are padded to start on even addresses. - * - * In the BSD format, file names can be upto 16 characters. File - * names shorter than 16 characters are padded to 16 characters using - * (ASCII) space characters. File names with embedded spaces and file - * names longer than 16 characters are stored immediately after the - * archive header and the name field set to a special indirect name - * matching the pattern "#1/[0-9]+". The digits form a decimal number - * that corresponds to the actual length of the file name following - * the archive header. The content of the archive member immediately - * follows the file name, and the size field of the archive member - * holds the sum of the sizes of the member and of the appended file - * name. - * - * Archives may also have a symbol table (see ranlib(1)), mapping - * program symbols to object files inside the archive. - * - * In the SVR4 format, a symbol table uses a file name of "/ " in its - * archive header. The symbol table is structured as: - * - a 4-byte count of entries stored as a binary value, MSB first - * - 'n' 4-byte offsets, stored as binary values, MSB first - * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. - * - * In the BSD format, the symbol table uses a file name of "__.SYMDEF". - * It is structured as two parts: - * - The first part is an array of "ranlib" structures preceded by - * the size of the array in bytes. Each "ranlib" structure - * describes one symbol. Each structure contains an offset into - * the string table for the symbol name, and a file offset into the - * archive for the member defining the symbol. - * - The second part is a string table containing NUL-terminated - * strings, preceded by the size of the string table in bytes. - * - * If the symbol table and string table are is present in an archive - * they must be the very first objects and in that order. - */ - - -/* - * Retrieve an archive header descriptor. - */ - -Elf_Arhdr * -_libelf_ar_gethdr(Elf *e) -{ - Elf *parent; - char *namelen; - Elf_Arhdr *eh; - size_t n, nlen; - struct ar_hdr *arh; - - if ((parent = e->e_parent) == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert((e->e_flags & LIBELF_F_AR_HEADER) == 0); - - arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr; - - assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG); - assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile + - parent->e_rawsize - sizeof(struct ar_hdr)); - - if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - e->e_hdr.e_arhdr = eh; - e->e_flags |= LIBELF_F_AR_HEADER; - - eh->ar_name = eh->ar_rawname = NULL; - - if ((eh->ar_name = _libelf_ar_get_translated_name(arh, parent)) == - NULL) - goto error; - - if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, - &n) == 0) - goto error; - eh->ar_uid = (uid_t) n; - - if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, - &n) == 0) - goto error; - eh->ar_gid = (gid_t) n; - - if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, - &n) == 0) - goto error; - eh->ar_mode = (mode_t) n; - - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, - &n) == 0) - goto error; - - /* - * Get the true size of the member if extended naming is being used. - */ - if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { - namelen = arh->ar_name + - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nlen) == 0) - goto error; - n -= nlen; - } - - eh->ar_size = n; - - if ((eh->ar_rawname = _libelf_ar_get_raw_name(arh)) == NULL) - goto error; - - eh->ar_flags = 0; - - return (eh); - - error: - if (eh) { - if (eh->ar_name) - free(eh->ar_name); - if (eh->ar_rawname) - free(eh->ar_rawname); - free(eh); - } - - e->e_flags &= ~LIBELF_F_AR_HEADER; - e->e_hdr.e_rawhdr = (char *) arh; - - return (NULL); -} - -Elf * -_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) -{ - Elf *e; - char *member, *namelen; - size_t nsz, sz; - off_t next; - struct ar_hdr *arh; - - assert(elf->e_kind == ELF_K_AR); - - next = elf->e_u.e_ar.e_next; - - /* - * `next' is only set to zero by elf_next() when the last - * member of an archive is processed. - */ - if (next == (off_t) 0) - return (NULL); - - assert((next & 1) == 0); - - arh = (struct ar_hdr *) (elf->e_rawfile + next); - - /* - * Retrieve the size of the member. - */ - if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, - &sz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - /* - * Adjust the size field for members in BSD archives using - * extended naming. - */ - if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { - namelen = arh->ar_name + - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nsz) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - member = (char *) (arh + 1) + nsz; - sz -= nsz; - } else - member = (char *) (arh + 1); - - - if ((e = elf_memory((char *) member, sz)) == NULL) - return (NULL); - - e->e_fd = fd; - e->e_cmd = c; - e->e_hdr.e_rawhdr = (char *) arh; - - elf->e_u.e_ar.e_nchildren++; - e->e_parent = elf; - - return (e); -} - -/* - * A BSD-style ar(1) symbol table has the following layout: - * - * - A count of bytes used by the following array of 'ranlib' - * structures, stored as a 'long'. - * - An array of 'ranlib' structures. Each array element is - * two 'long's in size. - * - A count of bytes used for the following symbol table. - * - The symbol table itself. - */ - -/* - * A helper macro to read in a 'long' value from the archive. We use - * memcpy() since the source pointer may be misaligned with respect to - * the natural alignment for a C 'long'. - */ -#define GET_LONG(P, V)do { \ - memcpy(&(V), (P), sizeof(long)); \ - (P) += sizeof(long); \ - } while (0) - -Elf_Arsym * -_libelf_ar_process_bsd_symtab(Elf *e, size_t *count) -{ - Elf_Arsym *symtab, *sym; - unsigned char *end, *p, *p0, *s, *s0; - const unsigned int entrysize = 2 * sizeof(long); - long arraysize, fileoffset, n, nentries, stroffset, strtabsize; - - assert(e != NULL); - assert(count != NULL); - assert(e->e_u.e_ar.e_symtab == NULL); - - symtab = NULL; - - /* - * The BSD symbol table always contains the count fields even - * if there are no entries in it. - */ - if (e->e_u.e_ar.e_rawsymtabsz < 2 * sizeof(long)) - goto symtaberror; - - p = p0 = (unsigned char *) e->e_u.e_ar.e_rawsymtab; - end = p0 + e->e_u.e_ar.e_rawsymtabsz; - - /* - * Retrieve the size of the array of ranlib descriptors and - * check it for validity. - */ - GET_LONG(p, arraysize); - - if (p0 + arraysize >= end || (arraysize % entrysize != 0)) - goto symtaberror; - - /* - * Check the value of the string table size. - */ - s = p + arraysize; - GET_LONG(s, strtabsize); - - s0 = s; /* Start of string table. */ - if (s0 + strtabsize > end) - goto symtaberror; - - nentries = arraysize / entrysize; - - /* - * Allocate space for the returned Elf_Arsym array. - */ - if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries + 1))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - /* Read in symbol table entries. */ - for (n = 0, sym = symtab; n < nentries; n++, sym++) { - GET_LONG(p, stroffset); - GET_LONG(p, fileoffset); - - s = s0 + stroffset; - - if (s >= end) - goto symtaberror; - - sym->as_off = fileoffset; - sym->as_hash = elf_hash((char *) s); - sym->as_name = (char *) s; - } - - /* Fill up the sentinel entry. */ - sym->as_name = NULL; - sym->as_hash = ~0UL; - sym->as_off = (off_t) 0; - - /* Remember the processed symbol table. */ - e->e_u.e_ar.e_symtab = symtab; - - *count = e->e_u.e_ar.e_symtabsz = nentries + 1; - - return (symtab); - -symtaberror: - if (symtab) - free(symtab); - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); -} - -/* - * An SVR4-style ar(1) symbol table has the following layout: - * - * - The first 4 bytes are a binary count of the number of entries in the - * symbol table, stored MSB-first. - * - Then there are 'n' 4-byte binary offsets, also stored MSB first. - * - Following this, there are 'n' null-terminated strings. - */ - -#define GET_WORD(P, V) do { \ - (V) = 0; \ - (V) = (P)[0]; (V) <<= 8; \ - (V) += (P)[1]; (V) <<= 8; \ - (V) += (P)[2]; (V) <<= 8; \ - (V) += (P)[3]; \ - } while (0) - -#define INTSZ 4 - - -Elf_Arsym * -_libelf_ar_process_svr4_symtab(Elf *e, size_t *count) -{ - size_t n, nentries, off; - Elf_Arsym *symtab, *sym; - unsigned char *p, *s, *end; - - assert(e != NULL); - assert(count != NULL); - assert(e->e_u.e_ar.e_symtab == NULL); - - symtab = NULL; - - if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) - goto symtaberror; - - p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; - end = p + e->e_u.e_ar.e_rawsymtabsz; - - GET_WORD(p, nentries); - p += INTSZ; - - if (nentries == 0 || p + nentries * INTSZ >= end) - goto symtaberror; - - /* Allocate space for a nentries + a sentinel. */ - if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - s = p + (nentries * INTSZ); /* start of the string table. */ - - for (n = nentries, sym = symtab; n > 0; n--) { - - if (s >= end) - goto symtaberror; - - off = 0; - - GET_WORD(p, off); - - sym->as_off = off; - sym->as_hash = elf_hash((char *) s); - sym->as_name = (char *) s; - - p += INTSZ; - sym++; - - for (; s < end && *s++ != '\0';) /* skip to next string */ - ; - } - - /* Fill up the sentinel entry. */ - sym->as_name = NULL; - sym->as_hash = ~0UL; - sym->as_off = (off_t) 0; - - *count = e->e_u.e_ar.e_symtabsz = nentries + 1; - e->e_u.e_ar.e_symtab = symtab; - - return (symtab); - -symtaberror: - if (symtab) - free(symtab); - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); -} diff --git a/linkers/elftoolchain/libelf/libelf_ar_util.c b/linkers/elftoolchain/libelf/libelf_ar_util.c deleted file mode 100644 index 7051fe8..0000000 --- a/linkers/elftoolchain/libelf/libelf_ar_util.c +++ /dev/null @@ -1,354 +0,0 @@ -/*- - * Copyright (c) 2006,2009,2010 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include "_libelf.h" -#include "_libelf_ar.h" - -LIBELF_VCSID("$Id: libelf_ar_util.c 2066 2011-10-26 15:40:28Z jkoshy $"); - -/* - * Convert a string bounded by `start' and `start+sz' (exclusive) to a - * number in the specified base. - */ -int -_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) -{ - int c, v; - size_t r; - const char *e; - - assert(base <= 10); - - e = s + sz; - - /* skip leading blanks */ - for (;s < e && (c = *s) == ' '; s++) - ; - - r = 0L; - for (;s < e; s++) { - if ((c = *s) == ' ') - break; - if (c < '0' || c > '9') - return (0); - v = c - '0'; - if (v >= base) /* Illegal digit. */ - break; - r *= base; - r += v; - } - - *ret = r; - - return (1); -} - -/* - * Return the translated name for an archive member. - */ -char * -_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) -{ - char c, *s; - size_t len, offset; - const char *buf, *p, *q, *r; - const size_t bufsize = sizeof(arh->ar_name); - - assert(arh != NULL); - assert(ar->e_kind == ELF_K_AR); - assert((const char *) arh >= ar->e_rawfile && - (const char *) arh < ar->e_rawfile + ar->e_rawsize); - - buf = arh->ar_name; - - /* - * Check for extended naming. - * - * If the name matches the pattern "^/[0-9]+", it is an - * SVR4-style extended name. If the name matches the pattern - * "#1/[0-9]+", the entry uses BSD style extended naming. - */ - if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { - /* - * The value in field ar_name is a decimal offset into - * the archive string table where the actual name - * resides. - */ - if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, - &offset) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - if (offset > ar->e_u.e_ar.e_rawstrtabsz) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - p = q = ar->e_u.e_ar.e_rawstrtab + offset; - r = ar->e_u.e_ar.e_rawstrtab + ar->e_u.e_ar.e_rawstrtabsz; - - for (; p < r && *p != '/'; p++) - ; - len = p - q + 1; /* space for the trailing NUL */ - - if ((s = malloc(len)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(s, q, len - 1); - s[len - 1] = '\0'; - - return (s); - } else if (IS_EXTENDED_BSD_NAME(buf)) { - r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - - if (_libelf_ar_get_number(r, bufsize - - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, - &len) == 0) { - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - } - - /* - * Allocate space for the file name plus a - * trailing NUL. - */ - if ((s = malloc(len + 1)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - /* - * The file name follows the archive header. - */ - q = (const char *) (arh + 1); - - (void) strncpy(s, q, len); - s[len] = '\0'; - - return (s); - } - - /* - * A 'normal' name. - * - * Skip back over trailing blanks from the end of the field. - * In the SVR4 format, a '/' is used as a terminator for - * non-special names. - */ - for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) - ; - - if (q >= buf) { - if (*q == '/') { - /* - * SVR4 style names: ignore the trailing - * character '/', but only if the name is not - * one of the special names "/" and "//". - */ - if (q > buf + 1 || - (q == (buf + 1) && *buf != '/')) - q--; - } - - len = q - buf + 2; /* Add space for a trailing NUL. */ - } else { - /* The buffer only had blanks. */ - buf = ""; - len = 1; - } - - if ((s = malloc(len)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(s, buf, len - 1); - s[len - 1] = '\0'; - - return (s); -} - -/* - * Return the raw name for an archive member, inclusive of any - * formatting characters. - */ -char * -_libelf_ar_get_raw_name(const struct ar_hdr *arh) -{ - char *rawname; - const size_t namesz = sizeof(arh->ar_name); - - if ((rawname = malloc(namesz + 1)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - (void) strncpy(rawname, arh->ar_name, namesz); - rawname[namesz] = '\0'; - return (rawname); -} - -/* - * Open an 'ar' archive. - */ -Elf * -_libelf_ar_open(Elf *e) -{ - int scanahead; - char *s, *end; - size_t sz; - struct ar_hdr arh; - - e->e_kind = ELF_K_AR; - e->e_u.e_ar.e_nchildren = 0; - e->e_u.e_ar.e_next = (off_t) -1; - - /* - * Look for special members. - */ - - s = e->e_rawfile + SARMAG; - end = e->e_rawfile + e->e_rawsize; - - assert(e->e_rawsize > 0); - - /* - * We use heuristics to determine the flavor of the archive we - * are examining. - * - * SVR4 flavor archives use the name "/ " and "// " for - * special members. - * - * In BSD flavor archives the symbol table, if present, is the - * first archive with name "__.SYMDEF". - */ - -#define READ_AR_HEADER(S, ARH, SZ, END) \ - do { \ - if ((S) + sizeof((ARH)) > (END)) \ - goto error; \ - (void) memcpy(&(ARH), (S), sizeof((ARH))); \ - if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \ - goto error; \ - if (_libelf_ar_get_number((ARH).ar_size, \ - sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ - goto error; \ - } while (0) - - READ_AR_HEADER(s, arh, sz, end); - - /* - * Handle special archive members for the SVR4 format. - */ - if (arh.ar_name[0] == '/') { - - assert(sz > 0); - - e->e_flags |= LIBELF_F_AR_VARIANT_SVR4; - - scanahead = 0; - - /* - * The symbol table (file name "/ ") always comes before the - * string table (file name "// "). - */ - if (arh.ar_name[1] == ' ') { - /* "/ " => symbol table. */ - scanahead = 1; /* The string table to follow. */ - - s += sizeof(arh); - e->e_u.e_ar.e_rawsymtab = s; - e->e_u.e_ar.e_rawsymtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - - } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { - /* "// " => string table for long file names. */ - s += sizeof(arh); - e->e_u.e_ar.e_rawstrtab = s; - e->e_u.e_ar.e_rawstrtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - - /* - * If the string table hasn't been seen yet, look for - * it in the next member. - */ - if (scanahead) { - READ_AR_HEADER(s, arh, sz, end); - - /* "// " => string table for long file names. */ - if (arh.ar_name[0] == '/' && arh.ar_name[1] == '/' && - arh.ar_name[2] == ' ') { - - s += sizeof(arh); - - e->e_u.e_ar.e_rawstrtab = s; - e->e_u.e_ar.e_rawstrtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - } - } else if (strncmp(arh.ar_name, LIBELF_AR_BSD_SYMTAB_NAME, - sizeof(LIBELF_AR_BSD_SYMTAB_NAME) - 1) == 0) { - /* - * BSD style archive symbol table. - */ - s += sizeof(arh); - e->e_u.e_ar.e_rawsymtab = s; - e->e_u.e_ar.e_rawsymtabsz = sz; - - sz = LIBELF_ADJUST_AR_SIZE(sz); - s += sz; - } - - /* - * Update the 'next' offset, so that a subsequent elf_begin() - * works as expected. - */ - e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); - - return (e); - -error: - LIBELF_SET_ERROR(ARCHIVE, 0); - return (NULL); - -} diff --git a/linkers/elftoolchain/libelf/libelf_checksum.c b/linkers/elftoolchain/libelf/libelf_checksum.c deleted file mode 100644 index 0bece9a..0000000 --- a/linkers/elftoolchain/libelf/libelf_checksum.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_checksum.c 189 2008-07-20 10:38:08Z jkoshy $"); - -static unsigned long -_libelf_sum(unsigned long c, const unsigned char *s, size_t size) -{ - if (s == NULL || size == 0) - return (c); - - while (size--) - c += *s++; - - return (c); -} - -unsigned long -_libelf_checksum(Elf *e, int elfclass) -{ - size_t shn; - Elf_Scn *scn; - Elf_Data *d; - unsigned long checksum; - GElf_Ehdr eh; - GElf_Shdr shdr; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (0L); - } - - if (e->e_class != elfclass) { - LIBELF_SET_ERROR(CLASS, 0); - return (0L); - } - - if (gelf_getehdr(e, &eh) == NULL) - return (0); - - /* - * Iterate over all sections in the ELF file, computing the - * checksum along the way. - * - * The first section is always SHN_UNDEF and can be skipped. - * Non-allocatable sections are skipped, as are sections that - * could be affected by utilities such as strip(1). - */ - - checksum = 0; - for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { - if ((scn = elf_getscn(e, shn)) == NULL) - return (0); - if (gelf_getshdr(scn, &shdr) == NULL) - return (0); - if ((shdr.sh_flags & SHF_ALLOC) == 0 || - shdr.sh_type == SHT_DYNAMIC || - shdr.sh_type == SHT_DYNSYM) - continue; - - d = NULL; - while ((d = elf_rawdata(scn, d)) != NULL) - checksum = _libelf_sum(checksum, - (unsigned char *) d->d_buf, d->d_size); - } - - /* - * Return a 16-bit checksum compatible with Solaris. - */ - return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); -} diff --git a/linkers/elftoolchain/libelf/libelf_convert.m4 b/linkers/elftoolchain/libelf/libelf_convert.m4 deleted file mode 100644 index 9b1679a..0000000 --- a/linkers/elftoolchain/libelf/libelf_convert.m4 +++ /dev/null @@ -1,1086 +0,0 @@ -/*- - * Copyright (c) 2006-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_convert.m4 1734 2011-08-16 09:55:07Z jkoshy $"); - -/* WARNING: GENERATED FROM __file__. */ - -divert(-1) - -# Generate conversion routines for converting between in-memory and -# file representations of Elf data structures. -# -# These conversions use the type information defined in `elf_types.m4'. - -include(SRCDIR`/elf_types.m4') - -# For the purposes of generating conversion code, ELF types may be -# classified according to the following characteristics: -# -# 1. Whether the ELF type can be directly mapped to an integral C -# language type. For example, the ELF_T_WORD type maps directly to -# a 'uint32_t', but ELF_T_GNUHASH lacks a matching C type. -# -# 2. Whether the type has word size dependent variants. For example, -# ELT_T_EHDR is represented using C types Elf32_Ehdr and El64_Ehdr, -# and the ELF_T_ADDR and ELF_T_OFF types have integral C types that -# can be 32- or 64- bit wide. -# -# 3. Whether the ELF types has a fixed representation or not. For -# example, the ELF_T_SYM type has a fixed size file representation, -# some types like ELF_T_NOTE and ELF_T_GNUHASH use a variable size -# representation. -# -# We use m4 macros to generate conversion code for ELF types that have -# a fixed size representation. Conversion functions for the remaining -# types are coded by hand. -# -#* Handling File and Memory Representations -# -# `In-memory' representations of an Elf data structure use natural -# alignments and native byte ordering. This allows pointer arithmetic -# and casting to work as expected. On the other hand, the `file' -# representation of an ELF data structure could possibly be packed -# tighter than its `in-memory' representation, and could be of a -# differing byte order. Reading ELF objects that are members of `ar' -# archives present an additional complication: `ar' pads file data to -# even addresses, so file data structures in an archive member -# residing inside an `ar' archive could be at misaligned memory -# addresses when brought into memory. -# -# In summary, casting the `char *' pointers that point to memory -# representations (i.e., source pointers for the *_tof() functions and -# the destination pointers for the *_tom() functions), is safe, as -# these pointers should be correctly aligned for the memory type -# already. However, pointers to file representations have to be -# treated as being potentially unaligned and no casting can be done. - -# NOCVT(TYPE) -- Do not generate the cvt[] structure entry for TYPE -define(`NOCVT',`define(`NOCVT_'$1,1)') - -# NOFUNC(TYPE) -- Do not generate a conversion function for TYPE -define(`NOFUNC',`define(`NOFUNC_'$1,1)') - -# IGNORE(TYPE) -- Completely ignore the type. -define(`IGNORE',`NOCVT($1)NOFUNC($1)') - -# Mark ELF types that should not be processed by the M4 macros below. - -# Types for which we use functions with non-standard names. -IGNORE(`BYTE') # Uses a wrapper around memcpy(). -IGNORE(`NOTE') # Not a fixed size type. - -# Types for which we supply hand-coded functions. -NOFUNC(`GNUHASH') # A type with complex internal structure. -NOFUNC(`VDEF') # See MAKE_VERSION_CONVERTERS below. -NOFUNC(`VNEED') # .. - -# Unimplemented types. -IGNORE(`MOVEP') - -# ELF types that don't exist in a 32-bit world. -NOFUNC(`XWORD32') -NOFUNC(`SXWORD32') - -# `Primitive' ELF types are those that are an alias for an integral -# type. As they have no internal structure, they can be copied using -# a `memcpy()', and byteswapped in straightforward way. -# -# Mark all ELF types that directly map to integral C types. -define(`PRIM_ADDR', 1) -define(`PRIM_BYTE', 1) -define(`PRIM_HALF', 1) -define(`PRIM_LWORD', 1) -define(`PRIM_OFF', 1) -define(`PRIM_SWORD', 1) -define(`PRIM_SXWORD', 1) -define(`PRIM_WORD', 1) -define(`PRIM_XWORD', 1) - -# Note the primitive types that are size-dependent. -define(`SIZEDEP_ADDR', 1) -define(`SIZEDEP_OFF', 1) - -# Generate conversion functions for primitive types. -# -# Macro use: MAKEPRIMFUNCS(ELFTYPE,CTYPE,TYPESIZE,SYMSIZE) -# `$1': Name of the ELF type. -# `$2': C structure name suffix. -# `$3': ELF class specifier for types, one of [`32', `64']. -# `$4': Additional ELF class specifier, one of [`', `32', `64']. -# -# Generates a pair of conversion functions. -define(`MAKEPRIMFUNCS',` -static int -libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; - size_t c; - - (void) dsz; - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*s)); - return (1); - } - - for (c = 0; c < count; c++) { - t = *s++; - SWAP_$1$4(t); - WRITE_$1$4(dst,t); - } - - return (1); -} - -static int -libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; - size_t c; - - if (dsz < count * sizeof(Elf$3_$2)) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(*d)); - return (1); - } - - for (c = 0; c < count; c++) { - READ_$1$4(src,t); - SWAP_$1$4(t); - *d++ = t; - } - - return (1); -} -') - -# -# Handling composite ELF types -# - -# SWAP_FIELD(FIELDNAME,ELFTYPE) -- Generate code to swap one field. -define(`SWAP_FIELD', - `ifdef(`SIZEDEP_'$2, - `SWAP_$2'SZ()`(t.$1); - ', - `SWAP_$2(t.$1); - ')') - -# SWAP_MEMBERS(STRUCT) -- Iterate over a structure definition. -define(`SWAP_MEMBERS', - `ifelse($#,1,`/**/', - `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') - -# SWAP_STRUCT(CTYPE,SIZE) -- Generate code to swap an ELF structure. -define(`SWAP_STRUCT', - `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ - SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - -# WRITE_FIELD(ELFTYPE,FIELDNAME) -- Generate code to write one field. -define(`WRITE_FIELD', - `ifdef(`SIZEDEP_'$2, - `WRITE_$2'SZ()`(dst,t.$1); - ', - `WRITE_$2(dst,t.$1); - ')') - -# WRITE_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. -define(`WRITE_MEMBERS', - `ifelse($#,1,`/**/', - `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') - -# WRITE_STRUCT(CTYPE,SIZE) -- Generate code to write out an ELF structure. -define(`WRITE_STRUCT', - `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ - WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - -# READ_FIELD(ELFTYPE,CTYPE) -- Generate code to read one field. -define(`READ_FIELD', - `ifdef(`SIZEDEP_'$2, - `READ_$2'SZ()`(s,t.$1); - ', - `READ_$2(s,t.$1); - ')') - -# READ_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. -define(`READ_MEMBERS', - `ifelse($#,1,`/**/', - `READ_FIELD($1)READ_MEMBERS(shift($@))')') - -# READ_STRUCT(CTYPE,SIZE) -- Generate code to read an ELF structure. -define(`READ_STRUCT', - `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ - READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') - - -# MAKECOMPFUNCS -- Generate converters for composite ELF structures. -# -# When converting data to file representation, the source pointer will -# be naturally aligned for a data structure's in-memory -# representation. When converting data to memory, the destination -# pointer will be similarly aligned. -# -# For in-place conversions, when converting to file representations, -# the source buffer is large enough to hold `file' data. When -# converting from file to memory, we need to be careful to work -# `backwards', to avoid overwriting unconverted data. -# -# Macro use: -# `$1': Name of the ELF type. -# `$2': C structure name suffix. -# `$3': ELF class specifier, one of [`', `32', `64'] -define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',` -static int -libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *s; - size_t c; - - (void) dsz; - - s = (Elf$3_$2 *) (uintptr_t) src; - for (c = 0; c < count; c++) { - t = *s++; - if (byteswap) { - SWAP_STRUCT($2,$3) - } - WRITE_STRUCT($2,$3) - } - - return (1); -} - -static int -libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$3_$2 t, *d; - char *s,*s0; - size_t fsz; - - fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); - d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); - s0 = (char *) src + (count - 1) * fsz; - - if (dsz < count * sizeof(Elf$3_$2)) - return (0); - - while (count--) { - s = s0; - READ_STRUCT($2,$3) - if (byteswap) { - SWAP_STRUCT($2,$3) - } - *d-- = t; s0 -= fsz; - } - - return (1); -} -')') - -# MAKE_TYPE_CONVERTER(ELFTYPE,CTYPE) -# -# Make type convertor functions from the type definition -# of the ELF type: -# - Skip convertors marked as `NOFUNC'. -# - Invoke `MAKEPRIMFUNCS' or `MAKECOMPFUNCS' as appropriate. -define(`MAKE_TYPE_CONVERTER', - `ifdef(`NOFUNC_'$1,`', - `ifdef(`PRIM_'$1, - `ifdef(`SIZEDEP_'$1, - `MAKEPRIMFUNCS($1,$2,32,32)dnl - MAKEPRIMFUNCS($1,$2,64,64)', - `MAKEPRIMFUNCS($1,$2,64)')', - `MAKECOMPFUNCS($1,$2,32)dnl - MAKECOMPFUNCS($1,$2,64)')')') - -# MAKE_TYPE_CONVERTERS(ELFTYPELIST) -- Generate conversion functions. -define(`MAKE_TYPE_CONVERTERS', - `ifelse($#,1,`', - `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') - - -# -# Macros to generate entries for the table of convertors. -# - -# CONV(ELFTYPE,SIZE,DIRECTION) -# -# Generate the name of a convertor function. -define(`CONV', - `ifdef(`NOFUNC_'$1$2, - `.$3$2 = NULL', - `ifdef(`PRIM_'$1, - `ifdef(`SIZEDEP_'$1, - `.$3$2 = libelf_cvt_$1$2_$3', - `.$3$2 = libelf_cvt_$1_$3')', - `.$3$2 = libelf_cvt_$1$2_$3')')') - -# CONVERTER_NAME(ELFTYPE) -# -# Generate the contents of one `struct cvt' instance. -define(`CONVERTER_NAME', - `ifdef(`NOCVT_'$1,`', - ` [ELF_T_$1] = { - CONV($1,32,tof), - CONV($1,32,tom), - CONV($1,64,tof), - CONV($1,64,tom) - }, - -')') - -# CONVERTER_NAMES(ELFTYPELIST) -# -# Generate the `struct cvt[]' array. -define(`CONVERTER_NAMES', - `ifelse($#,1,`', - `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') - -# -# Handling ELF version sections. -# - -# _FSZ(FIELD,BASETYPE) - return the file size for a field. -define(`_FSZ', - `ifelse($2,`HALF',2, - $2,`WORD',4)') - -# FSZ(STRUCT) - determine the file size of a structure. -define(`FSZ', - `ifelse($#,1,0, - `eval(_FSZ($1) + FSZ(shift($@)))')') - -# MAKE_VERSION_CONVERTERS(TYPE,BASE,AUX,PFX) -- Generate conversion -# functions for versioning structures. -define(`MAKE_VERSION_CONVERTERS', - `MAKE_VERSION_CONVERTER($1,$2,$3,$4,32) - MAKE_VERSION_CONVERTER($1,$2,$3,$4,64)') - -# MAKE_VERSION_CONVERTOR(TYPE,CBASE,CAUX,PFX,SIZE) -- Generate a -# conversion function. -define(`MAKE_VERSION_CONVERTER',` -static int -libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$5_$2 t; - Elf$5_$3 a; - const size_t verfsz = FSZ(Elf$5_$2_DEF); - const size_t auxfsz = FSZ(Elf$5_$3_DEF); - const size_t vermsz = sizeof(Elf$5_$2); - const size_t auxmsz = sizeof(Elf$5_$3); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; - Elf$5_Word aux, anext, cnt, vnext; - - for (dtmp = dst, vnext = ~0; - vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; - dtmp += vnext, src += vnext) { - - /* Read in an Elf$5_$2 structure. */ - t = *((Elf$5_$2 *) (uintptr_t) src); - - aux = t.$4_aux; - cnt = t.$4_cnt; - vnext = t.$4_next; - - if (byteswap) { - SWAP_STRUCT($2, $5) - } - - dst = dtmp; - WRITE_STRUCT($2, $5) - - if (aux < verfsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; - cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && - srcaux + auxmsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - /* Read in an Elf$5_$3 structure. */ - a = *((Elf$5_$3 *) (uintptr_t) srcaux); - anext = a.$4a_next; - - if (byteswap) { - pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') - } - - dst = dstaux; - pushdef(`t',`a')WRITE_STRUCT($3, $5)popdef(`t') - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -} - -static int -libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - Elf$5_$2 t, *dp; - Elf$5_$3 a, *ap; - const size_t verfsz = FSZ(Elf$5_$2_DEF); - const size_t auxfsz = FSZ(Elf$5_$3_DEF); - const size_t vermsz = sizeof(Elf$5_$2); - const size_t auxmsz = sizeof(Elf$5_$3); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; - Elf$5_Word aux, anext, cnt, vnext; - - for (stmp = src, vnext = ~0; - vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; - stmp += vnext, dst += vnext) { - - /* Read in a $1 structure. */ - s = stmp; - READ_STRUCT($2, $5) - if (byteswap) { - SWAP_STRUCT($2, $5) - } - - dp = (Elf$5_$2 *) (uintptr_t) dst; - *dp = t; - - aux = t.$4_aux; - cnt = t.$4_cnt; - vnext = t.$4_next; - - if (aux < vermsz) - return (0); - - /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; - cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && - srcaux + auxfsz <= srcend; - dstaux += anext, srcaux += anext, cnt--) { - - s = srcaux; - pushdef(`t',`a')READ_STRUCT($3, $5)popdef(`t') - - if (byteswap) { - pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') - } - - anext = a.$4a_next; - - ap = ((Elf$5_$3 *) (uintptr_t) dstaux); - *ap = a; - } - - if (anext || cnt) - return (0); - } - - if (vnext) - return (0); - - return (1); -}') - -divert(0) - -/* - * C macros to byte swap integral quantities. - */ - -#define SWAP_BYTE(X) do { (void) (X); } while (0) -#define SWAP_IDENT(X) do { (void) (X); } while (0) -#define SWAP_HALF(X) do { \ - uint16_t _x = (uint16_t) (X); \ - uint16_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_WORD(X) do { \ - uint32_t _x = (uint32_t) (X); \ - uint32_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR32(X) SWAP_WORD(X) -#define SWAP_OFF32(X) SWAP_WORD(X) -#define SWAP_SWORD(X) SWAP_WORD(X) -#define SWAP_WORD64(X) do { \ - uint64_t _x = (uint64_t) (X); \ - uint64_t _t = _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ - } while (0) -#define SWAP_ADDR64(X) SWAP_WORD64(X) -#define SWAP_LWORD(X) SWAP_WORD64(X) -#define SWAP_OFF64(X) SWAP_WORD64(X) -#define SWAP_SXWORD(X) SWAP_WORD64(X) -#define SWAP_XWORD(X) SWAP_WORD64(X) - -/* - * C macros to write out various integral values. - * - * Note: - * - The destination pointer could be unaligned. - * - Values are written out in native byte order. - * - The destination pointer is incremented after the write. - */ -#define WRITE_BYTE(P,X) do { \ - char *const _p = (char *) (P); \ - _p[0] = (char) (X); \ - (P) = _p + 1; \ - } while (0) -#define WRITE_HALF(P,X) do { \ - uint16_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - (P) = _p + 2; \ - } while (0) -#define WRITE_WORD(P,X) do { \ - uint32_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - (P) = _p + 4; \ - } while (0) -#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) -#define WRITE_OFF32(P,X) WRITE_WORD(P,X) -#define WRITE_SWORD(P,X) WRITE_WORD(P,X) -#define WRITE_WORD64(P,X) do { \ - uint64_t _t = (X); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ - _p[0] = _q[0]; \ - _p[1] = _q[1]; \ - _p[2] = _q[2]; \ - _p[3] = _q[3]; \ - _p[4] = _q[4]; \ - _p[5] = _q[5]; \ - _p[6] = _q[6]; \ - _p[7] = _q[7]; \ - (P) = _p + 8; \ - } while (0) -#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) -#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) -#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) -#define WRITE_IDENT(P,X) do { \ - (void) memcpy((P), (X), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -/* - * C macros to read in various integral values. - * - * Note: - * - The source pointer could be unaligned. - * - Values are read in native byte order. - * - The source pointer is incremented appropriately. - */ - -#define READ_BYTE(P,X) do { \ - const char *const _p = \ - (const char *) (P); \ - (X) = _p[0]; \ - (P) = (P) + 1; \ - } while (0) -#define READ_HALF(P,X) do { \ - uint16_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - (P) = (P) + 2; \ - (X) = _t; \ - } while (0) -#define READ_WORD(P,X) do { \ - uint32_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - (P) = (P) + 4; \ - (X) = _t; \ - } while (0) -#define READ_ADDR32(P,X) READ_WORD(P,X) -#define READ_OFF32(P,X) READ_WORD(P,X) -#define READ_SWORD(P,X) READ_WORD(P,X) -#define READ_WORD64(P,X) do { \ - uint64_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ - _q[0] = _p[0]; \ - _q[1] = _p[1]; \ - _q[2] = _p[2]; \ - _q[3] = _p[3]; \ - _q[4] = _p[4]; \ - _q[5] = _p[5]; \ - _q[6] = _p[6]; \ - _q[7] = _p[7]; \ - (P) = (P) + 8; \ - (X) = _t; \ - } while (0) -#define READ_ADDR64(P,X) READ_WORD64(P,X) -#define READ_LWORD(P,X) READ_WORD64(P,X) -#define READ_OFF64(P,X) READ_WORD64(P,X) -#define READ_SXWORD(P,X) READ_WORD64(P,X) -#define READ_XWORD(P,X) READ_WORD64(P,X) -#define READ_IDENT(P,X) do { \ - (void) memcpy((X), (P), sizeof((X))); \ - (P) = (P) + EI_NIDENT; \ - } while (0) - -#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) - -/*[*/ -MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) -MAKE_VERSION_CONVERTERS(VDEF,Verdef,Verdaux,vd) -MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) -/*]*/ - -/* - * Sections of type ELF_T_BYTE are never byteswapped, consequently a - * simple memcpy suffices for both directions of conversion. - */ - -static int -libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - (void) byteswap; - if (dsz < count) - return (0); - if (dst != src) - (void) memcpy(dst, src, count); - return (1); -} - -/* - * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit - * words. Bloom filter data comes next, followed by hash buckets and the - * hash chain. - * - * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit - * wide on ELFCLASS32 objects. The other objects in this section are 32 - * bits wide. - * - * Argument `srcsz' denotes the number of bytes to be converted. In the - * 32-bit case we need to translate `srcsz' to a count of 32-bit words. - */ - -static int -libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - return (libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), - byteswap)); -} - -static int -libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - size_t sz; - uint64_t t64, *bloom64; - Elf_GNU_Hash_Header *gh; - uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; - uint32_t *buckets, *chains; - - sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ - if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) - return (0); - - /* Read in the section header and byteswap if needed. */ - READ_WORD(src, nbuckets); - READ_WORD(src, symndx); - READ_WORD(src, maskwords); - READ_WORD(src, shift2); - - srcsz -= sz; - - if (byteswap) { - SWAP_WORD(nbuckets); - SWAP_WORD(symndx); - SWAP_WORD(maskwords); - SWAP_WORD(shift2); - } - - /* Check source buffer and destination buffer sizes. */ - sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); - if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; - gh->gh_nbuckets = nbuckets; - gh->gh_symndx = symndx; - gh->gh_maskwords = maskwords; - gh->gh_shift2 = shift2; - - dsz -= sizeof(Elf_GNU_Hash_Header); - dst += sizeof(Elf_GNU_Hash_Header); - - bloom64 = (uint64_t *) (uintptr_t) dst; - - /* Copy bloom filter data. */ - for (n = 0; n < maskwords; n++) { - READ_XWORD(src, t64); - if (byteswap) - SWAP_XWORD(t64); - bloom64[n] = t64; - } - - /* The hash buckets follows the bloom filter. */ - dst += maskwords * sizeof(uint64_t); - buckets = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nbuckets; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - buckets[n] = t32; - } - - dst += nbuckets * sizeof(uint32_t); - - /* The hash chain follows the hash buckets. */ - dsz -= sz; - srcsz -= sz; - - if (dsz < srcsz) /* Destination lacks space. */ - return (0); - - nchains = srcsz / sizeof(uint32_t); - chains = (uint32_t *) (uintptr_t) dst; - - for (n = 0; n < nchains; n++) { - READ_WORD(src, t32); - if (byteswap) - SWAP_WORD(t32); - *chains++ = t32; - } - - return (1); -} - -static int -libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) -{ - uint32_t *s32; - size_t sz, hdrsz; - uint64_t *s64, t64; - Elf_GNU_Hash_Header *gh; - uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; - - hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ - if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) - return (0); - - gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; - - t0 = nbuckets = gh->gh_nbuckets; - t1 = gh->gh_symndx; - t2 = maskwords = gh->gh_maskwords; - t3 = gh->gh_shift2; - - src += sizeof(Elf_GNU_Hash_Header); - srcsz -= sizeof(Elf_GNU_Hash_Header); - dsz -= hdrsz; - - sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * - sizeof(uint64_t); - - if (srcsz < sz || dsz < sz) - return (0); - - /* Write out the header. */ - if (byteswap) { - SWAP_WORD(t0); - SWAP_WORD(t1); - SWAP_WORD(t2); - SWAP_WORD(t3); - } - - WRITE_WORD(dst, t0); - WRITE_WORD(dst, t1); - WRITE_WORD(dst, t2); - WRITE_WORD(dst, t3); - - /* Copy the bloom filter and the hash table. */ - s64 = (uint64_t *) (uintptr_t) src; - for (n = 0; n < maskwords; n++) { - t64 = *s64++; - if (byteswap) - SWAP_XWORD(t64); - WRITE_WORD64(dst, t64); - } - - s32 = (uint32_t *) s64; - for (n = 0; n < nbuckets; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - srcsz -= sz; - dsz -= sz; - - /* Copy out the hash chains. */ - if (dsz < srcsz) - return (0); - - nchains = srcsz / sizeof(uint32_t); - for (n = 0; n < nchains; n++) { - t32 = *s32++; - if (byteswap) - SWAP_WORD(t32); - WRITE_WORD(dst, t32); - } - - return (1); -} - -/* - * Elf_Note structures comprise a fixed size header followed by variable - * length strings. The fixed size header needs to be byte swapped, but - * not the strings. - * - * Argument `count' denotes the total number of bytes to be converted. - * The destination buffer needs to be at least `count' bytes in size. - */ -static int -libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz, hdrsz; - - if (dsz < count) /* Destination buffer is too small. */ - return (0); - - hdrsz = 3 * sizeof(uint32_t); - if (count < hdrsz) /* Source too small. */ - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - /* Process all notes in the section. */ - while (count > hdrsz) { - /* Read the note header. */ - READ_WORD(src, namesz); - READ_WORD(src, descsz); - READ_WORD(src, type); - - /* Translate. */ - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - /* Copy out the translated note header. */ - en = (Elf_Note *) (uintptr_t) dst; - en->n_namesz = namesz; - en->n_descsz = descsz; - en->n_type = type; - - dsz -= sizeof(Elf_Note); - dst += sizeof(Elf_Note); - count -= hdrsz; - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz || dsz < sz) /* Buffers are too small. */ - return (0); - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - - count -= sz; - dsz -= sz; - } - - return (1); -} - -static int -libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) -{ - uint32_t namesz, descsz, type; - Elf_Note *en; - size_t sz; - - if (dsz < count) - return (0); - - if (!byteswap) { - (void) memcpy(dst, src, count); - return (1); - } - - while (count > sizeof(Elf_Note)) { - - en = (Elf_Note *) (uintptr_t) src; - namesz = en->n_namesz; - descsz = en->n_descsz; - type = en->n_type; - - SWAP_WORD(namesz); - SWAP_WORD(descsz); - SWAP_WORD(type); - - WRITE_WORD(dst, namesz); - WRITE_WORD(dst, descsz); - WRITE_WORD(dst, type); - - src += sizeof(Elf_Note); - - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); - - sz = namesz + descsz; - - if (count < sz) - sz = count; - - (void) memcpy(dst, src, sz); - - src += sz; - dst += sz; - count -= sz; - } - - return (1); -} - -struct converters { - int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); - int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt, - int byteswap); -}; - - -static struct converters cvt[ELF_T_NUM] = { - /*[*/ -CONVERTER_NAMES(ELF_TYPE_LIST) - /*]*/ - - /* - * Types that need hand-coded converters follow. - */ - - [ELF_T_BYTE] = { - .tof32 = libelf_cvt_BYTE_tox, - .tom32 = libelf_cvt_BYTE_tox, - .tof64 = libelf_cvt_BYTE_tox, - .tom64 = libelf_cvt_BYTE_tox - }, - - [ELF_T_NOTE] = { - .tof32 = libelf_cvt_NOTE_tof, - .tom32 = libelf_cvt_NOTE_tom, - .tof64 = libelf_cvt_NOTE_tof, - .tom64 = libelf_cvt_NOTE_tom - } -}; - -int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) -{ - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (t >= ELF_T_NUM || - (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || - (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) - return (NULL); - - return ((elfclass == ELFCLASS32) ? - (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : - (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); -} diff --git a/linkers/elftoolchain/libelf/libelf_data.c b/linkers/elftoolchain/libelf/libelf_data.c deleted file mode 100644 index 8044c74..0000000 --- a/linkers/elftoolchain/libelf/libelf_data.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_data.c 1264 2010-11-12 14:53:23Z jkoshy $"); - -int -_libelf_xlate_shtype(uint32_t sht) -{ - switch (sht) { - case SHT_DYNAMIC: - return (ELF_T_DYN); - case SHT_DYNSYM: - return (ELF_T_SYM); - case SHT_FINI_ARRAY: - return (ELF_T_ADDR); - case SHT_GNU_HASH: - return (ELF_T_GNUHASH); - case SHT_GNU_LIBLIST: - return (ELF_T_WORD); - case SHT_GROUP: - return (ELF_T_WORD); - case SHT_HASH: - return (ELF_T_WORD); - case SHT_INIT_ARRAY: - return (ELF_T_ADDR); - case SHT_NOBITS: - return (ELF_T_BYTE); - case SHT_NOTE: - return (ELF_T_NOTE); - case SHT_PREINIT_ARRAY: - return (ELF_T_ADDR); - case SHT_PROGBITS: - return (ELF_T_BYTE); - case SHT_REL: - return (ELF_T_REL); - case SHT_RELA: - return (ELF_T_RELA); - case SHT_STRTAB: - return (ELF_T_BYTE); - case SHT_SYMTAB: - return (ELF_T_SYM); - case SHT_SYMTAB_SHNDX: - return (ELF_T_WORD); - case SHT_SUNW_dof: - return (ELF_T_BYTE); - case SHT_SUNW_move: - return (ELF_T_MOVE); - case SHT_SUNW_syminfo: - return (ELF_T_SYMINFO); - case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ - return (ELF_T_VDEF); - case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ - return (ELF_T_VNEED); - case SHT_SUNW_versym: /* == SHT_GNU_versym */ - return (ELF_T_HALF); - default: - return (-1); - } -} diff --git a/linkers/elftoolchain/libelf/libelf_ehdr.c b/linkers/elftoolchain/libelf/libelf_ehdr.c deleted file mode 100644 index affe541..0000000 --- a/linkers/elftoolchain/libelf/libelf_ehdr.c +++ /dev/null @@ -1,204 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_ehdr.c 1677 2011-07-28 04:35:53Z jkoshy $"); - -/* - * Retrieve counts for sections, phdrs and the section string table index - * from section header #0 of the ELF object. - */ -static int -_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, - uint16_t strndx) -{ - Elf_Scn *scn; - size_t fsz; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - uint32_t shtype; - - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); - - fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); - assert(fsz > 0); - - if (e->e_rawsize < shoff + fsz) { /* raw file too small */ - LIBELF_SET_ERROR(HEADER, 0); - return (0); - } - - if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) - return (0); - - xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), - e->e_rawfile + shoff, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - -#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ - scn->s_shdr.s_shdr64.M) - - if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { - LIBELF_SET_ERROR(SECTION, 0); - return (0); - } - - e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); - e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : - GET_SHDR_MEMBER(sh_info); - e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : - GET_SHDR_MEMBER(sh_link); -#undef GET_SHDR_MEMBER - - return (1); -} - -#define EHDR_INIT(E,SZ) do { \ - Elf##SZ##_Ehdr *eh = (E); \ - eh->e_ident[EI_MAG0] = ELFMAG0; \ - eh->e_ident[EI_MAG1] = ELFMAG1; \ - eh->e_ident[EI_MAG2] = ELFMAG2; \ - eh->e_ident[EI_MAG3] = ELFMAG3; \ - eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ - eh->e_ident[EI_DATA] = ELFDATANONE; \ - eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ - eh->e_machine = EM_NONE; \ - eh->e_type = ELF_K_NONE; \ - eh->e_version = LIBELF_PRIVATE(version); \ - } while (0) - -void * -_libelf_ehdr(Elf *e, int ec, int allocate) -{ - void *ehdr; - size_t fsz, msz; - uint16_t phnum, shnum, strndx; - uint64_t shoff; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL || e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (e->e_class != ELFCLASSNONE && e->e_class != ec) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - if (e->e_version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (NULL); - } - - if (e->e_class == ELFCLASSNONE) - e->e_class = ec; - - if (ec == ELFCLASS32) - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; - else - ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; - - if (ehdr != NULL) /* already have a translated ehdr */ - return (ehdr); - - fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); - assert(fsz > 0); - - if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((ehdr = calloc((size_t) 1, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; - EHDR_INIT(ehdr,32); - } else { - e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; - EHDR_INIT(ehdr,64); - } - - if (allocate) - e->e_flags |= ELF_F_DIRTY; - - if (e->e_cmd == ELF_C_WRITE) - return (ehdr); - - xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); - (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - /* - * If extended numbering is being used, read the correct - * number of sections and program header entries. - */ - if (ec == ELFCLASS32) { - phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; - } else { - phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; - shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; - shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; - strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; - } - - if (shnum >= SHN_LORESERVE || - (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || - strndx == SHN_XINDEX))) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ - e->e_u.e_elf.e_nphdr = phnum; - e->e_u.e_elf.e_nscn = shnum; - e->e_u.e_elf.e_strndx = strndx; - } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) - return (NULL); - - return (ehdr); -} diff --git a/linkers/elftoolchain/libelf/libelf_extended.c b/linkers/elftoolchain/libelf/libelf_extended.c deleted file mode 100644 index 10590bb..0000000 --- a/linkers/elftoolchain/libelf/libelf_extended.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_extended.c 1360 2011-01-08 08:27:41Z jkoshy $"); - -/* - * Retrieve section #0, allocating a new section if needed. - */ -static Elf_Scn * -_libelf_getscn0(Elf *e) -{ - Elf_Scn *s; - - if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) - return (s); - - return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); -} - -int -_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) -{ - Elf_Scn *scn; - - if (shnum >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_size = shnum; - else - scn->s_shdr.s_shdr64.sh_size = shnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shnum = 0; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shnum = shnum; - else - ((Elf64_Ehdr *) eh)->e_shnum = shnum; - - - return (1); -} - -int -_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) -{ - Elf_Scn *scn; - - if (shstrndx >= SHN_LORESERVE) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_link = shstrndx; - else - scn->s_shdr.s_shdr64.sh_link = shstrndx; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - shstrndx = SHN_XINDEX; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; - else - ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; - - return (1); -} - -int -_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) -{ - Elf_Scn *scn; - - if (phnum >= PN_XNUM) { - if ((scn = _libelf_getscn0(e)) == NULL) - return (0); - - assert(scn->s_ndx == SHN_UNDEF); - - if (ec == ELFCLASS32) - scn->s_shdr.s_shdr32.sh_info = phnum; - else - scn->s_shdr.s_shdr64.sh_info = phnum; - - (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); - - phnum = PN_XNUM; - } - - if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_phnum = phnum; - else - ((Elf64_Ehdr *) eh)->e_phnum = phnum; - - return (1); -} diff --git a/linkers/elftoolchain/libelf/libelf_fsize.m4 b/linkers/elftoolchain/libelf/libelf_fsize.m4 deleted file mode 100644 index 4829789..0000000 --- a/linkers/elftoolchain/libelf/libelf_fsize.m4 +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_fsize.m4 1724 2011-08-13 05:35:42Z jkoshy $"); - -/* WARNING: GENERATED FROM __file__. */ - -/* - * Create an array of file sizes from the elf_type definitions - */ - -divert(-1) -include(SRCDIR`/elf_types.m4') - -/* - * Translations from structure definitions to the size of their file - * representations. - */ - -/* `Basic' types. */ -define(`BYTE_SIZE', 1) -define(`IDENT_SIZE', `EI_NIDENT') - -/* Types that have variable length. */ -define(`GNUHASH_SIZE', 1) -define(`NOTE_SIZE', 1) -define(`VDEF_SIZE', 1) -define(`VNEED_SIZE', 1) - -/* Currently unimplemented types. */ -define(`MOVEP_SIZE', 0) - -/* Overrides for 32 bit types that do not exist. */ -define(`XWORD_SIZE32', 0) -define(`SXWORD_SIZE32', 0) - -/* - * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. - */ - -define(`FSZ32',`_FSZ32($1_DEF)') -define(`_FSZ32', - `ifelse($#,1,0, - `_BSZ32($1)+_FSZ32(shift($@))')') -define(`_BSZ32',`$2_SIZE32') - -define(`FSZ64',`_FSZ64($1_DEF)') -define(`_FSZ64', - `ifelse($#,1,0, - `_BSZ64($1)+_FSZ64(shift($@))')') -define(`_BSZ64',`$2_SIZE64') - -/* - * DEFINE_ELF_FSIZES(TYPE,NAME) - * - * Shorthand for defining for 32 and 64 versions - * of elf type TYPE. - * - * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit - * sizes. - * - * Otherwise, look for a explicit 32/64 bit size definition for TYPE, - * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there - * is nothing further to do. - * - * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, - * compute an expression that adds up the sizes of the structure's - * constituents. - * - * If such a structure definition is not known, treat TYPE as a primitive - * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its - * file representation size. - */ - -define(`DEFINE_ELF_FSIZE', - `ifdef($1`_SIZE', - `define($1_SIZE32,$1_SIZE) - define($1_SIZE64,$1_SIZE)', - `ifdef($1`_SIZE32',`', - `ifdef(`Elf32_'$2`_DEF', - `define($1_SIZE32,FSZ32(Elf32_$2))', - `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') - ifdef($1`_SIZE64',`', - `ifdef(`Elf64_'$2`_DEF', - `define($1_SIZE64,FSZ64(Elf64_$2))', - `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') - -define(`DEFINE_ELF_FSIZES', - `ifelse($#,1,`', - `DEFINE_ELF_FSIZE($1) - DEFINE_ELF_FSIZES(shift($@))')') - -DEFINE_ELF_FSIZES(ELF_TYPE_LIST) -DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type - -define(`FSIZE', - `[ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, -') -define(`FSIZES', - `ifelse($#,1,`', - `FSIZE($1) -FSIZES(shift($@))')') - -divert(0) - -struct fsize { - size_t fsz32; - size_t fsz64; -}; - -static struct fsize fsize[ELF_T_NUM] = { -FSIZES(ELF_TYPE_LIST) -}; - -size_t -_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) -{ - size_t sz; - - sz = 0; - if (v != EV_CURRENT) - LIBELF_SET_ERROR(VERSION, 0); - else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) - LIBELF_SET_ERROR(ARGUMENT, 0); - else { - sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; - if (sz == 0) - LIBELF_SET_ERROR(UNIMPL, 0); - } - - return (sz*c); -} diff --git a/linkers/elftoolchain/libelf/libelf_msize.m4 b/linkers/elftoolchain/libelf/libelf_msize.m4 deleted file mode 100644 index 95621fb..0000000 --- a/linkers/elftoolchain/libelf/libelf_msize.m4 +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2006,2008-2011 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_msize.m4 1724 2011-08-13 05:35:42Z jkoshy $"); - -/* WARNING: GENERATED FROM __file__. */ - -struct msize { - size_t msz32; - size_t msz64; -}; - -divert(-1) -include(SRCDIR`/elf_types.m4') - -/* - * ELF types whose memory representations have a variable size. - */ -define(BYTE_SIZE, 1) -define(GNUHASH_SIZE, 1) -define(NOTE_SIZE, 1) -define(VDEF_SIZE, 1) -define(VNEED_SIZE, 1) - -/* - * Unimplemented types. - */ -define(MOVEP_SIZE, 0) -define(SXWORD_SIZE32, 0) -define(XWORD_SIZE32, 0) - -define(`DEFINE_ELF_MSIZE', - `ifdef($1`_SIZE', - `define($1_SIZE32,$1_SIZE) - define($1_SIZE64,$1_SIZE)', - `ifdef($1`_SIZE32',`', - `define($1_SIZE32,sizeof(Elf32_$2))') - ifdef($1`_SIZE64',`', - `define($1_SIZE64,sizeof(Elf64_$2))')')') -define(`DEFINE_ELF_MSIZES', - `ifelse($#,1,`', - `DEFINE_ELF_MSIZE($1) - DEFINE_ELF_MSIZES(shift($@))')') - -DEFINE_ELF_MSIZES(ELF_TYPE_LIST) - -define(`MSIZE', - `[ELF_T_$1] = { .msz32 = $1_SIZE32, .msz64 = $1_SIZE64 }, -') -define(`MSIZES', - `ifelse($#,1,`', - `MSIZE($1) -MSIZES(shift($@))')') - -divert(0) - -static struct msize msize[ELF_T_NUM] = { -MSIZES(ELF_TYPE_LIST) -}; - -size_t -_libelf_msize(Elf_Type t, int elfclass, unsigned int version) -{ - size_t sz; - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); - - if (version != EV_CURRENT) { - LIBELF_SET_ERROR(VERSION, 0); - return (0); - } - - sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; - - return (sz); -} diff --git a/linkers/elftoolchain/libelf/libelf_phdr.c b/linkers/elftoolchain/libelf/libelf_phdr.c deleted file mode 100644 index 5a5bb5f..0000000 --- a/linkers/elftoolchain/libelf/libelf_phdr.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_phdr.c 1677 2011-07-28 04:35:53Z jkoshy $"); - -void * -_libelf_getphdr(Elf *e, int ec) -{ - size_t phnum, phentsize; - size_t fsz, msz; - uint64_t phoff; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; - void *ehdr, *phdr; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((phdr = (ec == ELFCLASS32 ? - (void *) e->e_u.e_elf.e_phdr.e_phdr32 : - (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) - return (phdr); - - /* - * Check the PHDR related fields in the EHDR for sanity. - */ - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) - return (NULL); - - phnum = e->e_u.e_elf.e_nphdr; - - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - phentsize = eh32->e_phentsize; - phoff = (uint64_t) eh32->e_phoff; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - phentsize = eh64->e_phentsize; - phoff = (uint64_t) eh64->e_phoff; - } - - fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); - - assert(fsz > 0); - - if ((uint64_t) e->e_rawsize < (phoff + fsz)) { - LIBELF_SET_ERROR(HEADER, 0); - return (NULL); - } - - msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); - - assert(msz > 0); - - if ((phdr = calloc(phnum, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) - e->e_u.e_elf.e_phdr.e_phdr32 = phdr; - else - e->e_u.e_elf.e_phdr.e_phdr64 = phdr; - - - xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec); - (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - - return (phdr); -} - -void * -_libelf_newphdr(Elf *e, int ec, size_t count) -{ - void *ehdr, *newphdr, *oldphdr; - size_t msz; - - if (e == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { - LIBELF_SET_ERROR(SEQUENCE, 0); - return (NULL); - } - - assert(e->e_class == ec); - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - assert(e->e_version == EV_CURRENT); - - msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version); - - assert(msz > 0); - - newphdr = NULL; - if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { - LIBELF_SET_ERROR(RESOURCE, 0); - return (NULL); - } - - if (ec == ELFCLASS32) { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; - } else { - if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) - free(oldphdr); - e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; - } - - e->e_u.e_elf.e_nphdr = count; - - elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - - return (newphdr); -} diff --git a/linkers/elftoolchain/libelf/libelf_shdr.c b/linkers/elftoolchain/libelf/libelf_shdr.c deleted file mode 100644 index a696cef..0000000 --- a/linkers/elftoolchain/libelf/libelf_shdr.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_shdr.c 189 2008-07-20 10:38:08Z jkoshy $"); - -void * -_libelf_getshdr(Elf_Scn *s, int ec) -{ - Elf *e; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - if (ec == ELFCLASSNONE) - ec = e->e_class; - - if (ec != e->e_class) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - return ((void *) &s->s_shdr); -} diff --git a/linkers/elftoolchain/libelf/libelf_xlate.c b/linkers/elftoolchain/libelf/libelf_xlate.c deleted file mode 100644 index ace4e09..0000000 --- a/linkers/elftoolchain/libelf/libelf_xlate.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * Copyright (c) 2006,2008 Joseph Koshy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "_libelf.h" - -LIBELF_VCSID("$Id: libelf_xlate.c 316 2009-02-28 16:08:44Z jkoshy $"); - -/* - * Translate to/from the file representation of ELF objects. - * - * Translation could potentially involve the following - * transformations: - * - * - an endianness conversion, - * - a change of layout, as the file representation of ELF objects - * can differ from their in-memory representation. - * - a change in representation due to a layout version change. - */ - -Elf_Data * -_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, - int elfclass, int direction) -{ - int byteswap; - size_t cnt, dsz, fsz, msz; - uintptr_t sb, se, db, de; - - if (encoding == ELFDATANONE) - encoding = LIBELF_PRIVATE(byteorder); - - if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || - dst == NULL || src == NULL || dst == src) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); - assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); - - if (dst->d_version != src->d_version) { - LIBELF_SET_ERROR(UNIMPL, 0); - return (NULL); - } - - if (src->d_buf == NULL || dst->d_buf == NULL) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) - (src->d_type, (size_t) 1, src->d_version)) == 0) - return (NULL); - - msz = _libelf_msize(src->d_type, elfclass, src->d_version); - - assert(msz > 0); - - if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - /* - * Determine the number of objects that need to be converted, and - * the space required for the converted objects in the destination - * buffer. - */ - if (direction == ELF_TOMEMORY) { - cnt = src->d_size / fsz; - dsz = cnt * msz; - } else { - cnt = src->d_size / msz; - dsz = cnt * fsz; - } - - if (dst->d_size < dsz) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - sb = (uintptr_t) src->d_buf; - se = sb + src->d_size; - db = (uintptr_t) dst->d_buf; - de = db + dst->d_size; - - /* - * Check for overlapping buffers. Note that db == sb is - * allowed. - */ - if (db != sb && de > sb && se > db) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - if ((direction == ELF_TOMEMORY ? db : sb) % - _libelf_malign(src->d_type, elfclass)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - dst->d_type = src->d_type; - dst->d_size = dsz; - - byteswap = encoding != LIBELF_PRIVATE(byteorder); - - if (src->d_size == 0 || - (db == sb && !byteswap && fsz == msz)) - return (dst); /* nothing more to do */ - - if (!(_libelf_get_translator(src->d_type, direction, elfclass)) - (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { - LIBELF_SET_ERROR(DATA, 0); - return (NULL); - } - - return (dst); -} diff --git a/linkers/elftoolchain/libelf/mmap_win32.c b/linkers/elftoolchain/libelf/mmap_win32.c deleted file mode 100644 index f801fc6..0000000 --- a/linkers/elftoolchain/libelf/mmap_win32.c +++ /dev/null @@ -1,247 +0,0 @@ -/*- - * Copyright (c) 2011 Chris Johns - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Basic mmap/munmap set of functions that allows software that needs to use - * these functions to work without changing. Currently only the basic read - * has been tested. - * - * The basic was taken from the implementation in Python 3.x by Sam Rushing - * . - */ - -#ifndef __WIN32__ -#error "Wrong OS; only for WIN32" -#endif - -#include -#include -#include - -/* - * Bring in the local mman.h header to make sure the interface is in sync. - */ -#include - -/* - * The data for each map. Maintained as a list. If performance is important maybe - * some other container can be used. - */ -typedef struct mmap_data_s -{ - struct mmap_data_s* next; - void* data; - HANDLE file_handle; - HANDLE map_handle; - size_t size; - off_t offset; -} mmap_data; - -/* - * Head of the map list. - */ -static mmap_data* map_head; - -void* -mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset) -{ - mmap_data* map = NULL; - DWORD flProtect; - DWORD dwDesiredAccess; - HANDLE fh = 0; - DWORD dwErr = 0; - DWORD size_lo; - DWORD size_hi; - DWORD off_lo; - DWORD off_hi; - uint64_t size = 0; - - if ((fd == 0) || (fd == -1)) - return MAP_FAILED; - - /* - * Not implemented. Patches welcome. - */ - if (prot & PROT_EXEC) - return MAP_FAILED; - - /* - * Map the protection. - */ - if ((prot & PROT_READ) == PROT_READ) - { - flProtect = PAGE_READONLY; - dwDesiredAccess = FILE_MAP_READ; - } - if ((prot & PROT_WRITE) == PROT_WRITE) - { - flProtect = PAGE_WRITECOPY; - dwDesiredAccess = FILE_MAP_WRITE; - } - if ((prot & (PROT_READ | PROT_WRITE)) == (PROT_READ | PROT_WRITE)) - { - flProtect = PAGE_READWRITE; - dwDesiredAccess = FILE_MAP_WRITE; - } - - fh = (HANDLE) _get_osfhandle (fd); - if (fh == (HANDLE) -1) - return MAP_FAILED; - - /* - * Win9x appears to need us seeked to zero. - */ - lseek (fd, 0, SEEK_SET); - - /* - * Allocate the space to handle the mapping. - */ - map = malloc (sizeof (mmap_data)); - if (!map) - return MAP_FAILED; - - map->next = NULL; - map->data = NULL; - map->file_handle = fh; - map->map_handle = NULL; - map->offset = offset; - - if (len == 0) - { - DWORD low; - DWORD high; - - low = GetFileSize (fh, &high); - - /* - * Low might just happen to have the value INVALID_FILE_SIZE; so we need to - * check the last error also. - */ - if ((low == INVALID_FILE_SIZE) && (dwErr = GetLastError()) != NO_ERROR) - { - free (map); - return MAP_FAILED; - } - - size = (((uint64_t) high) << 32) + low; - - if (offset >= size) - { - free (map); - return MAP_FAILED; - } - - if (offset - size > (size_t) -1LL) - /* Map area too large to fit in memory */ - map->size = (size_t) -1; - else - map->size = (size_t) (size - offset); - } - else - { - map->size = len; - size = offset + len; - } - - size_hi = (DWORD)(size >> 32); - size_lo = (DWORD)(size & 0xFFFFFFFF); - off_hi = (DWORD)(0); - off_lo = (DWORD)(offset & 0xFFFFFFFF); - - /* - * For files, it would be sufficient to pass 0 as size. For anonymous maps, - * we have to pass the size explicitly. - */ - map->map_handle = CreateFileMapping (map->file_handle, - NULL, - flProtect, - size_hi, - size_lo, - NULL); - if (!map->map_handle) - { - free (map); - return MAP_FAILED; - } - - map->data = (char *) MapViewOfFileEx (map->map_handle, - dwDesiredAccess, - off_hi, - off_lo, - map->size, - addr); - if (!map->data) - { - CloseHandle (map->map_handle); - free (map); - return MAP_FAILED; - } - - /* - * Add to the list. - */ - map->next = map_head; - map_head = map; - - return map->data; -} - -int -munmap (void* addr, size_t len) -{ - mmap_data* map = map_head; - mmap_data** prev_next = &map_head; - - /* - * Find the map and remove from the list. - */ - while (map) - { - if (map->data == addr) - { - *prev_next = map->next; - break; - } - prev_next = &map->next; - map = map->next; - } - - if (!map) - { - errno = EINVAL; - return -1; - } - - if (map->data != NULL) - UnmapViewOfFile (map->data); - if (map->map_handle != NULL) - CloseHandle (map->map_handle); - - free (map); - - errno = 0; - return 0; -} diff --git a/linkers/elftoolchain/libelf/os.FreeBSD.mk b/linkers/elftoolchain/libelf/os.FreeBSD.mk deleted file mode 100644 index 72834b7..0000000 --- a/linkers/elftoolchain/libelf/os.FreeBSD.mk +++ /dev/null @@ -1,7 +0,0 @@ -# -# Building for a FreeBSD target. -# -# $Id: os.FreeBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ - -# Symbol versioning support [FreeBSD 7.X and later] -VERSION_MAP= ${.CURDIR}/Version.map diff --git a/linkers/elftoolchain/libelf/os.NetBSD.mk b/linkers/elftoolchain/libelf/os.NetBSD.mk deleted file mode 100644 index 96b8335..0000000 --- a/linkers/elftoolchain/libelf/os.NetBSD.mk +++ /dev/null @@ -1,7 +0,0 @@ -# -# Build recipes for NetBSD. -# -# $Id: os.NetBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ -# - -MKLINT= no # lint dies with a sigbus diff --git a/linkers/fastlz.c b/linkers/fastlz.c deleted file mode 100644 index 3c9d6f6..0000000 --- a/linkers/fastlz.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - FastLZ - lightning-fast lossless compression library - - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) - -/* - * Always check for bound when decompressing. - * Generally it is best to leave it defined. - */ -#define FASTLZ_SAFE - -/* - * Give hints to the compiler for branch prediction optimization. - */ -#if defined(__GNUC__) && (__GNUC__ > 2) -#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) -#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) -#else -#define FASTLZ_EXPECT_CONDITIONAL(c) (c) -#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) -#endif - -/* - * Use inlined functions for supported systems. - */ -#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) -#define FASTLZ_INLINE inline -#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) -#define FASTLZ_INLINE __inline -#else -#define FASTLZ_INLINE -#endif - -/* - * Prevent accessing more than 8-bit at once, except on x86 architectures. - */ -#if !defined(FASTLZ_STRICT_ALIGN) -#define FASTLZ_STRICT_ALIGN -#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(_M_IX86) /* Intel, MSVC */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__386) -#undef FASTLZ_STRICT_ALIGN -#elif defined(_X86_) /* MinGW */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__I86__) /* Digital Mars */ -#undef FASTLZ_STRICT_ALIGN -#endif -#endif - -/* - * FIXME: use preprocessor magic to set this on different platforms! - */ -typedef unsigned char flzuint8; -typedef unsigned short flzuint16; -typedef unsigned int flzuint32; - -/* prototypes */ -int fastlz_compress(const void* input, int length, void* output); -int fastlz_compress_level(int level, const void* input, int length, void* output); -int fastlz_decompress(const void* input, int length, void* output, int maxout); - -#define MAX_COPY 32 -#define MAX_LEN 264 /* 256 + 8 */ -#define MAX_DISTANCE 8192 - -#if !defined(FASTLZ_STRICT_ALIGN) -#define FASTLZ_READU16(p) *((const flzuint16*)(p)) -#else -#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) -#endif - -#define HASH_LOG 13 -#define HASH_SIZE (1<< HASH_LOG) -#define HASH_MASK (HASH_SIZE-1) -#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } - -#undef FASTLZ_LEVEL -#define FASTLZ_LEVEL 1 - -#undef FASTLZ_COMPRESSOR -#undef FASTLZ_DECOMPRESSOR -#define FASTLZ_COMPRESSOR fastlz1_compress -#define FASTLZ_DECOMPRESSOR fastlz1_decompress -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); -#include "fastlz.c" - -#undef FASTLZ_LEVEL -#define FASTLZ_LEVEL 2 - -#undef MAX_DISTANCE -#define MAX_DISTANCE 8191 -#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) - -#undef FASTLZ_COMPRESSOR -#undef FASTLZ_DECOMPRESSOR -#define FASTLZ_COMPRESSOR fastlz2_compress -#define FASTLZ_DECOMPRESSOR fastlz2_decompress -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); -#include "fastlz.c" - -int fastlz_compress(const void* input, int length, void* output) -{ - /* for short block, choose fastlz1 */ - if(length < 65536) - return fastlz1_compress(input, length, output); - - /* else... */ - return fastlz2_compress(input, length, output); -} - -int fastlz_decompress(const void* input, int length, void* output, int maxout) -{ - /* magic identifier for compression level */ - int level = ((*(const flzuint8*)input) >> 5) + 1; - - if(level == 1) - return fastlz1_decompress(input, length, output, maxout); - if(level == 2) - return fastlz2_decompress(input, length, output, maxout); - - /* unknown level, trigger error */ - return 0; -} - -int fastlz_compress_level(int level, const void* input, int length, void* output) -{ - if(level == 1) - return fastlz1_compress(input, length, output); - if(level == 2) - return fastlz2_compress(input, length, output); - - return 0; -} - -#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ - -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) -{ - const flzuint8* ip = (const flzuint8*) input; - const flzuint8* ip_bound = ip + length - 2; - const flzuint8* ip_limit = ip + length - 12; - flzuint8* op = (flzuint8*) output; - - const flzuint8* htab[HASH_SIZE]; - const flzuint8** hslot; - flzuint32 hval; - - flzuint32 copy; - - /* sanity check */ - if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) - { - if(length) - { - /* create literal copy only */ - *op++ = length-1; - ip_bound++; - while(ip <= ip_bound) - *op++ = *ip++; - return length+1; - } - else - return 0; - } - - /* initializes hash table */ - for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) - *hslot = ip; - - /* we start with literal copy */ - copy = 2; - *op++ = MAX_COPY-1; - *op++ = *ip++; - *op++ = *ip++; - - /* main loop */ - while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) - { - const flzuint8* ref; - flzuint32 distance; - - /* minimum match length */ - flzuint32 len = 3; - - /* comparison starting-point */ - const flzuint8* anchor = ip; - - /* check for a run */ -#if FASTLZ_LEVEL==2 - if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) - { - distance = 1; - ip += 3; - ref = anchor - 1 + 3; - goto match; - } -#endif - - /* find potential match */ - HASH_FUNCTION(hval,ip); - hslot = htab + hval; - ref = htab[hval]; - - /* calculate distance to the match */ - distance = anchor - ref; - - /* update hash table */ - *hslot = anchor; - - /* is this a match? check the first 3 bytes */ - if(distance==0 || -#if FASTLZ_LEVEL==1 - (distance >= MAX_DISTANCE) || -#else - (distance >= MAX_FARDISTANCE) || -#endif - *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) - goto literal; - -#if FASTLZ_LEVEL==2 - /* far, needs at least 5-byte match */ - if(distance >= MAX_DISTANCE) - { - if(*ip++ != *ref++ || *ip++!= *ref++) - goto literal; - len += 2; - } - - match: -#endif - - /* last matched byte */ - ip = anchor + len; - - /* distance is biased */ - distance--; - - if(!distance) - { - /* zero distance means a run */ - flzuint8 x = ip[-1]; - while(ip < ip_bound) - if(*ref++ != x) break; else ip++; - } - else - for(;;) - { - /* safe because the outer check against ip limit */ - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - while(ip < ip_bound) - if(*ref++ != *ip++) break; - break; - } - - /* if we have copied something, adjust the copy count */ - if(copy) - /* copy is biased, '0' means 1 byte copy */ - *(op-copy-1) = copy-1; - else - /* back, to overwrite the copy count */ - op--; - - /* reset literal counter */ - copy = 0; - - /* length is biased, '1' means a match of 3 bytes */ - ip -= 3; - len = ip - anchor; - - /* encode the match */ -#if FASTLZ_LEVEL==2 - if(distance < MAX_DISTANCE) - { - if(len < 7) - { - *op++ = (len << 5) + (distance >> 8); - *op++ = (distance & 255); - } - else - { - *op++ = (7 << 5) + (distance >> 8); - for(len-=7; len >= 255; len-= 255) - *op++ = 255; - *op++ = len; - *op++ = (distance & 255); - } - } - else - { - /* far away, but not yet in the another galaxy... */ - if(len < 7) - { - distance -= MAX_DISTANCE; - *op++ = (len << 5) + 31; - *op++ = 255; - *op++ = distance >> 8; - *op++ = distance & 255; - } - else - { - distance -= MAX_DISTANCE; - *op++ = (7 << 5) + 31; - for(len-=7; len >= 255; len-= 255) - *op++ = 255; - *op++ = len; - *op++ = 255; - *op++ = distance >> 8; - *op++ = distance & 255; - } - } -#else - - if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) - while(len > MAX_LEN-2) - { - *op++ = (7 << 5) + (distance >> 8); - *op++ = MAX_LEN - 2 - 7 -2; - *op++ = (distance & 255); - len -= MAX_LEN-2; - } - - if(len < 7) - { - *op++ = (len << 5) + (distance >> 8); - *op++ = (distance & 255); - } - else - { - *op++ = (7 << 5) + (distance >> 8); - *op++ = len - 7; - *op++ = (distance & 255); - } -#endif - - /* update the hash at match boundary */ - HASH_FUNCTION(hval,ip); - htab[hval] = ip++; - HASH_FUNCTION(hval,ip); - htab[hval] = ip++; - - /* assuming literal copy */ - *op++ = MAX_COPY-1; - - continue; - - literal: - *op++ = *anchor++; - ip = anchor; - copy++; - if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) - { - copy = 0; - *op++ = MAX_COPY-1; - } - } - - /* left-over as literal copy */ - ip_bound++; - while(ip <= ip_bound) - { - *op++ = *ip++; - copy++; - if(copy == MAX_COPY) - { - copy = 0; - *op++ = MAX_COPY-1; - } - } - - /* if we have copied something, adjust the copy length */ - if(copy) - *(op-copy-1) = copy-1; - else - op--; - -#if FASTLZ_LEVEL==2 - /* marker for fastlz2 */ - *(flzuint8*)output |= (1 << 5); -#endif - - return op - (flzuint8*)output; -} - -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) -{ - const flzuint8* ip = (const flzuint8*) input; - const flzuint8* ip_limit = ip + length; - flzuint8* op = (flzuint8*) output; - flzuint8* op_limit = op + maxout; - flzuint32 ctrl = (*ip++) & 31; - int loop = 1; - - do - { - const flzuint8* ref = op; - flzuint32 len = ctrl >> 5; - flzuint32 ofs = (ctrl & 31) << 8; - - if(ctrl >= 32) - { -#if FASTLZ_LEVEL==2 - flzuint8 code; -#endif - len--; - ref -= ofs; - if (len == 7-1) -#if FASTLZ_LEVEL==1 - len += *ip++; - ref -= *ip++; -#else - do - { - code = *ip++; - len += code; - } while (code==255); - code = *ip++; - ref -= code; - - /* match from 16-bit distance */ - if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) - if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) - { - ofs = (*ip++) << 8; - ofs += *ip++; - ref = op - ofs - MAX_DISTANCE; - } -#endif - -#ifdef FASTLZ_SAFE - if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) - return 0; - - if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) - return 0; -#endif - - if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) - ctrl = *ip++; - else - loop = 0; - - if(ref == op) - { - /* optimize copy for a run */ - flzuint8 b = ref[-1]; - *op++ = b; - *op++ = b; - *op++ = b; - for(; len; --len) - *op++ = b; - } - else - { -#if !defined(FASTLZ_STRICT_ALIGN) - const flzuint16* p; - flzuint16* q; -#endif - /* copy from reference */ - ref--; - *op++ = *ref++; - *op++ = *ref++; - *op++ = *ref++; - -#if !defined(FASTLZ_STRICT_ALIGN) - /* copy a byte, so that now it's word aligned */ - if(len & 1) - { - *op++ = *ref++; - len--; - } - - /* copy 16-bit at once */ - q = (flzuint16*) op; - op += len; - p = (const flzuint16*) ref; - for(len>>=1; len > 4; len-=4) - { - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - } - for(; len; --len) - *q++ = *p++; -#else - for(; len; --len) - *op++ = *ref++; -#endif - } - } - else - { - ctrl++; -#ifdef FASTLZ_SAFE - if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) - return 0; - if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) - return 0; -#endif - - *op++ = *ip++; - for(--ctrl; ctrl; ctrl--) - *op++ = *ip++; - - loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); - if(loop) - ctrl = *ip++; - } - } - while(FASTLZ_EXPECT_CONDITIONAL(loop)); - - return op - (flzuint8*)output; -} - -#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ diff --git a/linkers/fastlz.h b/linkers/fastlz.h deleted file mode 100644 index f87bc7b..0000000 --- a/linkers/fastlz.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - FastLZ - lightning-fast lossless compression library - - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef FASTLZ_H -#define FASTLZ_H - -#define FASTLZ_VERSION 0x000100 - -#define FASTLZ_VERSION_MAJOR 0 -#define FASTLZ_VERSION_MINOR 0 -#define FASTLZ_VERSION_REVISION 0 - -#define FASTLZ_VERSION_STRING "0.1.0" - -#if defined (__cplusplus) -extern "C" { -#endif - -/** - Compress a block of data in the input buffer and returns the size of - compressed block. The size of input buffer is specified by length. The - minimum input buffer size is 16. - - The output buffer must be at least 5% larger than the input buffer - and can not be smaller than 66 bytes. - - If the input is not compressible, the return value might be larger than - length (input buffer size). - - The input buffer and the output buffer can not overlap. -*/ - -int fastlz_compress(const void* input, int length, void* output); - -/** - Decompress a block of compressed data and returns the size of the - decompressed block. If error occurs, e.g. the compressed data is - corrupted or the output buffer is not large enough, then 0 (zero) - will be returned instead. - - The input buffer and the output buffer can not overlap. - - Decompression is memory safe and guaranteed not to write the output buffer - more than what is specified in maxout. - */ - -int fastlz_decompress(const void* input, int length, void* output, int maxout); - -/** - Compress a block of data in the input buffer and returns the size of - compressed block. The size of input buffer is specified by length. The - minimum input buffer size is 16. - - The output buffer must be at least 5% larger than the input buffer - and can not be smaller than 66 bytes. - - If the input is not compressible, the return value might be larger than - length (input buffer size). - - The input buffer and the output buffer can not overlap. - - Compression level can be specified in parameter level. At the moment, - only level 1 and level 2 are supported. - Level 1 is the fastest compression and generally useful for short data. - Level 2 is slightly slower but it gives better compression ratio. - - Note that the compressed data, regardless of the level, can always be - decompressed using the function fastlz_decompress above. -*/ - -int fastlz_compress_level(int level, const void* input, int length, void* output); - -#if defined (__cplusplus) -} -#endif - -#endif /* FASTLZ_H */ diff --git a/linkers/libiberty/ansidecl.h b/linkers/libiberty/ansidecl.h deleted file mode 100644 index 86b0944..0000000 --- a/linkers/libiberty/ansidecl.h +++ /dev/null @@ -1,423 +0,0 @@ -/* ANSI and traditional C compatability macros - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2009 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* ANSI and traditional C compatibility macros - - ANSI C is assumed if __STDC__ is #defined. - - Macro ANSI C definition Traditional C definition - ----- ---- - ---------- ----------- - ---------- - ANSI_PROTOTYPES 1 not defined - PTR `void *' `char *' - PTRCONST `void *const' `char *' - LONG_DOUBLE `long double' `double' - const not defined `' - volatile not defined `' - signed not defined `' - VA_START(ap, var) va_start(ap, var) va_start(ap) - - Note that it is safe to write "void foo();" indicating a function - with no return value, in all K+R compilers we have been able to test. - - For declaring functions with prototypes, we also provide these: - - PARAMS ((prototype)) - -- for functions which take a fixed number of arguments. Use this - when declaring the function. When defining the function, write a - K+R style argument list. For example: - - char *strcpy PARAMS ((char *dest, char *source)); - ... - char * - strcpy (dest, source) - char *dest; - char *source; - { ... } - - - VPARAMS ((prototype, ...)) - -- for functions which take a variable number of arguments. Use - PARAMS to declare the function, VPARAMS to define it. For example: - - int printf PARAMS ((const char *format, ...)); - ... - int - printf VPARAMS ((const char *format, ...)) - { - ... - } - - For writing functions which take variable numbers of arguments, we - also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These - hide the differences between K+R and C89 more - thoroughly than the simple VA_START() macro mentioned above. - - VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. - Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls - corresponding to the list of fixed arguments. Then use va_arg - normally to get the variable arguments, or pass your va_list object - around. You do not declare the va_list yourself; VA_OPEN does it - for you. - - Here is a complete example: - - int - printf VPARAMS ((const char *format, ...)) - { - int result; - - VA_OPEN (ap, format); - VA_FIXEDARG (ap, const char *, format); - - result = vfprintf (stdout, format, ap); - VA_CLOSE (ap); - - return result; - } - - - You can declare variables either before or after the VA_OPEN, - VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning - and end of a block. They must appear at the same nesting level, - and any variables declared after VA_OPEN go out of scope at - VA_CLOSE. Unfortunately, with a K+R compiler, that includes the - argument list. You can have multiple instances of VA_OPEN/VA_CLOSE - pairs in a single function in case you need to traverse the - argument list more than once. - - For ease of writing code which uses GCC extensions but needs to be - portable to other compilers, we provide the GCC_VERSION macro that - simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various - wrappers around __attribute__. Also, __extension__ will be #defined - to nothing if it doesn't work. See below. - - This header also defines a lot of obsolete macros: - CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, - AND, DOTS, NOARGS. Don't use them. */ - -#ifndef _ANSIDECL_H -#define _ANSIDECL_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Every source file includes this file, - so they will all get the switch for lint. */ -/* LINTLIBRARY */ - -/* Using MACRO(x,y) in cpp #if conditionals does not work with some - older preprocessors. Thus we can't define something like this: - -#define HAVE_GCC_VERSION(MAJOR, MINOR) \ - (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) - -and then test "#if HAVE_GCC_VERSION(2,7)". - -So instead we use the macro below and test it against specific values. */ - -/* This macro simplifies testing whether we are using gcc, and if it - is of a particular minimum version. (Both major & minor numbers are - significant.) This macro will evaluate to 0 if we are not using - gcc at all. */ -#ifndef GCC_VERSION -#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) -#endif /* GCC_VERSION */ - -#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) -/* All known AIX compilers implement these things (but don't always - define __STDC__). The RISC/OS MIPS compiler defines these things - in SVR4 mode, but does not define __STDC__. */ -/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other - C++ compilers, does not define __STDC__, though it acts as if this - was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ - -#define ANSI_PROTOTYPES 1 -#define PTR void * -#define PTRCONST void *const -#define LONG_DOUBLE long double - -/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in - a #ifndef. */ -#ifndef PARAMS -#define PARAMS(ARGS) ARGS -#endif - -#define VPARAMS(ARGS) ARGS -#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) - -/* variadic function helper macros */ -/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's - use without inhibiting further decls and without declaring an - actual variable. */ -#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy -#define VA_CLOSE(AP) } va_end(AP); } -#define VA_FIXEDARG(AP, T, N) struct Qdmy - -#undef const -#undef volatile -#undef signed - -/* inline requires special treatment; it's in C99, and GCC >=2.7 supports - it too, but it's not in C89. */ -#undef inline -#if __STDC_VERSION__ > 199901L || defined(__cplusplus) -/* it's a keyword */ -#else -# if GCC_VERSION >= 2007 -# define inline __inline__ /* __inline__ prevents -pedantic warnings */ -# else -# define inline /* nothing */ -# endif -#endif - -/* These are obsolete. Do not use. */ -#ifndef IN_GCC -#define CONST const -#define VOLATILE volatile -#define SIGNED signed - -#define PROTO(type, name, arglist) type name arglist -#define EXFUN(name, proto) name proto -#define DEFUN(name, arglist, args) name(args) -#define DEFUN_VOID(name) name(void) -#define AND , -#define DOTS , ... -#define NOARGS void -#endif /* ! IN_GCC */ - -#else /* Not ANSI C. */ - -#undef ANSI_PROTOTYPES -#define PTR char * -#define PTRCONST PTR -#define LONG_DOUBLE double - -#define PARAMS(args) () -#define VPARAMS(args) (va_alist) va_dcl -#define VA_START(va_list, var) va_start(va_list) - -#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy -#define VA_CLOSE(AP) } va_end(AP); } -#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) - -/* some systems define these in header files for non-ansi mode */ -#undef const -#undef volatile -#undef signed -#undef inline -#define const -#define volatile -#define signed -#define inline - -#ifndef IN_GCC -#define CONST -#define VOLATILE -#define SIGNED - -#define PROTO(type, name, arglist) type name () -#define EXFUN(name, proto) name() -#define DEFUN(name, arglist, args) name arglist args; -#define DEFUN_VOID(name) name() -#define AND ; -#define DOTS -#define NOARGS -#endif /* ! IN_GCC */ - -#endif /* ANSI C. */ - -/* Define macros for some gcc attributes. This permits us to use the - macros freely, and know that they will come into play for the - version of gcc in which they are supported. */ - -#if (GCC_VERSION < 2007) -# define __attribute__(x) -#endif - -/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ -#ifndef ATTRIBUTE_MALLOC -# if (GCC_VERSION >= 2096) -# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -# else -# define ATTRIBUTE_MALLOC -# endif /* GNUC >= 2.96 */ -#endif /* ATTRIBUTE_MALLOC */ - -/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For - g++ an attribute on a label must be followed by a semicolon. */ -#ifndef ATTRIBUTE_UNUSED_LABEL -# ifndef __cplusplus -# if GCC_VERSION >= 2093 -# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED -# else -# define ATTRIBUTE_UNUSED_LABEL -# endif -# else -# if GCC_VERSION >= 4005 -# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ; -# else -# define ATTRIBUTE_UNUSED_LABEL -# endif -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif /* ATTRIBUTE_UNUSED */ - -/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the - identifier name. */ -#if ! defined(__cplusplus) || (GCC_VERSION >= 3004) -# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED -#else /* !__cplusplus || GNUC >= 3.4 */ -# define ARG_UNUSED(NAME) NAME -#endif /* !__cplusplus || GNUC >= 3.4 */ - -#ifndef ATTRIBUTE_NORETURN -#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -#endif /* ATTRIBUTE_NORETURN */ - -/* Attribute `nonnull' was valid as of gcc 3.3. */ -#ifndef ATTRIBUTE_NONNULL -# if (GCC_VERSION >= 3003) -# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) -# else -# define ATTRIBUTE_NONNULL(m) -# endif /* GNUC >= 3.3 */ -#endif /* ATTRIBUTE_NONNULL */ - -/* Attribute `pure' was valid as of gcc 3.0. */ -#ifndef ATTRIBUTE_PURE -# if (GCC_VERSION >= 3000) -# define ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define ATTRIBUTE_PURE -# endif /* GNUC >= 3.0 */ -#endif /* ATTRIBUTE_PURE */ - -/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. - This was the case for the `printf' format attribute by itself - before GCC 3.3, but as of 3.3 we need to add the `nonnull' - attribute to retain this behavior. */ -#ifndef ATTRIBUTE_PRINTF -#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) -#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) -#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) -#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) -#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) -#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) -#endif /* ATTRIBUTE_PRINTF */ - -/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on - a function pointer. Format attributes were allowed on function - pointers as of gcc 3.1. */ -#ifndef ATTRIBUTE_FPTR_PRINTF -# if (GCC_VERSION >= 3001) -# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) -# else -# define ATTRIBUTE_FPTR_PRINTF(m, n) -# endif /* GNUC >= 3.1 */ -# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) -# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) -# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) -# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) -# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) -#endif /* ATTRIBUTE_FPTR_PRINTF */ - -/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A - NULL format specifier was allowed as of gcc 3.3. */ -#ifndef ATTRIBUTE_NULL_PRINTF -# if (GCC_VERSION >= 3003) -# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) -# else -# define ATTRIBUTE_NULL_PRINTF(m, n) -# endif /* GNUC >= 3.3 */ -# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) -# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) -# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) -# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) -# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) -#endif /* ATTRIBUTE_NULL_PRINTF */ - -/* Attribute `sentinel' was valid as of gcc 3.5. */ -#ifndef ATTRIBUTE_SENTINEL -# if (GCC_VERSION >= 3005) -# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) -# else -# define ATTRIBUTE_SENTINEL -# endif /* GNUC >= 3.5 */ -#endif /* ATTRIBUTE_SENTINEL */ - - -#ifndef ATTRIBUTE_ALIGNED_ALIGNOF -# if (GCC_VERSION >= 3000) -# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) -# else -# define ATTRIBUTE_ALIGNED_ALIGNOF(m) -# endif /* GNUC >= 3.0 */ -#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ - -/* Useful for structures whose layout must much some binary specification - regardless of the alignment and padding qualities of the compiler. */ -#ifndef ATTRIBUTE_PACKED -# define ATTRIBUTE_PACKED __attribute__ ((packed)) -#endif - -/* Attribute `hot' and `cold' was valid as of gcc 4.3. */ -#ifndef ATTRIBUTE_COLD -# if (GCC_VERSION >= 4003) -# define ATTRIBUTE_COLD __attribute__ ((__cold__)) -# else -# define ATTRIBUTE_COLD -# endif /* GNUC >= 4.3 */ -#endif /* ATTRIBUTE_COLD */ -#ifndef ATTRIBUTE_HOT -# if (GCC_VERSION >= 4003) -# define ATTRIBUTE_HOT __attribute__ ((__hot__)) -# else -# define ATTRIBUTE_HOT -# endif /* GNUC >= 4.3 */ -#endif /* ATTRIBUTE_HOT */ - -/* We use __extension__ in some places to suppress -pedantic warnings - about GCC extensions. This feature didn't work properly before - gcc 2.8. */ -#if GCC_VERSION < 2008 -#define __extension__ -#endif - -/* This is used to declare a const variable which should be visible - outside of the current compilation unit. Use it as - EXPORTED_CONST int i = 1; - This is because the semantics of const are different in C and C++. - "extern const" is permitted in C but it looks strange, and gcc - warns about it when -Wc++-compat is not used. */ -#ifdef __cplusplus -#define EXPORTED_CONST extern const -#else -#define EXPORTED_CONST const -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ansidecl.h */ diff --git a/linkers/libiberty/concat.c b/linkers/libiberty/concat.c deleted file mode 100644 index 9779d56..0000000 --- a/linkers/libiberty/concat.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Concatenate variable number of strings. - Copyright (C) 1991, 1994, 2001, 2011 Free Software Foundation, Inc. - Written by Fred Fish @ Cygnus Support - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - - -/* - -@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @ - @dots{}, @code{NULL}) - -Concatenate zero or more of strings and return the result in freshly -@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is -available. The argument list is terminated by the first @code{NULL} -pointer encountered. Pointers to empty strings are ignored. - -@end deftypefn - -NOTES - - This function uses xmalloc() which is expected to be a front end - function to malloc() that deals with low memory situations. In - typical use, if malloc() returns NULL then xmalloc() diverts to an - error handler routine which never returns, and thus xmalloc will - never return a NULL pointer. If the client application wishes to - deal with low memory situations itself, it should supply an xmalloc - that just directly invokes malloc and blindly returns whatever - malloc returns. - -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "ansidecl.h" -#include "libiberty.h" -#include /* size_t */ - -#include - -# if HAVE_STRING_H -# include -# else -# if HAVE_STRINGS_H -# include -# endif -# endif - -#if HAVE_STDLIB_H -#include -#endif - -static inline unsigned long vconcat_length (const char *, va_list); -static inline unsigned long -vconcat_length (const char *first, va_list args) -{ - unsigned long length = 0; - const char *arg; - - for (arg = first; arg ; arg = va_arg (args, const char *)) - length += strlen (arg); - - return length; -} - -static inline char * -vconcat_copy (char *dst, const char *first, va_list args) -{ - char *end = dst; - const char *arg; - - for (arg = first; arg ; arg = va_arg (args, const char *)) - { - unsigned long length = strlen (arg); - memcpy (end, arg, length); - end += length; - } - *end = '\000'; - - return dst; -} - -/* @undocumented concat_length */ - -unsigned long -concat_length (const char *first, ...) -{ - unsigned long length; - - VA_OPEN (args, first); - VA_FIXEDARG (args, const char *, first); - length = vconcat_length (first, args); - VA_CLOSE (args); - - return length; -} - -/* @undocumented concat_copy */ - -char * -concat_copy (char *dst, const char *first, ...) -{ - char *save_dst; - - VA_OPEN (args, first); - VA_FIXEDARG (args, char *, dst); - VA_FIXEDARG (args, const char *, first); - vconcat_copy (dst, first, args); - save_dst = dst; /* With K&R C, dst goes out of scope here. */ - VA_CLOSE (args); - - return save_dst; -} - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -char *libiberty_concat_ptr; -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/* @undocumented concat_copy2 */ - -char * -concat_copy2 (const char *first, ...) -{ - VA_OPEN (args, first); - VA_FIXEDARG (args, const char *, first); - vconcat_copy (libiberty_concat_ptr, first, args); - VA_CLOSE (args); - - return libiberty_concat_ptr; -} - -char * -concat (const char *first, ...) -{ - char *newstr; - - /* First compute the size of the result and get sufficient memory. */ - VA_OPEN (args, first); - VA_FIXEDARG (args, const char *, first); - newstr = XNEWVEC (char, vconcat_length (first, args) + 1); - VA_CLOSE (args); - - /* Now copy the individual pieces to the result string. */ - VA_OPEN (args, first); - VA_FIXEDARG (args, const char *, first); - vconcat_copy (newstr, first, args); - VA_CLOSE (args); - - return newstr; -} - -/* - -@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @ - @dots{}, @code{NULL}) - -Same as @code{concat}, except that if @var{optr} is not @code{NULL} it -is freed after the string is created. This is intended to be useful -when you're extending an existing string or building up a string in a -loop: - -@example - str = reconcat (str, "pre-", str, NULL); -@end example - -@end deftypefn - -*/ - -char * -reconcat (char *optr, const char *first, ...) -{ - char *newstr; - - /* First compute the size of the result and get sufficient memory. */ - VA_OPEN (args, first); - VA_FIXEDARG (args, char *, optr); - VA_FIXEDARG (args, const char *, first); - newstr = XNEWVEC (char, vconcat_length (first, args) + 1); - VA_CLOSE (args); - - /* Now copy the individual pieces to the result string. */ - VA_OPEN (args, first); - VA_FIXEDARG (args, char *, optr); - VA_FIXEDARG (args, const char *, first); - vconcat_copy (newstr, first, args); - if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */ - free (optr); - VA_CLOSE (args); - - return newstr; -} - -#ifdef MAIN -#define NULLP (char *)0 - -/* Simple little test driver. */ - -#include - -int -main (void) -{ - printf ("\"\" = \"%s\"\n", concat (NULLP)); - printf ("\"a\" = \"%s\"\n", concat ("a", NULLP)); - printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP)); - printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP)); - printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP)); - printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP)); - printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP)); - return 0; -} - -#endif diff --git a/linkers/libiberty/cp-demangle.c b/linkers/libiberty/cp-demangle.c deleted file mode 100644 index c590561..0000000 --- a/linkers/libiberty/cp-demangle.c +++ /dev/null @@ -1,5064 +0,0 @@ -/* Demangler for g++ V3 ABI. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of the libiberty library, which is part of GCC. - - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - In addition to the permissions in the GNU General Public License, the - Free Software Foundation gives you unlimited permission to link the - compiled version of this file into combinations with other programs, - and to distribute those combinations without any restriction coming - from the use of this file. (The General Public License restrictions - do apply in other respects; for example, they cover modification of - the file, and distribution when not linked into a combined - executable.) - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -/* This code implements a demangler for the g++ V3 ABI. The ABI is - described on this web page: - http://www.codesourcery.com/cxx-abi/abi.html#mangling - - This code was written while looking at the demangler written by - Alex Samuel . - - This code first pulls the mangled name apart into a list of - components, and then walks the list generating the demangled - name. - - This file will normally define the following functions, q.v.: - char *cplus_demangle_v3(const char *mangled, int options) - char *java_demangle_v3(const char *mangled) - int cplus_demangle_v3_callback(const char *mangled, int options, - demangle_callbackref callback) - int java_demangle_v3_callback(const char *mangled, - demangle_callbackref callback) - enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name) - enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name) - - Also, the interface to the component list is public, and defined in - demangle.h. The interface consists of these types, which are - defined in demangle.h: - enum demangle_component_type - struct demangle_component - demangle_callbackref - and these functions defined in this file: - cplus_demangle_fill_name - cplus_demangle_fill_extended_operator - cplus_demangle_fill_ctor - cplus_demangle_fill_dtor - cplus_demangle_print - cplus_demangle_print_callback - and other functions defined in the file cp-demint.c. - - This file also defines some other functions and variables which are - only to be used by the file cp-demint.c. - - Preprocessor macros you can define while compiling this file: - - IN_LIBGCC2 - If defined, this file defines the following functions, q.v.: - char *__cxa_demangle (const char *mangled, char *buf, size_t *len, - int *status) - int __gcclibcxx_demangle_callback (const char *, - void (*) - (const char *, size_t, void *), - void *) - instead of cplus_demangle_v3[_callback]() and - java_demangle_v3[_callback](). - - IN_GLIBCPP_V3 - If defined, this file defines only __cxa_demangle() and - __gcclibcxx_demangle_callback(), and no other publically visible - functions or variables. - - STANDALONE_DEMANGLER - If defined, this file defines a main() function which demangles - any arguments, or, if none, demangles stdin. - - CP_DEMANGLE_DEBUG - If defined, turns on debugging mode, which prints information on - stdout about the mangled string. This is not generally useful. -*/ - -#if defined (_AIX) && !defined (__GNUC__) - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#ifdef HAVE_ALLOCA_H -# include -#else -# ifndef alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# else -extern char *alloca (); -# endif /* __GNUC__ */ -# endif /* alloca */ -#endif /* HAVE_ALLOCA_H */ - -#include "ansidecl.h" -#include "libiberty.h" -#include "demangle.h" -#include "cp-demangle.h" - -/* If IN_GLIBCPP_V3 is defined, some functions are made static. We - also rename them via #define to avoid compiler errors when the - static definition conflicts with the extern declaration in a header - file. */ -#ifdef IN_GLIBCPP_V3 - -#define CP_STATIC_IF_GLIBCPP_V3 static - -#define cplus_demangle_fill_name d_fill_name -static int d_fill_name (struct demangle_component *, const char *, int); - -#define cplus_demangle_fill_extended_operator d_fill_extended_operator -static int -d_fill_extended_operator (struct demangle_component *, int, - struct demangle_component *); - -#define cplus_demangle_fill_ctor d_fill_ctor -static int -d_fill_ctor (struct demangle_component *, enum gnu_v3_ctor_kinds, - struct demangle_component *); - -#define cplus_demangle_fill_dtor d_fill_dtor -static int -d_fill_dtor (struct demangle_component *, enum gnu_v3_dtor_kinds, - struct demangle_component *); - -#define cplus_demangle_mangled_name d_mangled_name -static struct demangle_component *d_mangled_name (struct d_info *, int); - -#define cplus_demangle_type d_type -static struct demangle_component *d_type (struct d_info *); - -#define cplus_demangle_print d_print -static char *d_print (int, const struct demangle_component *, int, size_t *); - -#define cplus_demangle_print_callback d_print_callback -static int d_print_callback (int, const struct demangle_component *, - demangle_callbackref, void *); - -#define cplus_demangle_init_info d_init_info -static void d_init_info (const char *, int, size_t, struct d_info *); - -#else /* ! defined(IN_GLIBCPP_V3) */ -#define CP_STATIC_IF_GLIBCPP_V3 -#endif /* ! defined(IN_GLIBCPP_V3) */ - -/* See if the compiler supports dynamic arrays. */ - -#ifdef __GNUC__ -#define CP_DYNAMIC_ARRAYS -#else -#ifdef __STDC__ -#ifdef __STDC_VERSION__ -#if __STDC_VERSION__ >= 199901L -#define CP_DYNAMIC_ARRAYS -#endif /* __STDC__VERSION >= 199901L */ -#endif /* defined (__STDC_VERSION__) */ -#endif /* defined (__STDC__) */ -#endif /* ! defined (__GNUC__) */ - -/* We avoid pulling in the ctype tables, to prevent pulling in - additional unresolved symbols when this code is used in a library. - FIXME: Is this really a valid reason? This comes from the original - V3 demangler code. - - As of this writing this file has the following undefined references - when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy, - strcat, strlen. */ - -#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') -#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z') -#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z') - -/* The prefix prepended by GCC to an identifier represnting the - anonymous namespace. */ -#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_" -#define ANONYMOUS_NAMESPACE_PREFIX_LEN \ - (sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1) - -/* Information we keep for the standard substitutions. */ - -struct d_standard_sub_info -{ - /* The code for this substitution. */ - char code; - /* The simple string it expands to. */ - const char *simple_expansion; - /* The length of the simple expansion. */ - int simple_len; - /* The results of a full, verbose, expansion. This is used when - qualifying a constructor/destructor, or when in verbose mode. */ - const char *full_expansion; - /* The length of the full expansion. */ - int full_len; - /* What to set the last_name field of d_info to; NULL if we should - not set it. This is only relevant when qualifying a - constructor/destructor. */ - const char *set_last_name; - /* The length of set_last_name. */ - int set_last_name_len; -}; - -/* Accessors for subtrees of struct demangle_component. */ - -#define d_left(dc) ((dc)->u.s_binary.left) -#define d_right(dc) ((dc)->u.s_binary.right) - -/* A list of templates. This is used while printing. */ - -struct d_print_template -{ - /* Next template on the list. */ - struct d_print_template *next; - /* This template. */ - const struct demangle_component *template_decl; -}; - -/* A list of type modifiers. This is used while printing. */ - -struct d_print_mod -{ - /* Next modifier on the list. These are in the reverse of the order - in which they appeared in the mangled string. */ - struct d_print_mod *next; - /* The modifier. */ - const struct demangle_component *mod; - /* Whether this modifier was printed. */ - int printed; - /* The list of templates which applies to this modifier. */ - struct d_print_template *templates; -}; - -/* We use these structures to hold information during printing. */ - -struct d_growable_string -{ - /* Buffer holding the result. */ - char *buf; - /* Current length of data in buffer. */ - size_t len; - /* Allocated size of buffer. */ - size_t alc; - /* Set to 1 if we had a memory allocation failure. */ - int allocation_failure; -}; - -enum { D_PRINT_BUFFER_LENGTH = 256 }; -struct d_print_info -{ - /* The options passed to the demangler. */ - int options; - /* Fixed-length allocated buffer for demangled data, flushed to the - callback with a NUL termination once full. */ - char buf[D_PRINT_BUFFER_LENGTH]; - /* Current length of data in buffer. */ - size_t len; - /* The last character printed, saved individually so that it survives - any buffer flush. */ - char last_char; - /* Callback function to handle demangled buffer flush. */ - demangle_callbackref callback; - /* Opaque callback argument. */ - void *opaque; - /* The current list of templates, if any. */ - struct d_print_template *templates; - /* The current list of modifiers (e.g., pointer, reference, etc.), - if any. */ - struct d_print_mod *modifiers; - /* Set to 1 if we saw a demangling error. */ - int demangle_failure; - /* The current index into any template argument packs we are using - for printing. */ - int pack_index; -}; - -#ifdef CP_DEMANGLE_DEBUG -static void d_dump (struct demangle_component *, int); -#endif - -static struct demangle_component * -d_make_empty (struct d_info *); - -static struct demangle_component * -d_make_comp (struct d_info *, enum demangle_component_type, - struct demangle_component *, - struct demangle_component *); - -static struct demangle_component * -d_make_name (struct d_info *, const char *, int); - -static struct demangle_component * -d_make_builtin_type (struct d_info *, - const struct demangle_builtin_type_info *); - -static struct demangle_component * -d_make_operator (struct d_info *, - const struct demangle_operator_info *); - -static struct demangle_component * -d_make_extended_operator (struct d_info *, int, - struct demangle_component *); - -static struct demangle_component * -d_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds, - struct demangle_component *); - -static struct demangle_component * -d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds, - struct demangle_component *); - -static struct demangle_component * -d_make_template_param (struct d_info *, long); - -static struct demangle_component * -d_make_sub (struct d_info *, const char *, int); - -static int -has_return_type (struct demangle_component *); - -static int -is_ctor_dtor_or_conversion (struct demangle_component *); - -static struct demangle_component *d_encoding (struct d_info *, int); - -static struct demangle_component *d_name (struct d_info *); - -static struct demangle_component *d_nested_name (struct d_info *); - -static struct demangle_component *d_prefix (struct d_info *); - -static struct demangle_component *d_unqualified_name (struct d_info *); - -static struct demangle_component *d_source_name (struct d_info *); - -static long d_number (struct d_info *); - -static struct demangle_component *d_identifier (struct d_info *, int); - -static struct demangle_component *d_operator_name (struct d_info *); - -static struct demangle_component *d_special_name (struct d_info *); - -static int d_call_offset (struct d_info *, int); - -static struct demangle_component *d_ctor_dtor_name (struct d_info *); - -static struct demangle_component ** -d_cv_qualifiers (struct d_info *, struct demangle_component **, int); - -static struct demangle_component * -d_function_type (struct d_info *); - -static struct demangle_component * -d_bare_function_type (struct d_info *, int); - -static struct demangle_component * -d_class_enum_type (struct d_info *); - -static struct demangle_component *d_array_type (struct d_info *); - -static struct demangle_component * -d_pointer_to_member_type (struct d_info *); - -static struct demangle_component * -d_template_param (struct d_info *); - -static struct demangle_component *d_template_args (struct d_info *); - -static struct demangle_component * -d_template_arg (struct d_info *); - -static struct demangle_component *d_expression (struct d_info *); - -static struct demangle_component *d_expr_primary (struct d_info *); - -static struct demangle_component *d_local_name (struct d_info *); - -static int d_discriminator (struct d_info *); - -static int -d_add_substitution (struct d_info *, struct demangle_component *); - -static struct demangle_component *d_substitution (struct d_info *, int); - -static void d_growable_string_init (struct d_growable_string *, size_t); - -static inline void -d_growable_string_resize (struct d_growable_string *, size_t); - -static inline void -d_growable_string_append_buffer (struct d_growable_string *, - const char *, size_t); -static void -d_growable_string_callback_adapter (const char *, size_t, void *); - -static void -d_print_init (struct d_print_info *, int, demangle_callbackref, void *); - -static inline void d_print_error (struct d_print_info *); - -static inline int d_print_saw_error (struct d_print_info *); - -static inline void d_print_flush (struct d_print_info *); - -static inline void d_append_char (struct d_print_info *, char); - -static inline void d_append_buffer (struct d_print_info *, - const char *, size_t); - -static inline void d_append_string (struct d_print_info *, const char *); - -static inline char d_last_char (struct d_print_info *); - -static void -d_print_comp (struct d_print_info *, const struct demangle_component *); - -static void -d_print_java_identifier (struct d_print_info *, const char *, int); - -static void -d_print_mod_list (struct d_print_info *, struct d_print_mod *, int); - -static void -d_print_mod (struct d_print_info *, const struct demangle_component *); - -static void -d_print_function_type (struct d_print_info *, - const struct demangle_component *, - struct d_print_mod *); - -static void -d_print_array_type (struct d_print_info *, - const struct demangle_component *, - struct d_print_mod *); - -static void -d_print_expr_op (struct d_print_info *, const struct demangle_component *); - -static void -d_print_cast (struct d_print_info *, const struct demangle_component *); - -static int d_demangle_callback (const char *, int, - demangle_callbackref, void *); -static char *d_demangle (const char *, int, size_t *); - -#ifdef CP_DEMANGLE_DEBUG - -static void -d_dump (struct demangle_component *dc, int indent) -{ - int i; - - if (dc == NULL) - { - if (indent == 0) - printf ("failed demangling\n"); - return; - } - - for (i = 0; i < indent; ++i) - putchar (' '); - - switch (dc->type) - { - case DEMANGLE_COMPONENT_NAME: - printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s); - return; - case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - printf ("template parameter %ld\n", dc->u.s_number.number); - return; - case DEMANGLE_COMPONENT_CTOR: - printf ("constructor %d\n", (int) dc->u.s_ctor.kind); - d_dump (dc->u.s_ctor.name, indent + 2); - return; - case DEMANGLE_COMPONENT_DTOR: - printf ("destructor %d\n", (int) dc->u.s_dtor.kind); - d_dump (dc->u.s_dtor.name, indent + 2); - return; - case DEMANGLE_COMPONENT_SUB_STD: - printf ("standard substitution %s\n", dc->u.s_string.string); - return; - case DEMANGLE_COMPONENT_BUILTIN_TYPE: - printf ("builtin type %s\n", dc->u.s_builtin.type->name); - return; - case DEMANGLE_COMPONENT_OPERATOR: - printf ("operator %s\n", dc->u.s_operator.op->name); - return; - case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: - printf ("extended operator with %d args\n", - dc->u.s_extended_operator.args); - d_dump (dc->u.s_extended_operator.name, indent + 2); - return; - - case DEMANGLE_COMPONENT_QUAL_NAME: - printf ("qualified name\n"); - break; - case DEMANGLE_COMPONENT_LOCAL_NAME: - printf ("local name\n"); - break; - case DEMANGLE_COMPONENT_TYPED_NAME: - printf ("typed name\n"); - break; - case DEMANGLE_COMPONENT_TEMPLATE: - printf ("template\n"); - break; - case DEMANGLE_COMPONENT_VTABLE: - printf ("vtable\n"); - break; - case DEMANGLE_COMPONENT_VTT: - printf ("VTT\n"); - break; - case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: - printf ("construction vtable\n"); - break; - case DEMANGLE_COMPONENT_TYPEINFO: - printf ("typeinfo\n"); - break; - case DEMANGLE_COMPONENT_TYPEINFO_NAME: - printf ("typeinfo name\n"); - break; - case DEMANGLE_COMPONENT_TYPEINFO_FN: - printf ("typeinfo function\n"); - break; - case DEMANGLE_COMPONENT_THUNK: - printf ("thunk\n"); - break; - case DEMANGLE_COMPONENT_VIRTUAL_THUNK: - printf ("virtual thunk\n"); - break; - case DEMANGLE_COMPONENT_COVARIANT_THUNK: - printf ("covariant thunk\n"); - break; - case DEMANGLE_COMPONENT_JAVA_CLASS: - printf ("java class\n"); - break; - case DEMANGLE_COMPONENT_GUARD: - printf ("guard\n"); - break; - case DEMANGLE_COMPONENT_REFTEMP: - printf ("reference temporary\n"); - break; - case DEMANGLE_COMPONENT_HIDDEN_ALIAS: - printf ("hidden alias\n"); - break; - case DEMANGLE_COMPONENT_RESTRICT: - printf ("restrict\n"); - break; - case DEMANGLE_COMPONENT_VOLATILE: - printf ("volatile\n"); - break; - case DEMANGLE_COMPONENT_CONST: - printf ("const\n"); - break; - case DEMANGLE_COMPONENT_RESTRICT_THIS: - printf ("restrict this\n"); - break; - case DEMANGLE_COMPONENT_VOLATILE_THIS: - printf ("volatile this\n"); - break; - case DEMANGLE_COMPONENT_CONST_THIS: - printf ("const this\n"); - break; - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - printf ("vendor type qualifier\n"); - break; - case DEMANGLE_COMPONENT_POINTER: - printf ("pointer\n"); - break; - case DEMANGLE_COMPONENT_REFERENCE: - printf ("reference\n"); - break; - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: - printf ("rvalue reference\n"); - break; - case DEMANGLE_COMPONENT_COMPLEX: - printf ("complex\n"); - break; - case DEMANGLE_COMPONENT_IMAGINARY: - printf ("imaginary\n"); - break; - case DEMANGLE_COMPONENT_VENDOR_TYPE: - printf ("vendor type\n"); - break; - case DEMANGLE_COMPONENT_FUNCTION_TYPE: - printf ("function type\n"); - break; - case DEMANGLE_COMPONENT_ARRAY_TYPE: - printf ("array type\n"); - break; - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - printf ("pointer to member type\n"); - break; - case DEMANGLE_COMPONENT_FIXED_TYPE: - printf ("fixed-point type\n"); - break; - case DEMANGLE_COMPONENT_ARGLIST: - printf ("argument list\n"); - break; - case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: - printf ("template argument list\n"); - break; - case DEMANGLE_COMPONENT_CAST: - printf ("cast\n"); - break; - case DEMANGLE_COMPONENT_UNARY: - printf ("unary operator\n"); - break; - case DEMANGLE_COMPONENT_BINARY: - printf ("binary operator\n"); - break; - case DEMANGLE_COMPONENT_BINARY_ARGS: - printf ("binary operator arguments\n"); - break; - case DEMANGLE_COMPONENT_TRINARY: - printf ("trinary operator\n"); - break; - case DEMANGLE_COMPONENT_TRINARY_ARG1: - printf ("trinary operator arguments 1\n"); - break; - case DEMANGLE_COMPONENT_TRINARY_ARG2: - printf ("trinary operator arguments 1\n"); - break; - case DEMANGLE_COMPONENT_LITERAL: - printf ("literal\n"); - break; - case DEMANGLE_COMPONENT_LITERAL_NEG: - printf ("negative literal\n"); - break; - case DEMANGLE_COMPONENT_JAVA_RESOURCE: - printf ("java resource\n"); - break; - case DEMANGLE_COMPONENT_COMPOUND_NAME: - printf ("compound name\n"); - break; - case DEMANGLE_COMPONENT_CHARACTER: - printf ("character '%c'\n", dc->u.s_character.character); - return; - case DEMANGLE_COMPONENT_DECLTYPE: - printf ("decltype\n"); - break; - case DEMANGLE_COMPONENT_PACK_EXPANSION: - printf ("pack expansion\n"); - break; - } - - d_dump (d_left (dc), indent + 2); - d_dump (d_right (dc), indent + 2); -} - -#endif /* CP_DEMANGLE_DEBUG */ - -/* Fill in a DEMANGLE_COMPONENT_NAME. */ - -CP_STATIC_IF_GLIBCPP_V3 -int -cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len) -{ - if (p == NULL || s == NULL || len == 0) - return 0; - p->type = DEMANGLE_COMPONENT_NAME; - p->u.s_name.s = s; - p->u.s_name.len = len; - return 1; -} - -/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */ - -CP_STATIC_IF_GLIBCPP_V3 -int -cplus_demangle_fill_extended_operator (struct demangle_component *p, int args, - struct demangle_component *name) -{ - if (p == NULL || args < 0 || name == NULL) - return 0; - p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR; - p->u.s_extended_operator.args = args; - p->u.s_extended_operator.name = name; - return 1; -} - -/* Fill in a DEMANGLE_COMPONENT_CTOR. */ - -CP_STATIC_IF_GLIBCPP_V3 -int -cplus_demangle_fill_ctor (struct demangle_component *p, - enum gnu_v3_ctor_kinds kind, - struct demangle_component *name) -{ - if (p == NULL - || name == NULL - || (int) kind < gnu_v3_complete_object_ctor - || (int) kind > gnu_v3_complete_object_allocating_ctor) - return 0; - p->type = DEMANGLE_COMPONENT_CTOR; - p->u.s_ctor.kind = kind; - p->u.s_ctor.name = name; - return 1; -} - -/* Fill in a DEMANGLE_COMPONENT_DTOR. */ - -CP_STATIC_IF_GLIBCPP_V3 -int -cplus_demangle_fill_dtor (struct demangle_component *p, - enum gnu_v3_dtor_kinds kind, - struct demangle_component *name) -{ - if (p == NULL - || name == NULL - || (int) kind < gnu_v3_deleting_dtor - || (int) kind > gnu_v3_base_object_dtor) - return 0; - p->type = DEMANGLE_COMPONENT_DTOR; - p->u.s_dtor.kind = kind; - p->u.s_dtor.name = name; - return 1; -} - -/* Add a new component. */ - -static struct demangle_component * -d_make_empty (struct d_info *di) -{ - struct demangle_component *p; - - if (di->next_comp >= di->num_comps) - return NULL; - p = &di->comps[di->next_comp]; - ++di->next_comp; - return p; -} - -/* Add a new generic component. */ - -static struct demangle_component * -d_make_comp (struct d_info *di, enum demangle_component_type type, - struct demangle_component *left, - struct demangle_component *right) -{ - struct demangle_component *p; - - /* We check for errors here. A typical error would be a NULL return - from a subroutine. We catch those here, and return NULL - upward. */ - switch (type) - { - /* These types require two parameters. */ - case DEMANGLE_COMPONENT_QUAL_NAME: - case DEMANGLE_COMPONENT_LOCAL_NAME: - case DEMANGLE_COMPONENT_TYPED_NAME: - case DEMANGLE_COMPONENT_TEMPLATE: - case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - case DEMANGLE_COMPONENT_UNARY: - case DEMANGLE_COMPONENT_BINARY: - case DEMANGLE_COMPONENT_BINARY_ARGS: - case DEMANGLE_COMPONENT_TRINARY: - case DEMANGLE_COMPONENT_TRINARY_ARG1: - case DEMANGLE_COMPONENT_TRINARY_ARG2: - case DEMANGLE_COMPONENT_LITERAL: - case DEMANGLE_COMPONENT_LITERAL_NEG: - case DEMANGLE_COMPONENT_COMPOUND_NAME: - if (left == NULL || right == NULL) - return NULL; - break; - - /* These types only require one parameter. */ - case DEMANGLE_COMPONENT_VTABLE: - case DEMANGLE_COMPONENT_VTT: - case DEMANGLE_COMPONENT_TYPEINFO: - case DEMANGLE_COMPONENT_TYPEINFO_NAME: - case DEMANGLE_COMPONENT_TYPEINFO_FN: - case DEMANGLE_COMPONENT_THUNK: - case DEMANGLE_COMPONENT_VIRTUAL_THUNK: - case DEMANGLE_COMPONENT_COVARIANT_THUNK: - case DEMANGLE_COMPONENT_JAVA_CLASS: - case DEMANGLE_COMPONENT_GUARD: - case DEMANGLE_COMPONENT_REFTEMP: - case DEMANGLE_COMPONENT_HIDDEN_ALIAS: - case DEMANGLE_COMPONENT_POINTER: - case DEMANGLE_COMPONENT_REFERENCE: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: - case DEMANGLE_COMPONENT_COMPLEX: - case DEMANGLE_COMPONENT_IMAGINARY: - case DEMANGLE_COMPONENT_VENDOR_TYPE: - case DEMANGLE_COMPONENT_CAST: - case DEMANGLE_COMPONENT_JAVA_RESOURCE: - case DEMANGLE_COMPONENT_DECLTYPE: - case DEMANGLE_COMPONENT_PACK_EXPANSION: - case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: - case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: - if (left == NULL) - return NULL; - break; - - /* This needs a right parameter, but the left parameter can be - empty. */ - case DEMANGLE_COMPONENT_ARRAY_TYPE: - if (right == NULL) - return NULL; - break; - - /* These are allowed to have no parameters--in some cases they - will be filled in later. */ - case DEMANGLE_COMPONENT_FUNCTION_TYPE: - case DEMANGLE_COMPONENT_RESTRICT: - case DEMANGLE_COMPONENT_VOLATILE: - case DEMANGLE_COMPONENT_CONST: - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_ARGLIST: - case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: - break; - - /* Other types should not be seen here. */ - default: - return NULL; - } - - p = d_make_empty (di); - if (p != NULL) - { - p->type = type; - p->u.s_binary.left = left; - p->u.s_binary.right = right; - } - return p; -} - -/* Add a new name component. */ - -static struct demangle_component * -d_make_name (struct d_info *di, const char *s, int len) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (! cplus_demangle_fill_name (p, s, len)) - return NULL; - return p; -} - -/* Add a new builtin type component. */ - -static struct demangle_component * -d_make_builtin_type (struct d_info *di, - const struct demangle_builtin_type_info *type) -{ - struct demangle_component *p; - - if (type == NULL) - return NULL; - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE; - p->u.s_builtin.type = type; - } - return p; -} - -/* Add a new operator component. */ - -static struct demangle_component * -d_make_operator (struct d_info *di, const struct demangle_operator_info *op) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_OPERATOR; - p->u.s_operator.op = op; - } - return p; -} - -/* Add a new extended operator component. */ - -static struct demangle_component * -d_make_extended_operator (struct d_info *di, int args, - struct demangle_component *name) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (! cplus_demangle_fill_extended_operator (p, args, name)) - return NULL; - return p; -} - -/* Add a new constructor component. */ - -static struct demangle_component * -d_make_ctor (struct d_info *di, enum gnu_v3_ctor_kinds kind, - struct demangle_component *name) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (! cplus_demangle_fill_ctor (p, kind, name)) - return NULL; - return p; -} - -/* Add a new destructor component. */ - -static struct demangle_component * -d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind, - struct demangle_component *name) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (! cplus_demangle_fill_dtor (p, kind, name)) - return NULL; - return p; -} - -/* Add a new template parameter. */ - -static struct demangle_component * -d_make_template_param (struct d_info *di, long i) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM; - p->u.s_number.number = i; - } - return p; -} - -/* Add a new function parameter. */ - -static struct demangle_component * -d_make_function_param (struct d_info *di, long i) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM; - p->u.s_number.number = i; - } - return p; -} - -/* Add a new standard substitution component. */ - -static struct demangle_component * -d_make_sub (struct d_info *di, const char *name, int len) -{ - struct demangle_component *p; - - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_SUB_STD; - p->u.s_string.string = name; - p->u.s_string.len = len; - } - return p; -} - -/* ::= _Z - - TOP_LEVEL is non-zero when called at the top level. */ - -CP_STATIC_IF_GLIBCPP_V3 -struct demangle_component * -cplus_demangle_mangled_name (struct d_info *di, int top_level) -{ - if (! d_check_char (di, '_') - /* Allow missing _ if not at toplevel to work around a - bug in G++ abi-version=2 mangling; see the comment in - write_template_arg. */ - && top_level) - return NULL; - if (! d_check_char (di, 'Z')) - return NULL; - return d_encoding (di, top_level); -} - -/* Return whether a function should have a return type. The argument - is the function name, which may be qualified in various ways. The - rules are that template functions have return types with some - exceptions, function types which are not part of a function name - mangling have return types with some exceptions, and non-template - function names do not have return types. The exceptions are that - constructors, destructors, and conversion operators do not have - return types. */ - -static int -has_return_type (struct demangle_component *dc) -{ - if (dc == NULL) - return 0; - switch (dc->type) - { - default: - return 0; - case DEMANGLE_COMPONENT_TEMPLATE: - return ! is_ctor_dtor_or_conversion (d_left (dc)); - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - return has_return_type (d_left (dc)); - } -} - -/* Return whether a name is a constructor, a destructor, or a - conversion operator. */ - -static int -is_ctor_dtor_or_conversion (struct demangle_component *dc) -{ - if (dc == NULL) - return 0; - switch (dc->type) - { - default: - return 0; - case DEMANGLE_COMPONENT_QUAL_NAME: - case DEMANGLE_COMPONENT_LOCAL_NAME: - return is_ctor_dtor_or_conversion (d_right (dc)); - case DEMANGLE_COMPONENT_CTOR: - case DEMANGLE_COMPONENT_DTOR: - case DEMANGLE_COMPONENT_CAST: - return 1; - } -} - -/* ::= <(function) name> - ::= <(data) name> - ::= - - TOP_LEVEL is non-zero when called at the top level, in which case - if DMGL_PARAMS is not set we do not demangle the function - parameters. We only set this at the top level, because otherwise - we would not correctly demangle names in local scopes. */ - -static struct demangle_component * -d_encoding (struct d_info *di, int top_level) -{ - char peek = d_peek_char (di); - - if (peek == 'G' || peek == 'T') - return d_special_name (di); - else - { - struct demangle_component *dc; - - dc = d_name (di); - - if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0) - { - /* Strip off any initial CV-qualifiers, as they really apply - to the `this' parameter, and they were not output by the - v2 demangler without DMGL_PARAMS. */ - while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || dc->type == DEMANGLE_COMPONENT_CONST_THIS) - dc = d_left (dc); - - /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then - there may be CV-qualifiers on its right argument which - really apply here; this happens when parsing a class - which is local to a function. */ - if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME) - { - struct demangle_component *dcr; - - dcr = d_right (dc); - while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || dcr->type == DEMANGLE_COMPONENT_CONST_THIS) - dcr = d_left (dcr); - dc->u.s_binary.right = dcr; - } - - return dc; - } - - peek = d_peek_char (di); - if (dc == NULL || peek == '\0' || peek == 'E') - return dc; - return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc, - d_bare_function_type (di, has_return_type (dc))); - } -} - -/* ::= - ::= - ::= - ::= - - ::= - ::= St - - ::= - ::= -*/ - -static struct demangle_component * -d_name (struct d_info *di) -{ - char peek = d_peek_char (di); - struct demangle_component *dc; - - switch (peek) - { - case 'N': - return d_nested_name (di); - - case 'Z': - return d_local_name (di); - - case 'L': - return d_unqualified_name (di); - - case 'S': - { - int subst; - - if (d_peek_next_char (di) != 't') - { - dc = d_substitution (di, 0); - subst = 1; - } - else - { - d_advance (di, 2); - dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, - d_make_name (di, "std", 3), - d_unqualified_name (di)); - di->expansion += 3; - subst = 0; - } - - if (d_peek_char (di) != 'I') - { - /* The grammar does not permit this case to occur if we - called d_substitution() above (i.e., subst == 1). We - don't bother to check. */ - } - else - { - /* This is , which means that we just saw - , which is a substitution - candidate if we didn't just get it from a - substitution. */ - if (! subst) - { - if (! d_add_substitution (di, dc)) - return NULL; - } - dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, - d_template_args (di)); - } - - return dc; - } - - default: - dc = d_unqualified_name (di); - if (d_peek_char (di) == 'I') - { - /* This is , which means that we just saw - , which is a substitution - candidate. */ - if (! d_add_substitution (di, dc)) - return NULL; - dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, - d_template_args (di)); - } - return dc; - } -} - -/* ::= N [] E - ::= N [] E -*/ - -static struct demangle_component * -d_nested_name (struct d_info *di) -{ - struct demangle_component *ret; - struct demangle_component **pret; - - if (! d_check_char (di, 'N')) - return NULL; - - pret = d_cv_qualifiers (di, &ret, 1); - if (pret == NULL) - return NULL; - - *pret = d_prefix (di); - if (*pret == NULL) - return NULL; - - if (! d_check_char (di, 'E')) - return NULL; - - return ret; -} - -/* ::= - ::= - ::= - ::= - ::= - - ::= <(template) unqualified-name> - ::= - ::= -*/ - -static struct demangle_component * -d_prefix (struct d_info *di) -{ - struct demangle_component *ret = NULL; - - while (1) - { - char peek; - enum demangle_component_type comb_type; - struct demangle_component *dc; - - peek = d_peek_char (di); - if (peek == '\0') - return NULL; - - /* The older code accepts a here, but I don't see - that in the grammar. The older code does not accept a - here. */ - - comb_type = DEMANGLE_COMPONENT_QUAL_NAME; - if (IS_DIGIT (peek) - || IS_LOWER (peek) - || peek == 'C' - || peek == 'D' - || peek == 'L') - dc = d_unqualified_name (di); - else if (peek == 'S') - dc = d_substitution (di, 1); - else if (peek == 'I') - { - if (ret == NULL) - return NULL; - comb_type = DEMANGLE_COMPONENT_TEMPLATE; - dc = d_template_args (di); - } - else if (peek == 'T') - dc = d_template_param (di); - else if (peek == 'E') - return ret; - else - return NULL; - - if (ret == NULL) - ret = dc; - else - ret = d_make_comp (di, comb_type, ret, dc); - - if (peek != 'S' && d_peek_char (di) != 'E') - { - if (! d_add_substitution (di, ret)) - return NULL; - } - } -} - -/* ::= - ::= - ::= - ::= - - ::= L -*/ - -static struct demangle_component * -d_unqualified_name (struct d_info *di) -{ - char peek; - - peek = d_peek_char (di); - if (IS_DIGIT (peek)) - return d_source_name (di); - else if (IS_LOWER (peek)) - { - struct demangle_component *ret; - - ret = d_operator_name (di); - if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR) - di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2; - return ret; - } - else if (peek == 'C' || peek == 'D') - return d_ctor_dtor_name (di); - else if (peek == 'L') - { - struct demangle_component * ret; - - d_advance (di, 1); - - ret = d_source_name (di); - if (ret == NULL) - return NULL; - if (! d_discriminator (di)) - return NULL; - return ret; - } - else - return NULL; -} - -/* ::= <(positive length) number> */ - -static struct demangle_component * -d_source_name (struct d_info *di) -{ - long len; - struct demangle_component *ret; - - len = d_number (di); - if (len <= 0) - return NULL; - ret = d_identifier (di, len); - di->last_name = ret; - return ret; -} - -/* number ::= [n] <(non-negative decimal integer)> */ - -static long -d_number (struct d_info *di) -{ - int negative; - char peek; - long ret; - - negative = 0; - peek = d_peek_char (di); - if (peek == 'n') - { - negative = 1; - d_advance (di, 1); - peek = d_peek_char (di); - } - - ret = 0; - while (1) - { - if (! IS_DIGIT (peek)) - { - if (negative) - ret = - ret; - return ret; - } - ret = ret * 10 + peek - '0'; - d_advance (di, 1); - peek = d_peek_char (di); - } -} - -/* identifier ::= <(unqualified source code identifier)> */ - -static struct demangle_component * -d_identifier (struct d_info *di, int len) -{ - const char *name; - - name = d_str (di); - - if (di->send - name < len) - return NULL; - - d_advance (di, len); - - /* A Java mangled name may have a trailing '$' if it is a C++ - keyword. This '$' is not included in the length count. We just - ignore the '$'. */ - if ((di->options & DMGL_JAVA) != 0 - && d_peek_char (di) == '$') - d_advance (di, 1); - - /* Look for something which looks like a gcc encoding of an - anonymous namespace, and replace it with a more user friendly - name. */ - if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2 - && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX, - ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0) - { - const char *s; - - s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN; - if ((*s == '.' || *s == '_' || *s == '$') - && s[1] == 'N') - { - di->expansion -= len - sizeof "(anonymous namespace)"; - return d_make_name (di, "(anonymous namespace)", - sizeof "(anonymous namespace)" - 1); - } - } - - return d_make_name (di, name, len); -} - -/* operator_name ::= many different two character encodings. - ::= cv - ::= v -*/ - -#define NL(s) s, (sizeof s) - 1 - -CP_STATIC_IF_GLIBCPP_V3 -const struct demangle_operator_info cplus_demangle_operators[] = -{ - { "aN", NL ("&="), 2 }, - { "aS", NL ("="), 2 }, - { "aa", NL ("&&"), 2 }, - { "ad", NL ("&"), 1 }, - { "an", NL ("&"), 2 }, - { "cl", NL ("()"), 2 }, - { "cm", NL (","), 2 }, - { "co", NL ("~"), 1 }, - { "dV", NL ("/="), 2 }, - { "da", NL ("delete[]"), 1 }, - { "de", NL ("*"), 1 }, - { "dl", NL ("delete"), 1 }, - { "dt", NL ("."), 2 }, - { "dv", NL ("/"), 2 }, - { "eO", NL ("^="), 2 }, - { "eo", NL ("^"), 2 }, - { "eq", NL ("=="), 2 }, - { "ge", NL (">="), 2 }, - { "gt", NL (">"), 2 }, - { "ix", NL ("[]"), 2 }, - { "lS", NL ("<<="), 2 }, - { "le", NL ("<="), 2 }, - { "ls", NL ("<<"), 2 }, - { "lt", NL ("<"), 2 }, - { "mI", NL ("-="), 2 }, - { "mL", NL ("*="), 2 }, - { "mi", NL ("-"), 2 }, - { "ml", NL ("*"), 2 }, - { "mm", NL ("--"), 1 }, - { "na", NL ("new[]"), 1 }, - { "ne", NL ("!="), 2 }, - { "ng", NL ("-"), 1 }, - { "nt", NL ("!"), 1 }, - { "nw", NL ("new"), 1 }, - { "oR", NL ("|="), 2 }, - { "oo", NL ("||"), 2 }, - { "or", NL ("|"), 2 }, - { "pL", NL ("+="), 2 }, - { "pl", NL ("+"), 2 }, - { "pm", NL ("->*"), 2 }, - { "pp", NL ("++"), 1 }, - { "ps", NL ("+"), 1 }, - { "pt", NL ("->"), 2 }, - { "qu", NL ("?"), 3 }, - { "rM", NL ("%="), 2 }, - { "rS", NL (">>="), 2 }, - { "rm", NL ("%"), 2 }, - { "rs", NL (">>"), 2 }, - { "st", NL ("sizeof "), 1 }, - { "sz", NL ("sizeof "), 1 }, - { "at", NL ("alignof "), 1 }, - { "az", NL ("alignof "), 1 }, - { NULL, NULL, 0, 0 } -}; - -static struct demangle_component * -d_operator_name (struct d_info *di) -{ - char c1; - char c2; - - c1 = d_next_char (di); - c2 = d_next_char (di); - if (c1 == 'v' && IS_DIGIT (c2)) - return d_make_extended_operator (di, c2 - '0', d_source_name (di)); - else if (c1 == 'c' && c2 == 'v') - return d_make_comp (di, DEMANGLE_COMPONENT_CAST, - cplus_demangle_type (di), NULL); - else - { - /* LOW is the inclusive lower bound. */ - int low = 0; - /* HIGH is the exclusive upper bound. We subtract one to ignore - the sentinel at the end of the array. */ - int high = ((sizeof (cplus_demangle_operators) - / sizeof (cplus_demangle_operators[0])) - - 1); - - while (1) - { - int i; - const struct demangle_operator_info *p; - - i = low + (high - low) / 2; - p = cplus_demangle_operators + i; - - if (c1 == p->code[0] && c2 == p->code[1]) - return d_make_operator (di, p); - - if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1])) - high = i; - else - low = i + 1; - if (low == high) - return NULL; - } - } -} - -static struct demangle_component * -d_make_character (struct d_info *di, int c) -{ - struct demangle_component *p; - p = d_make_empty (di); - if (p != NULL) - { - p->type = DEMANGLE_COMPONENT_CHARACTER; - p->u.s_character.character = c; - } - return p; -} - -static struct demangle_component * -d_java_resource (struct d_info *di) -{ - struct demangle_component *p = NULL; - struct demangle_component *next = NULL; - long len, i; - char c; - const char *str; - - len = d_number (di); - if (len <= 1) - return NULL; - - /* Eat the leading '_'. */ - if (d_next_char (di) != '_') - return NULL; - len--; - - str = d_str (di); - i = 0; - - while (len > 0) - { - c = str[i]; - if (!c) - return NULL; - - /* Each chunk is either a '$' escape... */ - if (c == '$') - { - i++; - switch (str[i++]) - { - case 'S': - c = '/'; - break; - case '_': - c = '.'; - break; - case '$': - c = '$'; - break; - default: - return NULL; - } - next = d_make_character (di, c); - d_advance (di, i); - str = d_str (di); - len -= i; - i = 0; - if (next == NULL) - return NULL; - } - /* ... or a sequence of characters. */ - else - { - while (i < len && str[i] && str[i] != '$') - i++; - - next = d_make_name (di, str, i); - d_advance (di, i); - str = d_str (di); - len -= i; - i = 0; - if (next == NULL) - return NULL; - } - - if (p == NULL) - p = next; - else - { - p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next); - if (p == NULL) - return NULL; - } - } - - p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL); - - return p; -} - -/* ::= TV - ::= TT - ::= TI - ::= TS - ::= GV <(object) name> - ::= T <(base) encoding> - ::= Tc <(base) encoding> - Also g++ extensions: - ::= TC <(offset) number> _ <(base) type> - ::= TF - ::= TJ - ::= GR - ::= GA - ::= Gr -*/ - -static struct demangle_component * -d_special_name (struct d_info *di) -{ - di->expansion += 20; - if (d_check_char (di, 'T')) - { - switch (d_next_char (di)) - { - case 'V': - di->expansion -= 5; - return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE, - cplus_demangle_type (di), NULL); - case 'T': - di->expansion -= 10; - return d_make_comp (di, DEMANGLE_COMPONENT_VTT, - cplus_demangle_type (di), NULL); - case 'I': - return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO, - cplus_demangle_type (di), NULL); - case 'S': - return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME, - cplus_demangle_type (di), NULL); - - case 'h': - if (! d_call_offset (di, 'h')) - return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_THUNK, - d_encoding (di, 0), NULL); - - case 'v': - if (! d_call_offset (di, 'v')) - return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK, - d_encoding (di, 0), NULL); - - case 'c': - if (! d_call_offset (di, '\0')) - return NULL; - if (! d_call_offset (di, '\0')) - return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK, - d_encoding (di, 0), NULL); - - case 'C': - { - struct demangle_component *derived_type; - long offset; - struct demangle_component *base_type; - - derived_type = cplus_demangle_type (di); - offset = d_number (di); - if (offset < 0) - return NULL; - if (! d_check_char (di, '_')) - return NULL; - base_type = cplus_demangle_type (di); - /* We don't display the offset. FIXME: We should display - it in verbose mode. */ - di->expansion += 5; - return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, - base_type, derived_type); - } - - case 'F': - return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN, - cplus_demangle_type (di), NULL); - case 'J': - return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS, - cplus_demangle_type (di), NULL); - - default: - return NULL; - } - } - else if (d_check_char (di, 'G')) - { - switch (d_next_char (di)) - { - case 'V': - return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL); - - case 'R': - return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di), - NULL); - - case 'A': - return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS, - d_encoding (di, 0), NULL); - - case 'r': - return d_java_resource (di); - - default: - return NULL; - } - } - else - return NULL; -} - -/* ::= h _ - ::= v _ - - ::= <(offset) number> - - ::= <(offset) number> _ <(virtual offset) number> - - The C parameter, if not '\0', is a character we just read which is - the start of the . - - We don't display the offset information anywhere. FIXME: We should - display it in verbose mode. */ - -static int -d_call_offset (struct d_info *di, int c) -{ - if (c == '\0') - c = d_next_char (di); - - if (c == 'h') - d_number (di); - else if (c == 'v') - { - d_number (di); - if (! d_check_char (di, '_')) - return 0; - d_number (di); - } - else - return 0; - - if (! d_check_char (di, '_')) - return 0; - - return 1; -} - -/* ::= C1 - ::= C2 - ::= C3 - ::= D0 - ::= D1 - ::= D2 -*/ - -static struct demangle_component * -d_ctor_dtor_name (struct d_info *di) -{ - if (di->last_name != NULL) - { - if (di->last_name->type == DEMANGLE_COMPONENT_NAME) - di->expansion += di->last_name->u.s_name.len; - else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD) - di->expansion += di->last_name->u.s_string.len; - } - switch (d_peek_char (di)) - { - case 'C': - { - enum gnu_v3_ctor_kinds kind; - - switch (d_peek_next_char (di)) - { - case '1': - kind = gnu_v3_complete_object_ctor; - break; - case '2': - kind = gnu_v3_base_object_ctor; - break; - case '3': - kind = gnu_v3_complete_object_allocating_ctor; - break; - default: - return NULL; - } - d_advance (di, 2); - return d_make_ctor (di, kind, di->last_name); - } - - case 'D': - { - enum gnu_v3_dtor_kinds kind; - - switch (d_peek_next_char (di)) - { - case '0': - kind = gnu_v3_deleting_dtor; - break; - case '1': - kind = gnu_v3_complete_object_dtor; - break; - case '2': - kind = gnu_v3_base_object_dtor; - break; - default: - return NULL; - } - d_advance (di, 2); - return d_make_dtor (di, kind, di->last_name); - } - - default: - return NULL; - } -} - -/* ::= - ::= - ::= - ::= - ::= - ::= - ::= - ::= - ::= - ::= P - ::= R - ::= O (C++0x) - ::= C - ::= G - ::= U - - ::= various one letter codes - ::= u -*/ - -CP_STATIC_IF_GLIBCPP_V3 -const struct demangle_builtin_type_info -cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] = -{ - /* a */ { NL ("signed char"), NL ("signed char"), D_PRINT_DEFAULT }, - /* b */ { NL ("bool"), NL ("boolean"), D_PRINT_BOOL }, - /* c */ { NL ("char"), NL ("byte"), D_PRINT_DEFAULT }, - /* d */ { NL ("double"), NL ("double"), D_PRINT_FLOAT }, - /* e */ { NL ("long double"), NL ("long double"), D_PRINT_FLOAT }, - /* f */ { NL ("float"), NL ("float"), D_PRINT_FLOAT }, - /* g */ { NL ("__float128"), NL ("__float128"), D_PRINT_FLOAT }, - /* h */ { NL ("unsigned char"), NL ("unsigned char"), D_PRINT_DEFAULT }, - /* i */ { NL ("int"), NL ("int"), D_PRINT_INT }, - /* j */ { NL ("unsigned int"), NL ("unsigned"), D_PRINT_UNSIGNED }, - /* k */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, - /* l */ { NL ("long"), NL ("long"), D_PRINT_LONG }, - /* m */ { NL ("unsigned long"), NL ("unsigned long"), D_PRINT_UNSIGNED_LONG }, - /* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT }, - /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"), - D_PRINT_DEFAULT }, - /* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, - /* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, - /* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, - /* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT }, - /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT }, - /* u */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, - /* v */ { NL ("void"), NL ("void"), D_PRINT_VOID }, - /* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT }, - /* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG }, - /* y */ { NL ("unsigned long long"), NL ("unsigned long long"), - D_PRINT_UNSIGNED_LONG_LONG }, - /* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT }, - /* 26 */ { NL ("decimal32"), NL ("decimal32"), D_PRINT_DEFAULT }, - /* 27 */ { NL ("decimal64"), NL ("decimal64"), D_PRINT_DEFAULT }, - /* 28 */ { NL ("decimal128"), NL ("decimal128"), D_PRINT_DEFAULT }, - /* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT }, - /* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT }, - /* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT }, -}; - -CP_STATIC_IF_GLIBCPP_V3 -struct demangle_component * -cplus_demangle_type (struct d_info *di) -{ - char peek; - struct demangle_component *ret; - int can_subst; - - /* The ABI specifies that when CV-qualifiers are used, the base type - is substitutable, and the fully qualified type is substitutable, - but the base type with a strict subset of the CV-qualifiers is - not substitutable. The natural recursive implementation of the - CV-qualifiers would cause subsets to be substitutable, so instead - we pull them all off now. - - FIXME: The ABI says that order-insensitive vendor qualifiers - should be handled in the same way, but we have no way to tell - which vendor qualifiers are order-insensitive and which are - order-sensitive. So we just assume that they are all - order-sensitive. g++ 3.4 supports only one vendor qualifier, - __vector, and it treats it as order-sensitive when mangling - names. */ - - peek = d_peek_char (di); - if (peek == 'r' || peek == 'V' || peek == 'K') - { - struct demangle_component **pret; - - pret = d_cv_qualifiers (di, &ret, 0); - if (pret == NULL) - return NULL; - *pret = cplus_demangle_type (di); - if (! *pret || ! d_add_substitution (di, ret)) - return NULL; - return ret; - } - - can_subst = 1; - - switch (peek) - { - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': - case 'h': case 'i': case 'j': case 'l': case 'm': case 'n': - case 'o': case 's': case 't': - case 'v': case 'w': case 'x': case 'y': case 'z': - ret = d_make_builtin_type (di, - &cplus_demangle_builtin_types[peek - 'a']); - di->expansion += ret->u.s_builtin.type->len; - can_subst = 0; - d_advance (di, 1); - break; - - case 'u': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE, - d_source_name (di), NULL); - break; - - case 'F': - ret = d_function_type (di); - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'N': - case 'Z': - ret = d_class_enum_type (di); - break; - - case 'A': - ret = d_array_type (di); - break; - - case 'M': - ret = d_pointer_to_member_type (di); - break; - - case 'T': - ret = d_template_param (di); - if (d_peek_char (di) == 'I') - { - /* This is . The - part is a substitution - candidate. */ - if (! d_add_substitution (di, ret)) - return NULL; - ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, - d_template_args (di)); - } - break; - - case 'S': - /* If this is a special substitution, then it is the start of - . */ - { - char peek_next; - - peek_next = d_peek_next_char (di); - if (IS_DIGIT (peek_next) - || peek_next == '_' - || IS_UPPER (peek_next)) - { - ret = d_substitution (di, 0); - /* The substituted name may have been a template name and - may be followed by tepmlate args. */ - if (d_peek_char (di) == 'I') - ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, - d_template_args (di)); - else - can_subst = 0; - } - else - { - ret = d_class_enum_type (di); - /* If the substitution was a complete type, then it is not - a new substitution candidate. However, if the - substitution was followed by template arguments, then - the whole thing is a substitution candidate. */ - if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD) - can_subst = 0; - } - } - break; - - case 'O': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE, - cplus_demangle_type (di), NULL); - break; - - case 'P': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER, - cplus_demangle_type (di), NULL); - break; - - case 'R': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE, - cplus_demangle_type (di), NULL); - break; - - case 'C': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX, - cplus_demangle_type (di), NULL); - break; - - case 'G': - d_advance (di, 1); - ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY, - cplus_demangle_type (di), NULL); - break; - - case 'U': - d_advance (di, 1); - ret = d_source_name (di); - ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, - cplus_demangle_type (di), ret); - break; - - case 'D': - can_subst = 0; - d_advance (di, 1); - peek = d_next_char (di); - switch (peek) - { - case 'T': - case 't': - /* decltype (expression) */ - ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE, - d_expression (di), NULL); - if (ret && d_next_char (di) != 'E') - ret = NULL; - break; - - case 'p': - /* Pack expansion. */ - ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION, - cplus_demangle_type (di), NULL); - break; - - case 'f': - /* 32-bit decimal floating point */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]); - di->expansion += ret->u.s_builtin.type->len; - break; - case 'd': - /* 64-bit DFP */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]); - di->expansion += ret->u.s_builtin.type->len; - break; - case 'e': - /* 128-bit DFP */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]); - di->expansion += ret->u.s_builtin.type->len; - break; - case 'h': - /* 16-bit half-precision FP */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]); - di->expansion += ret->u.s_builtin.type->len; - break; - case 's': - /* char16_t */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]); - di->expansion += ret->u.s_builtin.type->len; - break; - case 'i': - /* char32_t */ - ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]); - di->expansion += ret->u.s_builtin.type->len; - break; - - case 'F': - /* Fixed point types. DF */ - ret = d_make_empty (di); - ret->type = DEMANGLE_COMPONENT_FIXED_TYPE; - if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di)))) - /* For demangling we don't care about the bits. */ - d_number (di); - ret->u.s_fixed.length = cplus_demangle_type (di); - d_number (di); - peek = d_next_char (di); - ret->u.s_fixed.sat = (peek == 's'); - break; - - default: - return NULL; - } - break; - - default: - return NULL; - } - - if (can_subst) - { - if (! d_add_substitution (di, ret)) - return NULL; - } - - return ret; -} - -/* ::= [r] [V] [K] */ - -static struct demangle_component ** -d_cv_qualifiers (struct d_info *di, - struct demangle_component **pret, int member_fn) -{ - char peek; - - peek = d_peek_char (di); - while (peek == 'r' || peek == 'V' || peek == 'K') - { - enum demangle_component_type t; - - d_advance (di, 1); - if (peek == 'r') - { - t = (member_fn - ? DEMANGLE_COMPONENT_RESTRICT_THIS - : DEMANGLE_COMPONENT_RESTRICT); - di->expansion += sizeof "restrict"; - } - else if (peek == 'V') - { - t = (member_fn - ? DEMANGLE_COMPONENT_VOLATILE_THIS - : DEMANGLE_COMPONENT_VOLATILE); - di->expansion += sizeof "volatile"; - } - else - { - t = (member_fn - ? DEMANGLE_COMPONENT_CONST_THIS - : DEMANGLE_COMPONENT_CONST); - di->expansion += sizeof "const"; - } - - *pret = d_make_comp (di, t, NULL, NULL); - if (*pret == NULL) - return NULL; - pret = &d_left (*pret); - - peek = d_peek_char (di); - } - - return pret; -} - -/* ::= F [Y] E */ - -static struct demangle_component * -d_function_type (struct d_info *di) -{ - struct demangle_component *ret; - - if (! d_check_char (di, 'F')) - return NULL; - if (d_peek_char (di) == 'Y') - { - /* Function has C linkage. We don't print this information. - FIXME: We should print it in verbose mode. */ - d_advance (di, 1); - } - ret = d_bare_function_type (di, 1); - if (! d_check_char (di, 'E')) - return NULL; - return ret; -} - -/* ::= [J]+ */ - -static struct demangle_component * -d_bare_function_type (struct d_info *di, int has_return_type) -{ - struct demangle_component *return_type; - struct demangle_component *tl; - struct demangle_component **ptl; - char peek; - - /* Detect special qualifier indicating that the first argument - is the return type. */ - peek = d_peek_char (di); - if (peek == 'J') - { - d_advance (di, 1); - has_return_type = 1; - } - - return_type = NULL; - tl = NULL; - ptl = &tl; - while (1) - { - struct demangle_component *type; - - peek = d_peek_char (di); - if (peek == '\0' || peek == 'E') - break; - type = cplus_demangle_type (di); - if (type == NULL) - return NULL; - if (has_return_type) - { - return_type = type; - has_return_type = 0; - } - else - { - *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL); - if (*ptl == NULL) - return NULL; - ptl = &d_right (*ptl); - } - } - - /* There should be at least one parameter type besides the optional - return type. A function which takes no arguments will have a - single parameter type void. */ - if (tl == NULL) - return NULL; - - /* If we have a single parameter type void, omit it. */ - if (d_right (tl) == NULL - && d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE - && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID) - { - di->expansion -= d_left (tl)->u.s_builtin.type->len; - tl = NULL; - } - - return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl); -} - -/* ::= */ - -static struct demangle_component * -d_class_enum_type (struct d_info *di) -{ - return d_name (di); -} - -/* ::= A <(positive dimension) number> _ <(element) type> - ::= A [<(dimension) expression>] _ <(element) type> -*/ - -static struct demangle_component * -d_array_type (struct d_info *di) -{ - char peek; - struct demangle_component *dim; - - if (! d_check_char (di, 'A')) - return NULL; - - peek = d_peek_char (di); - if (peek == '_') - dim = NULL; - else if (IS_DIGIT (peek)) - { - const char *s; - - s = d_str (di); - do - { - d_advance (di, 1); - peek = d_peek_char (di); - } - while (IS_DIGIT (peek)); - dim = d_make_name (di, s, d_str (di) - s); - if (dim == NULL) - return NULL; - } - else - { - dim = d_expression (di); - if (dim == NULL) - return NULL; - } - - if (! d_check_char (di, '_')) - return NULL; - - return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim, - cplus_demangle_type (di)); -} - -/* ::= M <(class) type> <(member) type> */ - -static struct demangle_component * -d_pointer_to_member_type (struct d_info *di) -{ - struct demangle_component *cl; - struct demangle_component *mem; - struct demangle_component **pmem; - - if (! d_check_char (di, 'M')) - return NULL; - - cl = cplus_demangle_type (di); - - /* The ABI specifies that any type can be a substitution source, and - that M is followed by two types, and that when a CV-qualified - type is seen both the base type and the CV-qualified types are - substitution sources. The ABI also specifies that for a pointer - to a CV-qualified member function, the qualifiers are attached to - the second type. Given the grammar, a plain reading of the ABI - suggests that both the CV-qualified member function and the - non-qualified member function are substitution sources. However, - g++ does not work that way. g++ treats only the CV-qualified - member function as a substitution source. FIXME. So to work - with g++, we need to pull off the CV-qualifiers here, in order to - avoid calling add_substitution() in cplus_demangle_type(). But - for a CV-qualified member which is not a function, g++ does - follow the ABI, so we need to handle that case here by calling - d_add_substitution ourselves. */ - - pmem = d_cv_qualifiers (di, &mem, 1); - if (pmem == NULL) - return NULL; - *pmem = cplus_demangle_type (di); - if (*pmem == NULL) - return NULL; - - if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE) - { - if (! d_add_substitution (di, mem)) - return NULL; - } - - return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem); -} - -/* ::= T_ - ::= T <(parameter-2 non-negative) number> _ -*/ - -static struct demangle_component * -d_template_param (struct d_info *di) -{ - long param; - - if (! d_check_char (di, 'T')) - return NULL; - - if (d_peek_char (di) == '_') - param = 0; - else - { - param = d_number (di); - if (param < 0) - return NULL; - param += 1; - } - - if (! d_check_char (di, '_')) - return NULL; - - ++di->did_subs; - - return d_make_template_param (di, param); -} - -/* ::= I + E */ - -static struct demangle_component * -d_template_args (struct d_info *di) -{ - struct demangle_component *hold_last_name; - struct demangle_component *al; - struct demangle_component **pal; - - /* Preserve the last name we saw--don't let the template arguments - clobber it, as that would give us the wrong name for a subsequent - constructor or destructor. */ - hold_last_name = di->last_name; - - if (! d_check_char (di, 'I')) - return NULL; - - if (d_peek_char (di) == 'E') - { - /* An argument pack can be empty. */ - d_advance (di, 1); - return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL); - } - - al = NULL; - pal = &al; - while (1) - { - struct demangle_component *a; - - a = d_template_arg (di); - if (a == NULL) - return NULL; - - *pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL); - if (*pal == NULL) - return NULL; - pal = &d_right (*pal); - - if (d_peek_char (di) == 'E') - { - d_advance (di, 1); - break; - } - } - - di->last_name = hold_last_name; - - return al; -} - -/* ::= - ::= X E - ::= -*/ - -static struct demangle_component * -d_template_arg (struct d_info *di) -{ - struct demangle_component *ret; - - switch (d_peek_char (di)) - { - case 'X': - d_advance (di, 1); - ret = d_expression (di); - if (! d_check_char (di, 'E')) - return NULL; - return ret; - - case 'L': - return d_expr_primary (di); - - case 'I': - /* An argument pack. */ - return d_template_args (di); - - default: - return cplus_demangle_type (di); - } -} - -/* Subroutine of ::= cl + E */ - -static struct demangle_component * -d_exprlist (struct d_info *di) -{ - struct demangle_component *list = NULL; - struct demangle_component **p = &list; - - if (d_peek_char (di) == 'E') - { - d_advance (di, 1); - return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL); - } - - while (1) - { - struct demangle_component *arg = d_expression (di); - if (arg == NULL) - return NULL; - - *p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL); - if (*p == NULL) - return NULL; - p = &d_right (*p); - - if (d_peek_char (di) == 'E') - { - d_advance (di, 1); - break; - } - } - - return list; -} - -/* ::= <(unary) operator-name> - ::= <(binary) operator-name> - ::= <(trinary) operator-name> - ::= cl + E - ::= st - ::= - ::= sr - ::= sr - ::= -*/ - -static struct demangle_component * -d_expression (struct d_info *di) -{ - char peek; - - peek = d_peek_char (di); - if (peek == 'L') - return d_expr_primary (di); - else if (peek == 'T') - return d_template_param (di); - else if (peek == 's' && d_peek_next_char (di) == 'r') - { - struct demangle_component *type; - struct demangle_component *name; - - d_advance (di, 2); - type = cplus_demangle_type (di); - name = d_unqualified_name (di); - if (d_peek_char (di) != 'I') - return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name); - else - return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, - d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, - d_template_args (di))); - } - else if (peek == 's' && d_peek_next_char (di) == 'p') - { - d_advance (di, 2); - return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION, - d_expression (di), NULL); - } - else if (peek == 'f' && d_peek_next_char (di) == 'p') - { - /* Function parameter used in a late-specified return type. */ - int index; - d_advance (di, 2); - if (d_peek_char (di) == '_') - index = 1; - else - { - index = d_number (di); - if (index < 0) - return NULL; - index += 2; - } - - if (! d_check_char (di, '_')) - return NULL; - - return d_make_function_param (di, index); - } - else if (IS_DIGIT (peek)) - { - /* We can get an unqualified name as an expression in the case of - a dependent member access, i.e. decltype(T().i). */ - struct demangle_component *name = d_unqualified_name (di); - if (name == NULL) - return NULL; - if (d_peek_char (di) == 'I') - return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, - d_template_args (di)); - else - return name; - } - else - { - struct demangle_component *op; - int args; - - op = d_operator_name (di); - if (op == NULL) - return NULL; - - if (op->type == DEMANGLE_COMPONENT_OPERATOR) - di->expansion += op->u.s_operator.op->len - 2; - - if (op->type == DEMANGLE_COMPONENT_OPERATOR - && strcmp (op->u.s_operator.op->code, "st") == 0) - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - cplus_demangle_type (di)); - - switch (op->type) - { - default: - return NULL; - case DEMANGLE_COMPONENT_OPERATOR: - args = op->u.s_operator.op->args; - break; - case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: - args = op->u.s_extended_operator.args; - break; - case DEMANGLE_COMPONENT_CAST: - args = 1; - break; - } - - switch (args) - { - case 1: - { - struct demangle_component *operand; - if (op->type == DEMANGLE_COMPONENT_CAST - && d_check_char (di, '_')) - operand = d_exprlist (di); - else - operand = d_expression (di); - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - operand); - } - case 2: - { - struct demangle_component *left; - struct demangle_component *right; - - left = d_expression (di); - if (!strcmp (op->u.s_operator.op->code, "cl")) - right = d_exprlist (di); - else - right = d_expression (di); - - return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op, - d_make_comp (di, - DEMANGLE_COMPONENT_BINARY_ARGS, - left, right)); - } - case 3: - { - struct demangle_component *first; - struct demangle_component *second; - - first = d_expression (di); - second = d_expression (di); - return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op, - d_make_comp (di, - DEMANGLE_COMPONENT_TRINARY_ARG1, - first, - d_make_comp (di, - DEMANGLE_COMPONENT_TRINARY_ARG2, - second, - d_expression (di)))); - } - default: - return NULL; - } - } -} - -/* ::= L <(value) number> E - ::= L <(value) float> E - ::= L E -*/ - -static struct demangle_component * -d_expr_primary (struct d_info *di) -{ - struct demangle_component *ret; - - if (! d_check_char (di, 'L')) - return NULL; - if (d_peek_char (di) == '_' - /* Workaround for G++ bug; see comment in write_template_arg. */ - || d_peek_char (di) == 'Z') - ret = cplus_demangle_mangled_name (di, 0); - else - { - struct demangle_component *type; - enum demangle_component_type t; - const char *s; - - type = cplus_demangle_type (di); - if (type == NULL) - return NULL; - - /* If we have a type we know how to print, we aren't going to - print the type name itself. */ - if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE - && type->u.s_builtin.type->print != D_PRINT_DEFAULT) - di->expansion -= type->u.s_builtin.type->len; - - /* Rather than try to interpret the literal value, we just - collect it as a string. Note that it's possible to have a - floating point literal here. The ABI specifies that the - format of such literals is machine independent. That's fine, - but what's not fine is that versions of g++ up to 3.2 with - -fabi-version=1 used upper case letters in the hex constant, - and dumped out gcc's internal representation. That makes it - hard to tell where the constant ends, and hard to dump the - constant in any readable form anyhow. We don't attempt to - handle these cases. */ - - t = DEMANGLE_COMPONENT_LITERAL; - if (d_peek_char (di) == 'n') - { - t = DEMANGLE_COMPONENT_LITERAL_NEG; - d_advance (di, 1); - } - s = d_str (di); - while (d_peek_char (di) != 'E') - { - if (d_peek_char (di) == '\0') - return NULL; - d_advance (di, 1); - } - ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s)); - } - if (! d_check_char (di, 'E')) - return NULL; - return ret; -} - -/* ::= Z <(function) encoding> E <(entity) name> [] - ::= Z <(function) encoding> E s [] -*/ - -static struct demangle_component * -d_local_name (struct d_info *di) -{ - struct demangle_component *function; - - if (! d_check_char (di, 'Z')) - return NULL; - - function = d_encoding (di, 0); - - if (! d_check_char (di, 'E')) - return NULL; - - if (d_peek_char (di) == 's') - { - d_advance (di, 1); - if (! d_discriminator (di)) - return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, - d_make_name (di, "string literal", - sizeof "string literal" - 1)); - } - else - { - struct demangle_component *name; - - name = d_name (di); - if (! d_discriminator (di)) - return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name); - } -} - -/* ::= _ <(non-negative) number> - - We demangle the discriminator, but we don't print it out. FIXME: - We should print it out in verbose mode. */ - -static int -d_discriminator (struct d_info *di) -{ - long discrim; - - if (d_peek_char (di) != '_') - return 1; - d_advance (di, 1); - discrim = d_number (di); - if (discrim < 0) - return 0; - return 1; -} - -/* Add a new substitution. */ - -static int -d_add_substitution (struct d_info *di, struct demangle_component *dc) -{ - if (dc == NULL) - return 0; - if (di->next_sub >= di->num_subs) - return 0; - di->subs[di->next_sub] = dc; - ++di->next_sub; - return 1; -} - -/* ::= S _ - ::= S_ - ::= St - ::= Sa - ::= Sb - ::= Ss - ::= Si - ::= So - ::= Sd - - If PREFIX is non-zero, then this type is being used as a prefix in - a qualified name. In this case, for the standard substitutions, we - need to check whether we are being used as a prefix for a - constructor or destructor, and return a full template name. - Otherwise we will get something like std::iostream::~iostream() - which does not correspond particularly well to any function which - actually appears in the source. -*/ - -static const struct d_standard_sub_info standard_subs[] = -{ - { 't', NL ("std"), - NL ("std"), - NULL, 0 }, - { 'a', NL ("std::allocator"), - NL ("std::allocator"), - NL ("allocator") }, - { 'b', NL ("std::basic_string"), - NL ("std::basic_string"), - NL ("basic_string") }, - { 's', NL ("std::string"), - NL ("std::basic_string, std::allocator >"), - NL ("basic_string") }, - { 'i', NL ("std::istream"), - NL ("std::basic_istream >"), - NL ("basic_istream") }, - { 'o', NL ("std::ostream"), - NL ("std::basic_ostream >"), - NL ("basic_ostream") }, - { 'd', NL ("std::iostream"), - NL ("std::basic_iostream >"), - NL ("basic_iostream") } -}; - -static struct demangle_component * -d_substitution (struct d_info *di, int prefix) -{ - char c; - - if (! d_check_char (di, 'S')) - return NULL; - - c = d_next_char (di); - if (c == '_' || IS_DIGIT (c) || IS_UPPER (c)) - { - unsigned int id; - - id = 0; - if (c != '_') - { - do - { - unsigned int new_id; - - if (IS_DIGIT (c)) - new_id = id * 36 + c - '0'; - else if (IS_UPPER (c)) - new_id = id * 36 + c - 'A' + 10; - else - return NULL; - if (new_id < id) - return NULL; - id = new_id; - c = d_next_char (di); - } - while (c != '_'); - - ++id; - } - - if (id >= (unsigned int) di->next_sub) - return NULL; - - ++di->did_subs; - - return di->subs[id]; - } - else - { - int verbose; - const struct d_standard_sub_info *p; - const struct d_standard_sub_info *pend; - - verbose = (di->options & DMGL_VERBOSE) != 0; - if (! verbose && prefix) - { - char peek; - - peek = d_peek_char (di); - if (peek == 'C' || peek == 'D') - verbose = 1; - } - - pend = (&standard_subs[0] - + sizeof standard_subs / sizeof standard_subs[0]); - for (p = &standard_subs[0]; p < pend; ++p) - { - if (c == p->code) - { - const char *s; - int len; - - if (p->set_last_name != NULL) - di->last_name = d_make_sub (di, p->set_last_name, - p->set_last_name_len); - if (verbose) - { - s = p->full_expansion; - len = p->full_len; - } - else - { - s = p->simple_expansion; - len = p->simple_len; - } - di->expansion += len; - return d_make_sub (di, s, len); - } - } - - return NULL; - } -} - -/* Initialize a growable string. */ - -static void -d_growable_string_init (struct d_growable_string *dgs, size_t estimate) -{ - dgs->buf = NULL; - dgs->len = 0; - dgs->alc = 0; - dgs->allocation_failure = 0; - - if (estimate > 0) - d_growable_string_resize (dgs, estimate); -} - -/* Grow a growable string to a given size. */ - -static inline void -d_growable_string_resize (struct d_growable_string *dgs, size_t need) -{ - size_t newalc; - char *newbuf; - - if (dgs->allocation_failure) - return; - - /* Start allocation at two bytes to avoid any possibility of confusion - with the special value of 1 used as a return in *palc to indicate - allocation failures. */ - newalc = dgs->alc > 0 ? dgs->alc : 2; - while (newalc < need) - newalc <<= 1; - - newbuf = (char *) realloc (dgs->buf, newalc); - if (newbuf == NULL) - { - free (dgs->buf); - dgs->buf = NULL; - dgs->len = 0; - dgs->alc = 0; - dgs->allocation_failure = 1; - return; - } - dgs->buf = newbuf; - dgs->alc = newalc; -} - -/* Append a buffer to a growable string. */ - -static inline void -d_growable_string_append_buffer (struct d_growable_string *dgs, - const char *s, size_t l) -{ - size_t need; - - need = dgs->len + l + 1; - if (need > dgs->alc) - d_growable_string_resize (dgs, need); - - if (dgs->allocation_failure) - return; - - memcpy (dgs->buf + dgs->len, s, l); - dgs->buf[dgs->len + l] = '\0'; - dgs->len += l; -} - -/* Bridge growable strings to the callback mechanism. */ - -static void -d_growable_string_callback_adapter (const char *s, size_t l, void *opaque) -{ - struct d_growable_string *dgs = (struct d_growable_string*) opaque; - - d_growable_string_append_buffer (dgs, s, l); -} - -/* Initialize a print information structure. */ - -static void -d_print_init (struct d_print_info *dpi, int options, - demangle_callbackref callback, void *opaque) -{ - dpi->options = options; - dpi->len = 0; - dpi->last_char = '\0'; - dpi->templates = NULL; - dpi->modifiers = NULL; - - dpi->callback = callback; - dpi->opaque = opaque; - - dpi->demangle_failure = 0; -} - -/* Indicate that an error occurred during printing, and test for error. */ - -static inline void -d_print_error (struct d_print_info *dpi) -{ - dpi->demangle_failure = 1; -} - -static inline int -d_print_saw_error (struct d_print_info *dpi) -{ - return dpi->demangle_failure != 0; -} - -/* Flush buffered characters to the callback. */ - -static inline void -d_print_flush (struct d_print_info *dpi) -{ - dpi->buf[dpi->len] = '\0'; - dpi->callback (dpi->buf, dpi->len, dpi->opaque); - dpi->len = 0; -} - -/* Append characters and buffers for printing. */ - -static inline void -d_append_char (struct d_print_info *dpi, char c) -{ - if (dpi->len == sizeof (dpi->buf) - 1) - d_print_flush (dpi); - - dpi->buf[dpi->len++] = c; - dpi->last_char = c; -} - -static inline void -d_append_buffer (struct d_print_info *dpi, const char *s, size_t l) -{ - size_t i; - - for (i = 0; i < l; i++) - d_append_char (dpi, s[i]); -} - -static inline void -d_append_string (struct d_print_info *dpi, const char *s) -{ - d_append_buffer (dpi, s, strlen (s)); -} - -static inline char -d_last_char (struct d_print_info *dpi) -{ - return dpi->last_char; -} - -/* Turn components into a human readable string. OPTIONS is the - options bits passed to the demangler. DC is the tree to print. - CALLBACK is a function to call to flush demangled string segments - as they fill the intermediate buffer, and OPAQUE is a generalized - callback argument. On success, this returns 1. On failure, - it returns 0, indicating a bad parse. It does not use heap - memory to build an output string, so cannot encounter memory - allocation failure. */ - -CP_STATIC_IF_GLIBCPP_V3 -int -cplus_demangle_print_callback (int options, - const struct demangle_component *dc, - demangle_callbackref callback, void *opaque) -{ - struct d_print_info dpi; - - d_print_init (&dpi, options, callback, opaque); - - d_print_comp (&dpi, dc); - - d_print_flush (&dpi); - - return ! d_print_saw_error (&dpi); -} - -/* Turn components into a human readable string. OPTIONS is the - options bits passed to the demangler. DC is the tree to print. - ESTIMATE is a guess at the length of the result. This returns a - string allocated by malloc, or NULL on error. On success, this - sets *PALC to the size of the allocated buffer. On failure, this - sets *PALC to 0 for a bad parse, or to 1 for a memory allocation - failure. */ - -CP_STATIC_IF_GLIBCPP_V3 -char * -cplus_demangle_print (int options, const struct demangle_component *dc, - int estimate, size_t *palc) -{ - struct d_growable_string dgs; - - d_growable_string_init (&dgs, estimate); - - if (! cplus_demangle_print_callback (options, dc, - d_growable_string_callback_adapter, - &dgs)) - { - free (dgs.buf); - *palc = 0; - return NULL; - } - - *palc = dgs.allocation_failure ? 1 : dgs.alc; - return dgs.buf; -} - -/* Returns the I'th element of the template arglist ARGS, or NULL on - failure. */ - -static struct demangle_component * -d_index_template_argument (struct demangle_component *args, int i) -{ - struct demangle_component *a; - - for (a = args; - a != NULL; - a = d_right (a)) - { - if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) - return NULL; - if (i <= 0) - break; - --i; - } - if (i != 0 || a == NULL) - return NULL; - - return d_left (a); -} - -/* Returns the template argument from the current context indicated by DC, - which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL. */ - -static struct demangle_component * -d_lookup_template_argument (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - if (dpi->templates == NULL) - { - d_print_error (dpi); - return NULL; - } - - return d_index_template_argument - (d_right (dpi->templates->template_decl), - dc->u.s_number.number); -} - -/* Returns a template argument pack used in DC (any will do), or NULL. */ - -static struct demangle_component * -d_find_pack (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - struct demangle_component *a; - if (dc == NULL) - return NULL; - - switch (dc->type) - { - case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - a = d_lookup_template_argument (dpi, dc); - if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) - return a; - return NULL; - - case DEMANGLE_COMPONENT_PACK_EXPANSION: - return NULL; - - case DEMANGLE_COMPONENT_NAME: - case DEMANGLE_COMPONENT_OPERATOR: - case DEMANGLE_COMPONENT_BUILTIN_TYPE: - case DEMANGLE_COMPONENT_SUB_STD: - case DEMANGLE_COMPONENT_CHARACTER: - case DEMANGLE_COMPONENT_FUNCTION_PARAM: - return NULL; - - case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: - return d_find_pack (dpi, dc->u.s_extended_operator.name); - case DEMANGLE_COMPONENT_CTOR: - return d_find_pack (dpi, dc->u.s_ctor.name); - case DEMANGLE_COMPONENT_DTOR: - return d_find_pack (dpi, dc->u.s_dtor.name); - - default: - a = d_find_pack (dpi, d_left (dc)); - if (a) - return a; - return d_find_pack (dpi, d_right (dc)); - } -} - -/* Returns the length of the template argument pack DC. */ - -static int -d_pack_length (const struct demangle_component *dc) -{ - int count = 0; - while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST - && d_left (dc) != NULL) - { - ++count; - dc = d_right (dc); - } - return count; -} - -/* DC is a component of a mangled expression. Print it, wrapped in parens - if needed. */ - -static void -d_print_subexpr (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - int simple = 0; - if (dc->type == DEMANGLE_COMPONENT_NAME - || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM) - simple = 1; - if (!simple) - d_append_char (dpi, '('); - d_print_comp (dpi, dc); - if (!simple) - d_append_char (dpi, ')'); -} - -/* Subroutine to handle components. */ - -static void -d_print_comp (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - if (dc == NULL) - { - d_print_error (dpi); - return; - } - if (d_print_saw_error (dpi)) - return; - - switch (dc->type) - { - case DEMANGLE_COMPONENT_NAME: - if ((dpi->options & DMGL_JAVA) == 0) - d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len); - else - d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len); - return; - - case DEMANGLE_COMPONENT_QUAL_NAME: - case DEMANGLE_COMPONENT_LOCAL_NAME: - d_print_comp (dpi, d_left (dc)); - if ((dpi->options & DMGL_JAVA) == 0) - d_append_string (dpi, "::"); - else - d_append_char (dpi, '.'); - d_print_comp (dpi, d_right (dc)); - return; - - case DEMANGLE_COMPONENT_TYPED_NAME: - { - struct d_print_mod *hold_modifiers; - struct demangle_component *typed_name; - struct d_print_mod adpm[4]; - unsigned int i; - struct d_print_template dpt; - - /* Pass the name down to the type so that it can be printed in - the right place for the type. We also have to pass down - any CV-qualifiers, which apply to the this parameter. */ - hold_modifiers = dpi->modifiers; - dpi->modifiers = 0; - i = 0; - typed_name = d_left (dc); - while (typed_name != NULL) - { - if (i >= sizeof adpm / sizeof adpm[0]) - { - d_print_error (dpi); - return; - } - - adpm[i].next = dpi->modifiers; - dpi->modifiers = &adpm[i]; - adpm[i].mod = typed_name; - adpm[i].printed = 0; - adpm[i].templates = dpi->templates; - ++i; - - if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS - && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS - && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS) - break; - - typed_name = d_left (typed_name); - } - - if (typed_name == NULL) - { - d_print_error (dpi); - return; - } - - /* If typed_name is a template, then it applies to the - function type as well. */ - if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE) - { - dpt.next = dpi->templates; - dpi->templates = &dpt; - dpt.template_decl = typed_name; - } - - /* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then - there may be CV-qualifiers on its right argument which - really apply here; this happens when parsing a class which - is local to a function. */ - if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME) - { - struct demangle_component *local_name; - - local_name = d_right (typed_name); - while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || local_name->type == DEMANGLE_COMPONENT_CONST_THIS) - { - if (i >= sizeof adpm / sizeof adpm[0]) - { - d_print_error (dpi); - return; - } - - adpm[i] = adpm[i - 1]; - adpm[i].next = &adpm[i - 1]; - dpi->modifiers = &adpm[i]; - - adpm[i - 1].mod = local_name; - adpm[i - 1].printed = 0; - adpm[i - 1].templates = dpi->templates; - ++i; - - local_name = d_left (local_name); - } - } - - d_print_comp (dpi, d_right (dc)); - - if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE) - dpi->templates = dpt.next; - - /* If the modifiers didn't get printed by the type, print them - now. */ - while (i > 0) - { - --i; - if (! adpm[i].printed) - { - d_append_char (dpi, ' '); - d_print_mod (dpi, adpm[i].mod); - } - } - - dpi->modifiers = hold_modifiers; - - return; - } - - case DEMANGLE_COMPONENT_TEMPLATE: - { - struct d_print_mod *hold_dpm; - struct demangle_component *dcl; - - /* Don't push modifiers into a template definition. Doing so - could give the wrong definition for a template argument. - Instead, treat the template essentially as a name. */ - - hold_dpm = dpi->modifiers; - dpi->modifiers = NULL; - - dcl = d_left (dc); - - if ((dpi->options & DMGL_JAVA) != 0 - && dcl->type == DEMANGLE_COMPONENT_NAME - && dcl->u.s_name.len == 6 - && strncmp (dcl->u.s_name.s, "JArray", 6) == 0) - { - /* Special-case Java arrays, so that JArray appears - instead as TYPE[]. */ - - d_print_comp (dpi, d_right (dc)); - d_append_string (dpi, "[]"); - } - else - { - d_print_comp (dpi, dcl); - if (d_last_char (dpi) == '<') - d_append_char (dpi, ' '); - d_append_char (dpi, '<'); - d_print_comp (dpi, d_right (dc)); - /* Avoid generating two consecutive '>' characters, to avoid - the C++ syntactic ambiguity. */ - if (d_last_char (dpi) == '>') - d_append_char (dpi, ' '); - d_append_char (dpi, '>'); - } - - dpi->modifiers = hold_dpm; - - return; - } - - case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - { - struct d_print_template *hold_dpt; - struct demangle_component *a = d_lookup_template_argument (dpi, dc); - - if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) - a = d_index_template_argument (a, dpi->pack_index); - - if (a == NULL) - { - d_print_error (dpi); - return; - } - - /* While processing this parameter, we need to pop the list of - templates. This is because the template parameter may - itself be a reference to a parameter of an outer - template. */ - - hold_dpt = dpi->templates; - dpi->templates = hold_dpt->next; - - d_print_comp (dpi, a); - - dpi->templates = hold_dpt; - - return; - } - - case DEMANGLE_COMPONENT_CTOR: - d_print_comp (dpi, dc->u.s_ctor.name); - return; - - case DEMANGLE_COMPONENT_DTOR: - d_append_char (dpi, '~'); - d_print_comp (dpi, dc->u.s_dtor.name); - return; - - case DEMANGLE_COMPONENT_VTABLE: - d_append_string (dpi, "vtable for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_VTT: - d_append_string (dpi, "VTT for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: - d_append_string (dpi, "construction vtable for "); - d_print_comp (dpi, d_left (dc)); - d_append_string (dpi, "-in-"); - d_print_comp (dpi, d_right (dc)); - return; - - case DEMANGLE_COMPONENT_TYPEINFO: - d_append_string (dpi, "typeinfo for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_TYPEINFO_NAME: - d_append_string (dpi, "typeinfo name for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_TYPEINFO_FN: - d_append_string (dpi, "typeinfo fn for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_THUNK: - d_append_string (dpi, "non-virtual thunk to "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_VIRTUAL_THUNK: - d_append_string (dpi, "virtual thunk to "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_COVARIANT_THUNK: - d_append_string (dpi, "covariant return thunk to "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_JAVA_CLASS: - d_append_string (dpi, "java Class for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_GUARD: - d_append_string (dpi, "guard variable for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_REFTEMP: - d_append_string (dpi, "reference temporary for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_HIDDEN_ALIAS: - d_append_string (dpi, "hidden alias for "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_SUB_STD: - d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len); - return; - - case DEMANGLE_COMPONENT_RESTRICT: - case DEMANGLE_COMPONENT_VOLATILE: - case DEMANGLE_COMPONENT_CONST: - { - struct d_print_mod *pdpm; - - /* When printing arrays, it's possible to have cases where the - same CV-qualifier gets pushed on the stack multiple times. - We only need to print it once. */ - - for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next) - { - if (! pdpm->printed) - { - if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT - && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE - && pdpm->mod->type != DEMANGLE_COMPONENT_CONST) - break; - if (pdpm->mod->type == dc->type) - { - d_print_comp (dpi, d_left (dc)); - return; - } - } - } - } - /* Fall through. */ - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - case DEMANGLE_COMPONENT_POINTER: - case DEMANGLE_COMPONENT_REFERENCE: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: - case DEMANGLE_COMPONENT_COMPLEX: - case DEMANGLE_COMPONENT_IMAGINARY: - { - /* We keep a list of modifiers on the stack. */ - struct d_print_mod dpm; - - dpm.next = dpi->modifiers; - dpi->modifiers = &dpm; - dpm.mod = dc; - dpm.printed = 0; - dpm.templates = dpi->templates; - - d_print_comp (dpi, d_left (dc)); - - /* If the modifier didn't get printed by the type, print it - now. */ - if (! dpm.printed) - d_print_mod (dpi, dc); - - dpi->modifiers = dpm.next; - - return; - } - - case DEMANGLE_COMPONENT_BUILTIN_TYPE: - if ((dpi->options & DMGL_JAVA) == 0) - d_append_buffer (dpi, dc->u.s_builtin.type->name, - dc->u.s_builtin.type->len); - else - d_append_buffer (dpi, dc->u.s_builtin.type->java_name, - dc->u.s_builtin.type->java_len); - return; - - case DEMANGLE_COMPONENT_VENDOR_TYPE: - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_FUNCTION_TYPE: - { - if ((dpi->options & DMGL_RET_POSTFIX) != 0) - d_print_function_type (dpi, dc, dpi->modifiers); - - /* Print return type if present */ - if (d_left (dc) != NULL) - { - struct d_print_mod dpm; - - /* We must pass this type down as a modifier in order to - print it in the right location. */ - dpm.next = dpi->modifiers; - dpi->modifiers = &dpm; - dpm.mod = dc; - dpm.printed = 0; - dpm.templates = dpi->templates; - - d_print_comp (dpi, d_left (dc)); - - dpi->modifiers = dpm.next; - - if (dpm.printed) - return; - - /* In standard prefix notation, there is a space between the - return type and the function signature. */ - if ((dpi->options & DMGL_RET_POSTFIX) == 0) - d_append_char (dpi, ' '); - } - - if ((dpi->options & DMGL_RET_POSTFIX) == 0) - d_print_function_type (dpi, dc, dpi->modifiers); - - return; - } - - case DEMANGLE_COMPONENT_ARRAY_TYPE: - { - struct d_print_mod *hold_modifiers; - struct d_print_mod adpm[4]; - unsigned int i; - struct d_print_mod *pdpm; - - /* We must pass this type down as a modifier in order to print - multi-dimensional arrays correctly. If the array itself is - CV-qualified, we act as though the element type were - CV-qualified. We do this by copying the modifiers down - rather than fiddling pointers, so that we don't wind up - with a d_print_mod higher on the stack pointing into our - stack frame after we return. */ - - hold_modifiers = dpi->modifiers; - - adpm[0].next = hold_modifiers; - dpi->modifiers = &adpm[0]; - adpm[0].mod = dc; - adpm[0].printed = 0; - adpm[0].templates = dpi->templates; - - i = 1; - pdpm = hold_modifiers; - while (pdpm != NULL - && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT - || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE - || pdpm->mod->type == DEMANGLE_COMPONENT_CONST)) - { - if (! pdpm->printed) - { - if (i >= sizeof adpm / sizeof adpm[0]) - { - d_print_error (dpi); - return; - } - - adpm[i] = *pdpm; - adpm[i].next = dpi->modifiers; - dpi->modifiers = &adpm[i]; - pdpm->printed = 1; - ++i; - } - - pdpm = pdpm->next; - } - - d_print_comp (dpi, d_right (dc)); - - dpi->modifiers = hold_modifiers; - - if (adpm[0].printed) - return; - - while (i > 1) - { - --i; - d_print_mod (dpi, adpm[i].mod); - } - - d_print_array_type (dpi, dc, dpi->modifiers); - - return; - } - - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - { - struct d_print_mod dpm; - - dpm.next = dpi->modifiers; - dpi->modifiers = &dpm; - dpm.mod = dc; - dpm.printed = 0; - dpm.templates = dpi->templates; - - d_print_comp (dpi, d_right (dc)); - - /* If the modifier didn't get printed by the type, print it - now. */ - if (! dpm.printed) - { - d_append_char (dpi, ' '); - d_print_comp (dpi, d_left (dc)); - d_append_string (dpi, "::*"); - } - - dpi->modifiers = dpm.next; - - return; - } - - case DEMANGLE_COMPONENT_FIXED_TYPE: - if (dc->u.s_fixed.sat) - d_append_string (dpi, "_Sat "); - /* Don't print "int _Accum". */ - if (dc->u.s_fixed.length->u.s_builtin.type - != &cplus_demangle_builtin_types['i'-'a']) - { - d_print_comp (dpi, dc->u.s_fixed.length); - d_append_char (dpi, ' '); - } - if (dc->u.s_fixed.accum) - d_append_string (dpi, "_Accum"); - else - d_append_string (dpi, "_Fract"); - return; - - case DEMANGLE_COMPONENT_ARGLIST: - case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: - if (d_left (dc) != NULL) - d_print_comp (dpi, d_left (dc)); - if (d_right (dc) != NULL) - { - size_t len; - d_append_string (dpi, ", "); - len = dpi->len; - d_print_comp (dpi, d_right (dc)); - /* If that didn't print anything (which can happen with empty - template argument packs), remove the comma and space. */ - if (dpi->len == len) - dpi->len -= 2; - } - return; - - case DEMANGLE_COMPONENT_OPERATOR: - { - char c; - - d_append_string (dpi, "operator"); - c = dc->u.s_operator.op->name[0]; - if (IS_LOWER (c)) - d_append_char (dpi, ' '); - d_append_buffer (dpi, dc->u.s_operator.op->name, - dc->u.s_operator.op->len); - return; - } - - case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: - d_append_string (dpi, "operator "); - d_print_comp (dpi, dc->u.s_extended_operator.name); - return; - - case DEMANGLE_COMPONENT_CAST: - d_append_string (dpi, "operator "); - d_print_cast (dpi, dc); - return; - - case DEMANGLE_COMPONENT_UNARY: - if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST) - d_print_expr_op (dpi, d_left (dc)); - else - { - d_append_char (dpi, '('); - d_print_cast (dpi, d_left (dc)); - d_append_char (dpi, ')'); - } - d_print_subexpr (dpi, d_right (dc)); - return; - - case DEMANGLE_COMPONENT_BINARY: - if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS) - { - d_print_error (dpi); - return; - } - - /* We wrap an expression which uses the greater-than operator in - an extra layer of parens so that it does not get confused - with the '>' which ends the template parameters. */ - if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR - && d_left (dc)->u.s_operator.op->len == 1 - && d_left (dc)->u.s_operator.op->name[0] == '>') - d_append_char (dpi, '('); - - d_print_subexpr (dpi, d_left (d_right (dc))); - if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) - d_print_expr_op (dpi, d_left (dc)); - d_print_subexpr (dpi, d_right (d_right (dc))); - - if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR - && d_left (dc)->u.s_operator.op->len == 1 - && d_left (dc)->u.s_operator.op->name[0] == '>') - d_append_char (dpi, ')'); - - return; - - case DEMANGLE_COMPONENT_BINARY_ARGS: - /* We should only see this as part of DEMANGLE_COMPONENT_BINARY. */ - d_print_error (dpi); - return; - - case DEMANGLE_COMPONENT_TRINARY: - if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1 - || d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2) - { - d_print_error (dpi); - return; - } - d_print_subexpr (dpi, d_left (d_right (dc))); - d_print_expr_op (dpi, d_left (dc)); - d_print_subexpr (dpi, d_left (d_right (d_right (dc)))); - d_append_string (dpi, " : "); - d_print_subexpr (dpi, d_right (d_right (d_right (dc)))); - return; - - case DEMANGLE_COMPONENT_TRINARY_ARG1: - case DEMANGLE_COMPONENT_TRINARY_ARG2: - /* We should only see these are part of DEMANGLE_COMPONENT_TRINARY. */ - d_print_error (dpi); - return; - - case DEMANGLE_COMPONENT_LITERAL: - case DEMANGLE_COMPONENT_LITERAL_NEG: - { - enum d_builtin_type_print tp; - - /* For some builtin types, produce simpler output. */ - tp = D_PRINT_DEFAULT; - if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE) - { - tp = d_left (dc)->u.s_builtin.type->print; - switch (tp) - { - case D_PRINT_INT: - case D_PRINT_UNSIGNED: - case D_PRINT_LONG: - case D_PRINT_UNSIGNED_LONG: - case D_PRINT_LONG_LONG: - case D_PRINT_UNSIGNED_LONG_LONG: - if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME) - { - if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG) - d_append_char (dpi, '-'); - d_print_comp (dpi, d_right (dc)); - switch (tp) - { - default: - break; - case D_PRINT_UNSIGNED: - d_append_char (dpi, 'u'); - break; - case D_PRINT_LONG: - d_append_char (dpi, 'l'); - break; - case D_PRINT_UNSIGNED_LONG: - d_append_string (dpi, "ul"); - break; - case D_PRINT_LONG_LONG: - d_append_string (dpi, "ll"); - break; - case D_PRINT_UNSIGNED_LONG_LONG: - d_append_string (dpi, "ull"); - break; - } - return; - } - break; - - case D_PRINT_BOOL: - if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME - && d_right (dc)->u.s_name.len == 1 - && dc->type == DEMANGLE_COMPONENT_LITERAL) - { - switch (d_right (dc)->u.s_name.s[0]) - { - case '0': - d_append_string (dpi, "false"); - return; - case '1': - d_append_string (dpi, "true"); - return; - default: - break; - } - } - break; - - default: - break; - } - } - - d_append_char (dpi, '('); - d_print_comp (dpi, d_left (dc)); - d_append_char (dpi, ')'); - if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG) - d_append_char (dpi, '-'); - if (tp == D_PRINT_FLOAT) - d_append_char (dpi, '['); - d_print_comp (dpi, d_right (dc)); - if (tp == D_PRINT_FLOAT) - d_append_char (dpi, ']'); - } - return; - - case DEMANGLE_COMPONENT_JAVA_RESOURCE: - d_append_string (dpi, "java resource "); - d_print_comp (dpi, d_left (dc)); - return; - - case DEMANGLE_COMPONENT_COMPOUND_NAME: - d_print_comp (dpi, d_left (dc)); - d_print_comp (dpi, d_right (dc)); - return; - - case DEMANGLE_COMPONENT_CHARACTER: - d_append_char (dpi, dc->u.s_character.character); - return; - - case DEMANGLE_COMPONENT_DECLTYPE: - d_append_string (dpi, "decltype ("); - d_print_comp (dpi, d_left (dc)); - d_append_char (dpi, ')'); - return; - - case DEMANGLE_COMPONENT_PACK_EXPANSION: - { - int len; - int i; - struct demangle_component *a = d_find_pack (dpi, d_left (dc)); - if (a == NULL) - { - /* d_find_pack won't find anything if the only packs involved - in this expansion are function parameter packs; in that - case, just print the pattern and "...". */ - d_print_subexpr (dpi, d_left (dc)); - d_append_string (dpi, "..."); - return; - } - - len = d_pack_length (a); - dc = d_left (dc); - for (i = 0; i < len; ++i) - { - dpi->pack_index = i; - d_print_comp (dpi, dc); - if (i < len-1) - d_append_string (dpi, ", "); - } - } - return; - - case DEMANGLE_COMPONENT_FUNCTION_PARAM: - { - char buf[25]; - d_append_string (dpi, "parm#"); - sprintf(buf,"%ld", dc->u.s_number.number); - d_append_string (dpi, buf); - return; - } - - case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: - d_append_string (dpi, "global constructors keyed to "); - d_print_comp (dpi, dc->u.s_binary.left); - return; - - case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: - d_append_string (dpi, "global destructors keyed to "); - d_print_comp (dpi, dc->u.s_binary.left); - return; - - default: - d_print_error (dpi); - return; - } -} - -/* Print a Java dentifier. For Java we try to handle encoded extended - Unicode characters. The C++ ABI doesn't mention Unicode encoding, - so we don't it for C++. Characters are encoded as - __U+_. */ - -static void -d_print_java_identifier (struct d_print_info *dpi, const char *name, int len) -{ - const char *p; - const char *end; - - end = name + len; - for (p = name; p < end; ++p) - { - if (end - p > 3 - && p[0] == '_' - && p[1] == '_' - && p[2] == 'U') - { - unsigned long c; - const char *q; - - c = 0; - for (q = p + 3; q < end; ++q) - { - int dig; - - if (IS_DIGIT (*q)) - dig = *q - '0'; - else if (*q >= 'A' && *q <= 'F') - dig = *q - 'A' + 10; - else if (*q >= 'a' && *q <= 'f') - dig = *q - 'a' + 10; - else - break; - - c = c * 16 + dig; - } - /* If the Unicode character is larger than 256, we don't try - to deal with it here. FIXME. */ - if (q < end && *q == '_' && c < 256) - { - d_append_char (dpi, c); - p = q; - continue; - } - } - - d_append_char (dpi, *p); - } -} - -/* Print a list of modifiers. SUFFIX is 1 if we are printing - qualifiers on this after printing a function. */ - -static void -d_print_mod_list (struct d_print_info *dpi, - struct d_print_mod *mods, int suffix) -{ - struct d_print_template *hold_dpt; - - if (mods == NULL || d_print_saw_error (dpi)) - return; - - if (mods->printed - || (! suffix - && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS))) - { - d_print_mod_list (dpi, mods->next, suffix); - return; - } - - mods->printed = 1; - - hold_dpt = dpi->templates; - dpi->templates = mods->templates; - - if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) - { - d_print_function_type (dpi, mods->mod, mods->next); - dpi->templates = hold_dpt; - return; - } - else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE) - { - d_print_array_type (dpi, mods->mod, mods->next); - dpi->templates = hold_dpt; - return; - } - else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME) - { - struct d_print_mod *hold_modifiers; - struct demangle_component *dc; - - /* When this is on the modifier stack, we have pulled any - qualifiers off the right argument already. Otherwise, we - print it as usual, but don't let the left argument see any - modifiers. */ - - hold_modifiers = dpi->modifiers; - dpi->modifiers = NULL; - d_print_comp (dpi, d_left (mods->mod)); - dpi->modifiers = hold_modifiers; - - if ((dpi->options & DMGL_JAVA) == 0) - d_append_string (dpi, "::"); - else - d_append_char (dpi, '.'); - - dc = d_right (mods->mod); - while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || dc->type == DEMANGLE_COMPONENT_CONST_THIS) - dc = d_left (dc); - - d_print_comp (dpi, dc); - - dpi->templates = hold_dpt; - return; - } - - d_print_mod (dpi, mods->mod); - - dpi->templates = hold_dpt; - - d_print_mod_list (dpi, mods->next, suffix); -} - -/* Print a modifier. */ - -static void -d_print_mod (struct d_print_info *dpi, - const struct demangle_component *mod) -{ - switch (mod->type) - { - case DEMANGLE_COMPONENT_RESTRICT: - case DEMANGLE_COMPONENT_RESTRICT_THIS: - d_append_string (dpi, " restrict"); - return; - case DEMANGLE_COMPONENT_VOLATILE: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - d_append_string (dpi, " volatile"); - return; - case DEMANGLE_COMPONENT_CONST: - case DEMANGLE_COMPONENT_CONST_THIS: - d_append_string (dpi, " const"); - return; - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - d_append_char (dpi, ' '); - d_print_comp (dpi, d_right (mod)); - return; - case DEMANGLE_COMPONENT_POINTER: - /* There is no pointer symbol in Java. */ - if ((dpi->options & DMGL_JAVA) == 0) - d_append_char (dpi, '*'); - return; - case DEMANGLE_COMPONENT_REFERENCE: - d_append_char (dpi, '&'); - return; - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: - d_append_string (dpi, "&&"); - return; - case DEMANGLE_COMPONENT_COMPLEX: - d_append_string (dpi, "complex "); - return; - case DEMANGLE_COMPONENT_IMAGINARY: - d_append_string (dpi, "imaginary "); - return; - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - if (d_last_char (dpi) != '(') - d_append_char (dpi, ' '); - d_print_comp (dpi, d_left (mod)); - d_append_string (dpi, "::*"); - return; - case DEMANGLE_COMPONENT_TYPED_NAME: - d_print_comp (dpi, d_left (mod)); - return; - default: - /* Otherwise, we have something that won't go back on the - modifier stack, so we can just print it. */ - d_print_comp (dpi, mod); - return; - } -} - -/* Print a function type, except for the return type. */ - -static void -d_print_function_type (struct d_print_info *dpi, - const struct demangle_component *dc, - struct d_print_mod *mods) -{ - int need_paren; - int saw_mod; - int need_space; - struct d_print_mod *p; - struct d_print_mod *hold_modifiers; - - need_paren = 0; - saw_mod = 0; - need_space = 0; - for (p = mods; p != NULL; p = p->next) - { - if (p->printed) - break; - - saw_mod = 1; - switch (p->mod->type) - { - case DEMANGLE_COMPONENT_POINTER: - case DEMANGLE_COMPONENT_REFERENCE: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: - need_paren = 1; - break; - case DEMANGLE_COMPONENT_RESTRICT: - case DEMANGLE_COMPONENT_VOLATILE: - case DEMANGLE_COMPONENT_CONST: - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - case DEMANGLE_COMPONENT_COMPLEX: - case DEMANGLE_COMPONENT_IMAGINARY: - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - need_space = 1; - need_paren = 1; - break; - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - break; - default: - break; - } - if (need_paren) - break; - } - - if (d_left (dc) != NULL && ! saw_mod) - need_paren = 1; - - if (need_paren) - { - if (! need_space) - { - if (d_last_char (dpi) != '(' - && d_last_char (dpi) != '*') - need_space = 1; - } - if (need_space && d_last_char (dpi) != ' ') - d_append_char (dpi, ' '); - d_append_char (dpi, '('); - } - - hold_modifiers = dpi->modifiers; - dpi->modifiers = NULL; - - d_print_mod_list (dpi, mods, 0); - - if (need_paren) - d_append_char (dpi, ')'); - - d_append_char (dpi, '('); - - if (d_right (dc) != NULL) - d_print_comp (dpi, d_right (dc)); - - d_append_char (dpi, ')'); - - d_print_mod_list (dpi, mods, 1); - - dpi->modifiers = hold_modifiers; -} - -/* Print an array type, except for the element type. */ - -static void -d_print_array_type (struct d_print_info *dpi, - const struct demangle_component *dc, - struct d_print_mod *mods) -{ - int need_space; - - need_space = 1; - if (mods != NULL) - { - int need_paren; - struct d_print_mod *p; - - need_paren = 0; - for (p = mods; p != NULL; p = p->next) - { - if (! p->printed) - { - if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE) - { - need_space = 0; - break; - } - else - { - need_paren = 1; - need_space = 1; - break; - } - } - } - - if (need_paren) - d_append_string (dpi, " ("); - - d_print_mod_list (dpi, mods, 0); - - if (need_paren) - d_append_char (dpi, ')'); - } - - if (need_space) - d_append_char (dpi, ' '); - - d_append_char (dpi, '['); - - if (d_left (dc) != NULL) - d_print_comp (dpi, d_left (dc)); - - d_append_char (dpi, ']'); -} - -/* Print an operator in an expression. */ - -static void -d_print_expr_op (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - if (dc->type == DEMANGLE_COMPONENT_OPERATOR) - d_append_buffer (dpi, dc->u.s_operator.op->name, - dc->u.s_operator.op->len); - else - d_print_comp (dpi, dc); -} - -/* Print a cast. */ - -static void -d_print_cast (struct d_print_info *dpi, - const struct demangle_component *dc) -{ - if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE) - d_print_comp (dpi, d_left (dc)); - else - { - struct d_print_mod *hold_dpm; - struct d_print_template dpt; - - /* It appears that for a templated cast operator, we need to put - the template parameters in scope for the operator name, but - not for the parameters. The effect is that we need to handle - the template printing here. */ - - hold_dpm = dpi->modifiers; - dpi->modifiers = NULL; - - dpt.next = dpi->templates; - dpi->templates = &dpt; - dpt.template_decl = d_left (dc); - - d_print_comp (dpi, d_left (d_left (dc))); - - dpi->templates = dpt.next; - - if (d_last_char (dpi) == '<') - d_append_char (dpi, ' '); - d_append_char (dpi, '<'); - d_print_comp (dpi, d_right (d_left (dc))); - /* Avoid generating two consecutive '>' characters, to avoid - the C++ syntactic ambiguity. */ - if (d_last_char (dpi) == '>') - d_append_char (dpi, ' '); - d_append_char (dpi, '>'); - - dpi->modifiers = hold_dpm; - } -} - -/* Initialize the information structure we use to pass around - information. */ - -CP_STATIC_IF_GLIBCPP_V3 -void -cplus_demangle_init_info (const char *mangled, int options, size_t len, - struct d_info *di) -{ - di->s = mangled; - di->send = mangled + len; - di->options = options; - - di->n = mangled; - - /* We can not need more components than twice the number of chars in - the mangled string. Most components correspond directly to - chars, but the ARGLIST types are exceptions. */ - di->num_comps = 2 * len; - di->next_comp = 0; - - /* Similarly, we can not need more substitutions than there are - chars in the mangled string. */ - di->num_subs = len; - di->next_sub = 0; - di->did_subs = 0; - - di->last_name = NULL; - - di->expansion = 0; -} - -/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI - mangled name, return strings in repeated callback giving the demangled - name. OPTIONS is the usual libiberty demangler options. On success, - this returns 1. On failure, returns 0. */ - -static int -d_demangle_callback (const char *mangled, int options, - demangle_callbackref callback, void *opaque) -{ - enum - { - DCT_TYPE, - DCT_MANGLED, - DCT_GLOBAL_CTORS, - DCT_GLOBAL_DTORS - } - type; - struct d_info di; - struct demangle_component *dc = NULL; - int status; - - if (mangled[0] == '_' && mangled[1] == 'Z') - type = DCT_MANGLED; - else if (strncmp (mangled, "_GLOBAL_", 8) == 0 - && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$') - && (mangled[9] == 'D' || mangled[9] == 'I') - && mangled[10] == '_') - type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS; - else - { - if ((options & DMGL_TYPES) == 0) - return 0; - type = DCT_TYPE; - } - - cplus_demangle_init_info (mangled, options, strlen (mangled), &di); - - { -#ifdef CP_DYNAMIC_ARRAYS - __extension__ struct demangle_component comps[di.num_comps]; - __extension__ struct demangle_component *subs[di.num_subs]; - - di.comps = comps; - di.subs = subs; -#else - di.comps = alloca (di.num_comps * sizeof (*di.comps)); - di.subs = alloca (di.num_subs * sizeof (*di.subs)); -#endif - - switch (type) - { - case DCT_TYPE: - dc = cplus_demangle_type (&di); - break; - case DCT_MANGLED: - dc = cplus_demangle_mangled_name (&di, 1); - break; - case DCT_GLOBAL_CTORS: - case DCT_GLOBAL_DTORS: - d_advance (&di, 11); - dc = d_make_comp (&di, - (type == DCT_GLOBAL_CTORS - ? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS - : DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS), - d_make_name (&di, d_str (&di), strlen (d_str (&di))), - NULL); - d_advance (&di, strlen (d_str (&di))); - break; - } - - /* If DMGL_PARAMS is set, then if we didn't consume the entire - mangled string, then we didn't successfully demangle it. If - DMGL_PARAMS is not set, we didn't look at the trailing - parameters. */ - if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0') - dc = NULL; - -#ifdef CP_DEMANGLE_DEBUG - d_dump (dc, 0); -#endif - - status = (dc != NULL) - ? cplus_demangle_print_callback (options, dc, callback, opaque) - : 0; - } - - return status; -} - -/* Entry point for the demangler. If MANGLED is a g++ v3 ABI mangled - name, return a buffer allocated with malloc holding the demangled - name. OPTIONS is the usual libiberty demangler options. On - success, this sets *PALC to the allocated size of the returned - buffer. On failure, this sets *PALC to 0 for a bad name, or 1 for - a memory allocation failure, and returns NULL. */ - -static char * -d_demangle (const char *mangled, int options, size_t *palc) -{ - struct d_growable_string dgs; - int status; - - d_growable_string_init (&dgs, 0); - - status = d_demangle_callback (mangled, options, - d_growable_string_callback_adapter, &dgs); - if (status == 0) - { - free (dgs.buf); - *palc = 0; - return NULL; - } - - *palc = dgs.allocation_failure ? 1 : 0; - return dgs.buf; -} - -#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3) - -extern char *__cxa_demangle (const char *, char *, size_t *, int *); - -/* ia64 ABI-mandated entry point in the C++ runtime library for - performing demangling. MANGLED_NAME is a NUL-terminated character - string containing the name to be demangled. - - OUTPUT_BUFFER is a region of memory, allocated with malloc, of - *LENGTH bytes, into which the demangled name is stored. If - OUTPUT_BUFFER is not long enough, it is expanded using realloc. - OUTPUT_BUFFER may instead be NULL; in that case, the demangled name - is placed in a region of memory allocated with malloc. - - If LENGTH is non-NULL, the length of the buffer containing the - demangled name, is placed in *LENGTH. - - The return value is a pointer to the start of the NUL-terminated - demangled name, or NULL if the demangling fails. The caller is - responsible for deallocating this memory using free. - - *STATUS is set to one of the following values: - 0: The demangling operation succeeded. - -1: A memory allocation failure occurred. - -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules. - -3: One of the arguments is invalid. - - The demangling is performed using the C++ ABI mangling rules, with - GNU extensions. */ - -char * -__cxa_demangle (const char *mangled_name, char *output_buffer, - size_t *length, int *status) -{ - char *demangled; - size_t alc; - - if (mangled_name == NULL) - { - if (status != NULL) - *status = -3; - return NULL; - } - - if (output_buffer != NULL && length == NULL) - { - if (status != NULL) - *status = -3; - return NULL; - } - - demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc); - - if (demangled == NULL) - { - if (status != NULL) - { - if (alc == 1) - *status = -1; - else - *status = -2; - } - return NULL; - } - - if (output_buffer == NULL) - { - if (length != NULL) - *length = alc; - } - else - { - if (strlen (demangled) < *length) - { - strcpy (output_buffer, demangled); - free (demangled); - demangled = output_buffer; - } - else - { - free (output_buffer); - *length = alc; - } - } - - if (status != NULL) - *status = 0; - - return demangled; -} - -extern int __gcclibcxx_demangle_callback (const char *, - void (*) - (const char *, size_t, void *), - void *); - -/* Alternative, allocationless entry point in the C++ runtime library - for performing demangling. MANGLED_NAME is a NUL-terminated character - string containing the name to be demangled. - - CALLBACK is a callback function, called with demangled string - segments as demangling progresses; it is called at least once, - but may be called more than once. OPAQUE is a generalized pointer - used as a callback argument. - - The return code is one of the following values, equivalent to - the STATUS values of __cxa_demangle() (excluding -1, since this - function performs no memory allocations): - 0: The demangling operation succeeded. - -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules. - -3: One of the arguments is invalid. - - The demangling is performed using the C++ ABI mangling rules, with - GNU extensions. */ - -int -__gcclibcxx_demangle_callback (const char *mangled_name, - void (*callback) (const char *, size_t, void *), - void *opaque) -{ - int status; - - if (mangled_name == NULL || callback == NULL) - return -3; - - status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES, - callback, opaque); - if (status == 0) - return -2; - - return 0; -} - -#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */ - -/* Entry point for libiberty demangler. If MANGLED is a g++ v3 ABI - mangled name, return a buffer allocated with malloc holding the - demangled name. Otherwise, return NULL. */ - -char * -cplus_demangle_v3 (const char *mangled, int options) -{ - size_t alc; - - return d_demangle (mangled, options, &alc); -} - -int -cplus_demangle_v3_callback (const char *mangled, int options, - demangle_callbackref callback, void *opaque) -{ - return d_demangle_callback (mangled, options, callback, opaque); -} - -/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling - conventions, but the output formatting is a little different. - This instructs the C++ demangler not to emit pointer characters ("*"), to - use Java's namespace separator symbol ("." instead of "::"), and to output - JArray as TYPE[]. */ - -char * -java_demangle_v3 (const char *mangled) -{ - size_t alc; - - return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc); -} - -int -java_demangle_v3_callback (const char *mangled, - demangle_callbackref callback, void *opaque) -{ - return d_demangle_callback (mangled, - DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, - callback, opaque); -} - -#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */ - -#ifndef IN_GLIBCPP_V3 - -/* Demangle a string in order to find out whether it is a constructor - or destructor. Return non-zero on success. Set *CTOR_KIND and - *DTOR_KIND appropriately. */ - -static int -is_ctor_or_dtor (const char *mangled, - enum gnu_v3_ctor_kinds *ctor_kind, - enum gnu_v3_dtor_kinds *dtor_kind) -{ - struct d_info di; - struct demangle_component *dc; - int ret; - - *ctor_kind = (enum gnu_v3_ctor_kinds) 0; - *dtor_kind = (enum gnu_v3_dtor_kinds) 0; - - cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di); - - { -#ifdef CP_DYNAMIC_ARRAYS - __extension__ struct demangle_component comps[di.num_comps]; - __extension__ struct demangle_component *subs[di.num_subs]; - - di.comps = comps; - di.subs = subs; -#else - di.comps = alloca (di.num_comps * sizeof (*di.comps)); - di.subs = alloca (di.num_subs * sizeof (*di.subs)); -#endif - - dc = cplus_demangle_mangled_name (&di, 1); - - /* Note that because we did not pass DMGL_PARAMS, we don't expect - to demangle the entire string. */ - - ret = 0; - while (dc != NULL) - { - switch (dc->type) - { - default: - dc = NULL; - break; - case DEMANGLE_COMPONENT_TYPED_NAME: - case DEMANGLE_COMPONENT_TEMPLATE: - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - dc = d_left (dc); - break; - case DEMANGLE_COMPONENT_QUAL_NAME: - case DEMANGLE_COMPONENT_LOCAL_NAME: - dc = d_right (dc); - break; - case DEMANGLE_COMPONENT_CTOR: - *ctor_kind = dc->u.s_ctor.kind; - ret = 1; - dc = NULL; - break; - case DEMANGLE_COMPONENT_DTOR: - *dtor_kind = dc->u.s_dtor.kind; - ret = 1; - dc = NULL; - break; - } - } - } - - return ret; -} - -/* Return whether NAME is the mangled form of a g++ V3 ABI constructor - name. A non-zero return indicates the type of constructor. */ - -enum gnu_v3_ctor_kinds -is_gnu_v3_mangled_ctor (const char *name) -{ - enum gnu_v3_ctor_kinds ctor_kind; - enum gnu_v3_dtor_kinds dtor_kind; - - if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind)) - return (enum gnu_v3_ctor_kinds) 0; - return ctor_kind; -} - - -/* Return whether NAME is the mangled form of a g++ V3 ABI destructor - name. A non-zero return indicates the type of destructor. */ - -enum gnu_v3_dtor_kinds -is_gnu_v3_mangled_dtor (const char *name) -{ - enum gnu_v3_ctor_kinds ctor_kind; - enum gnu_v3_dtor_kinds dtor_kind; - - if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind)) - return (enum gnu_v3_dtor_kinds) 0; - return dtor_kind; -} - -#endif /* IN_GLIBCPP_V3 */ - -#ifdef STANDALONE_DEMANGLER - -#include "getopt.h" -#include "dyn-string.h" - -static void print_usage (FILE* fp, int exit_value); - -#define IS_ALPHA(CHAR) \ - (((CHAR) >= 'a' && (CHAR) <= 'z') \ - || ((CHAR) >= 'A' && (CHAR) <= 'Z')) - -/* Non-zero if CHAR is a character than can occur in a mangled name. */ -#define is_mangled_char(CHAR) \ - (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \ - || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$') - -/* The name of this program, as invoked. */ -const char* program_name; - -/* Prints usage summary to FP and then exits with EXIT_VALUE. */ - -static void -print_usage (FILE* fp, int exit_value) -{ - fprintf (fp, "Usage: %s [options] [names ...]\n", program_name); - fprintf (fp, "Options:\n"); - fprintf (fp, " -h,--help Display this message.\n"); - fprintf (fp, " -p,--no-params Don't display function parameters\n"); - fprintf (fp, " -v,--verbose Produce verbose demanglings.\n"); - fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n"); - - exit (exit_value); -} - -/* Option specification for getopt_long. */ -static const struct option long_options[] = -{ - { "help", no_argument, NULL, 'h' }, - { "no-params", no_argument, NULL, 'p' }, - { "verbose", no_argument, NULL, 'v' }, - { NULL, no_argument, NULL, 0 }, -}; - -/* Main entry for a demangling filter executable. It will demangle - its command line arguments, if any. If none are provided, it will - filter stdin to stdout, replacing any recognized mangled C++ names - with their demangled equivalents. */ - -int -main (int argc, char *argv[]) -{ - int i; - int opt_char; - int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; - - /* Use the program name of this program, as invoked. */ - program_name = argv[0]; - - /* Parse options. */ - do - { - opt_char = getopt_long (argc, argv, "hpv", long_options, NULL); - switch (opt_char) - { - case '?': /* Unrecognized option. */ - print_usage (stderr, 1); - break; - - case 'h': - print_usage (stdout, 0); - break; - - case 'p': - options &= ~ DMGL_PARAMS; - break; - - case 'v': - options |= DMGL_VERBOSE; - break; - } - } - while (opt_char != -1); - - if (optind == argc) - /* No command line arguments were provided. Filter stdin. */ - { - dyn_string_t mangled = dyn_string_new (3); - char *s; - - /* Read all of input. */ - while (!feof (stdin)) - { - char c; - - /* Pile characters into mangled until we hit one that can't - occur in a mangled name. */ - c = getchar (); - while (!feof (stdin) && is_mangled_char (c)) - { - dyn_string_append_char (mangled, c); - if (feof (stdin)) - break; - c = getchar (); - } - - if (dyn_string_length (mangled) > 0) - { -#ifdef IN_GLIBCPP_V3 - s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL); -#else - s = cplus_demangle_v3 (dyn_string_buf (mangled), options); -#endif - - if (s != NULL) - { - fputs (s, stdout); - free (s); - } - else - { - /* It might not have been a mangled name. Print the - original text. */ - fputs (dyn_string_buf (mangled), stdout); - } - - dyn_string_clear (mangled); - } - - /* If we haven't hit EOF yet, we've read one character that - can't occur in a mangled name, so print it out. */ - if (!feof (stdin)) - putchar (c); - } - - dyn_string_delete (mangled); - } - else - /* Demangle command line arguments. */ - { - /* Loop over command line arguments. */ - for (i = optind; i < argc; ++i) - { - char *s; -#ifdef IN_GLIBCPP_V3 - int status; -#endif - - /* Attempt to demangle. */ -#ifdef IN_GLIBCPP_V3 - s = __cxa_demangle (argv[i], NULL, NULL, &status); -#else - s = cplus_demangle_v3 (argv[i], options); -#endif - - /* If it worked, print the demangled name. */ - if (s != NULL) - { - printf ("%s\n", s); - free (s); - } - else - { -#ifdef IN_GLIBCPP_V3 - fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status); -#else - fprintf (stderr, "Failed: %s\n", argv[i]); -#endif - } - } - } - - return 0; -} - -#endif /* STANDALONE_DEMANGLER */ diff --git a/linkers/libiberty/cp-demangle.h b/linkers/libiberty/cp-demangle.h deleted file mode 100644 index aad3743..0000000 --- a/linkers/libiberty/cp-demangle.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Internal demangler interface for g++ V3 ABI. - Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of the libiberty library, which is part of GCC. - - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - In addition to the permissions in the GNU General Public License, the - Free Software Foundation gives you unlimited permission to link the - compiled version of this file into combinations with other programs, - and to distribute those combinations without any restriction coming - from the use of this file. (The General Public License restrictions - do apply in other respects; for example, they cover modification of - the file, and distribution when not linked into a combined - executable.) - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -/* This file provides some definitions shared by cp-demangle.c and - cp-demint.c. It should not be included by any other files. */ - -/* Information we keep for operators. */ - -struct demangle_operator_info -{ - /* Mangled name. */ - const char *code; - /* Real name. */ - const char *name; - /* Length of real name. */ - int len; - /* Number of arguments. */ - int args; -}; - -/* How to print the value of a builtin type. */ - -enum d_builtin_type_print -{ - /* Print as (type)val. */ - D_PRINT_DEFAULT, - /* Print as integer. */ - D_PRINT_INT, - /* Print as unsigned integer, with trailing "u". */ - D_PRINT_UNSIGNED, - /* Print as long, with trailing "l". */ - D_PRINT_LONG, - /* Print as unsigned long, with trailing "ul". */ - D_PRINT_UNSIGNED_LONG, - /* Print as long long, with trailing "ll". */ - D_PRINT_LONG_LONG, - /* Print as unsigned long long, with trailing "ull". */ - D_PRINT_UNSIGNED_LONG_LONG, - /* Print as bool. */ - D_PRINT_BOOL, - /* Print as float--put value in square brackets. */ - D_PRINT_FLOAT, - /* Print in usual way, but here to detect void. */ - D_PRINT_VOID -}; - -/* Information we keep for a builtin type. */ - -struct demangle_builtin_type_info -{ - /* Type name. */ - const char *name; - /* Length of type name. */ - int len; - /* Type name when using Java. */ - const char *java_name; - /* Length of java name. */ - int java_len; - /* How to print a value of this type. */ - enum d_builtin_type_print print; -}; - -/* The information structure we pass around. */ - -struct d_info -{ - /* The string we are demangling. */ - const char *s; - /* The end of the string we are demangling. */ - const char *send; - /* The options passed to the demangler. */ - int options; - /* The next character in the string to consider. */ - const char *n; - /* The array of components. */ - struct demangle_component *comps; - /* The index of the next available component. */ - int next_comp; - /* The number of available component structures. */ - int num_comps; - /* The array of substitutions. */ - struct demangle_component **subs; - /* The index of the next substitution. */ - int next_sub; - /* The number of available entries in the subs array. */ - int num_subs; - /* The number of substitutions which we actually made from the subs - array, plus the number of template parameter references we - saw. */ - int did_subs; - /* The last name we saw, for constructors and destructors. */ - struct demangle_component *last_name; - /* A running total of the length of large expansions from the - mangled name to the demangled name, such as standard - substitutions and builtin types. */ - int expansion; -}; - -/* To avoid running past the ending '\0', don't: - - call d_peek_next_char if d_peek_char returned '\0' - - call d_advance with an 'i' that is too large - - call d_check_char(di, '\0') - Everything else is safe. */ -#define d_peek_char(di) (*((di)->n)) -#define d_peek_next_char(di) ((di)->n[1]) -#define d_advance(di, i) ((di)->n += (i)) -#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) -#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) -#define d_str(di) ((di)->n) - -/* Functions and arrays in cp-demangle.c which are referenced by - functions in cp-demint.c. */ -#ifdef IN_GLIBCPP_V3 -#define CP_STATIC_IF_GLIBCPP_V3 static -#else -#define CP_STATIC_IF_GLIBCPP_V3 extern -#endif - -#ifndef IN_GLIBCPP_V3 -extern const struct demangle_operator_info cplus_demangle_operators[]; -#endif - -#define D_BUILTIN_TYPE_COUNT (32) - -CP_STATIC_IF_GLIBCPP_V3 -const struct demangle_builtin_type_info -cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT]; - -CP_STATIC_IF_GLIBCPP_V3 -struct demangle_component * -cplus_demangle_mangled_name (struct d_info *, int); - -CP_STATIC_IF_GLIBCPP_V3 -struct demangle_component * -cplus_demangle_type (struct d_info *); - -extern void -cplus_demangle_init_info (const char *, int, size_t, struct d_info *); - -/* cp-demangle.c needs to define this a little differently */ -#undef CP_STATIC_IF_GLIBCPP_V3 diff --git a/linkers/libiberty/cplus-dem.c b/linkers/libiberty/cplus-dem.c deleted file mode 100644 index 6628514..0000000 --- a/linkers/libiberty/cplus-dem.c +++ /dev/null @@ -1,4728 +0,0 @@ -/* Demangler for GNU C++ - Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - Written by James Clark (jjc@jclark.uucp) - Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling - Modified by Satish Pai (pai@apollo.hp.com) for HP demangling - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -In addition to the permissions in the GNU Library General Public -License, the Free Software Foundation gives you unlimited permission -to link the compiled version of this file into combinations with other -programs, and to distribute those combinations without any restriction -coming from the use of this file. (The Library Public License -restrictions do apply in other respects; for example, they cover -modification of the file, and distribution when not linked into a -combined executable.) - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -/* This file exports two functions; cplus_mangle_opname and cplus_demangle. - - This file imports xmalloc and xrealloc, which are like malloc and - realloc except that they generate a fatal error if there is no - available memory. */ - -/* This file lives in both GCC and libiberty. When making changes, please - try not to break either. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "safe-ctype.h" - -#include -#include -#include - -#ifdef HAVE_STDLIB_H -#include -#else -void * malloc (); -void * realloc (); -#endif - -#include -#undef CURRENT_DEMANGLING_STYLE -#define CURRENT_DEMANGLING_STYLE work->options - -#include "libiberty.h" - -static char *ada_demangle (const char *, int); - -#define min(X,Y) (((X) < (Y)) ? (X) : (Y)) - -/* A value at least one greater than the maximum number of characters - that will be output when using the `%d' format with `printf'. */ -#define INTBUF_SIZE 32 - -extern void fancy_abort (void) ATTRIBUTE_NORETURN; - -/* In order to allow a single demangler executable to demangle strings - using various common values of CPLUS_MARKER, as well as any specific - one set at compile time, we maintain a string containing all the - commonly used ones, and check to see if the marker we are looking for - is in that string. CPLUS_MARKER is usually '$' on systems where the - assembler can deal with that. Where the assembler can't, it's usually - '.' (but on many systems '.' is used for other things). We put the - current defined CPLUS_MARKER first (which defaults to '$'), followed - by the next most common value, followed by an explicit '$' in case - the value of CPLUS_MARKER is not '$'. - - We could avoid this if we could just get g++ to tell us what the actual - cplus marker character is as part of the debug information, perhaps by - ensuring that it is the character that terminates the gcc_compiled - marker symbol (FIXME). */ - -#if !defined (CPLUS_MARKER) -#define CPLUS_MARKER '$' -#endif - -enum demangling_styles current_demangling_style = auto_demangling; - -static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; - -static char char_str[2] = { '\000', '\000' }; - -void -set_cplus_marker_for_demangling (int ch) -{ - cplus_markers[0] = ch; -} - -typedef struct string /* Beware: these aren't required to be */ -{ /* '\0' terminated. */ - char *b; /* pointer to start of string */ - char *p; /* pointer after last character */ - char *e; /* pointer after end of allocated space */ -} string; - -/* Stuff that is shared between sub-routines. - Using a shared structure allows cplus_demangle to be reentrant. */ - -struct work_stuff -{ - int options; - char **typevec; - char **ktypevec; - char **btypevec; - int numk; - int numb; - int ksize; - int bsize; - int ntypes; - int typevec_size; - int constructor; - int destructor; - int static_type; /* A static member function */ - int temp_start; /* index in demangled to start of template args */ - int type_quals; /* The type qualifiers. */ - int dllimported; /* Symbol imported from a PE DLL */ - char **tmpl_argvec; /* Template function arguments. */ - int ntmpl_args; /* The number of template function arguments. */ - int forgetting_types; /* Nonzero if we are not remembering the types - we see. */ - string* previous_argument; /* The last function argument demangled. */ - int nrepeats; /* The number of times to repeat the previous - argument. */ -}; - -#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) -#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) - -static const struct optable -{ - const char *const in; - const char *const out; - const int flags; -} optable[] = { - {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ - {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ - {"new", " new", 0}, /* old (1.91, and 1.x) */ - {"delete", " delete", 0}, /* old (1.91, and 1.x) */ - {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ - {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ - {"as", "=", DMGL_ANSI}, /* ansi */ - {"ne", "!=", DMGL_ANSI}, /* old, ansi */ - {"eq", "==", DMGL_ANSI}, /* old, ansi */ - {"ge", ">=", DMGL_ANSI}, /* old, ansi */ - {"gt", ">", DMGL_ANSI}, /* old, ansi */ - {"le", "<=", DMGL_ANSI}, /* old, ansi */ - {"lt", "<", DMGL_ANSI}, /* old, ansi */ - {"plus", "+", 0}, /* old */ - {"pl", "+", DMGL_ANSI}, /* ansi */ - {"apl", "+=", DMGL_ANSI}, /* ansi */ - {"minus", "-", 0}, /* old */ - {"mi", "-", DMGL_ANSI}, /* ansi */ - {"ami", "-=", DMGL_ANSI}, /* ansi */ - {"mult", "*", 0}, /* old */ - {"ml", "*", DMGL_ANSI}, /* ansi */ - {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ - {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ - {"convert", "+", 0}, /* old (unary +) */ - {"negate", "-", 0}, /* old (unary -) */ - {"trunc_mod", "%", 0}, /* old */ - {"md", "%", DMGL_ANSI}, /* ansi */ - {"amd", "%=", DMGL_ANSI}, /* ansi */ - {"trunc_div", "/", 0}, /* old */ - {"dv", "/", DMGL_ANSI}, /* ansi */ - {"adv", "/=", DMGL_ANSI}, /* ansi */ - {"truth_andif", "&&", 0}, /* old */ - {"aa", "&&", DMGL_ANSI}, /* ansi */ - {"truth_orif", "||", 0}, /* old */ - {"oo", "||", DMGL_ANSI}, /* ansi */ - {"truth_not", "!", 0}, /* old */ - {"nt", "!", DMGL_ANSI}, /* ansi */ - {"postincrement","++", 0}, /* old */ - {"pp", "++", DMGL_ANSI}, /* ansi */ - {"postdecrement","--", 0}, /* old */ - {"mm", "--", DMGL_ANSI}, /* ansi */ - {"bit_ior", "|", 0}, /* old */ - {"or", "|", DMGL_ANSI}, /* ansi */ - {"aor", "|=", DMGL_ANSI}, /* ansi */ - {"bit_xor", "^", 0}, /* old */ - {"er", "^", DMGL_ANSI}, /* ansi */ - {"aer", "^=", DMGL_ANSI}, /* ansi */ - {"bit_and", "&", 0}, /* old */ - {"ad", "&", DMGL_ANSI}, /* ansi */ - {"aad", "&=", DMGL_ANSI}, /* ansi */ - {"bit_not", "~", 0}, /* old */ - {"co", "~", DMGL_ANSI}, /* ansi */ - {"call", "()", 0}, /* old */ - {"cl", "()", DMGL_ANSI}, /* ansi */ - {"alshift", "<<", 0}, /* old */ - {"ls", "<<", DMGL_ANSI}, /* ansi */ - {"als", "<<=", DMGL_ANSI}, /* ansi */ - {"arshift", ">>", 0}, /* old */ - {"rs", ">>", DMGL_ANSI}, /* ansi */ - {"ars", ">>=", DMGL_ANSI}, /* ansi */ - {"component", "->", 0}, /* old */ - {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ - {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ - {"indirect", "*", 0}, /* old */ - {"method_call", "->()", 0}, /* old */ - {"addr", "&", 0}, /* old (unary &) */ - {"array", "[]", 0}, /* old */ - {"vc", "[]", DMGL_ANSI}, /* ansi */ - {"compound", ", ", 0}, /* old */ - {"cm", ", ", DMGL_ANSI}, /* ansi */ - {"cond", "?:", 0}, /* old */ - {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ - {"max", ">?", 0}, /* old */ - {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ - {"min", "*", DMGL_ANSI}, /* ansi */ - {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */ -}; - -/* These values are used to indicate the various type varieties. - They are all non-zero so that they can be used as `success' - values. */ -typedef enum type_kind_t -{ - tk_none, - tk_pointer, - tk_reference, - tk_integral, - tk_bool, - tk_char, - tk_real -} type_kind_t; - -const struct demangler_engine libiberty_demanglers[] = -{ - { - NO_DEMANGLING_STYLE_STRING, - no_demangling, - "Demangling disabled" - } - , - { - AUTO_DEMANGLING_STYLE_STRING, - auto_demangling, - "Automatic selection based on executable" - } - , - { - GNU_DEMANGLING_STYLE_STRING, - gnu_demangling, - "GNU (g++) style demangling" - } - , - { - LUCID_DEMANGLING_STYLE_STRING, - lucid_demangling, - "Lucid (lcc) style demangling" - } - , - { - ARM_DEMANGLING_STYLE_STRING, - arm_demangling, - "ARM style demangling" - } - , - { - HP_DEMANGLING_STYLE_STRING, - hp_demangling, - "HP (aCC) style demangling" - } - , - { - EDG_DEMANGLING_STYLE_STRING, - edg_demangling, - "EDG style demangling" - } - , - { - GNU_V3_DEMANGLING_STYLE_STRING, - gnu_v3_demangling, - "GNU (g++) V3 ABI-style demangling" - } - , - { - JAVA_DEMANGLING_STYLE_STRING, - java_demangling, - "Java style demangling" - } - , - { - GNAT_DEMANGLING_STYLE_STRING, - gnat_demangling, - "GNAT style demangling" - } - , - { - NULL, unknown_demangling, NULL - } -}; - -#define STRING_EMPTY(str) ((str) -> b == (str) -> p) -#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_append(str, " ");} -#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) - -/* The scope separator appropriate for the language being demangled. */ - -#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::") - -#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ -#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ - -/* Prototypes for local functions */ - -static void delete_work_stuff (struct work_stuff *); - -static void delete_non_B_K_work_stuff (struct work_stuff *); - -static char *mop_up (struct work_stuff *, string *, int); - -static void squangle_mop_up (struct work_stuff *); - -static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *); - -#if 0 -static int -demangle_method_args (struct work_stuff *, const char **, string *); -#endif - -static char * -internal_cplus_demangle (struct work_stuff *, const char *); - -static int -demangle_template_template_parm (struct work_stuff *work, - const char **, string *); - -static int -demangle_template (struct work_stuff *work, const char **, string *, - string *, int, int); - -static int -arm_pt (struct work_stuff *, const char *, int, const char **, - const char **); - -static int -demangle_class_name (struct work_stuff *, const char **, string *); - -static int -demangle_qualified (struct work_stuff *, const char **, string *, - int, int); - -static int demangle_class (struct work_stuff *, const char **, string *); - -static int demangle_fund_type (struct work_stuff *, const char **, string *); - -static int demangle_signature (struct work_stuff *, const char **, string *); - -static int demangle_prefix (struct work_stuff *, const char **, string *); - -static int gnu_special (struct work_stuff *, const char **, string *); - -static int arm_special (const char **, string *); - -static void string_need (string *, int); - -static void string_delete (string *); - -static void -string_init (string *); - -static void string_clear (string *); - -#if 0 -static int string_empty (string *); -#endif - -static void string_append (string *, const char *); - -static void string_appends (string *, string *); - -static void string_appendn (string *, const char *, int); - -static void string_prepend (string *, const char *); - -static void string_prependn (string *, const char *, int); - -static void string_append_template_idx (string *, int); - -static int get_count (const char **, int *); - -static int consume_count (const char **); - -static int consume_count_with_underscores (const char**); - -static int demangle_args (struct work_stuff *, const char **, string *); - -static int demangle_nested_args (struct work_stuff*, const char**, string*); - -static int do_type (struct work_stuff *, const char **, string *); - -static int do_arg (struct work_stuff *, const char **, string *); - -static int -demangle_function_name (struct work_stuff *, const char **, string *, - const char *); - -static int -iterate_demangle_function (struct work_stuff *, - const char **, string *, const char *); - -static void remember_type (struct work_stuff *, const char *, int); - -static void remember_Btype (struct work_stuff *, const char *, int, int); - -static int register_Btype (struct work_stuff *); - -static void remember_Ktype (struct work_stuff *, const char *, int); - -static void forget_types (struct work_stuff *); - -static void forget_B_and_K_types (struct work_stuff *); - -static void string_prepends (string *, string *); - -static int -demangle_template_value_parm (struct work_stuff*, const char**, - string*, type_kind_t); - -static int -do_hpacc_template_const_value (struct work_stuff *, const char **, string *); - -static int -do_hpacc_template_literal (struct work_stuff *, const char **, string *); - -static int snarf_numeric_literal (const char **, string *); - -/* There is a TYPE_QUAL value for each type qualifier. They can be - combined by bitwise-or to form the complete set of qualifiers for a - type. */ - -#define TYPE_UNQUALIFIED 0x0 -#define TYPE_QUAL_CONST 0x1 -#define TYPE_QUAL_VOLATILE 0x2 -#define TYPE_QUAL_RESTRICT 0x4 - -static int code_for_qualifier (int); - -static const char* qualifier_string (int); - -static const char* demangle_qualifier (int); - -static int demangle_expression (struct work_stuff *, const char **, string *, - type_kind_t); - -static int -demangle_integral_value (struct work_stuff *, const char **, string *); - -static int -demangle_real_value (struct work_stuff *, const char **, string *); - -static void -demangle_arm_hp_template (struct work_stuff *, const char **, int, string *); - -static void -recursively_demangle (struct work_stuff *, const char **, string *, int); - -static void grow_vect (char **, size_t *, size_t, int); - -/* Translate count to integer, consuming tokens in the process. - Conversion terminates on the first non-digit character. - - Trying to consume something that isn't a count results in no - consumption of input and a return of -1. - - Overflow consumes the rest of the digits, and returns -1. */ - -static int -consume_count (const char **type) -{ - int count = 0; - - if (! ISDIGIT ((unsigned char)**type)) - return -1; - - while (ISDIGIT ((unsigned char)**type)) - { - count *= 10; - - /* Check for overflow. - We assume that count is represented using two's-complement; - no power of two is divisible by ten, so if an overflow occurs - when multiplying by ten, the result will not be a multiple of - ten. */ - if ((count % 10) != 0) - { - while (ISDIGIT ((unsigned char) **type)) - (*type)++; - return -1; - } - - count += **type - '0'; - (*type)++; - } - - if (count < 0) - count = -1; - - return (count); -} - - -/* Like consume_count, but for counts that are preceded and followed - by '_' if they are greater than 10. Also, -1 is returned for - failure, since 0 can be a valid value. */ - -static int -consume_count_with_underscores (const char **mangled) -{ - int idx; - - if (**mangled == '_') - { - (*mangled)++; - if (!ISDIGIT ((unsigned char)**mangled)) - return -1; - - idx = consume_count (mangled); - if (**mangled != '_') - /* The trailing underscore was missing. */ - return -1; - - (*mangled)++; - } - else - { - if (**mangled < '0' || **mangled > '9') - return -1; - - idx = **mangled - '0'; - (*mangled)++; - } - - return idx; -} - -/* C is the code for a type-qualifier. Return the TYPE_QUAL - corresponding to this qualifier. */ - -static int -code_for_qualifier (int c) -{ - switch (c) - { - case 'C': - return TYPE_QUAL_CONST; - - case 'V': - return TYPE_QUAL_VOLATILE; - - case 'u': - return TYPE_QUAL_RESTRICT; - - default: - break; - } - - /* C was an invalid qualifier. */ - abort (); -} - -/* Return the string corresponding to the qualifiers given by - TYPE_QUALS. */ - -static const char* -qualifier_string (int type_quals) -{ - switch (type_quals) - { - case TYPE_UNQUALIFIED: - return ""; - - case TYPE_QUAL_CONST: - return "const"; - - case TYPE_QUAL_VOLATILE: - return "volatile"; - - case TYPE_QUAL_RESTRICT: - return "__restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: - return "const volatile"; - - case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: - return "const __restrict"; - - case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "volatile __restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "const volatile __restrict"; - - default: - break; - } - - /* TYPE_QUALS was an invalid qualifier set. */ - abort (); -} - -/* C is the code for a type-qualifier. Return the string - corresponding to this qualifier. This function should only be - called with a valid qualifier code. */ - -static const char* -demangle_qualifier (int c) -{ - return qualifier_string (code_for_qualifier (c)); -} - -int -cplus_demangle_opname (const char *opname, char *result, int options) -{ - int len, len1, ret; - string type; - struct work_stuff work[1]; - const char *tem; - - len = strlen(opname); - result[0] = '\0'; - ret = 0; - memset ((char *) work, 0, sizeof (work)); - work->options = options; - - if (opname[0] == '_' && opname[1] == '_' - && opname[2] == 'o' && opname[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = opname + 4; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - else if (opname[0] == '_' && opname[1] == '_' - && ISLOWER((unsigned char)opname[2]) - && ISLOWER((unsigned char)opname[3])) - { - if (opname[4] == '\0') - { - /* Operator. */ - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, opname + 2, 2) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - else - { - if (opname[2] == 'a' && opname[5] == '\0') - { - /* Assignment. */ - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, opname + 2, 3) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - } - else if (len >= 3 - && opname[0] == 'o' - && opname[1] == 'p' - && strchr (cplus_markers, opname[2]) != NULL) - { - /* see if it's an assignment expression */ - if (len >= 10 /* op$assign_ */ - && memcmp (opname + 3, "assign_", 7) == 0) - { - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - len1 = len - 10; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 10, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - strcat (result, "="); - ret = 1; - break; - } - } - } - else - { - size_t i; - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - len1 = len - 3; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 3, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - else if (len >= 5 && memcmp (opname, "type", 4) == 0 - && strchr (cplus_markers, opname[4]) != NULL) - { - /* type conversion operator */ - tem = opname + 5; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - squangle_mop_up (work); - return ret; - -} - -/* Takes operator name as e.g. "++" and returns mangled - operator name (e.g. "postincrement_expr"), or NULL if not found. - - If OPTIONS & DMGL_ANSI == 1, return the ANSI name; - if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ - -const char * -cplus_mangle_opname (const char *opname, int options) -{ - size_t i; - int len; - - len = strlen (opname); - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if ((int) strlen (optable[i].out) == len - && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) - && memcmp (optable[i].out, opname, len) == 0) - return optable[i].in; - } - return (0); -} - -/* Add a routine to set the demangling style to be sure it is valid and - allow for any demangler initialization that maybe necessary. */ - -enum demangling_styles -cplus_demangle_set_style (enum demangling_styles style) -{ - const struct demangler_engine *demangler = libiberty_demanglers; - - for (; demangler->demangling_style != unknown_demangling; ++demangler) - if (style == demangler->demangling_style) - { - current_demangling_style = style; - return current_demangling_style; - } - - return unknown_demangling; -} - -/* Do string name to style translation */ - -enum demangling_styles -cplus_demangle_name_to_style (const char *name) -{ - const struct demangler_engine *demangler = libiberty_demanglers; - - for (; demangler->demangling_style != unknown_demangling; ++demangler) - if (strcmp (name, demangler->demangling_style_name) == 0) - return demangler->demangling_style; - - return unknown_demangling; -} - -/* char *cplus_demangle (const char *mangled, int options) - - If MANGLED is a mangled function name produced by GNU C++, then - a pointer to a @code{malloc}ed string giving a C++ representation - of the name will be returned; otherwise NULL will be returned. - It is the caller's responsibility to free the string which - is returned. - - The OPTIONS arg may contain one or more of the following bits: - - DMGL_ANSI ANSI qualifiers such as `const' and `void' are - included. - DMGL_PARAMS Function parameters are included. - - For example, - - cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" - cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" - cplus_demangle ("foo__1Ai", 0) => "A::foo" - - cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" - cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" - cplus_demangle ("foo__1Afe", 0) => "A::foo" - - Note that any leading underscores, or other such characters prepended by - the compilation system, are presumed to have already been stripped from - MANGLED. */ - -char * -cplus_demangle (const char *mangled, int options) -{ - char *ret; - struct work_stuff work[1]; - - if (current_demangling_style == no_demangling) - return xstrdup (mangled); - - memset ((char *) work, 0, sizeof (work)); - work->options = options; - if ((work->options & DMGL_STYLE_MASK) == 0) - work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; - - /* The V3 ABI demangling is implemented elsewhere. */ - if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) - { - ret = cplus_demangle_v3 (mangled, work->options); - if (ret || GNU_V3_DEMANGLING) - return ret; - } - - if (JAVA_DEMANGLING) - { - ret = java_demangle_v3 (mangled); - if (ret) - return ret; - } - - if (GNAT_DEMANGLING) - return ada_demangle(mangled,options); - - ret = internal_cplus_demangle (work, mangled); - squangle_mop_up (work); - return (ret); -} - - -/* Assuming *OLD_VECT points to an array of *SIZE objects of size - ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, - updating *OLD_VECT and *SIZE as necessary. */ - -static void -grow_vect (char **old_vect, size_t *size, size_t min_size, int element_size) -{ - if (*size < min_size) - { - *size *= 2; - if (*size < min_size) - *size = min_size; - *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size); - } -} - -/* Demangle ada names: - 1. Discard final __{DIGIT}+ or ${DIGIT}+ - 2. Convert other instances of embedded "__" to `.'. - 3. Discard leading _ada_. - 4. Remove everything after first ___ if it is followed by 'X'. - 5. Put symbols that should be suppressed in <...> brackets. - The resulting string is valid until the next call of ada_demangle. */ - -static char * -ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) -{ - int i, j; - int len0; - const char* p; - char *demangled = NULL; - int changed; - size_t demangled_size = 0; - - changed = 0; - - if (strncmp (mangled, "_ada_", 5) == 0) - { - mangled += 5; - changed = 1; - } - - if (mangled[0] == '_' || mangled[0] == '<') - goto Suppress; - - p = strstr (mangled, "___"); - if (p == NULL) - len0 = strlen (mangled); - else - { - if (p[3] == 'X') - { - len0 = p - mangled; - changed = 1; - } - else - goto Suppress; - } - - /* Make demangled big enough for possible expansion by operator name. */ - grow_vect (&demangled, - &demangled_size, 2 * len0 + 1, - sizeof (char)); - - if (ISDIGIT ((unsigned char) mangled[len0 - 1])) { - for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1) - ; - if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') - { - len0 = i - 1; - changed = 1; - } - else if (mangled[i] == '$') - { - len0 = i; - changed = 1; - } - } - - for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]); - i += 1, j += 1) - demangled[j] = mangled[i]; - - while (i < len0) - { - if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') - { - demangled[j] = '.'; - changed = 1; - i += 2; j += 1; - } - else - { - demangled[j] = mangled[i]; - i += 1; j += 1; - } - } - demangled[j] = '\000'; - - for (i = 0; demangled[i] != '\0'; i += 1) - if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') - goto Suppress; - - if (! changed) - { - free (demangled); - return NULL; - } - else - return demangled; - - Suppress: - grow_vect (&demangled, - &demangled_size, strlen (mangled) + 3, - sizeof (char)); - - if (mangled[0] == '<') - strcpy (demangled, mangled); - else - sprintf (demangled, "<%s>", mangled); - - return demangled; -} - -/* This function performs most of what cplus_demangle use to do, but - to be able to demangle a name with a B, K or n code, we need to - have a longer term memory of what types have been seen. The original - now initializes and cleans up the squangle code info, while internal - calls go directly to this routine to avoid resetting that info. */ - -static char * -internal_cplus_demangle (struct work_stuff *work, const char *mangled) -{ - - string decl; - int success = 0; - char *demangled = NULL; - int s1, s2, s3, s4; - s1 = work->constructor; - s2 = work->destructor; - s3 = work->static_type; - s4 = work->type_quals; - work->constructor = work->destructor = 0; - work->type_quals = TYPE_UNQUALIFIED; - work->dllimported = 0; - - if ((mangled != NULL) && (*mangled != '\0')) - { - string_init (&decl); - - /* First check to see if gnu style demangling is active and if the - string to be demangled contains a CPLUS_MARKER. If so, attempt to - recognize one of the gnu special forms rather than looking for a - standard prefix. In particular, don't worry about whether there - is a "__" string in the mangled string. Consider "_$_5__foo" for - example. */ - - if ((AUTO_DEMANGLING || GNU_DEMANGLING)) - { - success = gnu_special (work, &mangled, &decl); - } - if (!success) - { - success = demangle_prefix (work, &mangled, &decl); - } - if (success && (*mangled != '\0')) - { - success = demangle_signature (work, &mangled, &decl); - } - if (work->constructor == 2) - { - string_prepend (&decl, "global constructors keyed to "); - work->constructor = 0; - } - else if (work->destructor == 2) - { - string_prepend (&decl, "global destructors keyed to "); - work->destructor = 0; - } - else if (work->dllimported == 1) - { - string_prepend (&decl, "import stub for "); - work->dllimported = 0; - } - demangled = mop_up (work, &decl, success); - } - work->constructor = s1; - work->destructor = s2; - work->static_type = s3; - work->type_quals = s4; - return demangled; -} - - -/* Clear out and squangling related storage */ -static void -squangle_mop_up (struct work_stuff *work) -{ - /* clean up the B and K type mangling types. */ - forget_B_and_K_types (work); - if (work -> btypevec != NULL) - { - free ((char *) work -> btypevec); - } - if (work -> ktypevec != NULL) - { - free ((char *) work -> ktypevec); - } -} - - -/* Copy the work state and storage. */ - -static void -work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) -{ - int i; - - delete_work_stuff (to); - - /* Shallow-copy scalars. */ - memcpy (to, from, sizeof (*to)); - - /* Deep-copy dynamic storage. */ - if (from->typevec_size) - to->typevec = XNEWVEC (char *, from->typevec_size); - - for (i = 0; i < from->ntypes; i++) - { - int len = strlen (from->typevec[i]) + 1; - - to->typevec[i] = XNEWVEC (char, len); - memcpy (to->typevec[i], from->typevec[i], len); - } - - if (from->ksize) - to->ktypevec = XNEWVEC (char *, from->ksize); - - for (i = 0; i < from->numk; i++) - { - int len = strlen (from->ktypevec[i]) + 1; - - to->ktypevec[i] = XNEWVEC (char, len); - memcpy (to->ktypevec[i], from->ktypevec[i], len); - } - - if (from->bsize) - to->btypevec = XNEWVEC (char *, from->bsize); - - for (i = 0; i < from->numb; i++) - { - int len = strlen (from->btypevec[i]) + 1; - - to->btypevec[i] = XNEWVEC (char , len); - memcpy (to->btypevec[i], from->btypevec[i], len); - } - - if (from->ntmpl_args) - to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); - - for (i = 0; i < from->ntmpl_args; i++) - { - int len = strlen (from->tmpl_argvec[i]) + 1; - - to->tmpl_argvec[i] = XNEWVEC (char, len); - memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); - } - - if (from->previous_argument) - { - to->previous_argument = XNEW (string); - string_init (to->previous_argument); - string_appends (to->previous_argument, from->previous_argument); - } -} - - -/* Delete dynamic stuff in work_stuff that is not to be re-used. */ - -static void -delete_non_B_K_work_stuff (struct work_stuff *work) -{ - /* Discard the remembered types, if any. */ - - forget_types (work); - if (work -> typevec != NULL) - { - free ((char *) work -> typevec); - work -> typevec = NULL; - work -> typevec_size = 0; - } - if (work->tmpl_argvec) - { - int i; - - for (i = 0; i < work->ntmpl_args; i++) - if (work->tmpl_argvec[i]) - free ((char*) work->tmpl_argvec[i]); - - free ((char*) work->tmpl_argvec); - work->tmpl_argvec = NULL; - } - if (work->previous_argument) - { - string_delete (work->previous_argument); - free ((char*) work->previous_argument); - work->previous_argument = NULL; - } -} - - -/* Delete all dynamic storage in work_stuff. */ -static void -delete_work_stuff (struct work_stuff *work) -{ - delete_non_B_K_work_stuff (work); - squangle_mop_up (work); -} - - -/* Clear out any mangled storage */ - -static char * -mop_up (struct work_stuff *work, string *declp, int success) -{ - char *demangled = NULL; - - delete_non_B_K_work_stuff (work); - - /* If demangling was successful, ensure that the demangled string is null - terminated and return it. Otherwise, free the demangling decl. */ - - if (!success) - { - string_delete (declp); - } - else - { - string_appendn (declp, "", 1); - demangled = declp->b; - } - return (demangled); -} - -/* - -LOCAL FUNCTION - - demangle_signature -- demangle the signature part of a mangled name - -SYNOPSIS - - static int - demangle_signature (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the signature portion of the mangled name. - - DECLP is the string where demangled output is being built. At - entry it contains the demangled root name from the mangled name - prefix. I.E. either a demangled operator name or the root function - name. In some special cases, it may contain nothing. - - *MANGLED points to the current unconsumed location in the mangled - name. As tokens are consumed and demangling is performed, the - pointer is updated to continuously point at the next token to - be consumed. - - Demangling GNU style mangled names is nasty because there is no - explicit token that marks the start of the outermost function - argument list. */ - -static int -demangle_signature (struct work_stuff *work, - const char **mangled, string *declp) -{ - int success = 1; - int func_done = 0; - int expect_func = 0; - int expect_return_type = 0; - const char *oldmangled = NULL; - string trawname; - string tname; - - while (success && (**mangled != '\0')) - { - switch (**mangled) - { - case 'Q': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (success) - remember_type (work, oldmangled, *mangled - oldmangled); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - expect_func = 1; - oldmangled = NULL; - break; - - case 'K': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'S': - /* Static member function */ - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - (*mangled)++; - work -> static_type = 1; - break; - - case 'C': - case 'V': - case 'u': - work->type_quals |= code_for_qualifier (**mangled); - - /* a qualified member function */ - if (oldmangled == NULL) - oldmangled = *mangled; - (*mangled)++; - break; - - case 'L': - /* Local class name follows after "Lnnn_" */ - if (HP_DEMANGLING) - { - while (**mangled && (**mangled != '_')) - (*mangled)++; - if (!**mangled) - success = 0; - else - (*mangled)++; - } - else - success = 0; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - work->temp_start = -1; /* uppermost call to demangle_class */ - success = demangle_class (work, mangled, declp); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) - { - /* EDG and others will have the "F", so we let the loop cycle - if we are looking at one. */ - if (**mangled != 'F') - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'B': - { - string s; - success = do_type (work, mangled, &s); - if (success) - { - string_append (&s, SCOPE_STRING (work)); - string_prepends (declp, &s); - string_delete (&s); - } - oldmangled = NULL; - expect_func = 1; - } - break; - - case 'F': - /* Function */ - /* ARM/HP style demangling includes a specific 'F' character after - the class name. For GNU style, it is just implied. So we can - safely just consume any 'F' at this point and be compatible - with either style. */ - - oldmangled = NULL; - func_done = 1; - (*mangled)++; - - /* For lucid/ARM/HP style we have to forget any types we might - have remembered up to this point, since they were not argument - types. GNU style considers all types seen as available for - back references. See comment in demangle_args() */ - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* After picking off the function args, we expect to either - find the function return type (preceded by an '_') or the - end of the string. */ - if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') - { - ++(*mangled); - /* At this level, we do not care about the return type. */ - success = do_type (work, mangled, &tname); - string_delete (&tname); - } - - break; - - case 't': - /* G++ Template */ - string_init(&trawname); - string_init(&tname); - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - success = demangle_template (work, mangled, &tname, - &trawname, 1, 1); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - string_append (&tname, SCOPE_STRING (work)); - - string_prepends(declp, &tname); - if (work -> destructor & 1) - { - string_prepend (&trawname, "~"); - string_appends (declp, &trawname); - work->destructor -= 1; - } - if ((work->constructor & 1) || (work->destructor & 1)) - { - string_appends (declp, &trawname); - work->constructor -= 1; - } - string_delete(&trawname); - string_delete(&tname); - oldmangled = NULL; - expect_func = 1; - break; - - case '_': - if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type) - { - /* Read the return type. */ - string return_type; - - (*mangled)++; - success = do_type (work, mangled, &return_type); - APPEND_BLANK (&return_type); - - string_prepends (declp, &return_type); - string_delete (&return_type); - break; - } - else - /* At the outermost level, we cannot have a return type specified, - so if we run into another '_' at this point we are dealing with - a mangled name that is either bogus, or has been mangled by - some algorithm we don't know how to deal with. So just - reject the entire demangling. */ - /* However, "_nnn" is an expected suffix for alternate entry point - numbered nnn for a function, with HP aCC, so skip over that - without reporting failure. pai/1997-09-04 */ - if (HP_DEMANGLING) - { - (*mangled)++; - while (**mangled && ISDIGIT ((unsigned char)**mangled)) - (*mangled)++; - } - else - success = 0; - break; - - case 'H': - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* A G++ template function. Read the template arguments. */ - success = demangle_template (work, mangled, declp, 0, 0, - 0); - if (!(work->constructor & 1)) - expect_return_type = 1; - (*mangled)++; - break; - } - else - /* fall through */ - {;} - - default: - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = 1; - success = demangle_args (work, mangled, declp); - } - else - { - /* Non-GNU demanglers use a specific token to mark the start - of the outermost function argument tokens. Typically 'F', - for ARM/HP-demangling, for example. So if we find something - we are not prepared for, it must be an error. */ - success = 0; - } - break; - } - /* - if (AUTO_DEMANGLING || GNU_DEMANGLING) - */ - { - if (success && expect_func) - { - func_done = 1; - if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* Since template include the mangling of their return types, - we must set expect_func to 0 so that we don't try do - demangle more arguments the next time we get here. */ - expect_func = 0; - } - } - } - if (success && !func_done) - { - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added to - the current declp. Note that with ARM/HP, the first case - represents the name of a static data member 'foo::bar', - which is in the current declp, so we leave it alone. */ - success = demangle_args (work, mangled, declp); - } - } - if (success && PRINT_ARG_TYPES) - { - if (work->static_type) - string_append (declp, " static"); - if (work->type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (declp); - string_append (declp, qualifier_string (work->type_quals)); - } - } - - return (success); -} - -#if 0 - -static int -demangle_method_args (struct work_stuff *work, const char **mangled, - string *declp) -{ - int success = 0; - - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - return (success); -} - -#endif - -static int -demangle_template_template_parm (struct work_stuff *work, - const char **mangled, string *tname) -{ - int i; - int r; - int need_comma = 0; - int success = 1; - string temp; - - string_append (tname, "template <"); - /* get size of template parameter list */ - if (get_count (mangled, &r)) - { - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - string_append (tname, "class"); - } - /* z for template parameters */ - else if (**mangled == 'z') - { - (*mangled)++; - success = - demangle_template_template_parm (work, mangled, tname); - if (!success) - { - break; - } - } - else - { - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - } - string_delete(&temp); - if (!success) - { - break; - } - } - need_comma = 1; - } - - } - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, "> class"); - return (success); -} - -static int -demangle_expression (struct work_stuff *work, const char **mangled, - string *s, type_kind_t tk) -{ - int need_operator = 0; - int success; - - success = 1; - string_appendn (s, "(", 1); - (*mangled)++; - while (success && **mangled != 'W' && **mangled != '\0') - { - if (need_operator) - { - size_t i; - size_t len; - - success = 0; - - len = strlen (*mangled); - - for (i = 0; i < ARRAY_SIZE (optable); ++i) - { - size_t l = strlen (optable[i].in); - - if (l <= len - && memcmp (optable[i].in, *mangled, l) == 0) - { - string_appendn (s, " ", 1); - string_append (s, optable[i].out); - string_appendn (s, " ", 1); - success = 1; - (*mangled) += l; - break; - } - } - - if (!success) - break; - } - else - need_operator = 1; - - success = demangle_template_value_parm (work, mangled, s, tk); - } - - if (**mangled != 'W') - success = 0; - else - { - string_appendn (s, ")", 1); - (*mangled)++; - } - - return success; -} - -static int -demangle_integral_value (struct work_stuff *work, - const char **mangled, string *s) -{ - int success; - - if (**mangled == 'E') - success = demangle_expression (work, mangled, s, tk_integral); - else if (**mangled == 'Q' || **mangled == 'K') - success = demangle_qualified (work, mangled, s, 0, 1); - else - { - int value; - - /* By default, we let the number decide whether we shall consume an - underscore. */ - int multidigit_without_leading_underscore = 0; - int leave_following_underscore = 0; - - success = 0; - - if (**mangled == '_') - { - if (mangled[0][1] == 'm') - { - /* Since consume_count_with_underscores does not handle the - `m'-prefix we must do it here, using consume_count and - adjusting underscores: we have to consume the underscore - matching the prepended one. */ - multidigit_without_leading_underscore = 1; - string_appendn (s, "-", 1); - (*mangled) += 2; - } - else - { - /* Do not consume a following underscore; - consume_count_with_underscores will consume what - should be consumed. */ - leave_following_underscore = 1; - } - } - else - { - /* Negative numbers are indicated with a leading `m'. */ - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - /* Since consume_count_with_underscores does not handle - multi-digit numbers that do not start with an underscore, - and this number can be an integer template parameter, - we have to call consume_count. */ - multidigit_without_leading_underscore = 1; - /* These multi-digit numbers never end on an underscore, - so if there is one then don't eat it. */ - leave_following_underscore = 1; - } - - /* We must call consume_count if we expect to remove a trailing - underscore, since consume_count_with_underscores expects - the leading underscore (that we consumed) if it is to handle - multi-digit numbers. */ - if (multidigit_without_leading_underscore) - value = consume_count (mangled); - else - value = consume_count_with_underscores (mangled); - - if (value != -1) - { - char buf[INTBUF_SIZE]; - sprintf (buf, "%d", value); - string_append (s, buf); - - /* Numbers not otherwise delimited, might have an underscore - appended as a delimeter, which we should skip. - - ??? This used to always remove a following underscore, which - is wrong. If other (arbitrary) cases are followed by an - underscore, we need to do something more radical. */ - - if ((value > 9 || multidigit_without_leading_underscore) - && ! leave_following_underscore - && **mangled == '_') - (*mangled)++; - - /* All is well. */ - success = 1; - } - } - - return success; -} - -/* Demangle the real value in MANGLED. */ - -static int -demangle_real_value (struct work_stuff *work, - const char **mangled, string *s) -{ - if (**mangled == 'E') - return demangle_expression (work, mangled, s, tk_real); - - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - if (**mangled == '.') /* fraction */ - { - string_appendn (s, ".", 1); - (*mangled)++; - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - if (**mangled == 'e') /* exponent */ - { - string_appendn (s, "e", 1); - (*mangled)++; - while (ISDIGIT ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - - return 1; -} - -static int -demangle_template_value_parm (struct work_stuff *work, const char **mangled, - string *s, type_kind_t tk) -{ - int success = 1; - - if (**mangled == 'Y') - { - /* The next argument is a template parameter. */ - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return -1; - if (work->tmpl_argvec) - string_append (s, work->tmpl_argvec[idx]); - else - string_append_template_idx (s, idx); - } - else if (tk == tk_integral) - success = demangle_integral_value (work, mangled, s); - else if (tk == tk_char) - { - char tmp[2]; - int val; - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - string_appendn (s, "'", 1); - val = consume_count(mangled); - if (val <= 0) - success = 0; - else - { - tmp[0] = (char)val; - tmp[1] = '\0'; - string_appendn (s, &tmp[0], 1); - string_appendn (s, "'", 1); - } - } - else if (tk == tk_bool) - { - int val = consume_count (mangled); - if (val == 0) - string_appendn (s, "false", 5); - else if (val == 1) - string_appendn (s, "true", 4); - else - success = 0; - } - else if (tk == tk_real) - success = demangle_real_value (work, mangled, s); - else if (tk == tk_pointer || tk == tk_reference) - { - if (**mangled == 'Q') - success = demangle_qualified (work, mangled, s, - /*isfuncname=*/0, - /*append=*/1); - else - { - int symbol_len = consume_count (mangled); - if (symbol_len == -1) - return -1; - if (symbol_len == 0) - string_appendn (s, "0", 1); - else - { - char *p = XNEWVEC (char, symbol_len + 1), *q; - strncpy (p, *mangled, symbol_len); - p [symbol_len] = '\0'; - /* We use cplus_demangle here, rather than - internal_cplus_demangle, because the name of the entity - mangled here does not make use of any of the squangling - or type-code information we have built up thus far; it is - mangled independently. */ - q = cplus_demangle (p, work->options); - if (tk == tk_pointer) - string_appendn (s, "&", 1); - /* FIXME: Pointer-to-member constants should get a - qualifying class name here. */ - if (q) - { - string_append (s, q); - free (q); - } - else - string_append (s, p); - free (p); - } - *mangled += symbol_len; - } - } - - return success; -} - -/* Demangle the template name in MANGLED. The full name of the - template (e.g., S) is placed in TNAME. The name without the - template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is - non-NULL. If IS_TYPE is nonzero, this template is a type template, - not a function template. If both IS_TYPE and REMEMBER are nonzero, - the template is remembered in the list of back-referenceable - types. */ - -static int -demangle_template (struct work_stuff *work, const char **mangled, - string *tname, string *trawname, - int is_type, int remember) -{ - int i; - int r; - int need_comma = 0; - int success = 0; - int is_java_array = 0; - string temp; - - (*mangled)++; - if (is_type) - { - /* get template name */ - if (**mangled == 'z') - { - int idx; - (*mangled)++; - (*mangled)++; - - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return (0); - - if (work->tmpl_argvec) - { - string_append (tname, work->tmpl_argvec[idx]); - if (trawname) - string_append (trawname, work->tmpl_argvec[idx]); - } - else - { - string_append_template_idx (tname, idx); - if (trawname) - string_append_template_idx (trawname, idx); - } - } - else - { - if ((r = consume_count (mangled)) <= 0 - || (int) strlen (*mangled) < r) - { - return (0); - } - is_java_array = (work -> options & DMGL_JAVA) - && strncmp (*mangled, "JArray1Z", 8) == 0; - if (! is_java_array) - { - string_appendn (tname, *mangled, r); - } - if (trawname) - string_appendn (trawname, *mangled, r); - *mangled += r; - } - } - if (!is_java_array) - string_append (tname, "<"); - /* get size of template parameter list */ - if (!get_count (mangled, &r)) - { - return (0); - } - if (!is_type) - { - /* Create an array for saving the template argument values. */ - work->tmpl_argvec = XNEWVEC (char *, r); - work->ntmpl_args = r; - for (i = 0; i < r; i++) - work->tmpl_argvec[i] = 0; - } - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - - if (!is_type) - { - /* Save the template argument. */ - int len = temp.p - temp.b; - work->tmpl_argvec[i] = XNEWVEC (char, len + 1); - memcpy (work->tmpl_argvec[i], temp.b, len); - work->tmpl_argvec[i][len] = '\0'; - } - } - string_delete(&temp); - if (!success) - { - break; - } - } - /* z for template parameters */ - else if (**mangled == 'z') - { - int r2; - (*mangled)++; - success = demangle_template_template_parm (work, mangled, tname); - - if (success - && (r2 = consume_count (mangled)) > 0 - && (int) strlen (*mangled) >= r2) - { - string_append (tname, " "); - string_appendn (tname, *mangled, r2); - if (!is_type) - { - /* Save the template argument. */ - int len = r2; - work->tmpl_argvec[i] = XNEWVEC (char, len + 1); - memcpy (work->tmpl_argvec[i], *mangled, len); - work->tmpl_argvec[i][len] = '\0'; - } - *mangled += r2; - } - if (!success) - { - break; - } - } - else - { - string param; - string* s; - - /* otherwise, value parameter */ - - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - string_delete(&temp); - if (!success) - break; - - if (!is_type) - { - s = ¶m; - string_init (s); - } - else - s = tname; - - success = demangle_template_value_parm (work, mangled, s, - (type_kind_t) success); - - if (!success) - { - if (!is_type) - string_delete (s); - success = 0; - break; - } - - if (!is_type) - { - int len = s->p - s->b; - work->tmpl_argvec[i] = XNEWVEC (char, len + 1); - memcpy (work->tmpl_argvec[i], s->b, len); - work->tmpl_argvec[i][len] = '\0'; - - string_appends (tname, s); - string_delete (s); - } - } - need_comma = 1; - } - if (is_java_array) - { - string_append (tname, "[]"); - } - else - { - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, ">"); - } - - if (is_type && remember) - { - const int bindex = register_Btype (work); - remember_Btype (work, tname->b, LEN_STRING (tname), bindex); - } - - /* - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - } - */ - return (success); -} - -static int -arm_pt (struct work_stuff *work, const char *mangled, - int n, const char **anchor, const char **args) -{ - /* Check if ARM template with "__pt__" in it ("parameterized type") */ - /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ - if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - if (AUTO_DEMANGLING || EDG_DEMANGLING) - { - if ((*anchor = strstr (mangled, "__tm__")) - || (*anchor = strstr (mangled, "__ps__")) - || (*anchor = strstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - else if ((*anchor = strstr (mangled, "__S"))) - { - int len; - *args = *anchor + 3; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - } - - return 0; -} - -static void -demangle_arm_hp_template (struct work_stuff *work, const char **mangled, - int n, string *declp) -{ - const char *p; - const char *args; - const char *e = *mangled + n; - string arg; - - /* Check for HP aCC template spec: classXt1t2 where t1, t2 are - template args */ - if (HP_DEMANGLING && ((*mangled)[n] == 'X')) - { - char *start_spec_args = NULL; - int hold_options; - - /* First check for and omit template specialization pseudo-arguments, - such as in "Spec<#1,#1.*>" */ - start_spec_args = strchr (*mangled, '<'); - if (start_spec_args && (start_spec_args - *mangled < n)) - string_appendn (declp, *mangled, start_spec_args - *mangled); - else - string_appendn (declp, *mangled, n); - (*mangled) += n + 1; - string_init (&arg); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - - /* We want to unconditionally demangle parameter types in - template parameters. */ - hold_options = work->options; - work->options |= DMGL_PARAMS; - - string_append (declp, "<"); - while (1) - { - string_delete (&arg); - switch (**mangled) - { - case 'T': - /* 'T' signals a type parameter */ - (*mangled)++; - if (!do_type (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'U': - case 'S': - /* 'U' or 'S' signals an integral value */ - if (!do_hpacc_template_const_value (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'A': - /* 'A' signals a named constant expression (literal) */ - if (!do_hpacc_template_literal (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - default: - /* Today, 1997-09-03, we have only the above types - of template parameters */ - /* FIXME: maybe this should fail and return null */ - goto hpacc_template_args_done; - } - string_appends (declp, &arg); - /* Check if we're at the end of template args. - 0 if at end of static member of template class, - _ if done with template args for a function */ - if ((**mangled == '\000') || (**mangled == '_')) - break; - else - string_append (declp, ","); - } - hpacc_template_args_done: - string_append (declp, ">"); - string_delete (&arg); - if (**mangled == '_') - (*mangled)++; - work->options = hold_options; - return; - } - /* ARM template? (Also handles HP cfront extensions) */ - else if (arm_pt (work, *mangled, n, &p, &args)) - { - int hold_options; - string type_str; - - string_init (&arg); - string_appendn (declp, *mangled, p - *mangled); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - - /* We want to unconditionally demangle parameter types in - template parameters. */ - hold_options = work->options; - work->options |= DMGL_PARAMS; - - string_append (declp, "<"); - /* should do error checking here */ - while (args < e) { - string_delete (&arg); - - /* Check for type or literal here */ - switch (*args) - { - /* HP cfront extensions to ARM for template args */ - /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ - /* FIXME: We handle only numeric literals for HP cfront */ - case 'X': - /* A typed constant value follows */ - args++; - if (!do_type (work, &args, &type_str)) - goto cfront_template_args_done; - string_append (&arg, "("); - string_appends (&arg, &type_str); - string_delete (&type_str); - string_append (&arg, ")"); - if (*args != 'L') - goto cfront_template_args_done; - args++; - /* Now snarf a literal value following 'L' */ - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - - case 'L': - /* Snarf a literal following 'L' */ - args++; - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - default: - /* Not handling other HP cfront stuff */ - { - const char* old_args = args; - if (!do_type (work, &args, &arg)) - goto cfront_template_args_done; - - /* Fail if we didn't make any progress: prevent infinite loop. */ - if (args == old_args) - { - work->options = hold_options; - return; - } - } - } - string_appends (declp, &arg); - string_append (declp, ","); - } - cfront_template_args_done: - string_delete (&arg); - if (args >= e) - --declp->p; /* remove extra comma */ - string_append (declp, ">"); - work->options = hold_options; - } - else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 - && (*mangled)[9] == 'N' - && (*mangled)[8] == (*mangled)[10] - && strchr (cplus_markers, (*mangled)[8])) - { - /* A member of the anonymous namespace. */ - string_append (declp, "{anonymous}"); - } - else - { - if (work->temp_start == -1) /* non-recursive call only */ - work->temp_start = 0; /* disable in recursive calls */ - string_appendn (declp, *mangled, n); - } - *mangled += n; -} - -/* Extract a class name, possibly a template with arguments, from the - mangled string; qualifiers, local class indicators, etc. have - already been dealt with */ - -static int -demangle_class_name (struct work_stuff *work, const char **mangled, - string *declp) -{ - int n; - int success = 0; - - n = consume_count (mangled); - if (n == -1) - return 0; - if ((int) strlen (*mangled) >= n) - { - demangle_arm_hp_template (work, mangled, n, declp); - success = 1; - } - - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_class -- demangle a mangled class sequence - -SYNOPSIS - - static int - demangle_class (struct work_stuff *work, const char **mangled, - strint *declp) - -DESCRIPTION - - DECLP points to the buffer into which demangling is being done. - - *MANGLED points to the current token to be demangled. On input, - it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) - On exit, it points to the next token after the mangled class on - success, or the first unconsumed token on failure. - - If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then - we are demangling a constructor or destructor. In this case - we prepend "class::class" or "class::~class" to DECLP. - - Otherwise, we prepend "class::" to the current DECLP. - - Reset the constructor/destructor flags once they have been - "consumed". This allows demangle_class to be called later during - the same demangling, to do normal class demangling. - - Returns 1 if demangling is successful, 0 otherwise. - -*/ - -static int -demangle_class (struct work_stuff *work, const char **mangled, string *declp) -{ - int success = 0; - int btype; - string class_name; - char *save_class_name_end = 0; - - string_init (&class_name); - btype = register_Btype (work); - if (demangle_class_name (work, mangled, &class_name)) - { - save_class_name_end = class_name.p; - if ((work->constructor & 1) || (work->destructor & 1)) - { - /* adjust so we don't include template args */ - if (work->temp_start && (work->temp_start != -1)) - { - class_name.p = class_name.b + work->temp_start; - } - string_prepends (declp, &class_name); - if (work -> destructor & 1) - { - string_prepend (declp, "~"); - work -> destructor -= 1; - } - else - { - work -> constructor -= 1; - } - } - class_name.p = save_class_name_end; - remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); - remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); - string_prepend (declp, SCOPE_STRING (work)); - string_prepends (declp, &class_name); - success = 1; - } - string_delete (&class_name); - return (success); -} - - -/* Called when there's a "__" in the mangled name, with `scan' pointing to - the rightmost guess. - - Find the correct "__"-sequence where the function name ends and the - signature starts, which is ambiguous with GNU mangling. - Call demangle_signature here, so we can make sure we found the right - one; *mangled will be consumed so caller will not make further calls to - demangle_signature. */ - -static int -iterate_demangle_function (struct work_stuff *work, const char **mangled, - string *declp, const char *scan) -{ - const char *mangle_init = *mangled; - int success = 0; - string decl_init; - struct work_stuff work_init; - - if (*(scan + 2) == '\0') - return 0; - - /* Do not iterate for some demangling modes, or if there's only one - "__"-sequence. This is the normal case. */ - if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING - || strstr (scan + 2, "__") == NULL) - return demangle_function_name (work, mangled, declp, scan); - - /* Save state so we can restart if the guess at the correct "__" was - wrong. */ - string_init (&decl_init); - string_appends (&decl_init, declp); - memset (&work_init, 0, sizeof work_init); - work_stuff_copy_to_from (&work_init, work); - - /* Iterate over occurrences of __, allowing names and types to have a - "__" sequence in them. We must start with the first (not the last) - occurrence, since "__" most often occur between independent mangled - parts, hence starting at the last occurence inside a signature - might get us a "successful" demangling of the signature. */ - - while (scan[2]) - { - if (demangle_function_name (work, mangled, declp, scan)) - { - success = demangle_signature (work, mangled, declp); - if (success) - break; - } - - /* Reset demangle state for the next round. */ - *mangled = mangle_init; - string_clear (declp); - string_appends (declp, &decl_init); - work_stuff_copy_to_from (work, &work_init); - - /* Leave this underscore-sequence. */ - scan += 2; - - /* Scan for the next "__" sequence. */ - while (*scan && (scan[0] != '_' || scan[1] != '_')) - scan++; - - /* Move to last "__" in this sequence. */ - while (*scan && *scan == '_') - scan++; - scan -= 2; - } - - /* Delete saved state. */ - delete_work_stuff (&work_init); - string_delete (&decl_init); - - return success; -} - -/* - -LOCAL FUNCTION - - demangle_prefix -- consume the mangled name prefix and find signature - -SYNOPSIS - - static int - demangle_prefix (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the prefix of the mangled name. - While processing the function name root, arrange to call - demangle_signature if the root is ambiguous. - - DECLP points to the string buffer into which demangled output is - placed. On entry, the buffer is empty. On exit it contains - the root function name, the demangled operator name, or in some - special cases either nothing or the completely demangled result. - - MANGLED points to the current pointer into the mangled name. As each - token of the mangled name is consumed, it is updated. Upon entry - the current mangled name pointer points to the first character of - the mangled name. Upon exit, it should point to the first character - of the signature if demangling was successful, or to the first - unconsumed character if demangling of the prefix was unsuccessful. - - Returns 1 on success, 0 otherwise. - */ - -static int -demangle_prefix (struct work_stuff *work, const char **mangled, - string *declp) -{ - int success = 1; - const char *scan; - int i; - - if (strlen(*mangled) > 6 - && (strncmp(*mangled, "_imp__", 6) == 0 - || strncmp(*mangled, "__imp_", 6) == 0)) - { - /* it's a symbol imported from a PE dynamic library. Check for both - new style prefix _imp__ and legacy __imp_ used by older versions - of dlltool. */ - (*mangled) += 6; - work->dllimported = 1; - } - else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) - { - char *marker = strchr (cplus_markers, (*mangled)[8]); - if (marker != NULL && *marker == (*mangled)[10]) - { - if ((*mangled)[9] == 'D') - { - /* it's a GNU global destructor to be executed at program exit */ - (*mangled) += 11; - work->destructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - else if ((*mangled)[9] == 'I') - { - /* it's a GNU global constructor to be executed at program init */ - (*mangled) += 11; - work->constructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - } - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0) - { - /* it's a ARM global destructor to be executed at program exit */ - (*mangled) += 7; - work->destructor = 2; - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0) - { - /* it's a ARM global constructor to be executed at program initial */ - (*mangled) += 7; - work->constructor = 2; - } - - /* This block of code is a reduction in strength time optimization - of: - scan = strstr (*mangled, "__"); */ - - { - scan = *mangled; - - do { - scan = strchr (scan, '_'); - } while (scan != NULL && *++scan != '_'); - - if (scan != NULL) --scan; - } - - if (scan != NULL) - { - /* We found a sequence of two or more '_', ensure that we start at - the last pair in the sequence. */ - i = strspn (scan, "_"); - if (i > 2) - { - scan += (i - 2); - } - } - - if (scan == NULL) - { - success = 0; - } - else if (work -> static_type) - { - if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't')) - { - success = 0; - } - } - else if ((scan == *mangled) - && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q') - || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) - { - /* The ARM says nothing about the mangling of local variables. - But cfront mangles local variables by prepending __ - to them. As an extension to ARM demangling we handle this case. */ - if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) - && ISDIGIT ((unsigned char)scan[2])) - { - *mangled = scan + 2; - consume_count (mangled); - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - else - { - /* A GNU style constructor starts with __[0-9Qt]. But cfront uses - names like __Q2_3foo3bar for nested type names. So don't accept - this style of constructor for cfront demangling. A GNU - style member-template constructor starts with 'H'. */ - if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)) - work -> constructor += 1; - *mangled = scan + 2; - } - } - else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') - { - /* Cfront-style parameterized type. Handled later as a signature. */ - success = 1; - - /* ARM template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm') - || (scan[2] == 'p' && scan[3] == 's') - || (scan[2] == 'p' && scan[3] == 't'))) - { - /* EDG-style parameterized type. Handled later as a signature. */ - success = 1; - - /* EDG template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2]) - && (scan[2] != 't')) - { - /* Mangled name starts with "__". Skip over any leading '_' characters, - then find the next "__" that separates the prefix from the signature. - */ - if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - || (arm_special (mangled, declp) == 0)) - { - while (*scan == '_') - { - scan++; - } - if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) - { - /* No separator (I.E. "__not_mangled"), or empty signature - (I.E. "__not_mangled_either__") */ - success = 0; - } - else - return iterate_demangle_function (work, mangled, declp, scan); - } - } - else if (*(scan + 2) != '\0') - { - /* Mangled name does not start with "__" but does have one somewhere - in there with non empty stuff after it. Looks like a global - function name. Iterate over all "__":s until the right - one is found. */ - return iterate_demangle_function (work, mangled, declp, scan); - } - else - { - /* Doesn't look like a mangled name */ - success = 0; - } - - if (!success && (work->constructor == 2 || work->destructor == 2)) - { - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - return (success); -} - -/* - -LOCAL FUNCTION - - gnu_special -- special handling of gnu mangled strings - -SYNOPSIS - - static int - gnu_special (struct work_stuff *work, const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special GNU style mangling forms that don't fit - the normal pattern. For example: - - _$_3foo (destructor for class foo) - _vt$foo (foo virtual table) - _vt$foo$bar (foo::bar virtual table) - __vt_foo (foo virtual table, new style with thunks) - _3foo$varname (static data member) - _Q22rs2tu$vw (static data member) - __t6vector1Zii (constructor with template) - __thunk_4__$_7ostream (virtual function thunk) - */ - -static int -gnu_special (struct work_stuff *work, const char **mangled, string *declp) -{ - int n; - int success = 1; - const char *p; - - if ((*mangled)[0] == '_' - && strchr (cplus_markers, (*mangled)[1]) != NULL - && (*mangled)[2] == '_') - { - /* Found a GNU style destructor, get past "__" */ - (*mangled) += 3; - work -> destructor += 1; - } - else if ((*mangled)[0] == '_' - && (((*mangled)[1] == '_' - && (*mangled)[2] == 'v' - && (*mangled)[3] == 't' - && (*mangled)[4] == '_') - || ((*mangled)[1] == 'v' - && (*mangled)[2] == 't' - && strchr (cplus_markers, (*mangled)[3]) != NULL))) - { - /* Found a GNU style virtual table, get past "_vt" - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - if ((*mangled)[2] == 'v') - (*mangled) += 5; /* New style, with thunks: "__vt_" */ - else - (*mangled) += 4; /* Old style, no thunks: "_vt" */ - while (**mangled != '\0') - { - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, - 1); - break; - default: - if (ISDIGIT((unsigned char)*mangled[0])) - { - n = consume_count(mangled); - /* We may be seeing a too-large size, or else a - "." indicating a static local symbol. In - any case, declare victory and move on; *don't* try - to use n to allocate. */ - if (n > (int) strlen (*mangled)) - { - success = 1; - break; - } - } - else - { - n = strcspn (*mangled, cplus_markers); - } - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - - p = strpbrk (*mangled, cplus_markers); - if (success && ((p == NULL) || (p == *mangled))) - { - if (p != NULL) - { - string_append (declp, SCOPE_STRING (work)); - (*mangled)++; - } - } - else - { - success = 0; - break; - } - } - if (success) - string_append (declp, " virtual table"); - } - else if ((*mangled)[0] == '_' - && (strchr("0123456789Qt", (*mangled)[1]) != NULL) - && (p = strpbrk (*mangled, cplus_markers)) != NULL) - { - /* static data member, "_3foo$varname" for example */ - (*mangled)++; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - n = consume_count (mangled); - if (n < 0 || n > (long) strlen (*mangled)) - { - success = 0; - break; - } - - if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 - && (*mangled)[9] == 'N' - && (*mangled)[8] == (*mangled)[10] - && strchr (cplus_markers, (*mangled)[8])) - { - /* A member of the anonymous namespace. There's information - about what identifier or filename it was keyed to, but - it's just there to make the mangled name unique; we just - step over it. */ - string_append (declp, "{anonymous}"); - (*mangled) += n; - - /* Now p points to the marker before the N, so we need to - update it to the first marker after what we consumed. */ - p = strpbrk (*mangled, cplus_markers); - break; - } - - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - if (success && (p == *mangled)) - { - /* Consumed everything up to the cplus_marker, append the - variable name. */ - (*mangled)++; - string_append (declp, SCOPE_STRING (work)); - n = strlen (*mangled); - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - else - { - success = 0; - } - } - else if (strncmp (*mangled, "__thunk_", 8) == 0) - { - int delta; - - (*mangled) += 8; - delta = consume_count (mangled); - if (delta == -1) - success = 0; - else - { - char *method = internal_cplus_demangle (work, ++*mangled); - - if (method) - { - char buf[50]; - sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); - string_append (declp, buf); - string_append (declp, method); - free (method); - n = strlen (*mangled); - (*mangled) += n; - } - else - { - success = 0; - } - } - } - else if (strncmp (*mangled, "__t", 3) == 0 - && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) - { - p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; - (*mangled) += 4; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - success = do_type (work, mangled, declp); - break; - } - if (success && **mangled != '\0') - success = 0; - if (success) - string_append (declp, p); - } - else - { - success = 0; - } - return (success); -} - -static void -recursively_demangle(struct work_stuff *work, const char **mangled, - string *result, int namelength) -{ - char * recurse = (char *)NULL; - char * recurse_dem = (char *)NULL; - - recurse = XNEWVEC (char, namelength + 1); - memcpy (recurse, *mangled, namelength); - recurse[namelength] = '\000'; - - recurse_dem = cplus_demangle (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, namelength); - } - free (recurse); - *mangled += namelength; -} - -/* - -LOCAL FUNCTION - - arm_special -- special handling of ARM/lucid mangled strings - -SYNOPSIS - - static int - arm_special (const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special ARM style mangling forms that don't fit - the normal pattern. For example: - - __vtbl__3foo (foo virtual table) - __vtbl__3foo__3bar (bar::foo virtual table) - - */ - -static int -arm_special (const char **mangled, string *declp) -{ - int n; - int success = 1; - const char *scan; - - if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) - { - /* Found a ARM style virtual table, get past ARM_VTABLE_STRING - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - scan = *mangled + ARM_VTABLE_STRLEN; - while (*scan != '\0') /* first check it can be demangled */ - { - n = consume_count (&scan); - if (n == -1) - { - return (0); /* no good */ - } - scan += n; - if (scan[0] == '_' && scan[1] == '_') - { - scan += 2; - } - } - (*mangled) += ARM_VTABLE_STRLEN; - while (**mangled != '\0') - { - n = consume_count (mangled); - if (n == -1 - || n > (long) strlen (*mangled)) - return 0; - string_prependn (declp, *mangled, n); - (*mangled) += n; - if ((*mangled)[0] == '_' && (*mangled)[1] == '_') - { - string_prepend (declp, "::"); - (*mangled) += 2; - } - } - string_append (declp, " virtual table"); - } - else - { - success = 0; - } - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_qualified -- demangle 'Q' qualified name strings - -SYNOPSIS - - static int - demangle_qualified (struct work_stuff *, const char *mangled, - string *result, int isfuncname, int append); - -DESCRIPTION - - Demangle a qualified name, such as "Q25Outer5Inner" which is - the mangled form of "Outer::Inner". The demangled output is - prepended or appended to the result string according to the - state of the append flag. - - If isfuncname is nonzero, then the qualified name we are building - is going to be used as a member function name, so if it is a - constructor or destructor function, append an appropriate - constructor or destructor name. I.E. for the above example, - the result for use as a constructor is "Outer::Inner::Inner" - and the result for use as a destructor is "Outer::Inner::~Inner". - -BUGS - - Numeric conversion is ASCII dependent (FIXME). - - */ - -static int -demangle_qualified (struct work_stuff *work, const char **mangled, - string *result, int isfuncname, int append) -{ - int qualifiers = 0; - int success = 1; - char num[2]; - string temp; - string last_name; - int bindex = register_Btype (work); - - /* We only make use of ISFUNCNAME if the entity is a constructor or - destructor. */ - isfuncname = (isfuncname - && ((work->constructor & 1) || (work->destructor & 1))); - - string_init (&temp); - string_init (&last_name); - - if ((*mangled)[0] == 'K') - { - /* Squangling qualified name reuse */ - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work -> numk) - success = 0; - else - string_append (&temp, work -> ktypevec[idx]); - } - else - switch ((*mangled)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is preceded - by an underscore (to distinguish it from the <= 9 case) and followed - by an underscore. */ - (*mangled)++; - qualifiers = consume_count_with_underscores (mangled); - if (qualifiers == -1) - success = 0; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* The count is in a single digit. */ - num[0] = (*mangled)[1]; - num[1] = '\0'; - qualifiers = atoi (num); - - /* If there is an underscore after the digit, skip it. This is - said to be for ARM-qualified names, but the ARM makes no - mention of such an underscore. Perhaps cfront uses one. */ - if ((*mangled)[2] == '_') - { - (*mangled)++; - } - (*mangled) += 2; - break; - - case '0': - default: - success = 0; - } - - if (!success) - return success; - - /* Pick off the names and collect them in the temp buffer in the order - in which they are found, separated by '::'. */ - - while (qualifiers-- > 0) - { - int remember_K = 1; - string_clear (&last_name); - - if (*mangled[0] == '_') - (*mangled)++; - - if (*mangled[0] == 't') - { - /* Here we always append to TEMP since we will want to use - the template name without the template parameters as a - constructor or destructor name. The appropriate - (parameter-less) value is returned by demangle_template - in LAST_NAME. We do not remember the template type here, - in order to match the G++ mangling algorithm. */ - success = demangle_template(work, mangled, &temp, - &last_name, 1, 0); - if (!success) - break; - } - else if (*mangled[0] == 'K') - { - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work->numk) - success = 0; - else - string_append (&temp, work->ktypevec[idx]); - remember_K = 0; - - if (!success) break; - } - else - { - if (EDG_DEMANGLING) - { - int namelength; - /* Now recursively demangle the qualifier - * This is necessary to deal with templates in - * mangling styles like EDG */ - namelength = consume_count (mangled); - if (namelength == -1) - { - success = 0; - break; - } - recursively_demangle(work, mangled, &temp, namelength); - } - else - { - string_delete (&last_name); - success = do_type (work, mangled, &last_name); - if (!success) - break; - string_appends (&temp, &last_name); - } - } - - if (remember_K) - remember_Ktype (work, temp.b, LEN_STRING (&temp)); - - if (qualifiers > 0) - string_append (&temp, SCOPE_STRING (work)); - } - - remember_Btype (work, temp.b, LEN_STRING (&temp), bindex); - - /* If we are using the result as a function name, we need to append - the appropriate '::' separated constructor or destructor name. - We do this here because this is the most convenient place, where - we already have a pointer to the name and the length of the name. */ - - if (isfuncname) - { - string_append (&temp, SCOPE_STRING (work)); - if (work -> destructor & 1) - string_append (&temp, "~"); - string_appends (&temp, &last_name); - } - - /* Now either prepend the temp buffer to the result, or append it, - depending upon the state of the append flag. */ - - if (append) - string_appends (result, &temp); - else - { - if (!STRING_EMPTY (result)) - string_append (&temp, SCOPE_STRING (work)); - string_prepends (result, &temp); - } - - string_delete (&last_name); - string_delete (&temp); - return (success); -} - -/* - -LOCAL FUNCTION - - get_count -- convert an ascii count to integer, consuming tokens - -SYNOPSIS - - static int - get_count (const char **type, int *count) - -DESCRIPTION - - Assume that *type points at a count in a mangled name; set - *count to its value, and set *type to the next character after - the count. There are some weird rules in effect here. - - If *type does not point at a string of digits, return zero. - - If *type points at a string of digits followed by an - underscore, set *count to their value as an integer, advance - *type to point *after the underscore, and return 1. - - If *type points at a string of digits not followed by an - underscore, consume only the first digit. Set *count to its - value as an integer, leave *type pointing after that digit, - and return 1. - - The excuse for this odd behavior: in the ARM and HP demangling - styles, a type can be followed by a repeat count of the form - `Nxy', where: - - `x' is a single digit specifying how many additional copies - of the type to append to the argument list, and - - `y' is one or more digits, specifying the zero-based index of - the first repeated argument in the list. Yes, as you're - unmangling the name you can figure this out yourself, but - it's there anyway. - - So, for example, in `bar__3fooFPiN51', the first argument is a - pointer to an integer (`Pi'), and then the next five arguments - are the same (`N5'), and the first repeat is the function's - second argument (`1'). -*/ - -static int -get_count (const char **type, int *count) -{ - const char *p; - int n; - - if (!ISDIGIT ((unsigned char)**type)) - return (0); - else - { - *count = **type - '0'; - (*type)++; - if (ISDIGIT ((unsigned char)**type)) - { - p = *type; - n = *count; - do - { - n *= 10; - n += *p - '0'; - p++; - } - while (ISDIGIT ((unsigned char)*p)); - if (*p == '_') - { - *type = p + 1; - *count = n; - } - } - } - return (1); -} - -/* RESULT will be initialised here; it will be freed on failure. The - value returned is really a type_kind_t. */ - -static int -do_type (struct work_stuff *work, const char **mangled, string *result) -{ - int n; - int done; - int success; - string decl; - const char *remembered_type; - int type_quals; - type_kind_t tk = tk_none; - - string_init (&decl); - string_init (result); - - done = 0; - success = 1; - while (success && !done) - { - int member; - switch (**mangled) - { - - /* A pointer type */ - case 'P': - case 'p': - (*mangled)++; - if (! (work -> options & DMGL_JAVA)) - string_prepend (&decl, "*"); - if (tk == tk_none) - tk = tk_pointer; - break; - - /* A reference type */ - case 'R': - (*mangled)++; - string_prepend (&decl, "&"); - if (tk == tk_none) - tk = tk_reference; - break; - - /* An array */ - case 'A': - { - ++(*mangled); - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - string_append (&decl, "["); - if (**mangled != '_') - success = demangle_template_value_parm (work, mangled, &decl, - tk_integral); - if (**mangled == '_') - ++(*mangled); - string_append (&decl, "]"); - break; - } - - /* A back reference to a previously seen type */ - case 'T': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> ntypes) - { - success = 0; - } - else - { - remembered_type = work -> typevec[n]; - mangled = &remembered_type; - } - break; - - /* A function */ - case 'F': - (*mangled)++; - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - /* After picking off the function args, we expect to either find the - function return type (preceded by an '_') or the end of the - string. */ - if (!demangle_nested_args (work, mangled, &decl) - || (**mangled != '_' && **mangled != '\0')) - { - success = 0; - break; - } - if (success && (**mangled == '_')) - (*mangled)++; - break; - - case 'M': - case 'O': - { - type_quals = TYPE_UNQUALIFIED; - - member = **mangled == 'M'; - (*mangled)++; - - string_append (&decl, ")"); - - /* We don't need to prepend `::' for a qualified name; - demangle_qualified will do that for us. */ - if (**mangled != 'Q') - string_prepend (&decl, SCOPE_STRING (work)); - - if (ISDIGIT ((unsigned char)**mangled)) - { - n = consume_count (mangled); - if (n == -1 - || (int) strlen (*mangled) < n) - { - success = 0; - break; - } - string_prependn (&decl, *mangled, n); - *mangled += n; - } - else if (**mangled == 'X' || **mangled == 'Y') - { - string temp; - do_type (work, mangled, &temp); - string_prepends (&decl, &temp); - string_delete (&temp); - } - else if (**mangled == 't') - { - string temp; - string_init (&temp); - success = demangle_template (work, mangled, &temp, - NULL, 1, 1); - if (success) - { - string_prependn (&decl, temp.b, temp.p - temp.b); - string_delete (&temp); - } - else - break; - } - else if (**mangled == 'Q') - { - success = demangle_qualified (work, mangled, &decl, - /*isfuncnam=*/0, - /*append=*/0); - if (!success) - break; - } - else - { - success = 0; - break; - } - - string_prepend (&decl, "("); - if (member) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - type_quals |= code_for_qualifier (**mangled); - (*mangled)++; - break; - - default: - break; - } - - if (*(*mangled)++ != 'F') - { - success = 0; - break; - } - } - if ((member && !demangle_nested_args (work, mangled, &decl)) - || **mangled != '_') - { - success = 0; - break; - } - (*mangled)++; - if (! PRINT_ANSI_QUALIFIERS) - { - break; - } - if (type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (&decl); - string_append (&decl, qualifier_string (type_quals)); - } - break; - } - case 'G': - (*mangled)++; - break; - - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (&decl)) - string_prepend (&decl, " "); - - string_prepend (&decl, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - /* - } - */ - - /* fall through */ - default: - done = 1; - break; - } - } - - if (success) switch (**mangled) - { - /* A qualified name, such as "Outer::Inner". */ - case 'Q': - case 'K': - { - success = demangle_qualified (work, mangled, result, 0, 1); - break; - } - - /* A back reference to a previously seen squangled type */ - case 'B': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> numb) - success = 0; - else - string_append (result, work->btypevec[n]); - break; - - case 'X': - case 'Y': - /* A template parm. We substitute the corresponding argument. */ - { - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - { - success = 0; - break; - } - - if (work->tmpl_argvec) - string_append (result, work->tmpl_argvec[idx]); - else - string_append_template_idx (result, idx); - - success = 1; - } - break; - - default: - success = demangle_fund_type (work, mangled, result); - if (tk == tk_none) - tk = (type_kind_t) success; - break; - } - - if (success) - { - if (!STRING_EMPTY (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - } - else - string_delete (result); - string_delete (&decl); - - if (success) - /* Assume an integral type, if we're not sure. */ - return (int) ((tk == tk_none) ? tk_integral : tk); - else - return 0; -} - -/* Given a pointer to a type string that represents a fundamental type - argument (int, long, unsigned int, etc) in TYPE, a pointer to the - string in which the demangled output is being built in RESULT, and - the WORK structure, decode the types and add them to the result. - - For example: - - "Ci" => "const int" - "Sl" => "signed long" - "CUs" => "const unsigned short" - - The value returned is really a type_kind_t. */ - -static int -demangle_fund_type (struct work_stuff *work, - const char **mangled, string *result) -{ - int done = 0; - int success = 1; - char buf[INTBUF_SIZE + 5 /* 'int%u_t' */]; - unsigned int dec = 0; - type_kind_t tk = tk_integral; - - /* First pick off any type qualifiers. There can be more than one. */ - - while (!done) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (result)) - string_prepend (result, " "); - string_prepend (result, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - case 'U': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "unsigned"); - break; - case 'S': /* signed char only */ - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "signed"); - break; - case 'J': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "__complex"); - break; - default: - done = 1; - break; - } - } - - /* Now pick off the fundamental type. There can be only one. */ - - switch (**mangled) - { - case '\0': - case '_': - break; - case 'v': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "void"); - break; - case 'x': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long long"); - break; - case 'l': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long"); - break; - case 'i': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "int"); - break; - case 's': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "short"); - break; - case 'b': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "bool"); - tk = tk_bool; - break; - case 'c': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "char"); - tk = tk_char; - break; - case 'w': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "wchar_t"); - tk = tk_char; - break; - case 'r': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long double"); - tk = tk_real; - break; - case 'd': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "double"); - tk = tk_real; - break; - case 'f': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "float"); - tk = tk_real; - break; - case 'G': - (*mangled)++; - if (!ISDIGIT ((unsigned char)**mangled)) - { - success = 0; - break; - } - case 'I': - (*mangled)++; - if (**mangled == '_') - { - int i; - (*mangled)++; - for (i = 0; - i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_'; - (*mangled)++, i++) - buf[i] = **mangled; - if (**mangled != '_') - { - success = 0; - break; - } - buf[i] = '\0'; - (*mangled)++; - } - else - { - strncpy (buf, *mangled, 2); - buf[2] = '\0'; - *mangled += min (strlen (*mangled), 2); - } - sscanf (buf, "%x", &dec); - sprintf (buf, "int%u_t", dec); - APPEND_BLANK (result); - string_append (result, buf); - break; - - /* fall through */ - /* An explicit type, such as "6mytype" or "7integer" */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - int bindex = register_Btype (work); - string btype; - string_init (&btype); - if (demangle_class_name (work, mangled, &btype)) { - remember_Btype (work, btype.b, LEN_STRING (&btype), bindex); - APPEND_BLANK (result); - string_appends (result, &btype); - } - else - success = 0; - string_delete (&btype); - break; - } - case 't': - { - string btype; - string_init (&btype); - success = demangle_template (work, mangled, &btype, 0, 1, 1); - string_appends (result, &btype); - string_delete (&btype); - break; - } - default: - success = 0; - break; - } - - return success ? ((int) tk) : 0; -} - - -/* Handle a template's value parameter for HP aCC (extension from ARM) - **mangled points to 'S' or 'U' */ - -static int -do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED, - const char **mangled, string *result) -{ - int unsigned_const; - - if (**mangled != 'U' && **mangled != 'S') - return 0; - - unsigned_const = (**mangled == 'U'); - - (*mangled)++; - - switch (**mangled) - { - case 'N': - string_append (result, "-"); - /* fall through */ - case 'P': - (*mangled)++; - break; - case 'M': - /* special case for -2^31 */ - string_append (result, "-2147483648"); - (*mangled)++; - return 1; - default: - return 0; - } - - /* We have to be looking at an integer now */ - if (!(ISDIGIT ((unsigned char)**mangled))) - return 0; - - /* We only deal with integral values for template - parameters -- so it's OK to look only for digits */ - while (ISDIGIT ((unsigned char)**mangled)) - { - char_str[0] = **mangled; - string_append (result, char_str); - (*mangled)++; - } - - if (unsigned_const) - string_append (result, "U"); - - /* FIXME? Some day we may have 64-bit (or larger :-) ) constants - with L or LL suffixes. pai/1997-09-03 */ - - return 1; /* success */ -} - -/* Handle a template's literal parameter for HP aCC (extension from ARM) - **mangled is pointing to the 'A' */ - -static int -do_hpacc_template_literal (struct work_stuff *work, const char **mangled, - string *result) -{ - int literal_len = 0; - char * recurse; - char * recurse_dem; - - if (**mangled != 'A') - return 0; - - (*mangled)++; - - literal_len = consume_count (mangled); - - if (literal_len <= 0) - return 0; - - /* Literal parameters are names of arrays, functions, etc. and the - canonical representation uses the address operator */ - string_append (result, "&"); - - /* Now recursively demangle the literal name */ - recurse = XNEWVEC (char, literal_len + 1); - memcpy (recurse, *mangled, literal_len); - recurse[literal_len] = '\000'; - - recurse_dem = cplus_demangle (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, literal_len); - } - (*mangled) += literal_len; - free (recurse); - - return 1; -} - -static int -snarf_numeric_literal (const char **args, string *arg) -{ - if (**args == '-') - { - char_str[0] = '-'; - string_append (arg, char_str); - (*args)++; - } - else if (**args == '+') - (*args)++; - - if (!ISDIGIT ((unsigned char)**args)) - return 0; - - while (ISDIGIT ((unsigned char)**args)) - { - char_str[0] = **args; - string_append (arg, char_str); - (*args)++; - } - - return 1; -} - -/* Demangle the next argument, given by MANGLED into RESULT, which - *should be an uninitialized* string. It will be initialized here, - and free'd should anything go wrong. */ - -static int -do_arg (struct work_stuff *work, const char **mangled, string *result) -{ - /* Remember where we started so that we can record the type, for - non-squangling type remembering. */ - const char *start = *mangled; - - string_init (result); - - if (work->nrepeats > 0) - { - --work->nrepeats; - - if (work->previous_argument == 0) - return 0; - - /* We want to reissue the previous type in this argument list. */ - string_appends (result, work->previous_argument); - return 1; - } - - if (**mangled == 'n') - { - /* A squangling-style repeat. */ - (*mangled)++; - work->nrepeats = consume_count(mangled); - - if (work->nrepeats <= 0) - /* This was not a repeat count after all. */ - return 0; - - if (work->nrepeats > 9) - { - if (**mangled != '_') - /* The repeat count should be followed by an '_' in this - case. */ - return 0; - else - (*mangled)++; - } - - /* Now, the repeat is all set up. */ - return do_arg (work, mangled, result); - } - - /* Save the result in WORK->previous_argument so that we can find it - if it's repeated. Note that saving START is not good enough: we - do not want to add additional types to the back-referenceable - type vector when processing a repeated type. */ - if (work->previous_argument) - string_delete (work->previous_argument); - else - work->previous_argument = XNEW (string); - - if (!do_type (work, mangled, work->previous_argument)) - return 0; - - string_appends (result, work->previous_argument); - - remember_type (work, start, *mangled - start); - return 1; -} - -static void -remember_type (struct work_stuff *work, const char *start, int len) -{ - char *tem; - - if (work->forgetting_types) - return; - - if (work -> ntypes >= work -> typevec_size) - { - if (work -> typevec_size == 0) - { - work -> typevec_size = 3; - work -> typevec = XNEWVEC (char *, work->typevec_size); - } - else - { - work -> typevec_size *= 2; - work -> typevec - = XRESIZEVEC (char *, work->typevec, work->typevec_size); - } - } - tem = XNEWVEC (char, len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> typevec[work -> ntypes++] = tem; -} - - -/* Remember a K type class qualifier. */ -static void -remember_Ktype (struct work_stuff *work, const char *start, int len) -{ - char *tem; - - if (work -> numk >= work -> ksize) - { - if (work -> ksize == 0) - { - work -> ksize = 5; - work -> ktypevec = XNEWVEC (char *, work->ksize); - } - else - { - work -> ksize *= 2; - work -> ktypevec - = XRESIZEVEC (char *, work->ktypevec, work->ksize); - } - } - tem = XNEWVEC (char, len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> ktypevec[work -> numk++] = tem; -} - -/* Register a B code, and get an index for it. B codes are registered - as they are seen, rather than as they are completed, so map > - registers map > as B0, and temp as B1 */ - -static int -register_Btype (struct work_stuff *work) -{ - int ret; - - if (work -> numb >= work -> bsize) - { - if (work -> bsize == 0) - { - work -> bsize = 5; - work -> btypevec = XNEWVEC (char *, work->bsize); - } - else - { - work -> bsize *= 2; - work -> btypevec - = XRESIZEVEC (char *, work->btypevec, work->bsize); - } - } - ret = work -> numb++; - work -> btypevec[ret] = NULL; - return(ret); -} - -/* Store a value into a previously registered B code type. */ - -static void -remember_Btype (struct work_stuff *work, const char *start, - int len, int index) -{ - char *tem; - - tem = XNEWVEC (char, len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> btypevec[index] = tem; -} - -/* Lose all the info related to B and K type codes. */ -static void -forget_B_and_K_types (struct work_stuff *work) -{ - int i; - - while (work -> numk > 0) - { - i = --(work -> numk); - if (work -> ktypevec[i] != NULL) - { - free (work -> ktypevec[i]); - work -> ktypevec[i] = NULL; - } - } - - while (work -> numb > 0) - { - i = --(work -> numb); - if (work -> btypevec[i] != NULL) - { - free (work -> btypevec[i]); - work -> btypevec[i] = NULL; - } - } -} -/* Forget the remembered types, but not the type vector itself. */ - -static void -forget_types (struct work_stuff *work) -{ - int i; - - while (work -> ntypes > 0) - { - i = --(work -> ntypes); - if (work -> typevec[i] != NULL) - { - free (work -> typevec[i]); - work -> typevec[i] = NULL; - } - } -} - -/* Process the argument list part of the signature, after any class spec - has been consumed, as well as the first 'F' character (if any). For - example: - - "__als__3fooRT0" => process "RT0" - "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" - - DECLP must be already initialised, usually non-empty. It won't be freed - on failure. - - Note that g++ differs significantly from ARM and lucid style mangling - with regards to references to previously seen types. For example, given - the source fragment: - - class foo { - public: - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); - }; - - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - - g++ produces the names: - - __3fooiRT0iT2iT2 - foo__FiR3fooiT1iT1 - - while lcc (and presumably other ARM style compilers as well) produces: - - foo__FiR3fooT1T2T1T2 - __ct__3fooFiR3fooT1T2T1T2 - - Note that g++ bases its type numbers starting at zero and counts all - previously seen types, while lucid/ARM bases its type numbers starting - at one and only considers types after it has seen the 'F' character - indicating the start of the function args. For lucid/ARM style, we - account for this difference by discarding any previously seen types when - we see the 'F' character, and subtracting one from the type number - reference. - - */ - -static int -demangle_args (struct work_stuff *work, const char **mangled, - string *declp) -{ - string arg; - int need_comma = 0; - int r; - int t; - const char *tem; - char temptype; - - if (PRINT_ARG_TYPES) - { - string_append (declp, "("); - if (**mangled == '\0') - { - string_append (declp, "void"); - } - } - - while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e') - || work->nrepeats > 0) - { - if ((**mangled == 'N') || (**mangled == 'T')) - { - temptype = *(*mangled)++; - - if (temptype == 'N') - { - if (!get_count (mangled, &r)) - { - return (0); - } - } - else - { - r = 1; - } - if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10) - { - /* If we have 10 or more types we might have more than a 1 digit - index so we'll have to consume the whole count here. This - will lose if the next thing is a type name preceded by a - count but it's impossible to demangle that case properly - anyway. Eg if we already have 12 types is T12Pc "(..., type1, - Pc, ...)" or "(..., type12, char *, ...)" */ - if ((t = consume_count(mangled)) <= 0) - { - return (0); - } - } - else - { - if (!get_count (mangled, &t)) - { - return (0); - } - } - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - t--; - } - /* Validate the type index. Protect against illegal indices from - malformed type strings. */ - if ((t < 0) || (t >= work -> ntypes)) - { - return (0); - } - while (work->nrepeats > 0 || --r >= 0) - { - tem = work -> typevec[t]; - if (need_comma && PRINT_ARG_TYPES) - { - string_append (declp, ", "); - } - if (!do_arg (work, &tem, &arg)) - { - return (0); - } - if (PRINT_ARG_TYPES) - { - string_appends (declp, &arg); - } - string_delete (&arg); - need_comma = 1; - } - } - else - { - if (need_comma && PRINT_ARG_TYPES) - string_append (declp, ", "); - if (!do_arg (work, mangled, &arg)) - return (0); - if (PRINT_ARG_TYPES) - string_appends (declp, &arg); - string_delete (&arg); - need_comma = 1; - } - } - - if (**mangled == 'e') - { - (*mangled)++; - if (PRINT_ARG_TYPES) - { - if (need_comma) - { - string_append (declp, ","); - } - string_append (declp, "..."); - } - } - - if (PRINT_ARG_TYPES) - { - string_append (declp, ")"); - } - return (1); -} - -/* Like demangle_args, but for demangling the argument lists of function - and method pointers or references, not top-level declarations. */ - -static int -demangle_nested_args (struct work_stuff *work, const char **mangled, - string *declp) -{ - string* saved_previous_argument; - int result; - int saved_nrepeats; - - /* The G++ name-mangling algorithm does not remember types on nested - argument lists, unless -fsquangling is used, and in that case the - type vector updated by remember_type is not used. So, we turn - off remembering of types here. */ - ++work->forgetting_types; - - /* For the repeat codes used with -fsquangling, we must keep track of - the last argument. */ - saved_previous_argument = work->previous_argument; - saved_nrepeats = work->nrepeats; - work->previous_argument = 0; - work->nrepeats = 0; - - /* Actually demangle the arguments. */ - result = demangle_args (work, mangled, declp); - - /* Restore the previous_argument field. */ - if (work->previous_argument) - { - string_delete (work->previous_argument); - free ((char *) work->previous_argument); - } - work->previous_argument = saved_previous_argument; - --work->forgetting_types; - work->nrepeats = saved_nrepeats; - - return result; -} - -/* Returns 1 if a valid function name was found or 0 otherwise. */ - -static int -demangle_function_name (struct work_stuff *work, const char **mangled, - string *declp, const char *scan) -{ - size_t i; - string type; - const char *tem; - - string_appendn (declp, (*mangled), scan - (*mangled)); - string_need (declp, 1); - *(declp -> p) = '\0'; - - /* Consume the function name, including the "__" separating the name - from the signature. We are guaranteed that SCAN points to the - separator. */ - - (*mangled) = scan + 2; - /* We may be looking at an instantiation of a template function: - foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a - following _F marks the start of the function arguments. Handle - the template arguments first. */ - - if (HP_DEMANGLING && (**mangled == 'X')) - { - demangle_arm_hp_template (work, mangled, 0, declp); - /* This leaves MANGLED pointing to the 'F' marking func args */ - } - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - - /* See if we have an ARM style constructor or destructor operator. - If so, then just record it, clear the decl, and return. - We can't build the actual constructor/destructor decl until later, - when we recover the class name from the signature. */ - - if (strcmp (declp -> b, "__ct") == 0) - { - work -> constructor += 1; - string_clear (declp); - return 1; - } - else if (strcmp (declp -> b, "__dt") == 0) - { - work -> destructor += 1; - string_clear (declp); - return 1; - } - } - - if (declp->p - declp->b >= 3 - && declp->b[0] == 'o' - && declp->b[1] == 'p' - && strchr (cplus_markers, declp->b[2]) != NULL) - { - /* see if it's an assignment expression */ - if (declp->p - declp->b >= 10 /* op$assign_ */ - && memcmp (declp->b + 3, "assign_", 7) == 0) - { - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - int len = declp->p - declp->b - 10; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 10, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - string_append (declp, "="); - break; - } - } - } - else - { - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - int len = declp->p - declp->b - 3; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 3, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 - && strchr (cplus_markers, declp->b[4]) != NULL) - { - /* type conversion operator */ - tem = declp->b + 5; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] == 'o' && declp->b[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = declp->b + 4; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && ISLOWER((unsigned char)declp->b[2]) - && ISLOWER((unsigned char)declp->b[3])) - { - if (declp->b[4] == '\0') - { - /* Operator. */ - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, declp->b + 2, 2) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - else - { - if (declp->b[2] == 'a' && declp->b[5] == '\0') - { - /* Assignment. */ - for (i = 0; i < ARRAY_SIZE (optable); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, declp->b + 2, 3) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - } - - /* If a function name was obtained but it's not valid, we were not - successful. */ - if (LEN_STRING (declp) == 1 && declp->b[0] == '.') - return 0; - else - return 1; -} - -/* a mini string-handling package */ - -static void -string_need (string *s, int n) -{ - int tem; - - if (s->b == NULL) - { - if (n < 32) - { - n = 32; - } - s->p = s->b = XNEWVEC (char, n); - s->e = s->b + n; - } - else if (s->e - s->p < n) - { - tem = s->p - s->b; - n += tem; - n *= 2; - s->b = XRESIZEVEC (char, s->b, n); - s->p = s->b + tem; - s->e = s->b + n; - } -} - -static void -string_delete (string *s) -{ - if (s->b != NULL) - { - free (s->b); - s->b = s->e = s->p = NULL; - } -} - -static void -string_init (string *s) -{ - s->b = s->p = s->e = NULL; -} - -static void -string_clear (string *s) -{ - s->p = s->b; -} - -#if 0 - -static int -string_empty (string *s) -{ - return (s->b == s->p); -} - -#endif - -static void -string_append (string *p, const char *s) -{ - int n; - if (s == NULL || *s == '\0') - return; - n = strlen (s); - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; -} - -static void -string_appends (string *p, string *s) -{ - int n; - - if (s->b != s->p) - { - n = s->p - s->b; - string_need (p, n); - memcpy (p->p, s->b, n); - p->p += n; - } -} - -static void -string_appendn (string *p, const char *s, int n) -{ - if (n != 0) - { - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; - } -} - -static void -string_prepend (string *p, const char *s) -{ - if (s != NULL && *s != '\0') - { - string_prependn (p, s, strlen (s)); - } -} - -static void -string_prepends (string *p, string *s) -{ - if (s->b != s->p) - { - string_prependn (p, s->b, s->p - s->b); - } -} - -static void -string_prependn (string *p, const char *s, int n) -{ - char *q; - - if (n != 0) - { - string_need (p, n); - for (q = p->p - 1; q >= p->b; q--) - { - q[n] = q[0]; - } - memcpy (p->b, s, n); - p->p += n; - } -} - -static void -string_append_template_idx (string *s, int idx) -{ - char buf[INTBUF_SIZE + 1 /* 'T' */]; - sprintf(buf, "T%d", idx); - string_append (s, buf); -} diff --git a/linkers/libiberty/demangle.h b/linkers/libiberty/demangle.h deleted file mode 100644 index 4b3565b..0000000 --- a/linkers/libiberty/demangle.h +++ /dev/null @@ -1,616 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, - 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License - as published by the Free Software Foundation; either version 2, or - (at your option) any later version. - - In addition to the permissions in the GNU Library General Public - License, the Free Software Foundation gives you unlimited - permission to link the compiled version of this file into - combinations with other programs, and to distribute those - combinations without any restriction coming from the use of this - file. (The Library Public License restrictions do apply in other - respects; for example, they cover modification of the file, and - distribution when not linked into a combined executable.) - - This program 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#include "libiberty.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ -#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */ -#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */ -#define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when - present) after function signature */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -#define DMGL_HP (1 << 12) /* For the HP aCC compiler; - same as ARM except for - template arguments, etc. */ -#define DMGL_EDG (1 << 13) -#define DMGL_GNU_V3 (1 << 14) -#define DMGL_GNAT (1 << 15) - -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - no_demangling = -1, - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM, - hp_demangling = DMGL_HP, - edg_demangling = DMGL_EDG, - gnu_v3_demangling = DMGL_GNU_V3, - java_demangling = DMGL_JAVA, - gnat_demangling = DMGL_GNAT -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define NO_DEMANGLING_STYLE_STRING "none" -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" -#define HP_DEMANGLING_STYLE_STRING "hp" -#define EDG_DEMANGLING_STYLE_STRING "edg" -#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3" -#define JAVA_DEMANGLING_STYLE_STRING "java" -#define GNAT_DEMANGLING_STYLE_STRING "gnat" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM) -#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP) -#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG) -#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3) -#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA) -#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) - -/* Provide information about the available demangle styles. This code is - pulled from gdb into libiberty because it is useful to binutils also. */ - -extern const struct demangler_engine -{ - const char *const demangling_style_name; - const enum demangling_styles demangling_style; - const char *const demangling_style_doc; -} libiberty_demanglers[]; - -extern char * -cplus_demangle (const char *mangled, int options); - -extern int -cplus_demangle_opname (const char *opname, char *result, int options); - -extern const char * -cplus_mangle_opname (const char *opname, int options); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling (int ch); - -extern enum demangling_styles -cplus_demangle_set_style (enum demangling_styles style); - -extern enum demangling_styles -cplus_demangle_name_to_style (const char *name); - -/* Callback typedef for allocation-less demangler interfaces. */ -typedef void (*demangle_callbackref) (const char *, size_t, void *); - -/* V3 ABI demangling entry points, defined in cp-demangle.c. Callback - variants return non-zero on success, zero on error. char* variants - return a string allocated by malloc on success, NULL on error. */ -extern int -cplus_demangle_v3_callback (const char *mangled, int options, - demangle_callbackref callback, void *opaque); - -extern char* -cplus_demangle_v3 (const char *mangled, int options); - -extern int -java_demangle_v3_callback (const char *mangled, - demangle_callbackref callback, void *opaque); - -extern char* -java_demangle_v3 (const char *mangled); - -enum gnu_v3_ctor_kinds { - gnu_v3_complete_object_ctor = 1, - gnu_v3_base_object_ctor, - gnu_v3_complete_object_allocating_ctor -}; - -/* Return non-zero iff NAME is the mangled form of a constructor name - in the G++ V3 ABI demangling style. Specifically, return an `enum - gnu_v3_ctor_kinds' value indicating what kind of constructor - it is. */ -extern enum gnu_v3_ctor_kinds - is_gnu_v3_mangled_ctor (const char *name); - - -enum gnu_v3_dtor_kinds { - gnu_v3_deleting_dtor = 1, - gnu_v3_complete_object_dtor, - gnu_v3_base_object_dtor -}; - -/* Return non-zero iff NAME is the mangled form of a destructor name - in the G++ V3 ABI demangling style. Specifically, return an `enum - gnu_v3_dtor_kinds' value, indicating what kind of destructor - it is. */ -extern enum gnu_v3_dtor_kinds - is_gnu_v3_mangled_dtor (const char *name); - -/* The V3 demangler works in two passes. The first pass builds a tree - representation of the mangled name, and the second pass turns the - tree representation into a demangled string. Here we define an - interface to permit a caller to build their own tree - representation, which they can pass to the demangler to get a - demangled string. This can be used to canonicalize user input into - something which the demangler might output. It could also be used - by other demanglers in the future. */ - -/* These are the component types which may be found in the tree. Many - component types have one or two subtrees, referred to as left and - right (a component type with only one subtree puts it in the left - subtree). */ - -enum demangle_component_type -{ - /* A name, with a length and a pointer to a string. */ - DEMANGLE_COMPONENT_NAME, - /* A qualified name. The left subtree is a class or namespace or - some such thing, and the right subtree is a name qualified by - that class. */ - DEMANGLE_COMPONENT_QUAL_NAME, - /* A local name. The left subtree describes a function, and the - right subtree is a name which is local to that function. */ - DEMANGLE_COMPONENT_LOCAL_NAME, - /* A typed name. The left subtree is a name, and the right subtree - describes that name as a function. */ - DEMANGLE_COMPONENT_TYPED_NAME, - /* A template. The left subtree is a template name, and the right - subtree is a template argument list. */ - DEMANGLE_COMPONENT_TEMPLATE, - /* A template parameter. This holds a number, which is the template - parameter index. */ - DEMANGLE_COMPONENT_TEMPLATE_PARAM, - /* A function parameter. This holds a number, which is the index. */ - DEMANGLE_COMPONENT_FUNCTION_PARAM, - /* A constructor. This holds a name and the kind of - constructor. */ - DEMANGLE_COMPONENT_CTOR, - /* A destructor. This holds a name and the kind of destructor. */ - DEMANGLE_COMPONENT_DTOR, - /* A vtable. This has one subtree, the type for which this is a - vtable. */ - DEMANGLE_COMPONENT_VTABLE, - /* A VTT structure. This has one subtree, the type for which this - is a VTT. */ - DEMANGLE_COMPONENT_VTT, - /* A construction vtable. The left subtree is the type for which - this is a vtable, and the right subtree is the derived type for - which this vtable is built. */ - DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, - /* A typeinfo structure. This has one subtree, the type for which - this is the tpeinfo structure. */ - DEMANGLE_COMPONENT_TYPEINFO, - /* A typeinfo name. This has one subtree, the type for which this - is the typeinfo name. */ - DEMANGLE_COMPONENT_TYPEINFO_NAME, - /* A typeinfo function. This has one subtree, the type for which - this is the tpyeinfo function. */ - DEMANGLE_COMPONENT_TYPEINFO_FN, - /* A thunk. This has one subtree, the name for which this is a - thunk. */ - DEMANGLE_COMPONENT_THUNK, - /* A virtual thunk. This has one subtree, the name for which this - is a virtual thunk. */ - DEMANGLE_COMPONENT_VIRTUAL_THUNK, - /* A covariant thunk. This has one subtree, the name for which this - is a covariant thunk. */ - DEMANGLE_COMPONENT_COVARIANT_THUNK, - /* A Java class. This has one subtree, the type. */ - DEMANGLE_COMPONENT_JAVA_CLASS, - /* A guard variable. This has one subtree, the name for which this - is a guard variable. */ - DEMANGLE_COMPONENT_GUARD, - /* A reference temporary. This has one subtree, the name for which - this is a temporary. */ - DEMANGLE_COMPONENT_REFTEMP, - /* A hidden alias. This has one subtree, the encoding for which it - is providing alternative linkage. */ - DEMANGLE_COMPONENT_HIDDEN_ALIAS, - /* A standard substitution. This holds the name of the - substitution. */ - DEMANGLE_COMPONENT_SUB_STD, - /* The restrict qualifier. The one subtree is the type which is - being qualified. */ - DEMANGLE_COMPONENT_RESTRICT, - /* The volatile qualifier. The one subtree is the type which is - being qualified. */ - DEMANGLE_COMPONENT_VOLATILE, - /* The const qualifier. The one subtree is the type which is being - qualified. */ - DEMANGLE_COMPONENT_CONST, - /* The restrict qualifier modifying a member function. The one - subtree is the type which is being qualified. */ - DEMANGLE_COMPONENT_RESTRICT_THIS, - /* The volatile qualifier modifying a member function. The one - subtree is the type which is being qualified. */ - DEMANGLE_COMPONENT_VOLATILE_THIS, - /* The const qualifier modifying a member function. The one subtree - is the type which is being qualified. */ - DEMANGLE_COMPONENT_CONST_THIS, - /* A vendor qualifier. The left subtree is the type which is being - qualified, and the right subtree is the name of the - qualifier. */ - DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, - /* A pointer. The one subtree is the type which is being pointed - to. */ - DEMANGLE_COMPONENT_POINTER, - /* A reference. The one subtree is the type which is being - referenced. */ - DEMANGLE_COMPONENT_REFERENCE, - /* C++0x: An rvalue reference. The one subtree is the type which is - being referenced. */ - DEMANGLE_COMPONENT_RVALUE_REFERENCE, - /* A complex type. The one subtree is the base type. */ - DEMANGLE_COMPONENT_COMPLEX, - /* An imaginary type. The one subtree is the base type. */ - DEMANGLE_COMPONENT_IMAGINARY, - /* A builtin type. This holds the builtin type information. */ - DEMANGLE_COMPONENT_BUILTIN_TYPE, - /* A vendor's builtin type. This holds the name of the type. */ - DEMANGLE_COMPONENT_VENDOR_TYPE, - /* A function type. The left subtree is the return type. The right - subtree is a list of ARGLIST nodes. Either or both may be - NULL. */ - DEMANGLE_COMPONENT_FUNCTION_TYPE, - /* An array type. The left subtree is the dimension, which may be - NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an - expression. The right subtree is the element type. */ - DEMANGLE_COMPONENT_ARRAY_TYPE, - /* A pointer to member type. The left subtree is the class type, - and the right subtree is the member type. CV-qualifiers appear - on the latter. */ - DEMANGLE_COMPONENT_PTRMEM_TYPE, - /* A fixed-point type. */ - DEMANGLE_COMPONENT_FIXED_TYPE, - /* An argument list. The left subtree is the current argument, and - the right subtree is either NULL or another ARGLIST node. */ - DEMANGLE_COMPONENT_ARGLIST, - /* A template argument list. The left subtree is the current - template argument, and the right subtree is either NULL or - another TEMPLATE_ARGLIST node. */ - DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, - /* An operator. This holds information about a standard - operator. */ - DEMANGLE_COMPONENT_OPERATOR, - /* An extended operator. This holds the number of arguments, and - the name of the extended operator. */ - DEMANGLE_COMPONENT_EXTENDED_OPERATOR, - /* A typecast, represented as a unary operator. The one subtree is - the type to which the argument should be cast. */ - DEMANGLE_COMPONENT_CAST, - /* A unary expression. The left subtree is the operator, and the - right subtree is the single argument. */ - DEMANGLE_COMPONENT_UNARY, - /* A binary expression. The left subtree is the operator, and the - right subtree is a BINARY_ARGS. */ - DEMANGLE_COMPONENT_BINARY, - /* Arguments to a binary expression. The left subtree is the first - argument, and the right subtree is the second argument. */ - DEMANGLE_COMPONENT_BINARY_ARGS, - /* A trinary expression. The left subtree is the operator, and the - right subtree is a TRINARY_ARG1. */ - DEMANGLE_COMPONENT_TRINARY, - /* Arguments to a trinary expression. The left subtree is the first - argument, and the right subtree is a TRINARY_ARG2. */ - DEMANGLE_COMPONENT_TRINARY_ARG1, - /* More arguments to a trinary expression. The left subtree is the - second argument, and the right subtree is the third argument. */ - DEMANGLE_COMPONENT_TRINARY_ARG2, - /* A literal. The left subtree is the type, and the right subtree - is the value, represented as a DEMANGLE_COMPONENT_NAME. */ - DEMANGLE_COMPONENT_LITERAL, - /* A negative literal. Like LITERAL, but the value is negated. - This is a minor hack: the NAME used for LITERAL points directly - to the mangled string, but since negative numbers are mangled - using 'n' instead of '-', we want a way to indicate a negative - number which involves neither modifying the mangled string nor - allocating a new copy of the literal in memory. */ - DEMANGLE_COMPONENT_LITERAL_NEG, - /* A libgcj compiled resource. The left subtree is the name of the - resource. */ - DEMANGLE_COMPONENT_JAVA_RESOURCE, - /* A name formed by the concatenation of two parts. The left - subtree is the first part and the right subtree the second. */ - DEMANGLE_COMPONENT_COMPOUND_NAME, - /* A name formed by a single character. */ - DEMANGLE_COMPONENT_CHARACTER, - /* A decltype type. */ - DEMANGLE_COMPONENT_DECLTYPE, - /* Global constructors keyed to name. */ - DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS, - /* Global destructors keyed to name. */ - DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS, - /* A pack expansion. */ - DEMANGLE_COMPONENT_PACK_EXPANSION -}; - -/* Types which are only used internally. */ - -struct demangle_operator_info; -struct demangle_builtin_type_info; - -/* A node in the tree representation is an instance of a struct - demangle_component. Note that the field names of the struct are - not well protected against macros defined by the file including - this one. We can fix this if it ever becomes a problem. */ - -struct demangle_component -{ - /* The type of this component. */ - enum demangle_component_type type; - - union - { - /* For DEMANGLE_COMPONENT_NAME. */ - struct - { - /* A pointer to the name (which need not NULL terminated) and - its length. */ - const char *s; - int len; - } s_name; - - /* For DEMANGLE_COMPONENT_OPERATOR. */ - struct - { - /* Operator. */ - const struct demangle_operator_info *op; - } s_operator; - - /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */ - struct - { - /* Number of arguments. */ - int args; - /* Name. */ - struct demangle_component *name; - } s_extended_operator; - - /* For DEMANGLE_COMPONENT_FIXED_TYPE. */ - struct - { - /* The length, indicated by a C integer type name. */ - struct demangle_component *length; - /* _Accum or _Fract? */ - short accum; - /* Saturating or not? */ - short sat; - } s_fixed; - - /* For DEMANGLE_COMPONENT_CTOR. */ - struct - { - /* Kind of constructor. */ - enum gnu_v3_ctor_kinds kind; - /* Name. */ - struct demangle_component *name; - } s_ctor; - - /* For DEMANGLE_COMPONENT_DTOR. */ - struct - { - /* Kind of destructor. */ - enum gnu_v3_dtor_kinds kind; - /* Name. */ - struct demangle_component *name; - } s_dtor; - - /* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */ - struct - { - /* Builtin type. */ - const struct demangle_builtin_type_info *type; - } s_builtin; - - /* For DEMANGLE_COMPONENT_SUB_STD. */ - struct - { - /* Standard substitution string. */ - const char* string; - /* Length of string. */ - int len; - } s_string; - - /* For DEMANGLE_COMPONENT_*_PARAM. */ - struct - { - /* Parameter index. */ - long number; - } s_number; - - /* For DEMANGLE_COMPONENT_CHARACTER. */ - struct - { - int character; - } s_character; - - /* For other types. */ - struct - { - /* Left (or only) subtree. */ - struct demangle_component *left; - /* Right subtree. */ - struct demangle_component *right; - } s_binary; - - } u; -}; - -/* People building mangled trees are expected to allocate instances of - struct demangle_component themselves. They can then call one of - the following functions to fill them in. */ - -/* Fill in most component types with a left subtree and a right - subtree. Returns non-zero on success, zero on failure, such as an - unrecognized or inappropriate component type. */ - -extern int -cplus_demangle_fill_component (struct demangle_component *fill, - enum demangle_component_type, - struct demangle_component *left, - struct demangle_component *right); - -/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success, - zero for bad arguments. */ - -extern int -cplus_demangle_fill_name (struct demangle_component *fill, - const char *, int); - -/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the - builtin type (e.g., "int", etc.). Returns non-zero on success, - zero if the type is not recognized. */ - -extern int -cplus_demangle_fill_builtin_type (struct demangle_component *fill, - const char *type_name); - -/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the - operator and the number of arguments which it takes (the latter is - used to disambiguate operators which can be both binary and unary, - such as '-'). Returns non-zero on success, zero if the operator is - not recognized. */ - -extern int -cplus_demangle_fill_operator (struct demangle_component *fill, - const char *opname, int args); - -/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the - number of arguments and the name. Returns non-zero on success, - zero for bad arguments. */ - -extern int -cplus_demangle_fill_extended_operator (struct demangle_component *fill, - int numargs, - struct demangle_component *nm); - -/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success, - zero for bad arguments. */ - -extern int -cplus_demangle_fill_ctor (struct demangle_component *fill, - enum gnu_v3_ctor_kinds kind, - struct demangle_component *name); - -/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success, - zero for bad arguments. */ - -extern int -cplus_demangle_fill_dtor (struct demangle_component *fill, - enum gnu_v3_dtor_kinds kind, - struct demangle_component *name); - -/* This function translates a mangled name into a struct - demangle_component tree. The first argument is the mangled name. - The second argument is DMGL_* options. This returns a pointer to a - tree on success, or NULL on failure. On success, the third - argument is set to a block of memory allocated by malloc. This - block should be passed to free when the tree is no longer - needed. */ - -extern struct demangle_component * -cplus_demangle_v3_components (const char *mangled, int options, void **mem); - -/* This function takes a struct demangle_component tree and returns - the corresponding demangled string. The first argument is DMGL_* - options. The second is the tree to demangle. The third is a guess - at the length of the demangled string, used to initially allocate - the return buffer. The fourth is a pointer to a size_t. On - success, this function returns a buffer allocated by malloc(), and - sets the size_t pointed to by the fourth argument to the size of - the allocated buffer (not the length of the returned string). On - failure, this function returns NULL, and sets the size_t pointed to - by the fourth argument to 0 for an invalid tree, or to 1 for a - memory allocation error. */ - -extern char * -cplus_demangle_print (int options, - const struct demangle_component *tree, - int estimated_length, - size_t *p_allocated_size); - -/* This function takes a struct demangle_component tree and passes back - a demangled string in one or more calls to a callback function. - The first argument is DMGL_* options. The second is the tree to - demangle. The third is a pointer to a callback function; on each call - this receives an element of the demangled string, its length, and an - opaque value. The fourth is the opaque value passed to the callback. - The callback is called once or more to return the full demangled - string. The demangled element string is always nul-terminated, though - its length is also provided for convenience. In contrast to - cplus_demangle_print(), this function does not allocate heap memory - to grow output strings (except perhaps where alloca() is implemented - by malloc()), and so is normally safe for use where the heap has been - corrupted. On success, this function returns 1; on failure, 0. */ - -extern int -cplus_demangle_print_callback (int options, - const struct demangle_component *tree, - demangle_callbackref callback, void *opaque); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* DEMANGLE_H */ diff --git a/linkers/libiberty/libiberty.h b/linkers/libiberty/libiberty.h deleted file mode 100644 index d2dfb1b..0000000 --- a/linkers/libiberty/libiberty.h +++ /dev/null @@ -1,342 +0,0 @@ -/* Function declarations for libiberty. - - Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - - Note - certain prototypes declared in this header file are for - functions whoes implementation copyright does not belong to the - FSF. Those prototypes are present in this file for reference - purposes only and their presence in this file should not construed - as an indication of ownership by the FSF of the implementation of - those functions in any way or form whatsoever. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. - - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. - - Hacked up libiberty.h file from the real one. -*/ - -#if !defined (_LIBIERTY_H_) -#define _LIBIERTY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) - -#define xstrdup strdup -#define xstrerror strerror - -/* These macros provide a K&R/C89/C++-friendly way of allocating structures - with nice encapsulation. The XDELETE*() macros are technically - superfluous, but provided here for symmetry. Using them consistently - makes it easier to update client code to use different allocators such - as new/delete and new[]/delete[]. */ - -/* Scalar allocators. */ - -#define XALLOCA(T) ((T *) alloca (sizeof (T))) -#define XNEW(T) ((T *) malloc (sizeof (T))) -#define XCNEW(T) ((T *) calloc (1, sizeof (T))) -#define XDUP(T, P) ((T *) memdup ((P), sizeof (T), sizeof (T))) -#define XDELETE(P) free ((void*) (P)) - -/* Array allocators. */ - -#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N))) -#define XNEWVEC(T, N) ((T *) malloc (sizeof (T) * (N))) -#define XCNEWVEC(T, N) ((T *) calloc ((N), sizeof (T))) -#define XDUPVEC(T, P, N) ((T *) memdup ((P), sizeof (T) * (N), sizeof (T) * (N))) -#define XRESIZEVEC(T, P, N) ((T *) realloc ((void *) (P), sizeof (T) * (N))) -#define XDELETEVEC(P) free ((void*) (P)) - -/* Allocators for variable-sized structures and raw buffers. */ - -#define XALLOCAVAR(T, S) ((T *) alloca ((S))) -#define XNEWVAR(T, S) ((T *) malloc ((S))) -#define XCNEWVAR(T, S) ((T *) calloc (1, (S))) -#define XDUPVAR(T, P, S1, S2) ((T *) memdup ((P), (S1), (S2))) -#define XRESIZEVAR(T, P, S) ((T *) realloc ((P), (S))) - -/* Concatenate an arbitrary number of strings. You must pass NULL as - the last argument of this function, to terminate the list of - strings. Allocates memory using xmalloc. */ - -extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL; - -/* Concatenate an arbitrary number of strings. You must pass NULL as - the last argument of this function, to terminate the list of - strings. Allocates memory using xmalloc. The first argument is - not one of the strings to be concatenated, but if not NULL is a - pointer to be freed after the new string is created, similar to the - way xrealloc works. */ - -extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL; - -/* Determine the length of concatenating an arbitrary number of - strings. You must pass NULL as the last argument of this function, - to terminate the list of strings. */ - -extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL; - -/* Concatenate an arbitrary number of strings into a SUPPLIED area of - memory. You must pass NULL as the last argument of this function, - to terminate the list of strings. The supplied memory is assumed - to be large enough. */ - -extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_SENTINEL; - -/* Concatenate an arbitrary number of strings into a GLOBAL area of - memory. You must pass NULL as the last argument of this function, - to terminate the list of strings. The supplied memory is assumed - to be large enough. */ - -extern char *concat_copy2 (const char *, ...) ATTRIBUTE_SENTINEL; - -/* This is the global area used by concat_copy2. */ - -extern char *libiberty_concat_ptr; - -/* Return a temporary file name or NULL if unable to create one. */ - -extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC; - -/* Flags for pex_init. These are bits to be or'ed together. */ - -/* Record subprocess times, if possible. */ -#define PEX_RECORD_TIMES 0x1 - -/* Use pipes for communication between processes, if possible. */ -#define PEX_USE_PIPES 0x2 - -/* Save files used for communication between processes. */ -#define PEX_SAVE_TEMPS 0x4 - -/* Prepare to execute one or more programs, with standard output of - each program fed to standard input of the next. - FLAGS As above. - PNAME The name of the program to report in error messages. - TEMPBASE A base name to use for temporary files; may be NULL to - use a random name. - Returns NULL on error. */ - -extern struct pex_obj *pex_init (int flags, const char *pname, - const char *tempbase); - -/* Flags for pex_run. These are bits to be or'ed together. */ - -/* Last program in pipeline. Standard output of program goes to - OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do - not set this if you want to call pex_read_output. After this is - set, pex_run may no longer be called with the same struct - pex_obj. */ -#define PEX_LAST 0x1 - -/* Search for program in executable search path. */ -#define PEX_SEARCH 0x2 - -/* OUTNAME is a suffix. */ -#define PEX_SUFFIX 0x4 - -/* Send program's standard error to standard output. */ -#define PEX_STDERR_TO_STDOUT 0x8 - -/* Input file should be opened in binary mode. This flag is ignored - on Unix. */ -#define PEX_BINARY_INPUT 0x10 - -/* Output file should be opened in binary mode. This flag is ignored - on Unix. For proper behaviour PEX_BINARY_INPUT and - PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using - PEX_BINARY_OUTPUT should be followed by a call using - PEX_BINARY_INPUT. */ -#define PEX_BINARY_OUTPUT 0x20 - -/* Capture stderr to a pipe. The output can be read by - calling pex_read_err and reading from the returned - FILE object. This flag may be specified only for - the last program in a pipeline. - - This flag is supported only on Unix and Windows. */ -#define PEX_STDERR_TO_PIPE 0x40 - -/* Capture stderr in binary mode. This flag is ignored - on Unix. */ -#define PEX_BINARY_ERROR 0x80 - - -/* Execute one program. Returns NULL on success. On error returns an - error string (typically just the name of a system call); the error - string is statically allocated. - - OBJ Returned by pex_init. - - FLAGS As above. - - EXECUTABLE The program to execute. - - ARGV NULL terminated array of arguments to pass to the program. - - OUTNAME Sets the output file name as follows: - - PEX_SUFFIX set (OUTNAME may not be NULL): - TEMPBASE parameter to pex_init not NULL: - Output file name is the concatenation of TEMPBASE - and OUTNAME. - TEMPBASE is NULL: - Output file name is a random file name ending in - OUTNAME. - PEX_SUFFIX not set: - OUTNAME not NULL: - Output file name is OUTNAME. - OUTNAME NULL, TEMPBASE not NULL: - Output file name is randomly chosen using - TEMPBASE. - OUTNAME NULL, TEMPBASE NULL: - Output file name is randomly chosen. - - If PEX_LAST is not set, the output file name is the - name to use for a temporary file holding stdout, if - any (there will not be a file if PEX_USE_PIPES is set - and the system supports pipes). If a file is used, it - will be removed when no longer needed unless - PEX_SAVE_TEMPS is set. - - If PEX_LAST is set, and OUTNAME is not NULL, standard - output is written to the output file name. The file - will not be removed. If PEX_LAST and PEX_SUFFIX are - both set, TEMPBASE may not be NULL. - - ERRNAME If not NULL, this is the name of a file to which - standard error is written. If NULL, standard error of - the program is standard error of the caller. - - ERR On an error return, *ERR is set to an errno value, or - to 0 if there is no relevant errno. -*/ - -extern const char *pex_run (struct pex_obj *obj, int flags, - const char *executable, char * const *argv, - const char *outname, const char *errname, - int *err); - -/* As for pex_run (), but takes an extra parameter to enable the - environment for the child process to be specified. - - ENV The environment for the child process, specified as - an array of character pointers. Each element of the - array should point to a string of the form VAR=VALUE, - with the exception of the last element which must be - a null pointer. -*/ - -extern const char *pex_run_in_environment (struct pex_obj *obj, int flags, - const char *executable, - char * const *argv, - char * const *env, - const char *outname, - const char *errname, int *err); - -/* Return a stream for a temporary file to pass to the first program - in the pipeline as input. The file name is chosen as for pex_run. - pex_run closes the file automatically; don't close it yourself. */ - -extern FILE *pex_input_file (struct pex_obj *obj, int flags, - const char *in_name); - -/* Return a stream for a pipe connected to the standard input of the - first program in the pipeline. You must have passed - `PEX_USE_PIPES' to `pex_init'. Close the returned stream - yourself. */ - -extern FILE *pex_input_pipe (struct pex_obj *obj, int binary); - -/* Read the standard output of the last program to be executed. - pex_run can not be called after this. BINARY should be non-zero if - the file should be opened in binary mode; this is ignored on Unix. - Returns NULL on error. Don't call fclose on the returned FILE; it - will be closed by pex_free. */ - -extern FILE *pex_read_output (struct pex_obj *, int binary); - -/* Read the standard error of the last program to be executed. - pex_run can not be called after this. BINARY should be non-zero if - the file should be opened in binary mode; this is ignored on Unix. - Returns NULL on error. Don't call fclose on the returned FILE; it - will be closed by pex_free. */ - -extern FILE *pex_read_err (struct pex_obj *, int binary); - -/* Return exit status of all programs in VECTOR. COUNT indicates the - size of VECTOR. The status codes in the vector are in the order of - the calls to pex_run. Returns 0 on error, 1 on success. */ - -extern int pex_get_status (struct pex_obj *, int count, int *vector); - -/* Return times of all programs in VECTOR. COUNT indicates the size - of VECTOR. struct pex_time is really just struct timeval, but that - is not portable to all systems. Returns 0 on error, 1 on - success. */ - -struct pex_time -{ - unsigned long user_seconds; - unsigned long user_microseconds; - unsigned long system_seconds; - unsigned long system_microseconds; -}; - -extern int pex_get_times (struct pex_obj *, int count, - struct pex_time *vector); - -/* Clean up a pex_obj. If you have not called pex_get_times or - pex_get_status, this will try to kill the subprocesses. */ - -extern void pex_free (struct pex_obj *); - -/* Just execute one program. Return value is as for pex_run. - FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT. - EXECUTABLE As for pex_run. - ARGV As for pex_run. - PNAME As for pex_init. - OUTNAME As for pex_run when PEX_LAST is set. - ERRNAME As for pex_run. - STATUS Set to exit status on success. - ERR As for pex_run. -*/ - -extern const char *pex_one (int flags, const char *executable, - char * const *argv, const char *pname, - const char *outname, const char *errname, - int *status, int *err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/linkers/libiberty/make-temp-file.c b/linkers/libiberty/make-temp-file.c deleted file mode 100644 index dc2fc1d..0000000 --- a/linkers/libiberty/make-temp-file.c +++ /dev/null @@ -1,217 +0,0 @@ -/* Utility to pick a temporary filename prefix. - Copyright (C) 1996, 1997, 1998, 2001, 2009, 2010 - Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* May get P_tmpdir. */ -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_SYS_FILE_H -#include /* May get R_OK, etc. on some systems. */ -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#endif - -#ifndef R_OK -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#endif - -#include "libiberty.h" -extern int mkstemps (char *, int); - -/* '/' works just fine on MS-DOS based systems. */ -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -/* Name of temporary file. - mktemp requires 6 trailing X's. */ -#define TEMP_FILE "rld--XXXXXX" -#define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1) - -#if !defined(_WIN32) || defined(__CYGWIN__) - -/* Subroutine of choose_tmpdir. - If BASE is non-NULL, return it. - Otherwise it checks if DIR is a usable directory. - If success, DIR is returned. - Otherwise NULL is returned. */ - -static inline const char *try_dir (const char *, const char *); - -static inline const char * -try_dir (const char *dir, const char *base) -{ - if (base != 0) - return base; - if (dir != 0 - && access (dir, R_OK | W_OK | X_OK) == 0) - return dir; - return 0; -} - -static const char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 }; -static const char usrtmp[] = -{ DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 }; -static const char vartmp[] = -{ DIR_SEPARATOR, 'v', 'a', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 }; - -#endif - -static char *memoized_tmpdir; - -/* - -@deftypefn Replacement char* choose_tmpdir () - -Returns a pointer to a directory path suitable for creating temporary -files in. - -@end deftypefn - -*/ - -char * -choose_tmpdir (void) -{ - if (!memoized_tmpdir) - { -#if !defined(_WIN32) || defined(__CYGWIN__) - const char *base = 0; - char *tmpdir; - unsigned int len; - -#ifdef VMS - /* Try VMS standard temp logical. */ - base = try_dir ("/sys$scratch", base); -#else - base = try_dir (getenv ("TMPDIR"), base); - base = try_dir (getenv ("TMP"), base); - base = try_dir (getenv ("TEMP"), base); -#endif - -#ifdef P_tmpdir - /* We really want a directory name here as if concatenated with say \dir - we do not end up with a double \\ which defines an UNC path. */ - if (strcmp (P_tmpdir, "\\") == 0) - base = try_dir ("\\.", base); - else - base = try_dir (P_tmpdir, base); -#endif - - /* Try /var/tmp, /usr/tmp, then /tmp. */ - base = try_dir (vartmp, base); - base = try_dir (usrtmp, base); - base = try_dir (tmp, base); - - /* If all else fails, use the current directory! */ - if (base == 0) - base = "."; - /* Append DIR_SEPARATOR to the directory we've chosen - and return it. */ - len = strlen (base); - tmpdir = XNEWVEC (char, len + 2); - strcpy (tmpdir, base); - tmpdir[len] = DIR_SEPARATOR; - tmpdir[len+1] = '\0'; - memoized_tmpdir = tmpdir; -#else /* defined(_WIN32) && !defined(__CYGWIN__) */ - DWORD len; - - /* Figure out how much space we need. */ - len = GetTempPath(0, NULL); - if (len) - { - memoized_tmpdir = XNEWVEC (char, len); - if (!GetTempPath(len, memoized_tmpdir)) - { - XDELETEVEC (memoized_tmpdir); - memoized_tmpdir = NULL; - } - } - if (!memoized_tmpdir) - /* If all else fails, use the current directory. */ - memoized_tmpdir = xstrdup (".\\"); -#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ - } - - return memoized_tmpdir; -} - -/* - -@deftypefn Replacement char* make_temp_file (const char *@var{suffix}) - -Return a temporary file name (as a string) or @code{NULL} if unable to -create one. @var{suffix} is a suffix to append to the file name. The -string is @code{malloc}ed, and the temporary file has been created. - -@end deftypefn - -*/ - -char * -make_temp_file (const char *suffix) -{ - const char *base = choose_tmpdir (); - char *temp_filename; - int base_len, suffix_len; - int fd; - - if (suffix == 0) - suffix = ""; - - base_len = strlen (base); - suffix_len = strlen (suffix); - - temp_filename = XNEWVEC (char, base_len - + TEMP_FILE_LEN - + suffix_len + 1); - strcpy (temp_filename, base); - strcpy (temp_filename + base_len, TEMP_FILE); - strcpy (temp_filename + base_len + TEMP_FILE_LEN, suffix); - - fd = mkstemps (temp_filename, suffix_len); - /* Mkstemps failed. It may be EPERM, ENOSPC etc. */ - if (fd == -1) - { - fprintf (stderr, "Cannot create temporary file in %s: %s\n", - base, strerror (errno)); - abort (); - } - /* We abort on failed close out of sheer paranoia. */ - if (close (fd)) - abort (); - return temp_filename; -} diff --git a/linkers/libiberty/mkstemps.c b/linkers/libiberty/mkstemps.c deleted file mode 100644 index a0e68a7..0000000 --- a/linkers/libiberty/mkstemps.c +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (C) 1991, 1992, 1996, 1998, 2004 Free Software Foundation, Inc. - This file is derived from mkstemp.c from 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include "ansidecl.h" - -/* We need to provide a type for gcc_uint64_t. */ -#ifdef __GNUC__ -__extension__ typedef unsigned long long gcc_uint64_t; -#else -typedef unsigned long gcc_uint64_t; -#endif - -#ifndef TMP_MAX -#define TMP_MAX 16384 -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -/* - -@deftypefn Replacement int mkstemps (char *@var{pattern}, int @var{suffix_len}) - -Generate a unique temporary file name from @var{pattern}. -@var{pattern} has the form: - -@example - @var{path}/ccXXXXXX@var{suffix} -@end example - -@var{suffix_len} tells us how long @var{suffix} is (it can be zero -length). The last six characters of @var{pattern} before @var{suffix} -must be @samp{XXXXXX}; they are replaced with a string that makes the -filename unique. Returns a file descriptor open on the file for -reading and writing. - -@end deftypefn - -*/ - -int -mkstemps (char *pattern, int suffix_len) -{ - static const char letters[] - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static gcc_uint64_t value; -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; -#endif - char *XXXXXX; - size_t len; - int count; - - len = strlen (pattern); - - if ((int) len < 6 + suffix_len - || strncmp (&pattern[len - 6 - suffix_len], "XXXXXX", 6)) - { - return -1; - } - - XXXXXX = &pattern[len - 6 - suffix_len]; - -#ifdef HAVE_GETTIMEOFDAY - /* Get some more or less random data. */ - gettimeofday (&tv, NULL); - value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); -#else - value += getpid (); -#endif - - for (count = 0; count < TMP_MAX; ++count) - { - gcc_uint64_t v = value; - int fd; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; - - fd = open (pattern, O_BINARY|O_RDWR|O_CREAT|O_EXCL, 0600); - if (fd >= 0) - /* The file does not exist. */ - return fd; - if (errno != EEXIST -#ifdef EISDIR - && errno != EISDIR -#endif - ) - /* Fatal error (EPERM, ENOSPC etc). Doesn't make sense to loop. */ - break; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* We return the null string if we can't find a unique file name. */ - pattern[0] = '\0'; - return -1; -} diff --git a/linkers/libiberty/pex-common.c b/linkers/libiberty/pex-common.c deleted file mode 100644 index 6fd3fde..0000000 --- a/linkers/libiberty/pex-common.c +++ /dev/null @@ -1,646 +0,0 @@ -/* Common code for executing a program in a sub-process. - Copyright (C) 2005, 2010 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "config.h" -#include "libiberty.h" -#include "pex-common.h" - -#include -#include -#ifdef NEED_DECLARATION_ERRNO -extern int errno; -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -extern int mkstemps (char *, int); - -/* This file contains subroutines for the program execution routines - (pex_init, pex_run, etc.). This file is compiled on all - systems. */ - -static void pex_add_remove (struct pex_obj *, const char *, int); -static int pex_get_status_and_time (struct pex_obj *, int, const char **, - int *); - -/* Initialize a pex_obj structure. */ - -struct pex_obj * -pex_init_common (int flags, const char *pname, const char *tempbase, - const struct pex_funcs *funcs) -{ - struct pex_obj *obj; - - obj = XNEW (struct pex_obj); - obj->flags = flags; - obj->pname = pname; - obj->tempbase = tempbase; - obj->next_input = STDIN_FILE_NO; - obj->next_input_name = NULL; - obj->next_input_name_allocated = 0; - obj->stderr_pipe = -1; - obj->count = 0; - obj->children = NULL; - obj->status = NULL; - obj->time = NULL; - obj->number_waited = 0; - obj->input_file = NULL; - obj->read_output = NULL; - obj->read_err = NULL; - obj->remove_count = 0; - obj->remove = NULL; - obj->funcs = funcs; - obj->sysdep = NULL; - return obj; -} - -/* Add a file to be removed when we are done. */ - -static void -pex_add_remove (struct pex_obj *obj, const char *name, int allocated) -{ - char *add; - - ++obj->remove_count; - obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count); - if (allocated) - add = (char *) name; - else - add = xstrdup (name); - obj->remove[obj->remove_count - 1] = add; -} - -/* Generate a temporary file name based on OBJ, FLAGS, and NAME. - Return NULL if we were unable to reserve a temporary filename. - - If non-NULL, the result is either allocated with malloc, or the - same pointer as NAME. */ -static char * -temp_file (struct pex_obj *obj, int flags, char *name) -{ - if (name == NULL) - { - if (obj->tempbase == NULL) - { - name = make_temp_file (NULL); - } - else - { - int len = strlen (obj->tempbase); - int out; - - if (len >= 6 - && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0) - name = xstrdup (obj->tempbase); - else - name = concat (obj->tempbase, "XXXXXX", NULL); - - out = mkstemps (name, 0); - if (out < 0) - { - free (name); - return NULL; - } - - /* This isn't obj->funcs->close because we got the - descriptor from mkstemps, not from a function in - obj->funcs. Calling close here is just like what - make_temp_file does. */ - close (out); - } - } - else if ((flags & PEX_SUFFIX) != 0) - { - if (obj->tempbase == NULL) - name = make_temp_file (name); - else - name = concat (obj->tempbase, name, NULL); - } - - return name; -} - - -/* As for pex_run (), but permits the environment for the child process - to be specified. */ - -const char * -pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable, - char * const * argv, char * const * env, - const char *orig_outname, const char *errname, - int *err) -{ - const char *errmsg; - int in, out, errdes; - char *outname; - int outname_allocated; - int p[2]; - int toclose; - pid_t pid; - - in = -1; - out = -1; - errdes = -1; - outname = (char *) orig_outname; - outname_allocated = 0; - - /* If the user called pex_input_file, close the file now. */ - if (obj->input_file) - { - if (fclose (obj->input_file) == EOF) - { - errmsg = "closing pipeline input file"; - goto error_exit; - } - obj->input_file = NULL; - } - - /* Set IN. */ - - if (obj->next_input_name != NULL) - { - /* We have to make sure that the previous process has completed - before we try to read the file. */ - if (!pex_get_status_and_time (obj, 0, &errmsg, err)) - goto error_exit; - - in = obj->funcs->open_read (obj, obj->next_input_name, - (flags & PEX_BINARY_INPUT) != 0); - if (in < 0) - { - *err = errno; - errmsg = "open temporary file"; - goto error_exit; - } - if (obj->next_input_name_allocated) - { - free (obj->next_input_name); - obj->next_input_name_allocated = 0; - } - obj->next_input_name = NULL; - } - else - { - in = obj->next_input; - if (in < 0) - { - *err = 0; - errmsg = "pipeline already complete"; - goto error_exit; - } - } - - /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME. */ - - if ((flags & PEX_LAST) != 0) - { - if (outname == NULL) - out = STDOUT_FILE_NO; - else if ((flags & PEX_SUFFIX) != 0) - { - outname = concat (obj->tempbase, outname, NULL); - outname_allocated = 1; - } - obj->next_input = -1; - } - else if ((obj->flags & PEX_USE_PIPES) == 0) - { - outname = temp_file (obj, flags, outname); - if (! outname) - { - *err = 0; - errmsg = "could not create temporary file"; - goto error_exit; - } - - if (outname != orig_outname) - outname_allocated = 1; - - if ((obj->flags & PEX_SAVE_TEMPS) == 0) - { - pex_add_remove (obj, outname, outname_allocated); - outname_allocated = 0; - } - - /* Hand off ownership of outname to the next stage. */ - obj->next_input_name = outname; - obj->next_input_name_allocated = outname_allocated; - outname_allocated = 0; - } - else - { - if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0) - { - *err = errno; - errmsg = "pipe"; - goto error_exit; - } - - out = p[WRITE_PORT]; - obj->next_input = p[READ_PORT]; - } - - if (out < 0) - { - out = obj->funcs->open_write (obj, outname, - (flags & PEX_BINARY_OUTPUT) != 0); - if (out < 0) - { - *err = errno; - errmsg = "open temporary output file"; - goto error_exit; - } - } - - if (outname_allocated) - { - free (outname); - outname_allocated = 0; - } - - /* Set ERRDES. */ - - if (errname != NULL && (flags & PEX_STDERR_TO_PIPE) != 0) - { - *err = 0; - errmsg = "both ERRNAME and PEX_STDERR_TO_PIPE specified."; - goto error_exit; - } - - if (obj->stderr_pipe != -1) - { - *err = 0; - errmsg = "PEX_STDERR_TO_PIPE used in the middle of pipeline"; - goto error_exit; - } - - if (errname == NULL) - { - if (flags & PEX_STDERR_TO_PIPE) - { - if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_ERROR) != 0) < 0) - { - *err = errno; - errmsg = "pipe"; - goto error_exit; - } - - errdes = p[WRITE_PORT]; - obj->stderr_pipe = p[READ_PORT]; - } - else - { - errdes = STDERR_FILE_NO; - } - } - else - { - errdes = obj->funcs->open_write (obj, errname, - (flags & PEX_BINARY_ERROR) != 0); - if (errdes < 0) - { - *err = errno; - errmsg = "open error file"; - goto error_exit; - } - } - - /* If we are using pipes, the child process has to close the next - input pipe. */ - - if ((obj->flags & PEX_USE_PIPES) == 0) - toclose = -1; - else - toclose = obj->next_input; - - /* Run the program. */ - - pid = obj->funcs->exec_child (obj, flags, executable, argv, env, - in, out, errdes, toclose, &errmsg, err); - if (pid < 0) - goto error_exit; - - ++obj->count; - obj->children = XRESIZEVEC (pid_t, obj->children, obj->count); - obj->children[obj->count - 1] = pid; - - return NULL; - - error_exit: - if (in >= 0 && in != STDIN_FILE_NO) - obj->funcs->close (obj, in); - if (out >= 0 && out != STDOUT_FILE_NO) - obj->funcs->close (obj, out); - if (errdes >= 0 && errdes != STDERR_FILE_NO) - obj->funcs->close (obj, errdes); - if (outname_allocated) - free (outname); - return errmsg; -} - -/* Run a program. */ - -const char * -pex_run (struct pex_obj *obj, int flags, const char *executable, - char * const * argv, const char *orig_outname, const char *errname, - int *err) -{ - return pex_run_in_environment (obj, flags, executable, argv, NULL, - orig_outname, errname, err); -} - -/* Return a FILE pointer for a temporary file to fill with input for - the pipeline. */ -FILE * -pex_input_file (struct pex_obj *obj, int flags, const char *in_name) -{ - char *name = (char *) in_name; - FILE *f; - - /* This must be called before the first pipeline stage is run, and - there must not have been any other input selected. */ - if (obj->count != 0 - || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) - || obj->next_input_name) - { - errno = EINVAL; - return NULL; - } - - name = temp_file (obj, flags, name); - if (! name) - return NULL; - - f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w"); - if (! f) - { - free (name); - return NULL; - } - - obj->input_file = f; - obj->next_input_name = name; - obj->next_input_name_allocated = (name != in_name); - - return f; -} - -/* Return a stream for a pipe connected to the standard input of the - first stage of the pipeline. */ -FILE * -pex_input_pipe (struct pex_obj *obj, int binary) -{ - int p[2]; - FILE *f; - - /* You must call pex_input_pipe before the first pex_run or pex_one. */ - if (obj->count > 0) - goto usage_error; - - /* You must be using pipes. Implementations that don't support - pipes clear this flag before calling pex_init_common. */ - if (! (obj->flags & PEX_USE_PIPES)) - goto usage_error; - - /* If we have somehow already selected other input, that's a - mistake. */ - if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) - || obj->next_input_name) - goto usage_error; - - if (obj->funcs->pipe (obj, p, binary != 0) < 0) - return NULL; - - f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0); - if (! f) - { - int saved_errno = errno; - obj->funcs->close (obj, p[READ_PORT]); - obj->funcs->close (obj, p[WRITE_PORT]); - errno = saved_errno; - return NULL; - } - - obj->next_input = p[READ_PORT]; - - return f; - - usage_error: - errno = EINVAL; - return NULL; -} - -/* Return a FILE pointer for the output of the last program - executed. */ - -FILE * -pex_read_output (struct pex_obj *obj, int binary) -{ - if (obj->next_input_name != NULL) - { - const char *errmsg; - int err; - - /* We have to make sure that the process has completed before we - try to read the file. */ - if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) - { - errno = err; - return NULL; - } - - obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r"); - - if (obj->next_input_name_allocated) - { - free (obj->next_input_name); - obj->next_input_name_allocated = 0; - } - obj->next_input_name = NULL; - } - else - { - int o; - - o = obj->next_input; - if (o < 0 || o == STDIN_FILE_NO) - return NULL; - obj->read_output = obj->funcs->fdopenr (obj, o, binary); - obj->next_input = -1; - } - - return obj->read_output; -} - -FILE * -pex_read_err (struct pex_obj *obj, int binary) -{ - int o; - - o = obj->stderr_pipe; - if (o < 0 || o == STDIN_FILE_NO) - return NULL; - obj->read_err = obj->funcs->fdopenr (obj, o, binary); - obj->stderr_pipe = -1; - return obj->read_err; -} - -/* Get the exit status and, if requested, the resource time for all - the child processes. Return 0 on failure, 1 on success. */ - -static int -pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg, - int *err) -{ - int ret; - int i; - - if (obj->number_waited == obj->count) - return 1; - - obj->status = XRESIZEVEC (int, obj->status, obj->count); - if ((obj->flags & PEX_RECORD_TIMES) != 0) - obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count); - - ret = 1; - for (i = obj->number_waited; i < obj->count; ++i) - { - if (obj->funcs->wait (obj, obj->children[i], &obj->status[i], - obj->time == NULL ? NULL : &obj->time[i], - done, errmsg, err) < 0) - ret = 0; - } - obj->number_waited = i; - - return ret; -} - -/* Get exit status of executed programs. */ - -int -pex_get_status (struct pex_obj *obj, int count, int *vector) -{ - if (obj->status == NULL) - { - const char *errmsg; - int err; - - if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) - return 0; - } - - if (count > obj->count) - { - memset (vector + obj->count, 0, (count - obj->count) * sizeof (int)); - count = obj->count; - } - - memcpy (vector, obj->status, count * sizeof (int)); - - return 1; -} - -/* Get process times of executed programs. */ - -int -pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector) -{ - if (obj->status == NULL) - { - const char *errmsg; - int err; - - if (!pex_get_status_and_time (obj, 0, &errmsg, &err)) - return 0; - } - - if (obj->time == NULL) - return 0; - - if (count > obj->count) - { - memset (vector + obj->count, 0, - (count - obj->count) * sizeof (struct pex_time)); - count = obj->count; - } - - memcpy (vector, obj->time, count * sizeof (struct pex_time)); - - return 1; -} - -/* Free a pex_obj structure. */ - -void -pex_free (struct pex_obj *obj) -{ - /* Close pipe file descriptors corresponding to child's stdout and - stderr so that the child does not hang trying to output something - while we're waiting for it. */ - if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO) - obj->funcs->close (obj, obj->next_input); - if (obj->stderr_pipe >= 0 && obj->stderr_pipe != STDIN_FILE_NO) - obj->funcs->close (obj, obj->stderr_pipe); - if (obj->read_output != NULL) - fclose (obj->read_output); - if (obj->read_err != NULL) - fclose (obj->read_err); - - /* If the caller forgot to wait for the children, we do it here, to - avoid zombies. */ - if (obj->status == NULL) - { - const char *errmsg; - int err; - - obj->flags &= ~ PEX_RECORD_TIMES; - pex_get_status_and_time (obj, 1, &errmsg, &err); - } - - if (obj->next_input_name_allocated) - free (obj->next_input_name); - free (obj->children); - free (obj->status); - free (obj->time); - - if (obj->remove_count > 0) - { - int i; - - for (i = 0; i < obj->remove_count; ++i) - { - remove (obj->remove[i]); - free (obj->remove[i]); - } - free (obj->remove); - } - - if (obj->funcs->cleanup != NULL) - obj->funcs->cleanup (obj); - - free (obj); -} diff --git a/linkers/libiberty/pex-common.h b/linkers/libiberty/pex-common.h deleted file mode 100644 index af338e6..0000000 --- a/linkers/libiberty/pex-common.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Utilities to execute a program in a subprocess (possibly linked by pipes - with other subprocesses), and wait for it. Shared logic. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 - Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#ifndef PEX_COMMON_H -#define PEX_COMMON_H - -#include "config.h" -#include "libiberty.h" -#include - -/* pid_t is may defined by config.h or sys/types.h needs to be - included. */ -#if !defined(pid_t) && defined(HAVE_SYS_TYPES_H) -#include -#endif - -#define install_error_msg "installation problem, cannot exec `%s'" - -/* stdin file number. */ -#define STDIN_FILE_NO 0 - -/* stdout file number. */ -#define STDOUT_FILE_NO 1 - -/* stderr file number. */ -#define STDERR_FILE_NO 2 - -/* value of `pipe': port index for reading. */ -#define READ_PORT 0 - -/* value of `pipe': port index for writing. */ -#define WRITE_PORT 1 - -/* The structure used by pex_init and friends. */ - -struct pex_obj -{ - /* Flags. */ - int flags; - /* Name of calling program, for error messages. */ - const char *pname; - /* Base name to use for temporary files. */ - const char *tempbase; - /* Pipe to use as stdin for next process. */ - int next_input; - /* File name to use as stdin for next process. */ - char *next_input_name; - /* Whether next_input_name was allocated using malloc. */ - int next_input_name_allocated; - /* If not -1, stderr pipe from the last process. */ - int stderr_pipe; - /* Number of child processes. */ - int count; - /* PIDs of child processes; array allocated using malloc. */ - pid_t *children; - /* Exit statuses of child processes; array allocated using malloc. */ - int *status; - /* Time used by child processes; array allocated using malloc. */ - struct pex_time *time; - /* Number of children we have already waited for. */ - int number_waited; - /* FILE created by pex_input_file. */ - FILE *input_file; - /* FILE created by pex_read_output. */ - FILE *read_output; - /* FILE created by pex_read_err. */ - FILE *read_err; - /* Number of temporary files to remove. */ - int remove_count; - /* List of temporary files to remove; array allocated using malloc - of strings allocated using malloc. */ - char **remove; - /* Pointers to system dependent functions. */ - const struct pex_funcs *funcs; - /* For use by system dependent code. */ - void *sysdep; -}; - -/* Functions passed to pex_run_common. */ - -struct pex_funcs -{ - /* Open file NAME for reading. If BINARY is non-zero, open in - binary mode. Return >= 0 on success, -1 on error. */ - int (*open_read) (struct pex_obj *, const char */* name */, int /* binary */); - /* Open file NAME for writing. If BINARY is non-zero, open in - binary mode. Return >= 0 on success, -1 on error. */ - int (*open_write) (struct pex_obj *, const char */* name */, - int /* binary */); - /* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from - pex_run. IN, OUT, ERRDES, TOCLOSE are all descriptors, from - open_read, open_write, or pipe, or they are one of STDIN_FILE_NO, - STDOUT_FILE_NO or STDERR_FILE_NO; if IN, OUT, and ERRDES are not - STD*_FILE_NO, they should be closed. If the descriptor TOCLOSE - is not -1, and the system supports pipes, TOCLOSE should be - closed in the child process. The function should handle the - PEX_STDERR_TO_STDOUT flag. Return >= 0 on success, or -1 on - error and set *ERRMSG and *ERR. */ - pid_t (*exec_child) (struct pex_obj *, int /* flags */, - const char */* executable */, char * const * /* argv */, - char * const * /* env */, - int /* in */, int /* out */, int /* errdes */, - int /* toclose */, const char **/* errmsg */, - int */* err */); - /* Close a descriptor. Return 0 on success, -1 on error. */ - int (*close) (struct pex_obj *, int); - /* Wait for a child to complete, returning exit status in *STATUS - and time in *TIME (if it is not null). CHILD is from fork. DONE - is 1 if this is called via pex_free. ERRMSG and ERR are as in - fork. Return 0 on success, -1 on error. */ - pid_t (*wait) (struct pex_obj *, pid_t /* child */, int * /* status */, - struct pex_time * /* time */, int /* done */, - const char ** /* errmsg */, int * /* err */); - /* Create a pipe (only called if PEX_USE_PIPES is set) storing two - descriptors in P[0] and P[1]. If BINARY is non-zero, open in - binary mode. Return 0 on success, -1 on error. */ - int (*pipe) (struct pex_obj *, int * /* p */, int /* binary */); - /* Get a FILE pointer to read from a file descriptor (only called if - PEX_USE_PIPES is set). If BINARY is non-zero, open in binary - mode. Return pointer on success, NULL on error. */ - FILE * (*fdopenr) (struct pex_obj *, int /* fd */, int /* binary */); - /* Get a FILE pointer to write to the file descriptor FD (only - called if PEX_USE_PIPES is set). If BINARY is non-zero, open in - binary mode. Arrange for FD not to be inherited by the child - processes. Return pointer on success, NULL on error. */ - FILE * (*fdopenw) (struct pex_obj *, int /* fd */, int /* binary */); - /* Free any system dependent data associated with OBJ. May be - NULL if there is nothing to do. */ - void (*cleanup) (struct pex_obj *); -}; - -extern struct pex_obj *pex_init_common (int, const char *, const char *, - const struct pex_funcs *); - -#endif diff --git a/linkers/libiberty/pex-djgpp.c b/linkers/libiberty/pex-djgpp.c deleted file mode 100644 index 0721139..0000000 --- a/linkers/libiberty/pex-djgpp.c +++ /dev/null @@ -1,294 +0,0 @@ -/* Utilities to execute a program in a subprocess (possibly linked by pipes - with other subprocesses), and wait for it. DJGPP specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005 - Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "pex-common.h" - -#include -#include -#ifdef NEED_DECLARATION_ERRNO -extern int errno; -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#include -#include -#include -#include -#include - -/* Use ECHILD if available, otherwise use EINVAL. */ -#ifdef ECHILD -#define PWAIT_ERROR ECHILD -#else -#define PWAIT_ERROR EINVAL -#endif - -static int pex_djgpp_open_read (struct pex_obj *, const char *, int); -static int pex_djgpp_open_write (struct pex_obj *, const char *, int); -static pid_t pex_djgpp_exec_child (struct pex_obj *, int, const char *, - char * const *, char * const *, - int, int, int, int, - const char **, int *); -static int pex_djgpp_close (struct pex_obj *, int); -static pid_t pex_djgpp_wait (struct pex_obj *, pid_t, int *, struct pex_time *, - int, const char **, int *); - -/* The list of functions we pass to the common routines. */ - -const struct pex_funcs funcs = -{ - pex_djgpp_open_read, - pex_djgpp_open_write, - pex_djgpp_exec_child, - pex_djgpp_close, - pex_djgpp_wait, - NULL, /* pipe */ - NULL, /* fdopenr */ - NULL, /* fdopenw */ - NULL /* cleanup */ -}; - -/* Return a newly initialized pex_obj structure. */ - -struct pex_obj * -pex_init (int flags, const char *pname, const char *tempbase) -{ - /* DJGPP does not support pipes. */ - flags &= ~ PEX_USE_PIPES; - return pex_init_common (flags, pname, tempbase, &funcs); -} - -/* Open a file for reading. */ - -static int -pex_djgpp_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, - const char *name, int binary) -{ - return open (name, O_RDONLY | (binary ? O_BINARY : O_TEXT)); -} - -/* Open a file for writing. */ - -static int -pex_djgpp_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, - const char *name, int binary) -{ - /* Note that we can't use O_EXCL here because gcc may have already - created the temporary file via make_temp_file. */ - return open (name, - (O_WRONLY | O_CREAT | O_TRUNC - | (binary ? O_BINARY : O_TEXT)), - S_IRUSR | S_IWUSR); -} - -/* Close a file. */ - -static int -pex_djgpp_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) -{ - return close (fd); -} - -/* Execute a child. */ - -static pid_t -pex_djgpp_exec_child (struct pex_obj *obj, int flags, const char *executable, - char * const * argv, char * const * env, - int in, int out, int errdes, - int toclose ATTRIBUTE_UNUSED, const char **errmsg, - int *err) -{ - int org_in, org_out, org_errdes; - int status; - int *statuses; - - org_in = -1; - org_out = -1; - org_errdes = -1; - - if (in != STDIN_FILE_NO) - { - org_in = dup (STDIN_FILE_NO); - if (org_in < 0) - { - *err = errno; - *errmsg = "dup"; - return (pid_t) -1; - } - if (dup2 (in, STDIN_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (close (in) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - if (out != STDOUT_FILE_NO) - { - org_out = dup (STDOUT_FILE_NO); - if (org_out < 0) - { - *err = errno; - *errmsg = "dup"; - return (pid_t) -1; - } - if (dup2 (out, STDOUT_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (close (out) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - if (errdes != STDERR_FILE_NO - || (flags & PEX_STDERR_TO_STDOUT) != 0) - { - org_errdes = dup (STDERR_FILE_NO); - if (org_errdes < 0) - { - *err = errno; - *errmsg = "dup"; - return (pid_t) -1; - } - if (dup2 ((flags & PEX_STDERR_TO_STDOUT) != 0 ? STDOUT_FILE_NO : errdes, - STDERR_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (errdes != STDERR_FILE_NO) - { - if (close (errdes) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - } - - if (env) - status = (((flags & PEX_SEARCH) != 0 ? spawnvpe : spawnve) - (P_WAIT, executable, argv, env)); - else - status = (((flags & PEX_SEARCH) != 0 ? spawnvp : spawnv) - (P_WAIT, executable, argv)); - - if (status == -1) - { - *err = errno; - *errmsg = ((flags & PEX_SEARCH) != 0) ? "spawnvp" : "spawnv"; - } - - if (in != STDIN_FILE_NO) - { - if (dup2 (org_in, STDIN_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (close (org_in) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - if (out != STDOUT_FILE_NO) - { - if (dup2 (org_out, STDOUT_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (close (org_out) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - if (errdes != STDERR_FILE_NO - || (flags & PEX_STDERR_TO_STDOUT) != 0) - { - if (dup2 (org_errdes, STDERR_FILE_NO) < 0) - { - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; - } - if (close (org_errdes) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - /* Save the exit status for later. When we are called, obj->count - is the number of children which have executed before this - one. */ - statuses = (int *) obj->sysdep; - statuses = XRESIZEVEC (int, statuses, obj->count + 1); - statuses[obj->count] = status; - obj->sysdep = (void *) statuses; - - return (pid_t) obj->count; -} - -/* Wait for a child process to complete. Actually the child process - has already completed, and we just need to return the exit - status. */ - -static pid_t -pex_djgpp_wait (struct pex_obj *obj, pid_t pid, int *status, - struct pex_time *time, int done ATTRIBUTE_UNUSED, - const char **errmsg ATTRIBUTE_UNUSED, - int *err ATTRIBUTE_UNUSED) -{ - int *statuses; - - if (time != NULL) - memset (time, 0, sizeof *time); - - statuses = (int *) obj->sysdep; - *status = statuses[pid]; - - return 0; -} diff --git a/linkers/libiberty/pex-msdos.c b/linkers/libiberty/pex-msdos.c deleted file mode 100644 index fa0f40a..0000000 --- a/linkers/libiberty/pex-msdos.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Utilities to execute a program in a subprocess (possibly linked by pipes - with other subprocesses), and wait for it. Generic MSDOS specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005 - Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "pex-common.h" - -#include -#include -#ifdef NEED_DECLARATION_ERRNO -extern int errno; -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "safe-ctype.h" -#include - -/* The structure we keep in obj->sysdep. */ - -#define PEX_MSDOS_FILE_COUNT 3 - -#define PEX_MSDOS_FD_OFFSET 10 - -struct pex_msdos -{ - /* An array of file names. We refer to these using file descriptors - of 10 + array index. */ - const char *files[PEX_MSDOS_FILE_COUNT]; - /* Exit statuses of programs which have been run. */ - int *statuses; -}; - -static int pex_msdos_open (struct pex_obj *, const char *, int); -static int pex_msdos_open (struct pex_obj *, const char *, int); -static int pex_msdos_fdindex (struct pex_msdos *, int); -static pid_t pex_msdos_exec_child (struct pex_obj *, int, const char *, - char * const *, char * const *, - int, int, int, int, - int, const char **, int *); -static int pex_msdos_close (struct pex_obj *, int); -static pid_t pex_msdos_wait (struct pex_obj *, pid_t, int *, struct pex_time *, - int, const char **, int *); -static void pex_msdos_cleanup (struct pex_obj *); - -/* The list of functions we pass to the common routines. */ - -const struct pex_funcs funcs = -{ - pex_msdos_open, - pex_msdos_open, - pex_msdos_exec_child, - pex_msdos_close, - pex_msdos_wait, - NULL, /* pipe */ - NULL, /* fdopenr */ - NULL, /* fdopenw */ - pex_msdos_cleanup -}; - -/* Return a newly initialized pex_obj structure. */ - -struct pex_obj * -pex_init (int flags, const char *pname, const char *tempbase) -{ - struct pex_obj *ret; - int i; - - /* MSDOS does not support pipes. */ - flags &= ~ PEX_USE_PIPES; - - ret = pex_init_common (flags, pname, tempbase, funcs); - - ret->sysdep = XNEW (struct pex_msdos); - for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) - ret->files[i] = NULL; - ret->statuses = NULL; - - return ret; -} - -/* Open a file. FIXME: We ignore the binary argument, since we have - no way to handle it. */ - -static int -pex_msdos_open (struct pex_obj *obj, const char *name, - int binary ATTRIBUTE_UNUSED) -{ - struct pex_msdos *ms; - int i; - - ms = (struct pex_msdos *) obj->sysdep; - - for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) - { - if (ms->files[i] == NULL) - { - ms->files[i] = xstrdup (name); - return i + PEX_MSDOS_FD_OFFSET; - } - } - - abort (); -} - -/* Get the index into msdos->files associated with an open file - descriptor. */ - -static int -pex_msdos_fdindex (struct pex_msdos *ms, int fd) -{ - fd -= PEX_MSDOS_FD_OFFSET; - if (fd < 0 || fd >= PEX_MSDOS_FILE_COUNT || ms->files[fd] == NULL) - abort (); - return fd; -} - - -/* Close a file. */ - -static int -pex_msdos_close (struct pex_obj *obj, int fd) -{ - struct pex_msdos *ms; - int fdinex; - - ms = (struct pex_msdos *) obj->sysdep; - fdindex = pe_msdos_fdindex (ms, fd); - free (ms->files[fdindex]); - ms->files[fdindex] = NULL; -} - -/* Execute a child. */ - -static pid_t -pex_msdos_exec_child (struct pex_obj *obj, int flags, const char *executable, - char * const * argv, char * const * env, int in, int out, - int toclose ATTRIBUTE_UNUSED, - int errdes ATTRIBUTE_UNUSED, const char **errmsg, - int *err) -{ - struct pex_msdos *ms; - char *temp_base; - int temp_base_allocated; - char *rf; - int inindex; - char *infile; - int outindex; - char *outfile; - char *scmd; - FILE *argfile; - int i; - int status; - - ms = (struct pex_msdos *) obj->sysdep; - - /* FIXME: I don't know how to redirect stderr, so we ignore ERRDES - and PEX_STDERR_TO_STDOUT. */ - - temp_base = obj->temp_base; - if (temp_base != NULL) - temp_base_allocated = 0; - else - { - temp_base = choose_temp_base (); - temp_base_allocated = 1; - } - - rf = concat (temp_base, ".gp", NULL); - - if (temp_base_allocated) - free (temp_base); - - if (in == STDIN_FILE_NO) - { - inindex = -1; - infile = ""; - } - else - { - inindex = pex_msdos_fdindex (ms, in); - infile = ms->files[inindex]; - } - - if (out == STDOUT_FILE_NO) - { - outindex = -1; - outfile = ""; - } - else - { - outindex = pex_msdos_fdindex (ms, out); - outfile = ms->files[outindex]; - } - - scmd = XNEWVEC (char, strlen (program) - + ((flags & PEXECUTE_SEARCH) != 0 ? 4 : 0) - + strlen (rf) - + strlen (infile) - + strlen (outfile) - + 10); - sprintf (scmd, "%s%s @%s%s%s%s%s", - program, - (flags & PEXECUTE_SEARCH) != 0 ? ".exe" : "", - rf, - inindex != -1 ? " <" : "", - infile, - outindex != -1 ? " >" : "", - outfile); - - argfile = fopen (rf, "w"); - if (argfile == NULL) - { - *err = errno; - free (scmd); - free (rf); - *errmsg = "cannot open temporary command file"; - return (pid_t) -1; - } - - for (i = 1; argv[i] != NULL; ++i) - { - char *p; - - for (p = argv[i]; *p != '\0'; ++p) - { - if (*p == '"' || *p == '\'' || *p == '\\' || ISSPACE (*p)) - putc ('\\', argfile); - putc (*p, argfile); - } - putc ('\n', argfile); - } - - fclose (argfile); - - status = system (scmd); - - if (status == -1) - { - *err = errno; - remove (rf); - free (scmd); - free (rf); - *errmsg = "system"; - return (pid_t) -1; - } - - remove (rf); - free (scmd); - free (rf); - - /* Save the exit status for later. When we are called, obj->count - is the number of children which have executed before this - one. */ - ms->statuses = XRESIZEVEC(int, ms->statuses, obj->count + 1); - ms->statuses[obj->count] = status; - - return (pid_t) obj->count; -} - -/* Wait for a child process to complete. Actually the child process - has already completed, and we just need to return the exit - status. */ - -static pid_t -pex_msdos_wait (struct pex_obj *obj, pid_t pid, int *status, - struct pex_time *time, int done ATTRIBUTE_UNUSED, - const char **errmsg ATTRIBUTE_UNUSED, - int *err ATTRIBUTE_UNUSED) -{ - struct pex_msdos *ms; - - ms = (struct pex_msdos *) obj->sysdep; - - if (time != NULL) - memset (time, 0, sizeof *time); - - *status = ms->statuses[pid]; - - return 0; -} - -/* Clean up the pex_msdos structure. */ - -static void -pex_msdos_cleanup (struct pex_obj *obj) -{ - struct pex_msdos *ms; - int i; - - ms = (struct pex_msdos *) obj->sysdep; - for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i) - free (msdos->files[i]); - free (msdos->statuses); - free (msdos); - obj->sysdep = NULL; -} diff --git a/linkers/libiberty/pex-one.c b/linkers/libiberty/pex-one.c deleted file mode 100644 index 696b8bc..0000000 --- a/linkers/libiberty/pex-one.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Execute a program and wait for a result. - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "config.h" -#include "libiberty.h" - -const char * -pex_one (int flags, const char *executable, char * const *argv, - const char *pname, const char *outname, const char *errname, - int *status, int *err) -{ - struct pex_obj *obj; - const char *errmsg; - - obj = pex_init (0, pname, NULL); - errmsg = pex_run (obj, flags, executable, argv, outname, errname, err); - if (errmsg == NULL) - { - if (!pex_get_status (obj, 1, status)) - { - *err = 0; - errmsg = "pex_get_status failed"; - } - } - pex_free (obj); - return errmsg; -} diff --git a/linkers/libiberty/pex-unix.c b/linkers/libiberty/pex-unix.c deleted file mode 100644 index 80a4770..0000000 --- a/linkers/libiberty/pex-unix.c +++ /dev/null @@ -1,788 +0,0 @@ -/* Utilities to execute a program in a subprocess (possibly linked by pipes - with other subprocesses), and wait for it. Generic Unix version - (also used for UWIN and VMS). - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009, - 2010 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "config.h" -#include "libiberty.h" -#include "pex-common.h" - -#include -#include -#include -#ifdef NEED_DECLARATION_ERRNO -extern int errno; -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_SYS_WAIT_H -#include -#endif -#ifdef HAVE_GETRUSAGE -#include -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_PROCESS_H -#include -#endif - -#ifdef vfork /* Autoconf may define this to fork for us. */ -# define VFORK_STRING "fork" -#else -# define VFORK_STRING "vfork" -#endif -#ifdef HAVE_VFORK_H -#include -#endif -#if defined(VMS) && defined (__LONG_POINTERS) -#ifndef __CHAR_PTR32 -typedef char * __char_ptr32 -__attribute__ ((mode (SI))); -#endif - -typedef __char_ptr32 *__char_ptr_char_ptr32 -__attribute__ ((mode (SI))); - -/* Return a 32 bit pointer to an array of 32 bit pointers - given a 64 bit pointer to an array of 64 bit pointers. */ - -static __char_ptr_char_ptr32 -to_ptr32 (char **ptr64) -{ - int argc; - __char_ptr_char_ptr32 short_argv; - - for (argc=0; ptr64[argc]; argc++); - - /* Reallocate argv with 32 bit pointers. */ - short_argv = (__char_ptr_char_ptr32) decc$malloc - (sizeof (__char_ptr32) * (argc + 1)); - - for (argc=0; ptr64[argc]; argc++) - short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]); - - short_argv[argc] = (__char_ptr32) 0; - return short_argv; - -} -#else -#define to_ptr32(argv) argv -#endif - -/* File mode to use for private and world-readable files. */ - -#if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) -#define PUBLIC_MODE \ - (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) -#else -#define PUBLIC_MODE 0666 -#endif - -/* Get the exit status of a particular process, and optionally get the - time that it took. This is simple if we have wait4, slightly - harder if we have waitpid, and is a pain if we only have wait. */ - -static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); - -#ifdef HAVE_WAIT4 - -static pid_t -pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, - struct pex_time *time) -{ - pid_t ret; - struct rusage r; - -#ifdef HAVE_WAITPID - if (time == NULL) - return waitpid (pid, status, 0); -#endif - - ret = wait4 (pid, status, 0, &r); - - if (time != NULL) - { - time->user_seconds = r.ru_utime.tv_sec; - time->user_microseconds= r.ru_utime.tv_usec; - time->system_seconds = r.ru_stime.tv_sec; - time->system_microseconds= r.ru_stime.tv_usec; - } - - return ret; -} - -#else /* ! defined (HAVE_WAIT4) */ - -#ifdef HAVE_WAITPID - -#ifndef HAVE_GETRUSAGE - -static pid_t -pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, - struct pex_time *time) -{ - if (time != NULL) - memset (time, 0, sizeof (struct pex_time)); - return waitpid (pid, status, 0); -} - -#else /* defined (HAVE_GETRUSAGE) */ - -static pid_t -pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, - struct pex_time *time) -{ - struct rusage r1, r2; - pid_t ret; - - if (time == NULL) - return waitpid (pid, status, 0); - - getrusage (RUSAGE_CHILDREN, &r1); - - ret = waitpid (pid, status, 0); - if (ret < 0) - return ret; - - getrusage (RUSAGE_CHILDREN, &r2); - - time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; - time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; - if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) - { - --time->user_seconds; - time->user_microseconds += 1000000; - } - - time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; - time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; - if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) - { - --time->system_seconds; - time->system_microseconds += 1000000; - } - - return ret; -} - -#endif /* defined (HAVE_GETRUSAGE) */ - -#else /* ! defined (HAVE_WAITPID) */ - -struct status_list -{ - struct status_list *next; - pid_t pid; - int status; - struct pex_time time; -}; - -static pid_t -pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) -{ - struct status_list **pp; - - for (pp = (struct status_list **) &obj->sysdep; - *pp != NULL; - pp = &(*pp)->next) - { - if ((*pp)->pid == pid) - { - struct status_list *p; - - p = *pp; - *status = p->status; - if (time != NULL) - *time = p->time; - *pp = p->next; - free (p); - return pid; - } - } - - while (1) - { - pid_t cpid; - struct status_list *psl; - struct pex_time pt; -#ifdef HAVE_GETRUSAGE - struct rusage r1, r2; -#endif - - if (time != NULL) - { -#ifdef HAVE_GETRUSAGE - getrusage (RUSAGE_CHILDREN, &r1); -#else - memset (&pt, 0, sizeof (struct pex_time)); -#endif - } - - cpid = wait (status); - -#ifdef HAVE_GETRUSAGE - if (time != NULL && cpid >= 0) - { - getrusage (RUSAGE_CHILDREN, &r2); - - pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; - pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; - if ((int) pt.user_microseconds < 0) - { - --pt.user_seconds; - pt.user_microseconds += 1000000; - } - - pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; - pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; - if ((int) pt.system_microseconds < 0) - { - --pt.system_seconds; - pt.system_microseconds += 1000000; - } - } -#endif - - if (cpid < 0 || cpid == pid) - { - if (time != NULL) - *time = pt; - return cpid; - } - - psl = XNEW (struct status_list); - psl->pid = cpid; - psl->status = *status; - if (time != NULL) - psl->time = pt; - psl->next = (struct status_list *) obj->sysdep; - obj->sysdep = (void *) psl; - } -} - -#endif /* ! defined (HAVE_WAITPID) */ -#endif /* ! defined (HAVE_WAIT4) */ - -static void pex_child_error (struct pex_obj *, const char *, const char *, int) - ATTRIBUTE_NORETURN; -static int pex_unix_open_read (struct pex_obj *, const char *, int); -static int pex_unix_open_write (struct pex_obj *, const char *, int); -static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *, - char * const *, char * const *, - int, int, int, int, - const char **, int *); -static int pex_unix_close (struct pex_obj *, int); -static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, - int, const char **, int *); -static int pex_unix_pipe (struct pex_obj *, int *, int); -static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); -static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); -static void pex_unix_cleanup (struct pex_obj *); - -/* The list of functions we pass to the common routines. */ - -const struct pex_funcs funcs = -{ - pex_unix_open_read, - pex_unix_open_write, - pex_unix_exec_child, - pex_unix_close, - pex_unix_wait, - pex_unix_pipe, - pex_unix_fdopenr, - pex_unix_fdopenw, - pex_unix_cleanup -}; - -/* Return a newly initialized pex_obj structure. */ - -struct pex_obj * -pex_init (int flags, const char *pname, const char *tempbase) -{ - return pex_init_common (flags, pname, tempbase, &funcs); -} - -/* Open a file for reading. */ - -static int -pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, - int binary ATTRIBUTE_UNUSED) -{ - return open (name, O_RDONLY); -} - -/* Open a file for writing. */ - -static int -pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, - int binary ATTRIBUTE_UNUSED) -{ - /* Note that we can't use O_EXCL here because gcc may have already - created the temporary file via make_temp_file. */ - return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE); -} - -/* Close a file. */ - -static int -pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) -{ - return close (fd); -} - -/* Report an error from a child process. We don't use stdio routines, - because we might be here due to a vfork call. */ - -static void -pex_child_error (struct pex_obj *obj, const char *executable, - const char *errmsg, int err) -{ - int retval = 0; -#define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0) - writeerr (obj->pname); - writeerr (": error trying to exec '"); - writeerr (executable); - writeerr ("': "); - writeerr (errmsg); - writeerr (": "); - writeerr (xstrerror (err)); - writeerr ("\n"); -#undef writeerr - /* Exit with -2 if the error output failed, too. */ - _exit (retval == 0 ? -1 : -2); -} - -/* Execute a child. */ - -extern char **environ; - -#if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE) -/* Implementation of pex->exec_child using the Cygwin spawn operation. */ - -/* Subroutine of pex_unix_exec_child. Move OLD_FD to a new file descriptor - to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the - saved copy to be close-on-exec. Move CHILD_FD into OLD_FD. If CHILD_FD - is -1, OLD_FD is to be closed. Return -1 on error. */ - -static int -save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd) -{ - int new_fd, flags; - - flags = fcntl (old_fd, F_GETFD); - - /* If we could not retrieve the flags, then OLD_FD was not open. */ - if (flags < 0) - { - new_fd = -1, flags = 0; - if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0) - return -1; - } - /* If we wish to close OLD_FD, just mark it CLOEXEC. */ - else if (child_fd == -1) - { - new_fd = old_fd; - if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0) - return -1; - } - /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD. */ - else - { -#ifdef F_DUPFD_CLOEXEC - new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3); - if (new_fd < 0) - return -1; -#else - /* Prefer F_DUPFD over dup in order to avoid getting a new fd - in the range 0-2, right where a new stderr fd might get put. */ - new_fd = fcntl (old_fd, F_DUPFD, 3); - if (new_fd < 0) - return -1; - if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0) - return -1; -#endif - if (dup2 (child_fd, old_fd) < 0) - return -1; - } - - *pflags = flags; - if (pnew_fd) - *pnew_fd = new_fd; - else if (new_fd != old_fd) - abort (); - - return 0; -} - -/* Subroutine of pex_unix_exec_child. Move SAVE_FD back to OLD_FD - restoring FLAGS. If SAVE_FD < 0, OLD_FD is to be closed. */ - -static int -restore_fd(int old_fd, int save_fd, int flags) -{ - /* For SAVE_FD < 0, all we have to do is restore the - "closed-ness" of the original. */ - if (save_fd < 0) - return close (old_fd); - - /* For SAVE_FD == OLD_FD, all we have to do is restore the - original setting of the CLOEXEC flag. */ - if (save_fd == old_fd) - { - if (flags & FD_CLOEXEC) - return 0; - return fcntl (old_fd, F_SETFD, flags); - } - - /* Otherwise we have to move the descriptor back, restore the flags, - and close the saved copy. */ -#ifdef HAVE_DUP3 - if (flags == FD_CLOEXEC) - { - if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0) - return -1; - } - else -#endif - { - if (dup2 (save_fd, old_fd) < 0) - return -1; - if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0) - return -1; - } - return close (save_fd); -} - -static pid_t -pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, - int flags, const char *executable, - char * const * argv, char * const * env, - int in, int out, int errdes, int toclose, - const char **errmsg, int *err) -{ - int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0; - int save_in = -1, save_out = -1, save_err = -1; - int max, retries; - pid_t pid; - - if (flags & PEX_STDERR_TO_STDOUT) - errdes = out; - - /* We need the three standard file descriptors to be set up as for - the child before we perform the spawn. The file descriptors for - the parent need to be moved and marked for close-on-exec. */ - if (in != STDIN_FILE_NO - && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0) - goto error_dup2; - if (out != STDOUT_FILE_NO - && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0) - goto error_dup2; - if (errdes != STDERR_FILE_NO - && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0) - goto error_dup2; - if (toclose >= 0 - && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0) - goto error_dup2; - - /* Now that we've moved the file descriptors for the child into place, - close the originals. Be careful not to close any of the standard - file descriptors that we just set up. */ - max = -1; - if (errdes >= 0) - max = STDERR_FILE_NO; - else if (out >= 0) - max = STDOUT_FILE_NO; - else if (in >= 0) - max = STDIN_FILE_NO; - if (in > max) - close (in); - if (out > max) - close (out); - if (errdes > max && errdes != out) - close (errdes); - - /* If we were not given an environment, use the global environment. */ - if (env == NULL) - env = environ; - - /* Launch the program. If we get EAGAIN (normally out of pid's), try - again a few times with increasing backoff times. */ - retries = 0; - while (1) - { - typedef const char * const *cc_cp; - - if (flags & PEX_SEARCH) - pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); - else - pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); - - if (pid > 0) - break; - - *err = errno; - *errmsg = "spawn"; - if (errno != EAGAIN || ++retries == 4) - return (pid_t) -1; - sleep (1 << retries); - } - - /* Success. Restore the parent's file descriptors that we saved above. */ - if (toclose >= 0 - && restore_fd (toclose, toclose, fl_tc) < 0) - goto error_dup2; - if (in != STDIN_FILE_NO - && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0) - goto error_dup2; - if (out != STDOUT_FILE_NO - && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0) - goto error_dup2; - if (errdes != STDERR_FILE_NO - && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0) - goto error_dup2; - - return pid; - - error_dup2: - *err = errno; - *errmsg = "dup2"; - return (pid_t) -1; -} - -#else -/* Implementation of pex->exec_child using standard vfork + exec. */ - -static pid_t -pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, - char * const * argv, char * const * env, - int in, int out, int errdes, - int toclose, const char **errmsg, int *err) -{ - pid_t pid; - - /* We declare these to be volatile to avoid warnings from gcc about - them being clobbered by vfork. */ - volatile int sleep_interval; - volatile int retries; - - /* We vfork and then set environ in the child before calling execvp. - This clobbers the parent's environ so we need to restore it. - It would be nice to use one of the exec* functions that takes an - environment as a parameter, but that may have portability issues. */ - char **save_environ = environ; - - sleep_interval = 1; - pid = -1; - for (retries = 0; retries < 4; ++retries) - { - pid = vfork (); - if (pid >= 0) - break; - sleep (sleep_interval); - sleep_interval *= 2; - } - - switch (pid) - { - case -1: - *err = errno; - *errmsg = VFORK_STRING; - return (pid_t) -1; - - case 0: - /* Child process. */ - if (in != STDIN_FILE_NO) - { - if (dup2 (in, STDIN_FILE_NO) < 0) - pex_child_error (obj, executable, "dup2", errno); - if (close (in) < 0) - pex_child_error (obj, executable, "close", errno); - } - if (out != STDOUT_FILE_NO) - { - if (dup2 (out, STDOUT_FILE_NO) < 0) - pex_child_error (obj, executable, "dup2", errno); - if (close (out) < 0) - pex_child_error (obj, executable, "close", errno); - } - if (errdes != STDERR_FILE_NO) - { - if (dup2 (errdes, STDERR_FILE_NO) < 0) - pex_child_error (obj, executable, "dup2", errno); - if (close (errdes) < 0) - pex_child_error (obj, executable, "close", errno); - } - if (toclose >= 0) - { - if (close (toclose) < 0) - pex_child_error (obj, executable, "close", errno); - } - if ((flags & PEX_STDERR_TO_STDOUT) != 0) - { - if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) - pex_child_error (obj, executable, "dup2", errno); - } - - if (env) - { - /* NOTE: In a standard vfork implementation this clobbers the - parent's copy of environ "too" (in reality there's only one copy). - This is ok as we restore it below. */ - environ = (char**) env; - } - - if ((flags & PEX_SEARCH) != 0) - { - execvp (executable, to_ptr32 (argv)); - pex_child_error (obj, executable, "execvp", errno); - } - else - { - execv (executable, to_ptr32 (argv)); - pex_child_error (obj, executable, "execv", errno); - } - - /* NOTREACHED */ - return (pid_t) -1; - - default: - /* Parent process. */ - - /* Restore environ. - Note that the parent either doesn't run until the child execs/exits - (standard vfork behaviour), or if it does run then vfork is behaving - more like fork. In either case we needn't worry about clobbering - the child's copy of environ. */ - environ = save_environ; - - if (in != STDIN_FILE_NO) - { - if (close (in) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - if (out != STDOUT_FILE_NO) - { - if (close (out) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - if (errdes != STDERR_FILE_NO) - { - if (close (errdes) < 0) - { - *err = errno; - *errmsg = "close"; - return (pid_t) -1; - } - } - - return pid; - } -} -#endif /* SPAWN */ - -/* Wait for a child process to complete. */ - -static int -pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status, - struct pex_time *time, int done, const char **errmsg, - int *err) -{ - /* If we are cleaning up when the caller didn't retrieve process - status for some reason, encourage the process to go away. */ - if (done) - kill (pid, SIGTERM); - - if (pex_wait (obj, pid, status, time) < 0) - { - *err = errno; - *errmsg = "wait"; - return -1; - } - - return 0; -} - -/* Create a pipe. */ - -static int -pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, - int binary ATTRIBUTE_UNUSED) -{ - return pipe (p); -} - -/* Get a FILE pointer to read from a file descriptor. */ - -static FILE * -pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, - int binary ATTRIBUTE_UNUSED) -{ - return fdopen (fd, "r"); -} - -static FILE * -pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, - int binary ATTRIBUTE_UNUSED) -{ - if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) - return NULL; - return fdopen (fd, "w"); -} - -static void -pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) -{ -#if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) - while (obj->sysdep != NULL) - { - struct status_list *this; - struct status_list *next; - - this = (struct status_list *) obj->sysdep; - next = this->next; - free (this); - obj->sysdep = (void *) next; - } -#endif -} diff --git a/linkers/libiberty/pex-win32.c b/linkers/libiberty/pex-win32.c deleted file mode 100644 index f1d47c7..0000000 --- a/linkers/libiberty/pex-win32.c +++ /dev/null @@ -1,943 +0,0 @@ -/* Utilities to execute a program in a subprocess (possibly linked by pipes - with other subprocesses), and wait for it. Generic Win32 specialization. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "pex-common.h" - -#include - -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* mingw32 headers may not define the following. */ - -#ifndef _P_WAIT -# define _P_WAIT 0 -# define _P_NOWAIT 1 -# define _P_OVERLAY 2 -# define _P_NOWAITO 3 -# define _P_DETACH 4 - -# define WAIT_CHILD 0 -# define WAIT_GRANDCHILD 1 -#endif - -#define MINGW_NAME "Minimalist GNU for Windows" -#define MINGW_NAME_LEN (sizeof(MINGW_NAME) - 1) - -extern char *stpcpy (char *dst, const char *src); - -/* Ensure that the executable pathname uses Win32 backslashes. This - is not necessary on NT, but on W9x, forward slashes causes - failure of spawn* and exec* functions (and probably any function - that calls CreateProcess) *iff* the executable pathname (argv[0]) - is a quoted string. And quoting is necessary in case a pathname - contains embedded white space. You can't win. */ -static void -backslashify (char *s) -{ - while ((s = strchr (s, '/')) != NULL) - *s = '\\'; - return; -} - -static int pex_win32_open_read (struct pex_obj *, const char *, int); -static int pex_win32_open_write (struct pex_obj *, const char *, int); -static pid_t pex_win32_exec_child (struct pex_obj *, int, const char *, - char * const *, char * const *, - int, int, int, int, - const char **, int *); -static int pex_win32_close (struct pex_obj *, int); -static pid_t pex_win32_wait (struct pex_obj *, pid_t, int *, - struct pex_time *, int, const char **, int *); -static int pex_win32_pipe (struct pex_obj *, int *, int); -static FILE *pex_win32_fdopenr (struct pex_obj *, int, int); -static FILE *pex_win32_fdopenw (struct pex_obj *, int, int); - -/* The list of functions we pass to the common routines. */ - -const struct pex_funcs funcs = -{ - pex_win32_open_read, - pex_win32_open_write, - pex_win32_exec_child, - pex_win32_close, - pex_win32_wait, - pex_win32_pipe, - pex_win32_fdopenr, - pex_win32_fdopenw, - NULL /* cleanup */ -}; - -/* Return a newly initialized pex_obj structure. */ - -struct pex_obj * -pex_init (int flags, const char *pname, const char *tempbase) -{ - return pex_init_common (flags, pname, tempbase, &funcs); -} - -/* Open a file for reading. */ - -static int -pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, - int binary) -{ - return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT)); -} - -/* Open a file for writing. */ - -static int -pex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, - int binary) -{ - /* Note that we can't use O_EXCL here because gcc may have already - created the temporary file via make_temp_file. */ - return _open (name, - (_O_WRONLY | _O_CREAT | _O_TRUNC - | (binary ? _O_BINARY : _O_TEXT)), - _S_IREAD | _S_IWRITE); -} - -/* Close a file. */ - -static int -pex_win32_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) -{ - return _close (fd); -} - -#ifdef USE_MINGW_MSYS -static const char *mingw_keys[] = {"SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall", NULL}; - -/* Tack the executable on the end of a (possibly slash terminated) buffer - and convert everything to \. */ -static const char * -tack_on_executable (char *buf, const char *executable) -{ - char *p = strchr (buf, '\0'); - if (p > buf && (p[-1] == '\\' || p[-1] == '/')) - p[-1] = '\0'; - backslashify (strcat (buf, executable)); - return buf; -} - -/* Walk down a registry hierarchy until the end. Return the key. */ -static HKEY -openkey (HKEY hStart, const char *keys[]) -{ - HKEY hKey, hTmp; - for (hKey = hStart; *keys; keys++) - { - LONG res; - hTmp = hKey; - res = RegOpenKey (hTmp, *keys, &hKey); - - if (hTmp != HKEY_LOCAL_MACHINE) - RegCloseKey (hTmp); - - if (res != ERROR_SUCCESS) - return NULL; - } - return hKey; -} - -/* Return the "mingw root" as derived from the mingw uninstall information. */ -static const char * -mingw_rootify (const char *executable) -{ - HKEY hKey, hTmp; - DWORD maxlen; - char *namebuf, *foundbuf; - DWORD i; - LONG res; - - /* Open the uninstall "directory". */ - hKey = openkey (HKEY_LOCAL_MACHINE, mingw_keys); - - /* Not found. */ - if (!hKey) - return executable; - - /* Need to enumerate all of the keys here looking for one the most recent - one for MinGW. */ - if (RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, &maxlen, NULL, NULL, - NULL, NULL, NULL, NULL) != ERROR_SUCCESS) - { - RegCloseKey (hKey); - return executable; - } - namebuf = XNEWVEC (char, ++maxlen); - foundbuf = XNEWVEC (char, maxlen); - foundbuf[0] = '\0'; - if (!namebuf || !foundbuf) - { - RegCloseKey (hKey); - free (namebuf); - free (foundbuf); - return executable; - } - - /* Look through all of the keys for one that begins with Minimal GNU... - Try to get the latest version by doing a string compare although that - string never really works with version number sorting. */ - for (i = 0; RegEnumKey (hKey, i, namebuf, maxlen) == ERROR_SUCCESS; i++) - { - int match = strcasecmp (namebuf, MINGW_NAME); - if (match < 0) - continue; - if (match > 0 && strncasecmp (namebuf, MINGW_NAME, MINGW_NAME_LEN) > 0) - continue; - if (strcasecmp (namebuf, foundbuf) > 0) - strcpy (foundbuf, namebuf); - } - free (namebuf); - - /* If foundbuf is empty, we didn't find anything. Punt. */ - if (!foundbuf[0]) - { - free (foundbuf); - RegCloseKey (hKey); - return executable; - } - - /* Open the key that we wanted */ - res = RegOpenKey (hKey, foundbuf, &hTmp); - RegCloseKey (hKey); - free (foundbuf); - - /* Don't know why this would fail, but you gotta check */ - if (res != ERROR_SUCCESS) - return executable; - - maxlen = 0; - /* Get the length of the value pointed to by InstallLocation */ - if (RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, NULL, - &maxlen) != ERROR_SUCCESS || maxlen == 0) - { - RegCloseKey (hTmp); - return executable; - } - - /* Allocate space for the install location */ - foundbuf = XNEWVEC (char, maxlen + strlen (executable)); - if (!foundbuf) - { - free (foundbuf); - RegCloseKey (hTmp); - } - - /* Read the install location into the buffer */ - res = RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, (LPBYTE) foundbuf, - &maxlen); - RegCloseKey (hTmp); - if (res != ERROR_SUCCESS) - { - free (foundbuf); - return executable; - } - - /* Concatenate the install location and the executable, turn all slashes - to backslashes, and return that. */ - return tack_on_executable (foundbuf, executable); -} - -/* Read the install location of msys from it's installation file and - rootify the executable based on that. */ -static const char * -msys_rootify (const char *executable) -{ - size_t bufsize = 64; - size_t execlen = strlen (executable) + 1; - char *buf; - DWORD res = 0; - for (;;) - { - buf = XNEWVEC (char, bufsize + execlen); - if (!buf) - break; - res = GetPrivateProfileString ("InstallSettings", "InstallPath", NULL, - buf, bufsize, "msys.ini"); - if (!res) - break; - if (strlen (buf) < bufsize) - break; - res = 0; - free (buf); - bufsize *= 2; - if (bufsize > 65536) - { - buf = NULL; - break; - } - } - - if (res) - return tack_on_executable (buf, executable); - - /* failed */ - free (buf); - return executable; -} -#endif - -/* Return the number of arguments in an argv array, not including the null - terminating argument. */ - -static int -argv_to_argc (char *const *argv) -{ - char *const *i = argv; - while (*i) - i++; - return i - argv; -} - -/* Return a Windows command-line from ARGV. It is the caller's - responsibility to free the string returned. */ - -static char * -argv_to_cmdline (char *const *argv) -{ - char *cmdline; - char *p; - size_t cmdline_len; - int i, j, k; - - cmdline_len = 0; - for (i = 0; argv[i]; i++) - { - /* We quote every last argument. This simplifies the problem; - we need only escape embedded double-quotes and immediately - preceeding backslash characters. A sequence of backslach characters - that is not follwed by a double quote character will not be - escaped. */ - for (j = 0; argv[i][j]; j++) - { - if (argv[i][j] == '"') - { - /* Escape preceeding backslashes. */ - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - cmdline_len++; - /* Escape the qote character. */ - cmdline_len++; - } - } - /* Trailing backslashes also need to be escaped because they will be - followed by the terminating quote. */ - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - cmdline_len++; - cmdline_len += j; - cmdline_len += 3; /* for leading and trailing quotes and space */ - } - cmdline = XNEWVEC (char, cmdline_len); - p = cmdline; - for (i = 0; argv[i]; i++) - { - *p++ = '"'; - for (j = 0; argv[i][j]; j++) - { - if (argv[i][j] == '"') - { - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - *p++ = '\\'; - *p++ = '\\'; - } - *p++ = argv[i][j]; - } - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - *p++ = '\\'; - *p++ = '"'; - *p++ = ' '; - } - p[-1] = '\0'; - return cmdline; -} - -/* We'll try the passed filename with all the known standard - extensions, and then without extension. We try no extension - last so that we don't try to run some random extension-less - file that might be hanging around. We try both extension - and no extension so that we don't need any fancy logic - to determine if a file has extension. */ -static const char *const -std_suffixes[] = { - ".com", - ".exe", - ".bat", - ".cmd", - "", - 0 -}; - -/* Returns the full path to PROGRAM. If SEARCH is true, look for - PROGRAM in each directory in PATH. */ - -static char * -find_executable (const char *program, BOOL search) -{ - char *full_executable; - char *e; - size_t fe_len; - const char *path = 0; - const char *const *ext; - const char *p, *q; - size_t proglen = strlen (program); - int has_slash = (strchr (program, '/') || strchr (program, '\\')); - HANDLE h; - - if (has_slash) - search = FALSE; - - if (search) - path = getenv ("PATH"); - if (!path) - path = ""; - - fe_len = 0; - for (p = path; *p; p = q) - { - q = p; - while (*q != ';' && *q != '\0') - q++; - if ((size_t)(q - p) > fe_len) - fe_len = q - p; - if (*q == ';') - q++; - } - fe_len = fe_len + 1 + proglen + 5 /* space for extension */; - full_executable = XNEWVEC (char, fe_len); - - p = path; - do - { - q = p; - while (*q != ';' && *q != '\0') - q++; - - e = full_executable; - memcpy (e, p, q - p); - e += (q - p); - if (q - p) - *e++ = '\\'; - strcpy (e, program); - - if (*q == ';') - q++; - - for (e = full_executable; *e; e++) - if (*e == '/') - *e = '\\'; - - /* At this point, e points to the terminating NUL character for - full_executable. */ - for (ext = std_suffixes; *ext; ext++) - { - /* Remove any current extension. */ - *e = '\0'; - /* Add the new one. */ - strcat (full_executable, *ext); - - /* Attempt to open this file. */ - h = CreateFile (full_executable, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (h != INVALID_HANDLE_VALUE) - goto found; - } - p = q; - } - while (*p); - free (full_executable); - return 0; - - found: - CloseHandle (h); - return full_executable; -} - -/* Low-level process creation function and helper. */ - -static int -env_compare (const void *a_ptr, const void *b_ptr) -{ - const char *a; - const char *b; - unsigned char c1; - unsigned char c2; - - a = *(const char **) a_ptr; - b = *(const char **) b_ptr; - - /* a and b will be of the form: VAR=VALUE - We compare only the variable name part here using a case-insensitive - comparison algorithm. It might appear that in fact strcasecmp () can - take the place of this whole function, and indeed it could, save for - the fact that it would fail in cases such as comparing A1=foo and - A=bar (because 1 is less than = in the ASCII character set). - (Environment variables containing no numbers would work in such a - scenario.) */ - - do - { - c1 = (unsigned char) tolower (*a++); - c2 = (unsigned char) tolower (*b++); - - if (c1 == '=') - c1 = '\0'; - - if (c2 == '=') - c2 = '\0'; - } - while (c1 == c2 && c1 != '\0'); - - return c1 - c2; -} - -/* Execute a Windows executable as a child process. This will fail if the - * target is not actually an executable, such as if it is a shell script. */ - -static pid_t -win32_spawn (const char *executable, - BOOL search, - char *const *argv, - char *const *env, /* array of strings of the form: VAR=VALUE */ - DWORD dwCreationFlags, - LPSTARTUPINFO si, - LPPROCESS_INFORMATION pi) -{ - char *full_executable; - char *cmdline; - char **env_copy; - char *env_block = NULL; - - full_executable = NULL; - cmdline = NULL; - - if (env) - { - int env_size; - - /* Count the number of environment bindings supplied. */ - for (env_size = 0; env[env_size]; env_size++) - continue; - - /* Assemble an environment block, if required. This consists of - VAR=VALUE strings juxtaposed (with one null character between each - pair) and an additional null at the end. */ - if (env_size > 0) - { - int var; - int total_size = 1; /* 1 is for the final null. */ - char *bufptr; - - /* Windows needs the members of the block to be sorted by variable - name. */ - env_copy = (char **) alloca (sizeof (char *) * env_size); - memcpy (env_copy, env, sizeof (char *) * env_size); - qsort (env_copy, env_size, sizeof (char *), env_compare); - - for (var = 0; var < env_size; var++) - total_size += strlen (env[var]) + 1; - - env_block = XNEWVEC (char, total_size); - bufptr = env_block; - for (var = 0; var < env_size; var++) - bufptr = stpcpy (bufptr, env_copy[var]) + 1; - - *bufptr = '\0'; - } - } - - full_executable = find_executable (executable, search); - if (!full_executable) - goto error; - cmdline = argv_to_cmdline (argv); - if (!cmdline) - goto error; - - /* Create the child process. */ - if (!CreateProcess (full_executable, cmdline, - /*lpProcessAttributes=*/NULL, - /*lpThreadAttributes=*/NULL, - /*bInheritHandles=*/TRUE, - dwCreationFlags, - (LPVOID) env_block, - /*lpCurrentDirectory=*/NULL, - si, - pi)) - { - free (env_block); - - free (full_executable); - - return (pid_t) -1; - } - - /* Clean up. */ - CloseHandle (pi->hThread); - free (full_executable); - free (env_block); - - return (pid_t) pi->hProcess; - - error: - free (env_block); - free (cmdline); - free (full_executable); - - return (pid_t) -1; -} - -/* Spawn a script. This simulates the Unix script execution mechanism. - This function is called as a fallback if win32_spawn fails. */ - -static pid_t -spawn_script (const char *executable, char *const *argv, - char* const *env, - DWORD dwCreationFlags, - LPSTARTUPINFO si, - LPPROCESS_INFORMATION pi) -{ - pid_t pid = (pid_t) -1; - int save_errno = errno; - int fd = _open (executable, _O_RDONLY); - - /* Try to open script, check header format, extract interpreter path, - and spawn script using that interpretter. */ - if (fd >= 0) - { - char buf[MAX_PATH + 5]; - int len = _read (fd, buf, sizeof (buf) - 1); - _close (fd); - if (len > 3) - { - char *eol; - buf[len] = '\0'; - eol = strchr (buf, '\n'); - if (eol && strncmp (buf, "#!", 2) == 0) - { - - /* Header format is OK. */ - char *executable1; - int new_argc; - const char **avhere; - - /* Extract interpreter path. */ - do - *eol = '\0'; - while (*--eol == '\r' || *eol == ' ' || *eol == '\t'); - for (executable1 = buf + 2; *executable1 == ' ' || *executable1 == '\t'; executable1++) - continue; - backslashify (executable1); - - /* Duplicate argv, prepending the interpreter path. */ - new_argc = argv_to_argc (argv) + 1; - avhere = XNEWVEC (const char *, new_argc + 1); - *avhere = executable1; - memcpy (avhere + 1, argv, new_argc * sizeof(*argv)); - argv = (char *const *)avhere; - - /* Spawn the child. */ -#ifndef USE_MINGW_MSYS - executable = strrchr (executable1, '\\') + 1; - if (!executable) - executable = executable1; - pid = win32_spawn (executable, TRUE, argv, env, - dwCreationFlags, si, pi); -#else - if (strchr (executable1, '\\') == NULL) - pid = win32_spawn (executable1, TRUE, argv, env, - dwCreationFlags, si, pi); - else if (executable1[0] != '\\') - pid = win32_spawn (executable1, FALSE, argv, env, - dwCreationFlags, si, pi); - else - { - const char *newex = mingw_rootify (executable1); - *avhere = newex; - pid = win32_spawn (newex, FALSE, argv, env, - dwCreationFlags, si, pi); - if (executable1 != newex) - free ((char *) newex); - if (pid == (pid_t) -1) - { - newex = msys_rootify (executable1); - if (newex != executable1) - { - *avhere = newex; - pid = win32_spawn (newex, FALSE, argv, env, - dwCreationFlags, si, pi); - free ((char *) newex); - } - } - } -#endif - free (avhere); - } - } - } - if (pid == (pid_t) -1) - errno = save_errno; - return pid; -} - -/* Execute a child. */ - -static pid_t -pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags, - const char *executable, char * const * argv, - char* const* env, - int in, int out, int errdes, - int toclose ATTRIBUTE_UNUSED, - const char **errmsg, - int *err) -{ - pid_t pid; - HANDLE stdin_handle; - HANDLE stdout_handle; - HANDLE stderr_handle; - DWORD dwCreationFlags; - OSVERSIONINFO version_info; - STARTUPINFO si; - PROCESS_INFORMATION pi; - int orig_out, orig_in, orig_err; - BOOL separate_stderr = !(flags & PEX_STDERR_TO_STDOUT); - - /* Ensure we have inheritable descriptors to pass to the child, and close the - original descriptors. */ - orig_in = in; - in = _dup (orig_in); - if (orig_in != STDIN_FILENO) - _close (orig_in); - - orig_out = out; - out = _dup (orig_out); - if (orig_out != STDOUT_FILENO) - _close (orig_out); - - if (separate_stderr) - { - orig_err = errdes; - errdes = _dup (orig_err); - if (orig_err != STDERR_FILENO) - _close (orig_err); - } - - stdin_handle = INVALID_HANDLE_VALUE; - stdout_handle = INVALID_HANDLE_VALUE; - stderr_handle = INVALID_HANDLE_VALUE; - - stdin_handle = (HANDLE) _get_osfhandle (in); - stdout_handle = (HANDLE) _get_osfhandle (out); - if (separate_stderr) - stderr_handle = (HANDLE) _get_osfhandle (errdes); - else - stderr_handle = stdout_handle; - - /* Determine the version of Windows we are running on. */ - version_info.dwOSVersionInfoSize = sizeof (version_info); - GetVersionEx (&version_info); - if (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) - /* On Windows 95/98/ME the CREATE_NO_WINDOW flag is not - supported, so we cannot avoid creating a console window. */ - dwCreationFlags = 0; - else - { - HANDLE conout_handle; - - /* Determine whether or not we have an associated console. */ - conout_handle = CreateFile("CONOUT$", - GENERIC_WRITE, - FILE_SHARE_WRITE, - /*lpSecurityAttributes=*/NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - /*hTemplateFile=*/NULL); - if (conout_handle == INVALID_HANDLE_VALUE) - /* There is no console associated with this process. Since - the child is a console process, the OS would normally - create a new console Window for the child. Since we'll be - redirecting the child's standard streams, we do not need - the console window. */ - dwCreationFlags = CREATE_NO_WINDOW; - else - { - /* There is a console associated with the process, so the OS - will not create a new console. And, if we use - CREATE_NO_WINDOW in this situation, the child will have - no associated console. Therefore, if the child's - standard streams are connected to the console, the output - will be discarded. */ - CloseHandle(conout_handle); - dwCreationFlags = 0; - } - } - - /* Since the child will be a console process, it will, by default, - connect standard input/output to its console. However, we want - the child to use the handles specifically designated above. In - addition, if there is no console (such as when we are running in - a Cygwin X window), then we must redirect the child's - input/output, as there is no console for the child to use. */ - memset (&si, 0, sizeof (si)); - si.cb = sizeof (si); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = stdin_handle; - si.hStdOutput = stdout_handle; - si.hStdError = stderr_handle; - - /* Create the child process. */ - pid = win32_spawn (executable, (flags & PEX_SEARCH) != 0, - argv, env, dwCreationFlags, &si, &pi); - if (pid == (pid_t) -1) - pid = spawn_script (executable, argv, env, dwCreationFlags, - &si, &pi); - if (pid == (pid_t) -1) - { - *err = ENOENT; - *errmsg = "CreateProcess"; - } - - /* Close the standard input, standard output and standard error handles - in the parent. */ - - _close (in); - _close (out); - if (separate_stderr) - _close (errdes); - - return pid; -} - -/* Wait for a child process to complete. MS CRTDLL doesn't return - enough information in status to decide if the child exited due to a - signal or not, rather it simply returns an integer with the exit - code of the child; eg., if the child exited with an abort() call - and didn't have a handler for SIGABRT, it simply returns with - status == 3. We fix the status code to conform to the usual WIF* - macros. Note that WIFSIGNALED will never be true under CRTDLL. */ - -static pid_t -pex_win32_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, - int *status, struct pex_time *time, int done ATTRIBUTE_UNUSED, - const char **errmsg, int *err) -{ - DWORD termstat; - HANDLE h; - - if (time != NULL) - memset (time, 0, sizeof *time); - - h = (HANDLE) pid; - - /* FIXME: If done is non-zero, we should probably try to kill the - process. */ - if (WaitForSingleObject (h, INFINITE) != WAIT_OBJECT_0) - { - CloseHandle (h); - *err = ECHILD; - *errmsg = "WaitForSingleObject"; - return -1; - } - - GetExitCodeProcess (h, &termstat); - CloseHandle (h); - - /* A value of 3 indicates that the child caught a signal, but not - which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we - report SIGABRT. */ - if (termstat == 3) - *status = SIGABRT; - else - *status = (termstat & 0xff) << 8; - - return 0; -} - -/* Create a pipe. */ - -static int -pex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, - int binary) -{ - return _pipe (p, 256, (binary ? _O_BINARY : _O_TEXT) | _O_NOINHERIT); -} - -/* Get a FILE pointer to read from a file descriptor. */ - -static FILE * -pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, - int binary) -{ - HANDLE h = (HANDLE) _get_osfhandle (fd); - if (h == INVALID_HANDLE_VALUE) - return NULL; - if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0)) - return NULL; - return fdopen (fd, binary ? "rb" : "r"); -} - -static FILE * -pex_win32_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, - int binary) -{ - HANDLE h = (HANDLE) _get_osfhandle (fd); - if (h == INVALID_HANDLE_VALUE) - return NULL; - if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0)) - return NULL; - return fdopen (fd, binary ? "wb" : "w"); -} - -#ifdef MAIN -#include - -int -main (int argc ATTRIBUTE_UNUSED, char **argv) -{ - char const *errmsg; - int err; - argv++; - printf ("%ld\n", (long) pex_win32_exec_child (NULL, PEX_SEARCH, argv[0], argv, NULL, 0, 0, 1, 2, &errmsg, &err)); - exit (0); -} -#endif diff --git a/linkers/libiberty/safe-ctype.c b/linkers/libiberty/safe-ctype.c deleted file mode 100644 index 0972b4b..0000000 --- a/linkers/libiberty/safe-ctype.c +++ /dev/null @@ -1,255 +0,0 @@ -/* replacement macros. - - Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005 Free Software Foundation, Inc. - Contributed by Zack Weinberg . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -/* - -@defvr Extension HOST_CHARSET -This macro indicates the basic character set and encoding used by the -host: more precisely, the encoding used for character constants in -preprocessor @samp{#if} statements (the C "execution character set"). -It is defined by @file{safe-ctype.h}, and will be an integer constant -with one of the following values: - -@ftable @code -@item HOST_CHARSET_UNKNOWN -The host character set is unknown - that is, not one of the next two -possibilities. - -@item HOST_CHARSET_ASCII -The host character set is ASCII. - -@item HOST_CHARSET_EBCDIC -The host character set is some variant of EBCDIC. (Only one of the -nineteen EBCDIC varying characters is tested; exercise caution.) -@end ftable -@end defvr - -@deffn Extension ISALPHA (@var{c}) -@deffnx Extension ISALNUM (@var{c}) -@deffnx Extension ISBLANK (@var{c}) -@deffnx Extension ISCNTRL (@var{c}) -@deffnx Extension ISDIGIT (@var{c}) -@deffnx Extension ISGRAPH (@var{c}) -@deffnx Extension ISLOWER (@var{c}) -@deffnx Extension ISPRINT (@var{c}) -@deffnx Extension ISPUNCT (@var{c}) -@deffnx Extension ISSPACE (@var{c}) -@deffnx Extension ISUPPER (@var{c}) -@deffnx Extension ISXDIGIT (@var{c}) - -These twelve macros are defined by @file{safe-ctype.h}. Each has the -same meaning as the corresponding macro (with name in lowercase) -defined by the standard header @file{ctype.h}. For example, -@code{ISALPHA} returns true for alphabetic characters and false for -others. However, there are two differences between these macros and -those provided by @file{ctype.h}: - -@itemize @bullet -@item These macros are guaranteed to have well-defined behavior for all -values representable by @code{signed char} and @code{unsigned char}, and -for @code{EOF}. - -@item These macros ignore the current locale; they are true for these -fixed sets of characters: -@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada} -@item @code{ALPHA} @tab @kbd{A-Za-z} -@item @code{ALNUM} @tab @kbd{A-Za-z0-9} -@item @code{BLANK} @tab @kbd{space tab} -@item @code{CNTRL} @tab @code{!PRINT} -@item @code{DIGIT} @tab @kbd{0-9} -@item @code{GRAPH} @tab @code{ALNUM || PUNCT} -@item @code{LOWER} @tab @kbd{a-z} -@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space} -@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?} -@item @code{SPACE} @tab @kbd{space tab \n \r \f \v} -@item @code{UPPER} @tab @kbd{A-Z} -@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f} -@end multitable - -Note that, if the host character set is ASCII or a superset thereof, -all these macros will return false for all values of @code{char} outside -the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return -false for characters with numeric values from 128 to 255. -@end itemize -@end deffn - -@deffn Extension ISIDNUM (@var{c}) -@deffnx Extension ISIDST (@var{c}) -@deffnx Extension IS_VSPACE (@var{c}) -@deffnx Extension IS_NVSPACE (@var{c}) -@deffnx Extension IS_SPACE_OR_NUL (@var{c}) -@deffnx Extension IS_ISOBASIC (@var{c}) -These six macros are defined by @file{safe-ctype.h} and provide -additional character classes which are useful when doing lexical -analysis of C or similar languages. They are true for the following -sets of characters: - -@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada} -@item @code{IDNUM} @tab @kbd{A-Za-z0-9_} -@item @code{IDST} @tab @kbd{A-Za-z_} -@item @code{VSPACE} @tab @kbd{\r \n} -@item @code{NVSPACE} @tab @kbd{space tab \f \v \0} -@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE} -@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT} -@end multitable -@end deffn - -*/ - -#include "ansidecl.h" -#include -#include /* for EOF */ - -#if EOF != -1 - #error " requires EOF == -1" -#endif - -/* Shorthand */ -#define bl _sch_isblank -#define cn _sch_iscntrl -#define di _sch_isdigit -#define is _sch_isidst -#define lo _sch_islower -#define nv _sch_isnvsp -#define pn _sch_ispunct -#define pr _sch_isprint -#define sp _sch_isspace -#define up _sch_isupper -#define vs _sch_isvsp -#define xd _sch_isxdigit - -/* Masks. */ -#define L (const unsigned short) (lo|is |pr) /* lower case letter */ -#define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */ -#define U (const unsigned short) (up|is |pr) /* upper case letter */ -#define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */ -#define D (const unsigned short) (di |xd|pr) /* decimal digit */ -#define P (const unsigned short) (pn |pr) /* punctuation */ -#define _ (const unsigned short) (pn|is |pr) /* underscore */ - -#define C (const unsigned short) ( cn) /* control character */ -#define Z (const unsigned short) (nv |cn) /* NUL */ -#define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */ -#define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */ -#define T (const unsigned short) (nv|sp|bl|cn) /* tab */ -#define S (const unsigned short) (nv|sp|bl|pr) /* space */ - -/* Are we ASCII? */ -#if HOST_CHARSET == HOST_CHARSET_ASCII - -const unsigned short _sch_istable[256] = -{ - Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */ - C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */ - C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ - C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */ - S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */ - P, P, P, P, P, P, P, P, /* ( ) * + , - . / */ - D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */ - D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */ - P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */ - U, U, U, U, U, U, U, U, /* H I J K L M N O */ - U, U, U, U, U, U, U, U, /* P Q R S T U V W */ - U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */ - P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */ - L, L, L, L, L, L, L, L, /* h i j k l m n o */ - L, L, L, L, L, L, L, L, /* p q r s t u v w */ - L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */ - - /* high half of unsigned char is locale-specific, so all tests are - false in "C" locale */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const unsigned char _sch_tolower[256] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, - - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - - 91, 92, 93, 94, 95, 96, - - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - - 123,124,125,126,127, - - 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, - 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, - 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, - 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, - - 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, - 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, - 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, - 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, -}; - -const unsigned char _sch_toupper[256] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, - - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - - 91, 92, 93, 94, 95, 96, - - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - - 123,124,125,126,127, - - 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, - 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, - 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, - 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, - - 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, - 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, - 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, - 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, -}; - -#else -# if HOST_CHARSET == HOST_CHARSET_EBCDIC - #error "FIXME: write tables for EBCDIC" -# else - #error "Unrecognized host character set" -# endif -#endif diff --git a/linkers/libiberty/safe-ctype.h b/linkers/libiberty/safe-ctype.h deleted file mode 100644 index 0266bf1..0000000 --- a/linkers/libiberty/safe-ctype.h +++ /dev/null @@ -1,150 +0,0 @@ -/* replacement macros. - - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Contributed by Zack Weinberg . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -/* This is a compatible replacement of the standard C library's - with the following properties: - - - Implements all isxxx() macros required by C99. - - Also implements some character classes useful when - parsing C-like languages. - - Does not change behavior depending on the current locale. - - Behaves properly for all values in the range of a signed or - unsigned char. - - To avoid conflicts, this header defines the isxxx functions in upper - case, e.g. ISALPHA not isalpha. */ - -#ifndef SAFE_CTYPE_H -#define SAFE_CTYPE_H - -/* Determine host character set. */ -#define HOST_CHARSET_UNKNOWN 0 -#define HOST_CHARSET_ASCII 1 -#define HOST_CHARSET_EBCDIC 2 - -#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ - && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 -# define HOST_CHARSET HOST_CHARSET_ASCII -#else -# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ - && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A -# define HOST_CHARSET HOST_CHARSET_EBCDIC -# else -# define HOST_CHARSET HOST_CHARSET_UNKNOWN -# endif -#endif - -/* Categories. */ - -enum { - /* In C99 */ - _sch_isblank = 0x0001, /* space \t */ - _sch_iscntrl = 0x0002, /* nonprinting characters */ - _sch_isdigit = 0x0004, /* 0-9 */ - _sch_islower = 0x0008, /* a-z */ - _sch_isprint = 0x0010, /* any printing character including ' ' */ - _sch_ispunct = 0x0020, /* all punctuation */ - _sch_isspace = 0x0040, /* space \t \n \r \f \v */ - _sch_isupper = 0x0080, /* A-Z */ - _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */ - - /* Extra categories useful to cpplib. */ - _sch_isidst = 0x0200, /* A-Za-z_ */ - _sch_isvsp = 0x0400, /* \n \r */ - _sch_isnvsp = 0x0800, /* space \t \f \v \0 */ - - /* Combinations of the above. */ - _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */ - _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */ - _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */ - _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */ - _sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */ - _sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C - (plus ` and @) */ -}; - -/* Character classification. */ -extern const unsigned short _sch_istable[256]; - -#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit)) - -#define ISALPHA(c) _sch_test(c, _sch_isalpha) -#define ISALNUM(c) _sch_test(c, _sch_isalnum) -#define ISBLANK(c) _sch_test(c, _sch_isblank) -#define ISCNTRL(c) _sch_test(c, _sch_iscntrl) -#define ISDIGIT(c) _sch_test(c, _sch_isdigit) -#define ISGRAPH(c) _sch_test(c, _sch_isgraph) -#define ISLOWER(c) _sch_test(c, _sch_islower) -#define ISPRINT(c) _sch_test(c, _sch_isprint) -#define ISPUNCT(c) _sch_test(c, _sch_ispunct) -#define ISSPACE(c) _sch_test(c, _sch_isspace) -#define ISUPPER(c) _sch_test(c, _sch_isupper) -#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit) - -#define ISIDNUM(c) _sch_test(c, _sch_isidnum) -#define ISIDST(c) _sch_test(c, _sch_isidst) -#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic) -#define IS_VSPACE(c) _sch_test(c, _sch_isvsp) -#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp) -#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp) - -/* Character transformation. */ -extern const unsigned char _sch_toupper[256]; -extern const unsigned char _sch_tolower[256]; -#define TOUPPER(c) _sch_toupper[(c) & 0xff] -#define TOLOWER(c) _sch_tolower[(c) & 0xff] - -/* Prevent the users of safe-ctype.h from accidently using the routines - from ctype.h. Initially, the approach was to produce an error when - detecting that ctype.h has been included. But this was causing - trouble as ctype.h might get indirectly included as a result of - including another system header (for instance gnulib's stdint.h). - So we include ctype.h here and then immediately redefine its macros. */ - -#include -#undef isalpha -#define isalpha(c) do_not_use_isalpha_with_safe_ctype -#undef isalnum -#define isalnum(c) do_not_use_isalnum_with_safe_ctype -#undef iscntrl -#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype -#undef isdigit -#define isdigit(c) do_not_use_isdigit_with_safe_ctype -#undef isgraph -#define isgraph(c) do_not_use_isgraph_with_safe_ctype -#undef islower -#define islower(c) do_not_use_islower_with_safe_ctype -#undef isprint -#define isprint(c) do_not_use_isprint_with_safe_ctype -#undef ispunct -#define ispunct(c) do_not_use_ispunct_with_safe_ctype -#undef isspace -#define isspace(c) do_not_use_isspace_with_safe_ctype -#undef isupper -#define isupper(c) do_not_use_isupper_with_safe_ctype -#undef isxdigit -#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype -#undef toupper -#define toupper(c) do_not_use_toupper_with_safe_ctype -#undef tolower -#define tolower(c) do_not_use_tolower_with_safe_ctype - -#endif /* SAFE_CTYPE_H */ diff --git a/linkers/libiberty/stpcpy.c b/linkers/libiberty/stpcpy.c deleted file mode 100644 index 57b32d1..0000000 --- a/linkers/libiberty/stpcpy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Implement the stpcpy function. - Copyright (C) 2003 Free Software Foundation, Inc. - Written by Kaveh R. Ghazi . - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -/* - -@deftypefn Supplemental char* stpcpy (char *@var{dst}, const char *@var{src}) - -Copies the string @var{src} into @var{dst}. Returns a pointer to -@var{dst} + strlen(@var{src}). - -@end deftypefn - -*/ - -#include -#include - -extern size_t strlen (const char *); -extern PTR memcpy (PTR, const PTR, size_t); - -char * -stpcpy (char *dst, const char *src) -{ - const size_t len = strlen (src); - return (char *) memcpy (dst, src, len + 1) + len; -} diff --git a/linkers/pkgconfig.cpp b/linkers/pkgconfig.cpp deleted file mode 100644 index 74edf59..0000000 --- a/linkers/pkgconfig.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include -#include - -namespace pkgconfig -{ - package::package (const std::string& name) - { - load (name); - } - - package::package () - { - } - - void - package::load (const std::string& name) - { - std::ifstream in (name.c_str (), std::ios::in); - - while (!in.eof ()) - { - char buffer[1024]; - - in.getline (buffer, sizeof (buffer)); - - std::string line (buffer); - size_t hash; - - hash = line.find ('#'); - if (hash != std::string::npos) - line.erase(hash); - - if (line.size () > 0) - { - size_t eq = line.find_first_of ('='); - size_t dd = line.find_first_of (':'); - - size_t d = std::string::npos; - bool def = false; - - if ((eq != std::string::npos) && (dd != std::string::npos)) - { - if (eq < dd) - { - d = eq; - def = true; - } - else - { - d = dd; - def = false; - } - } - else if (eq != std::string::npos) - { - d = eq; - def = true; - } - else if (dd != std::string::npos) - { - d = dd; - def = false; - } - - if (d != std::string::npos) - { - std::string lhs = rld::tolower (line.substr (0, d)); - std::string rhs = line.substr (d + 1); - if (def) - defines[lhs] = rhs; - else - fields[lhs] = rhs; - } - } - } - - in.close (); - } - - bool - package::get (const std::string& label, std::string& result) - { - result.erase (); - - std::string ll = rld::tolower (label); - table::iterator ti = fields.find (ll); - - if (ti == fields.end ()) - return false; - - /* - * Take a copy so we can expand the macros in it. - */ - std::string s = ti->second; - - /* - * Loop until there is nothing more to expand. - */ - bool expanded = true; - while (expanded) - { - /* - * Need to perform a regular expression search for '\$\{[^\}]+\}'. This - * means look for every '${' then accept any character that is not a '}' - * and finish with a '}'. - */ - expanded = false; - size_t p = 0; - while (p < s.length ()) - { - /* - * Find the start and end of the label. - */ - size_t ms = s.find ("${", p); - if (ms != std::string::npos) - { - size_t me = s.find ('}', ms); - if (me != std::string::npos) - { - std::string ml = rld::tolower(s.substr (ms + 2, me - ms - 2)); - table::iterator di = defines.find (ml); - if (di != defines.end ()) - { - s = rld::find_replace (s, s.substr (ms, me - ms + 1), di->second); - expanded = true; - } - p = me + 1; - } - else - { - p = ms + 2; - } - } - else - { - p = s.length (); - } - } - } - - result = rld::trim (s); - - return true; - } -} diff --git a/linkers/pkgconfig.h b/linkers/pkgconfig.h deleted file mode 100644 index 57b1c3b..0000000 --- a/linkers/pkgconfig.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if !defined (_PKGCONFIG_H_) -#define _PKGCONFIG_H_ - -#include -#include - -namespace pkgconfig -{ - /** - * A simple class to parse a pkgconfig file as used in RTEMS. The RTEMS use - * is simple and basically provides a simplified method to manage the various - * flags used to build and link modules for a specific BSP. - */ - class package - { - public: - /** - * The type of defines and fields parsed from a package config file. - */ - typedef std::map < std::string, std::string > table; - - /** - * Constructor and load the file. - */ - package (const std::string& name); - - /** - * Default constructor. - */ - package (); - - /** - * Load a package configuration file. - * - * @param name The file name of the package. - */ - void load (const std::string& name); - - /** - * Get a field from the package. - * - * @param label The label to search for. - * @param result The result of the search. - * @retval true The field was found. - * @retval false The field was not found. - */ - bool get (const std::string& label, std::string& result); - - private: - table defines; ///< The defines. - table fields; ///< The fields. - }; - -} - -#endif diff --git a/linkers/rld-cc.cpp b/linkers/rld-cc.cpp deleted file mode 100644 index a2b1be4..0000000 --- a/linkers/rld-cc.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include - -#include -#include -#include -#include - -namespace rld -{ - namespace cc - { - static std::string cc; //< The CC executable as absolute path. - static bool cc_set; //< True when the CC has been set. - static std::string cc_name = "gcc"; //< The CC name, ie gcc, clang. - - static std::string ld; //< The LD executable as absolute path. - static bool ld_set; //< True when the LD has been set. - static std::string ld_name = "gcc"; //< The LD name, ie gcc, clang. - - static std::string exec_prefix; //< The CC/LD executable prefix. - - static std::string cppflags; //< The CPP flags. - static std::string cflags; //< The CC flags. - static std::string cxxflags; //< The CXX flags. - static std::string ldflags; //< The LD flags. - - static std::string warning_cflags; //< The warning flags in cflags. - static std::string include_cflags; //< The include flags in cflags. - static std::string machine_cflags; //< The machine flags in cflags. - static std::string spec_cflags; //< The spec flags in cflags. - - static std::string install_path; //< The CC reported install path. - static std::string programs_path; //< The CC reported programs path. - static std::string libraries_path; //< The CC reported libraries path. - - /** - * The list of standard libraries. - */ - #define RPS RLD_PATHSTR_SEPARATOR_STR - static const char* std_lib_c = "libgcc.a" RPS "libssp.a" RPS "libc.a"; - static const char* std_lib_cplusplus = "libstdc++.a"; - - const std::string - strip_cflags (const std::string& flags) - { - std::string oflags; - rld::strings flags_; - rld::split (flags_, flags); - - for (rld::strings::iterator si = flags_.begin (); - si != flags_.end (); - ++si) - { - if (!rld::starts_with ((*si), "-O") && !rld::starts_with ((*si), "-g")) - oflags += ' ' + *si; - } - - return rld::trim (oflags); - } - - const std::string - filter_flags (const std::string& flags, - const std::string& , - const std::string& , - flag_type type, - std::string& warnings, - std::string& includes, - std::string& machines, - std::string& specs) - { - /* - * Defintion of flags to be filtered. - */ - enum flag_group - { - fg_warning, - fg_include, - fg_machine, - fg_specs - }; - struct flag_def - { - flag_group group; ///< The group this flag belong to. - const char* opt; ///< Option start. - int count; ///< Number of arguments with the option. - bool path; ///< Is this a path ? - int out; ///< If the flag type is set drop the opt.. - }; - const flag_def flag_defs[] = - { - { fg_warning, "-W", 1, false, ft_cppflags | ft_cflags | ft_ldflags }, - { fg_include, "-I", 2, true, 0 }, - { fg_include, "-isystem", 2, true, 0 }, - { fg_include, "-sysroot", 2, true, 0 }, - { fg_machine, "-O", 1, false, 0 }, - { fg_machine, "-m", 1, false, 0 }, - { fg_machine, "-f", 1, false, 0 }, - { fg_specs, "-q", 1, false, 0 }, - { fg_specs, "-B", 2, true, 0 }, - { fg_specs, "--specs", 2, false, 0 } - }; - const int flag_def_size = sizeof (flag_defs) / sizeof (flag_def); - - std::string oflags; - rld::strings flags_; - - rld::split (flags_, strip_cflags (flags)); - - warnings.clear (); - includes.clear (); - machines.clear (); - specs.clear (); - - for (rld::strings::iterator si = flags_.begin (); - si != flags_.end (); - ++si) - { - std::string opts; - std::string& opt = *(si); - bool in = true; - - for (int fd = 0; fd < flag_def_size; ++fd) - { - if (rld::starts_with (opt, flag_defs[fd].opt)) - { - int opt_count = flag_defs[fd].count; - if (opt_count > 1) - { - /* - * See if the flag is just the option. If is not take one less - * because the option's argument is joined to the option. - */ - if (opt != flag_defs[fd].opt) - { - opt_count -= 1; - /* - * @todo Path processing here. Not sure what it is needed for. - */ - } - } - opts += ' ' + opt; - while (opt_count > 1) - { - ++si; - /* - * @todo Path processing here. Not sure what it is needed for. - */ - opts += ' ' + (*si); - --opt_count; - } - switch (flag_defs[fd].group) - { - case fg_warning: - warnings += ' ' + opts; - break; - case fg_include: - includes += ' ' + opts; - break; - case fg_machine: - machines += ' ' + opts; - break; - case fg_specs: - specs += ' ' + opts; - break; - default: - throw rld::error ("Invalid group", "flag group"); - } - if ((flag_defs[fd].out & type) != 0) - in = false; - break; - } - } - - if (in) - oflags += ' ' + opts; - } - - rld::trim (warnings); - rld::trim (includes); - rld::trim (machines); - rld::trim (specs); - - return rld::trim (oflags); - } - - const std::string - filter_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type) - { - if (type != ft_cflags) - { - std::string warnings; - std::string includes; - std::string machines; - std::string specs; - return filter_flags (flags, - arch, - path, - type, - warnings, - includes, - machines, - specs); - } - else - { - return filter_flags (flags, - arch, - path, - type, - warning_cflags, - include_cflags, - machine_cflags, - spec_cflags); - } - } - - void - set_cc (const std::string& cc_) - { - cc = cc_; - cc_set = true; - } - - const std::string - get_cc () - { - return cc; - } - - bool - is_cc_set () - { - return cc_set; - } - - void - set_ld (const std::string& ld_) - { - ld = ld_; - ld_set = true; - } - - const std::string - get_ld () - { - return ld; - } - - bool - is_ld_set () - { - return ld_set; - } - - void - set_exec_prefix (const std::string& exec_prefix_) - { - exec_prefix = exec_prefix_; - } - - const std::string - get_exec_prefix () - { - return exec_prefix; - } - - bool is_exec_prefix_set () - { - return !exec_prefix.empty (); - } - - void - set_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type) - { - std::string* oflags; - switch (type) - { - case ft_cppflags: - oflags = &cppflags; - break; - case ft_cflags: - oflags = &cflags; - break; - case ft_cxxflags: - oflags = &cxxflags; - break; - case ft_ldflags: - oflags = &ldflags; - break; - default: - throw rld::error ("Invalid flag type", "CC set flags"); - } - (*oflags) = filter_flags (flags, arch, path, type); - } - - void - set_flags (const std::string& flags, flag_type type) - { - std::string arch; - std::string path; - set_flags (flags, arch, path, type); - } - - void - append_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type) - { - std::string* oflags; - switch (type) - { - case ft_cppflags: - oflags = &cppflags; - break; - case ft_cflags: - oflags = &cflags; - break; - case ft_cxxflags: - oflags = &cxxflags; - break; - case ft_ldflags: - oflags = &ldflags; - break; - default: - throw rld::error ("Invalid flag type", "CC set flags"); - } - if (oflags->empty ()) - *oflags += filter_flags (flags, arch, path, type); - else - *oflags += ' ' + filter_flags (flags, arch, path, type); - } - - void - append_flags (const std::string& flags, flag_type type) - { - std::string arch; - std::string path; - append_flags (flags, arch, path, type); - } - - const std::string - get_flags (flag_type type) - { - std::string* flags; - switch (type) - { - case ft_cppflags: - flags = &cppflags; - break; - case ft_cflags: - flags = &cflags; - break; - case ft_cxxflags: - flags = &cxxflags; - break; - case ft_ldflags: - flags = &ldflags; - break; - default: - throw rld::error ("Invalid flag type", "CC get flags"); - } - return *flags; - } - - const std::string - get_flags (flag_group group) - { - std::string* flags; - switch (group) - { - case fg_warning_flags: - flags = &warning_cflags; - break; - case fg_include_flags: - flags = &include_cflags; - break; - case fg_machine_flags: - flags = &machine_cflags; - break; - case fg_spec_flags: - flags = &spec_cflags; - break; - default: - throw rld::error ("Invalid flag group", "CC get flags"); - } - return *flags; - } - - void - append_flags (flag_type type, rld::process::arg_container& args) - { - const std::string* flags = 0; - switch (type) - { - case ft_cppflags: - flags = &cppflags; - break; - case ft_cflags: - flags = &cflags; - break; - case ft_cxxflags: - flags = &cxxflags; - break; - case ft_ldflags: - flags = &ldflags; - break; - default: - throw rld::error ("Invalid flag type", "CC append flags"); - } - if (!flags->empty ()) - rld::process::args_append (args, *flags); - } - - void - make_cc_command (rld::process::arg_container& args) - { - /* - * Use the absolute path to CC if provided. - */ - if (is_cc_set ()) - { - args.push_back (cc); - } - else - { - std::string cmd = cc_name; - if (!exec_prefix.empty ()) - cmd = exec_prefix + "-rtems" + rld::rtems::version () + '-' + cmd; - args.push_back (cmd); - } - } - - void - make_ld_command (rld::process::arg_container& args) - { - /* - * Use the absolute path to LD if provided. - */ - if (is_ld_set ()) - { - args.push_back (get_ld ()); - } - else - { - std::string cmd = ld_name; - if (!exec_prefix.empty ()) - cmd = exec_prefix + "-rtems" + rld::rtems::version () + '-' + cmd; - args.push_back (cmd); - } - } - - static bool - match_and_trim (const char* prefix, std::string& line, std::string& result) - { - std::string::size_type pos = ::strlen (prefix); - if (line.substr (0, pos) == prefix) - { - if (line[pos] == '=') - ++pos; - result = line.substr (pos, line.size () - pos - 1); - return true; - } - return false; - } - - static void - search_dirs () - { - rld::process::arg_container args; - - make_cc_command (args); - append_flags (ft_cppflags, args); - append_flags (ft_cflags, args); - args.push_back ("-print-search-dirs"); - - rld::process::tempfile out; - rld::process::tempfile err; - rld::process::status status; - - status = rld::process::execute (cc_name, args, out.name (), err.name ()); - - if ((status.type == rld::process::status::normal) && - (status.code == 0)) - { - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - out.output (cc_name, std::cout, true); - out.open (); - while (true) - { - std::string line; - out.read_line (line); - if (line.size () == 0) - break; - if (match_and_trim ("install: ", line, install_path)) - continue; - if (match_and_trim ("programs: ", line, programs_path)) - continue; - if (match_and_trim ("libraries: ", line, libraries_path)) - continue; - } - out.close (); - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - { - std::cout << "cc::install: " << install_path << std::endl - << "cc::programs: " << programs_path << std::endl - << "cc::libraries: " << libraries_path << std::endl; - } - } - else - { - err.output (cc_name, std::cout); - } - } - - void - get_library_path (std::string& name, std::string& path) - { - rld::process::arg_container args; - - make_cc_command (args); - append_flags (ft_cppflags, args); - append_flags (ft_cflags, args); - args.push_back ("-print-file-name=" + name); - - rld::process::tempfile out; - rld::process::tempfile err; - rld::process::status status; - - status = rld::process::execute (cc_name, args, out.name (), err.name ()); - - if ((status.type == rld::process::status::normal) && - (status.code == 0)) - { - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - out.output ("cc", std::cout, true); - out.open (); - out.read (path); - out.close (); - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - std::cout << "cc::libpath: " << name << " -> " << path << std::endl; - } - else - { - err.output ("cc", std::cout); - } - } - - void - get_standard_libpaths (rld::path::paths& libpaths) - { - search_dirs (); - rld::split (libpaths, libraries_path, RLD_PATHSTR_SEPARATOR); - } - - void - get_standard_libs (rld::path::paths& libs, - rld::path::paths& libpaths, - bool cplusplus) - { - strings libnames; - - rld::split (libnames, std_lib_c, RLD_PATHSTR_SEPARATOR); - if (cplusplus) - rld::path::path_split (std_lib_cplusplus, libnames); - - for (strings::iterator lni = libnames.begin (); - lni != libnames.end (); - ++lni) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "cc::stdlib: " << *lni << std::endl; - - std::string path; - - rld::path::find_file (path, *lni, libpaths); - if (path.empty ()) - throw rld::error ("Library not found: " + *lni, "getting standard libs"); - - libs.push_back (path); - } - } - } -} diff --git a/linkers/rld-cc.h b/linkers/rld-cc.h deleted file mode 100644 index 6c200d2..0000000 --- a/linkers/rld-cc.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief Various calls to CC. - * - */ - -#if !defined (_RLD_CC_H_) -#define _RLD_CC_H_ - -#include - -#include -#include - -namespace rld -{ - namespace cc - { - /* - * The type of flags. - */ - enum flag_type - { - ft_cppflags = 1 << 0, - ft_cflags = 1 << 1, - ft_cxxflags = 1 << 2, - ft_ldflags = 1 << 3 - }; - - /* - * Flags groups. - */ - enum flag_group - { - fg_warning_flags, - fg_include_flags, - fg_machine_flags, - fg_spec_flags - }; - - /** - * Strip the flags of -O and -g options. - * - * @param flags The flags a space delimited list to strip. - * @return const std::string The stripped flags. - */ - const std::string strip_cflags (const std::string& flags); - - /** - * Filter the flags. Provide the type of flags being passed, the flags as a - * space separated list, the architure, and a path. Provide strings - * containers for the different flag groups so they can be sorted and - * returned. - * - * @param flags The flags a space delimited list to strip. - * @param arch The architecure per the OS specific name. - * @param path A path to adjust based on the architecture. - * @param type The type of flags being passed. - * @param warnings Return warning flags in this string. - * @param includes Return include flags in this string. - * @param machines Return machine flags in this string. - * @param specs Return spec flags in this string. - * @return const std::string The filtered flags. - */ - const std::string filter_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type, - std::string& warnings, - std::string& includes, - std::string& machines, - std::string& specs); - - /** - * Filter the cflags and update the warnings, includes, machines and specs - * if the type of flags is cflags. Provide the cflags as a space separated - * list, the architure, and a path. - * - * @param flags The flags a space delimited list to strip. - * @param arch The architecure per the OS specific name. - * @param path A path to adjust based on the architecture. - * @param type The type of flags being passed. - * @return const std::string The filtered flags. - */ - const std::string filter_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type); - - /** - * Set CC. The exec-prefix is ignored if this is set. - */ - void set_cc (const std::string& cc); - - /** - * Get the CC. - */ - const std::string get_cc (); - - /** - * Is the CC set ? - */ - bool is_cc_set (); - - /** - * Set LD. The exec-prefix is ignored if this is set. - */ - void set_ld (const std::string& ld); - - /** - * Get the LD. - */ - const std::string get_ld (); - - /** - * Is the LD set ? - */ - bool is_ld_set (); - - /** - * Set the exec-prefix. If CC is set the exec-prefix is ignored. - */ - void set_exec_prefix (const std::string& exec_prefix); - - /** - * Get the exec-prefix. - */ - const std::string get_exec_prefix (); - - /** - * Is exec-prefix set ? - */ - bool is_exec_prefix_set (); - - /** - * Set the flags with a specific arch and include path. - */ - void set_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type); - - /** - * Set the flags. - */ - void set_flags (const std::string& flags, flag_type type); - - /** - * Append the flags with a specific arch and include path. - */ - void append_flags (const std::string& flags, - const std::string& arch, - const std::string& path, - flag_type type); - - /** - * Append the flags. - */ - void append_flags (const std::string& flags, flag_type type); - - /** - * Get the flags. - */ - const std::string get_flags (flag_type type); - const std::string get_flags (flag_group group); - - /** - * Append the flags if set. - */ - void append_flags (flag_type type, rld::process::arg_container& args); - - /** - * Make a CC command from the set arguments. - */ - void make_cc_command (rld::process::arg_container& args); - - /** - * Make a LD command from the set arguments. - */ - void make_ld_command (rld::process::arg_container& args); - - /** - * Get the standard libraries paths from the compiler. - */ - void get_standard_libpaths (rld::path::paths& libpaths); - - /** - * Get the standard libraries. Optionally add the C++ library. - */ - void get_standard_libs (rld::path::paths& libs, - rld::path::paths& libpaths, - bool cpp = false); - - } -} - -#endif diff --git a/linkers/rld-compression.cpp b/linkers/rld-compression.cpp deleted file mode 100644 index 2abeff1..0000000 --- a/linkers/rld-compression.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_ld - * - * @brief RTEMS Linker. - * - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include - -#include -#include - -#include "fastlz.h" - -namespace rld -{ - namespace compress - { - compressor::compressor (files::image& image, - size_t size, - bool out, - bool compress) - : image (image), - size (size), - out (out), - compress (compress), - buffer (0), - io (0), - level (0), - total (0), - total_compressed (0) - { - if (size > 0xffff) - throw rld::error ("Size too big, 16 bits only", "compression"); - - buffer = new uint8_t[size]; - io = new uint8_t[size + (size / 10)]; - } - - compressor::~compressor () - { - flush (); - delete [] buffer; - delete [] io; - } - - void - compressor::write (const void* data_, size_t length) - { - if (!out) - throw rld::error ("Write on read-only", "compression"); - - const uint8_t* data = static_cast (data_); - - while (length) - { - size_t appending; - - if (length > (size - level)) - appending = size - level; - else - appending = length; - - ::memcpy ((void*) (buffer + level), data, appending); - - data += appending; - level += appending; - length -= appending; - total += appending; - - output (); - } - } - - void - compressor::write (files::image& input, off_t offset, size_t length) - { - if (!out) - throw rld::error ("Write on read-only", "compression"); - - input.seek (offset); - - while (length) - { - size_t appending; - - if (length > (size - level)) - appending = size - level; - else - appending = length; - - input.read ((void*) (buffer + level), appending); - - level += appending; - length -= appending; - total += appending; - - output (); - } - } - - size_t - compressor::read (void* data_, size_t length) - { - if (out) - throw rld::error ("Read on write-only", "compression"); - - uint8_t* data = static_cast (data_); - - size_t amount = 0; - - while (length) - { - input (); - - if (level == 0) - break; - - size_t appending; - - if (length > level) - appending = level; - else - appending = length; - - ::memcpy (data, buffer, appending); - ::memmove (buffer, buffer + appending, level - appending); - - data += appending; - level -= appending; - length -= appending; - total += appending; - amount += appending; - } - - return amount; - } - - size_t - compressor::read (files::image& output_, off_t offset, size_t length) - { - if (out) - throw rld::error ("Read on write-only", "compression"); - - output_.seek (offset); - - return read (output_, length); - } - - size_t - compressor::read (files::image& output_, size_t length) - { - if (out) - throw rld::error ("Read on write-only", "compression"); - - size_t amount = 0; - - while (length) - { - input (); - - if (level == 0) - break; - - size_t appending; - - if (length > level) - appending = level; - else - appending = length; - - output_.write (buffer, appending); - - ::memmove (buffer, buffer + appending, level - appending); - - level -= appending; - length -= appending; - total += appending; - amount += appending; - } - - return amount; - } - - void - compressor::flush () - { - output (true); - } - - size_t - compressor::transferred () const - { - return total; - } - - size_t - compressor::compressed () const - { - return total_compressed; - } - - off_t - compressor::offset () const - { - return total; - } - - void - compressor::output (bool forced) - { - if (out && ((forced && level) || (level >= size))) - { - if (compress) - { - int writing = ::fastlz_compress (buffer, level, io); - uint8_t header[2]; - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rtl: comp: offset=" << total_compressed - << " block-size=" << writing << std::endl; - - header[0] = writing >> 8; - header[1] = writing; - - image.write (header, 2); - image.write (io, writing); - - total_compressed += 2 + writing; - } - else - { - image.write (buffer, level); - } - - level = 0; - } - } - - void - compressor::input () - { - if (!out && (level == 0)) - { - if (compress) - { - uint8_t header[2]; - - if (image.read (header, 2) == 2) - { - uint32_t block_size = - (((uint32_t) header[0]) << 8) | (uint32_t) header[1]; - - if (block_size == 0) - throw rld::error ("Block size is invalid (0)", "compression"); - - total_compressed += 2 + block_size; - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rtl: decomp: block-size=" << block_size - << std::endl; - - if (image.read (io, block_size) != block_size) - throw rld::error ("Read past end", "compression"); - - level = ::fastlz_decompress (io, block_size, buffer, size); - } - } - else - { - image.read (buffer, size); - level = size; - } - } - } - - } -} diff --git a/linkers/rld-compression.h b/linkers/rld-compression.h deleted file mode 100644 index 4710845..0000000 --- a/linkers/rld-compression.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker compression handles compressed images. - * - */ - -#if !defined (_RLD_COMPRESSION_H_) -#define _RLD_COMPRESSION_H_ - -#include - -namespace rld -{ - namespace compress - { - /** - * A compressor. - */ - class compressor - { - public: - /** - * Construct the compressor for the given image. - * - * @param image The image to read or write to. - * @param size The size of the input and output buffers. - * @param out The compressor is compressing. - * @param compress Set to false to disable compression. - */ - compressor (files::image& image, - size_t size, - bool out = true, - bool compress = true); - - /** - * Destruct the compressor. - */ - ~compressor (); - - /** - * Write the data to the output buffer and once the image buffer is full - * compress and write the compressed data to the image. - * - * @param data The data to write to the image compressed - * @param length The mount of data in bytes to write. - */ - void write (const void* data, size_t length); - - /** - * Write the section of the input image file to the output buffer and - * once the image buffer is full compress and write the compressed data - * to the image. - * - * @param input The input image. - * @param offset The input image offset to read from. - * @param length The mount of data in bytes to write. - */ - void write (files::image& input, off_t offset, size_t length); - - /** - * Flush the output buffer is data is present. - */ - void flush (); - - /** - * Read the compressed data into the input buffer and return the section - * requested. - * - * @param data Write the decompressed data here. - * @param length The mount of data in bytes to read. - * @return size_t The amount of data read. - */ - size_t read (void* data, size_t length); - - /** - * Read the decompressed data writing it to the image. - * - * @param output_ The output image. - * @param offset The output image offset to write from. - * @param length The mount of data in bytes to read. - * @return size_t The amount of data read. - */ - size_t read (files::image& output_, off_t offset, size_t length); - - /** - * Read the decompressed data writing it to the image. - * - * @param output_ The output image. - * @param length The mount of data in bytes to read. - * @return size_t The amount of data read. - */ - size_t read (files::image& output_, size_t length); - - /** - * The amount of uncompressed data transferred. - * - * @return size_t The amount of data tranferred. - */ - size_t transferred () const; - - /** - * The amount of compressed data transferred. - * - * @return size_t The amount of compressed data tranferred. - */ - size_t compressed () const; - - /** - * The current offset in the stream. - * - * @return off_t The current uncompressed offset. - */ - off_t offset () const; - - private: - - /** - * Output the block of data to the output file with the block header. - * - * @param forced If true output the buffer. - */ - void output (bool forced = false); - - /** - * Input a block of compressed data and decompress it. - */ - void input (); - - files::image& image; //< The image to read or write to or from. - size_t size; //< The size of the buffer. - bool out; //< If true the it is compression. - bool compress; //< If true compress the data. - uint8_t* buffer; //< The decompressed buffer - uint8_t* io; //< The I/O buffer. - size_t level; //< The amount of data in the buffer. - size_t total; //< The amount of uncompressed data - // transferred. - size_t total_compressed; //< The amount of compressed data - // transferred. - }; - - /** - * Compressor template function for writing data to the compressor. - */ - template < typename T > - void write (compressor& comp, const T value) - { - uint8_t bytes[sizeof (T)]; - T v = value; - int b = sizeof (T) - 1; - while (b >= 0) - { - bytes[b--] = (uint8_t) v; - v >>= 8; - } - comp.write (bytes, sizeof (T)); - } - - /** - * Compressor template function for reading data from the compressor. - */ - template < typename T > - T read (compressor& comp) - { - uint8_t bytes[sizeof (T)]; - T v = 0; - uint32_t b = 0; - if (comp.read (bytes, sizeof (T)) != sizeof (T)) - throw rld::error ("Reading of value failed", "compression"); - while (b < sizeof (T)) - { - v = (v << 8) | ((T) bytes[b++]); - } - return v; - } - - } -} - -static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, - const uint64_t value) { - rld::compress::write < uint64_t > (comp, value); - return comp; -} - -static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, - const uint32_t value) { - rld::compress::write < uint32_t > (comp, value); - return comp; -} - -static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, - const std::string& str) { - comp.write (str.c_str (), str.size ()); - return comp; -} - -static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp, - uint64_t& value) { - value = rld::compress::read < uint64_t > (comp); - return comp; -} - -static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp, - uint32_t& value) { - value = rld::compress::read < uint32_t > (comp); - return comp; -} - -#endif diff --git a/linkers/rld-config.cpp b/linkers/rld-config.cpp deleted file mode 100644 index c106120..0000000 --- a/linkers/rld-config.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_rld - * - * @brief INI Configuration reader. - * - */ - -#include - -#include - -#include - -namespace rld -{ - namespace config - { - item::item (const std::string& text) - : text (text) - { - } - - item::item (const char* text) - : text (text) - { - } - - bool - section::has_record (const std::string& name) const - { - for (records::const_iterator ri = recs.begin (); - ri != recs.end (); - ++ri) - { - if ((*ri).name == name) - return true; - } - return false; - } - - const record& - section::get_record (const std::string& name) const - { - for (records::const_iterator ri = recs.begin (); - ri != recs.end (); - ++ri) - { - if ((*ri).name == name) - return *ri; - } - - throw rld::error ("not found", "config record: " + this->name + '/' + name); - } - - const std::string - section::get_record_item (const std::string& rec_name) const - { - const record& rec = get_record (rec_name); - if (rec.items_.size () != 1) - throw rld::error ("duplicate", "record item: " + name + '/' + rec_name); - return rec.items_[0].text; - } - - void - section::get_record_items (const std::string& rec_name, rld::strings& items) const - { - const record& rec = get_record (rec_name); - items.clear (); - for (rld::config::items::const_iterator ii = rec.items_.begin (); - ii != rec.items_.end (); - ++ii) - { - items.push_back ((*ii).text); - } - } - - config::config(const std::string& search_path) - { - set_search_path (search_path); - } - - config::~config() - { - } - - void - config::set_search_path (const std::string& search_path) - { - if (!search_path.empty ()) - rld::path::path_split (search_path, search); - } - - void - config::clear () - { - secs.clear (); - } - - void - config::load (const std::string& path) - { - CSimpleIniCaseA ini (false, true, true); - - std::string checked_path; - - if (rld::path::check_file (path)) - { - checked_path = path; - } - else - { - bool found = false; - for (rld::path::paths::const_iterator spi = search.begin (); - spi != search.end (); - ++spi) - { - rld::path::path_join (*spi, path, checked_path); - if (rld::path::check_file (checked_path)) - { - found = true; - break; - } - } - if (!found) - throw rld::error ("Not found.", "load config: " + path); - } - - if (ini.LoadFile (checked_path.c_str ()) != SI_OK) - throw rld::error (::strerror (errno), "load config: " + path); - - paths_.push_back (checked_path); - - /* - * Merge the loaded configuration into our configuration. - */ - - CSimpleIniCaseA::TNamesDepend skeys; - - ini.GetAllSections(skeys); - - for (CSimpleIniCaseA::TNamesDepend::const_iterator si = skeys.begin (); - si != skeys.end (); - ++si) - { - section sec; - - sec.name = (*si).pItem; - - CSimpleIniCaseA::TNamesDepend rkeys; - - ini.GetAllKeys((*si).pItem, rkeys); - - for (CSimpleIniCaseA::TNamesDepend::const_iterator ri = rkeys.begin (); - ri != rkeys.end (); - ++ri) - { - record rec; - - rec.name = (*ri).pItem; - - CSimpleIniCaseA::TNamesDepend vals; - - ini.GetAllValues((*si).pItem, (*ri).pItem, vals); - - for (CSimpleIniCaseA::TNamesDepend::const_iterator vi = vals.begin (); - vi != vals.end (); - ++vi) - { - rec.items_.push_back (item ((*vi).pItem)); - } - - sec.recs.push_back (rec); - } - - secs.push_back (sec); - } - } - - - void - config::includes (const section& sec, bool must_exist) - { - bool have_includes = false; - - try - { - rld::strings is; - parse_items (sec, "include", is); - - have_includes = true; - - /* - * Include records are a paths which we can load. - */ - - for (rld::strings::const_iterator isi = is.begin (); - isi != is.end (); - ++isi) - { - load (*isi); - } - } - catch (rld::error re) - { - /* - * No include records, must be all inlined. If we have includes it must - * be another error so throw it. - */ - if (have_includes || (!have_includes && must_exist)) - throw; - } - } - - const section& - config::get_section (const std::string& name) const - { - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - if ((*si).name == name) - return *si; - } - - throw error ("not found", "config section: " + name); - } - - const paths& - config::get_paths () const - { - return paths_; - } - } -} diff --git a/linkers/rld-config.h b/linkers/rld-config.h deleted file mode 100644 index 4bcb964..0000000 --- a/linkers/rld-config.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_rld - * - * @brief INI Configuration reader. - * - */ - -#if !defined (_RLD_CONFIG_H_) -#define _RLD_CONFIG_H_ - -#include -#include -#include - -#include - -namespace rld -{ - namespace config - { - /** - * The configuration item. This is a data component of a record contained - * in a section. - */ - struct item - { - std::string text; /**< The text as read from the configuration. */ - - /** - * Construct an item. - */ - item (const std::string& text); - item (const char* text); - }; - - /** - * Configuration item container. - */ - typedef std::vector < item > items; - - /** - * Configuration record is a line in a section. There can be multiple - * records with the same key in a section. Keys are specific to a section. - */ - struct record - { - std::string name; //< Name of the record. - items items_; //< The record's items. - - /** - * Return true if there is only one item. - */ - bool single () const { - return items_.size () == 1; - } - }; - - /** - * Configuration record container. - */ - typedef std::list < record > records; - - /** - * Configuration section. A section contains a number of records and the - * records contain [1..n] items. - */ - struct section - { - std::string name; //< Name of the section. - records recs; //< The section's records. - - /** - * Has the section got a record ? - */ - bool has_record (const std::string& name) const; - - /** - * Find a record and throw an error if not found. - */ - const record& get_record (const std::string& name) const; - - /** - * Return the single item in a record. If the record is duplicated an - * error is thrown. - */ - const std::string get_record_item (const std::string& name) const; - - /** - * Return the list of items in a record in a strings container. - */ - void get_record_items (const std::string& name, rld::strings& items_) const; - }; - - /** - * Configuration section container. - */ - typedef std::list < section > sections; - - /** - * Container of configuration file paths loaded. - */ - typedef std::vector < std::string > paths; - - /** - * The configuration. - */ - class config - { - public: - /** - * Construct an empty configuration. - */ - config(const std::string& search_path = ""); - - /** - * Desctruct the configuration object. - */ - virtual ~config(); - - /** - * Set the search path. - */ - void set_search_path (const std::string& search_path); - - /** - * Clear the current configuration. - */ - void clear (); - - /** - * Load a configuration. - */ - void load (const std::string& name); - - /** - * Process any include records in the section named. If the section has - * any records named 'include' split the items and include the - * configuration files. - */ - void includes (const section& sec, bool must_exist = false); - - /** - * Get the section and throw an error if not found. - */ - const section& get_section (const std::string& name) const; - - /** - * Get the paths of loaded configuration files. - */ - const paths& get_paths () const; - - private: - - paths search; //< The paths to search for config files in. - paths paths_; //< The path's of the loaded files. - sections secs; //< The sections loaded from configuration files - }; - - /** - * Return the items from a record. - */ - template < typename T > - void parse_items (const rld::config::record& record, - T& items_, - bool clear = true, - bool split = true) - { - if (clear) - items_.clear (); - for (rld::config::items::const_iterator ii = record.items_.begin (); - ii != record.items_.end (); - ++ii) - { - if (split) - { - rld::strings ss; - rld::split (ss, (*ii).text, ','); - std::copy (ss.begin (), ss.end (), std::back_inserter (items_)); - } - else - { - items_.push_back ((*ii).text); - } - } - } - - /** - * Return the items from a record in a section. Optionally raise an error - * if the record is not found and it is to be present. - */ - template < typename T > - void parse_items (const rld::config::section& section, - const std::string& name, - T& items_, - bool present = false, - bool clear = true, - bool split = true) - { - if (clear) - items_.clear (); - const rld::config::record* rec = 0; - try - { - const rld::config::record& rr = section.get_record (name); - rec = &rr; - } - catch (rld::error re) - { - /* - * Ignore the error if it does not need to exist. - */ - if (present) - throw rld::error ("not found", "record: " + section.name + name); - } - - if (rec) - parse_items (*rec, items_, clear, split); - } - - /** - * Return the items from a record in a section in the - * configuration. Optionally raise an error if the section is not found and - * it is to be present. - */ - template < typename T > - void parse_items (const rld::config::config& config, - const std::string& section, - const std::string& record, - T& items_, - bool present = false) - { - items_.clear (); - const rld::config::section* sec = 0; - try - { - const rld::config::section& sr = config.get_section (section); - sec = &sr; - } - catch (rld::error re) - { - /* - * Ignore the error if it does not need to exist. - */ - if (present) - throw rld::error ("not found", "section: " + section); - } - - if (sec) - parse_items (*sec, record, items_); - } - } -} - -#endif diff --git a/linkers/rld-elf-types.h b/linkers/rld-elf-types.h deleted file mode 100644 index c0da295..0000000 --- a/linkers/rld-elf-types.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker ELF types. - * - */ - -#if !defined (_RLD_ELF_TYPES_H_) -#define _RLD_ELF_TYPES_H_ - -#define __LIBELF_INTERNAL__ 1 -#include -#include - -namespace rld -{ - namespace elf - { - /** - * Hide the types from libelf we use. - */ - typedef ::GElf_Half elf_half; - typedef ::GElf_Word elf_word; - typedef ::GElf_Xword elf_xword; - typedef ::GElf_Sxword elf_sxword; - typedef ::Elf_Type elf_type; - typedef ::GElf_Addr elf_addr; - typedef ::GElf_Off elf_off; - typedef ::GElf_Sym elf_sym; - typedef ::Elf_Kind elf_kind; - typedef ::Elf_Scn elf_scn; - typedef ::GElf_Ehdr elf_ehdr; - typedef ::Elf32_Ehdr elf32_ehdr; - typedef ::GElf_Shdr elf_shdr; - typedef ::GElf_Phdr elf_phdr; - typedef ::Elf_Data elf_data; - typedef ::GElf_Rel elf_rel; - typedef ::GElf_Rela elf_rela; - typedef ::Elf elf; - } -} - -#endif diff --git a/linkers/rld-elf.cpp b/linkers/rld-elf.cpp deleted file mode 100644 index 8b2ac5e..0000000 --- a/linkers/rld-elf.cpp +++ /dev/null @@ -1,1210 +0,0 @@ -/* - * Copyright (c) 2011-2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker ELF module manages the ELF format images. - * - */ - -#include - -#include - -namespace rld -{ - namespace elf - { - /** - * Throw an ELF error. - * - * @param where Where the error is raised. - */ - void libelf_error (const std::string& where) - { - throw rld::error (::elf_errmsg (-1), "libelf:" + where); - } - - /** - * We record the first class, machine and .. type of object file we get the - * header of and all header must match. We cannot mix object module types. - */ - static unsigned int elf_object_class = ELFCLASSNONE; - static unsigned int elf_object_machinetype = EM_NONE; - static unsigned int elf_object_datatype = ELFDATANONE; - - /** - * A single place to initialise the libelf library. This must be called - * before any libelf API calls are made. - */ - static void - libelf_initialise () - { - static bool libelf_initialised = false; - if (!libelf_initialised) - { - if (::elf_version (EV_CURRENT) == EV_NONE) - libelf_error ("initialisation"); - libelf_initialised = true; - } - } - - relocation::relocation (const symbols::symbol& sym, - elf_addr offset, - elf_xword info, - elf_sxword addend) - : sym (&sym), - offset_ (offset), - info_ (info), - addend_ (addend) - { - } - - relocation::relocation () - : sym (0), - offset_ (0), - info_ (0), - addend_ (0) - { - } - - elf_addr - relocation::offset () const - { - return offset_; - } - - uint32_t - relocation::type () const - { - return GELF_R_TYPE (info_); - } - - elf_xword - relocation::info () const - { - return info_; - } - - elf_sxword - relocation::addend () const - { - return addend_; - } - - const symbols::symbol& - relocation::symbol () const - { - if (sym) - return *sym; - throw rld::error ("no symbol", "elf:relocation"); - } - - section::section (file& file_, - int index_, - const std::string& name_, - elf_word type, - elf_xword alignment, - elf_xword flags, - elf_addr addr, - elf_off offset, - elf_xword size, - elf_word link, - elf_word info, - elf_xword entry_size) - : file_ (&file_), - index_ (index_), - name_ (name_), - scn (0), - data_ (0), - rela (false) - { - if (!file_.is_writable ()) - throw rld::error ("not writable", - "elf:section" + file_.name () + " (" + name_ + ')'); - - scn = ::elf_newscn (file_.get_elf ()); - if (!scn) - libelf_error ("elf_newscn: " + name_ + " (" + file_.name () + ')'); - - if (::gelf_getshdr(scn, &shdr) == 0) - libelf_error ("gelf_getshdr: " + name_ + " (" + file_.name () + ')'); - - shdr.sh_name = 0; - shdr.sh_type = type; - shdr.sh_flags = flags; - shdr.sh_addr = addr; - shdr.sh_offset = offset; - shdr.sh_size = size; - shdr.sh_link = link; - shdr.sh_info = info; - shdr.sh_addralign = alignment; - shdr.sh_entsize = entry_size; - - if (type == SHT_NOBITS) - add_data (ELF_T_BYTE, alignment, size); - - if (!gelf_update_shdr (scn, &shdr)) - libelf_error ("gelf_update_shdr: " + name_ + " (" + file_.name () + ')'); - } - - section::section (file& file_, int index_) - : file_ (&file_), - index_ (index_), - scn (0), - data_ (0), - rela (false) - { - memset (&shdr, 0, sizeof (shdr)); - - scn = ::elf_getscn (file_.get_elf (), index_); - if (!scn) - libelf_error ("elf_getscn: " + file_.name ()); - - if (!::gelf_getshdr (scn, &shdr)) - libelf_error ("gelf_getshdr: " + file_.name ()); - - if (shdr.sh_type != SHT_NULL) - { - name_ = file_.get_string (shdr.sh_name); - data_ = ::elf_getdata (scn, 0); - if (!data_) - { - data_ = ::elf_rawdata (scn, 0); - if (!data_) - libelf_error ("elf_getdata: " + name_ + '(' + file_.name () + ')'); - } - } - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf::section: index=" << index () - << " name='" << name () << "'" - << " size=" << size () - << " align=" << alignment () - << " flags=0x" << std::hex << flags () << std::dec - << std::endl; - } - - section::section (const section& orig) - : file_ (orig.file_), - index_ (orig.index_), - name_ (orig.name_), - scn (orig.scn), - shdr (orig.shdr), - data_ (orig.data_), - rela (orig.rela), - relocs (orig.relocs) - { - } - - section::section () - : file_ (0), - index_ (-1), - scn (0), - data_ (0), - rela (false) - { - memset (&shdr, 0, sizeof (shdr)); - } - - void - section::add_data (elf_type type, - elf_xword alignment, - elf_xword size, - void* buffer, - elf_off offset) - { - check_writable ("add_data"); - - data_ = ::elf_newdata(scn); - if (!data_) - libelf_error ("elf_newdata: " + name_ + " (" + file_->name () + ')'); - - data_->d_type = type; - data_->d_off = offset; - data_->d_size = size; - data_->d_align = alignment; - data_->d_version = EV_CURRENT; - data_->d_buf = buffer; - - if (!gelf_update_shdr (scn, &shdr)) - libelf_error ("gelf_update_shdr: " + name_ + " (" + file_->name () + ')'); - } - - int - section::index () const - { - check ("index"); - return index_; - } - - const std::string& - section::name () const - { - check ("name"); - return name_; - } - - elf_data* - section::data () - { - check ("data"); - return data_; - } - - elf_word - section::type () const - { - check ("type"); - return shdr.sh_type; - } - - elf_xword - section::flags () const - { - check ("flags"); - return shdr.sh_flags; - } - - elf_addr - section::address () const - { - check ("address"); - return shdr.sh_addr; - } - - elf_xword - section::alignment () const - { - check ("alignment"); - return shdr.sh_addralign; - } - - elf_off - section::offset () const - { - check ("offset"); - return shdr.sh_offset; - } - - elf_word - section::link () const - { - check ("link"); - return shdr.sh_link; - } - - elf_word - section::info () const - { - check ("info"); - return shdr.sh_info; - } - - elf_xword - section::size () const - { - check ("size"); - return shdr.sh_size; - } - - elf_xword - section::entry_size () const - { - check ("entry_size"); - return shdr.sh_entsize; - } - - int - section::entries () const - { - return size () / entry_size (); - } - - bool - section::get_reloc_type () const - { - return rela; - } - - void - section::set_name (unsigned int index) - { - check_writable ("set_name"); - shdr.sh_name = index; - if (!gelf_update_shdr (scn, &shdr)) - libelf_error ("gelf_update_shdr: " + name_ + " (" + file_->name () + ')'); - } - - void - section::set_reloc_type (bool rela_) - { - rela = rela_; - } - - void - section::add (const relocation& reloc) - { - relocs.push_back (reloc); - } - - const relocations& - section::get_relocations () const - { - return relocs; - } - - void - section::check (const char* where) const - { - if (!file_ || (index_ < 0) || !scn) - { - std::string w = where; - throw rld::error ("Section not initialised.", "section:check:" + w); - } - } - - void - section::check_writable (const char* where) const - { - check (where); - if (!file_->is_writable ()) - { - std::string w = where; - throw rld::error ("File is read-only.", "section:check:"); - } - } - - program_header::program_header () - { - memset (&phdr, 0, sizeof (phdr)); - } - - program_header::~program_header () - { - } - - void - program_header::set (elf_word type, - elf_word flags, - elf_off offset, - elf_xword filesz, - elf_xword memsz, - elf_xword align, - elf_addr vaddr, - elf_addr paddr) - { - phdr.p_type = type; - phdr.p_flags = flags; - phdr.p_offset = offset; - phdr.p_vaddr = vaddr; - phdr.p_paddr = paddr; - phdr.p_filesz = filesz; - phdr.p_memsz = memsz; - phdr.p_align = align; - } - - file::file () - : fd_ (-1), - archive (false), - writable (false), - elf_ (0), - oclass (0), - ident_str (0), - ident_size (0), - ehdr (0), - phdr (0) - { - } - - file::~file () - { - end (); - } - - void - file::begin (const std::string& name__, int fd__, const bool writable_) - { - begin (name__, fd__, writable_, 0, 0); - } - - void - file::begin (const std::string& name__, file& archive_, off_t offset) - { - archive_.check ("begin:archive"); - - if (archive_.writable) - throw rld::error ("archive is writable", "elf:file:begin"); - - begin (name__, archive_.fd_, false, &archive_, offset); - } - - #define rld_archive_fhdr_size (60) - - void - file::begin (const std::string& name__, - int fd__, - const bool writable_, - file* archive_, - off_t offset_) - { - if (fd__ < 0) - throw rld::error ("No file descriptor", "elf:file:begin"); - - /* - * Begin's are not nesting. - */ - if (elf_ || (fd_ >= 0)) - throw rld::error ("Already called", "elf:file:begin"); - - /* - * Cannot write directly into archive. Create a file then archive it. - */ - if (archive_ && writable_) - throw rld::error ("Cannot write into archives directly", - "elf:file:begin"); - - libelf_initialise (); - - /* - * Is this image part of an archive ? - */ - if (archive_) - { - ssize_t offset = offset_ - rld_archive_fhdr_size; - if (::elf_rand (archive_->elf_, offset) != offset) - libelf_error ("rand: " + archive_->name_); - } - - /* - * Note, the elf passed is either the archive or NULL. - */ - elf* elf__ = ::elf_begin (fd__, - writable_ ? ELF_C_WRITE : ELF_C_READ, - archive_ ? archive_->elf_ : 0); - if (!elf__) - libelf_error ("begin: " + name__); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf::begin: " << elf__ << ' ' << name__ << std::endl; - - elf_kind ek = ::elf_kind (elf__); - - /* - * If this is inside an archive it must be an ELF file. - */ - - if (archive_ && (ek != ELF_K_ELF)) - throw rld::error ("File format in archive not ELF", - "elf:file:begin: " + name__); - else - { - if (ek == ELF_K_AR) - archive = true; - else if (ek == ELF_K_ELF) - archive = false; - else - throw rld::error ("File format not ELF or archive", - "elf:file:begin: " + name__); - } - - if (!writable_) - { - /* - * If an ELF file make sure they all match. On the first file that - * begins an ELF session record its settings. - */ - if (ek == ELF_K_ELF) - { - oclass = ::gelf_getclass (elf__); - ident_str = elf_getident (elf__, &ident_size); - } - } - - fd_ = fd__; - name_ = name__; - writable = writable_; - elf_ = elf__; - - if (!archive && !writable) - { - load_header (); - load_sections (); - } - } - - void - file::end () - { - if (elf_) - { - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "libelf::end: " << elf_ - << ' ' << name_ << std::endl; - ::elf_end (elf_); - elf_ = 0; - } - - if (fd_ >= 0) - { - if (!writable) - { - if (ehdr) - { - delete ehdr; - ehdr = 0; - } - if (phdr) - { - delete phdr; - phdr = 0; - } - } - - fd_ = -1; - name_.clear (); - archive = false; - elf_ = 0; - oclass = 0; - ident_str = 0; - ident_size = 0; - writable = false; - secs.clear (); - } - } - - void - file::write () - { - check_writable ("write"); - - std::string shstrtab; - - for (section_table::iterator sti = secs.begin (); - sti != secs.end (); - ++sti) - { - section& sec = (*sti).second; - int added_at = shstrtab.size (); - shstrtab += '\0' + sec.name (); - sec.set_name (added_at + 1); - } - - unsigned int shstrtab_name = shstrtab.size () + 1; - - /* - * Done this way to clang happy on darwin. - */ - shstrtab += '\0'; - shstrtab += ".shstrtab"; - - /* - * Create the string table section. - */ - section shstrsec (*this, - secs.size () + 1, /* index */ - ".shstrtab", /* name */ - SHT_STRTAB, /* type */ - 1, /* alignment */ - SHF_STRINGS | SHF_ALLOC, /* flags */ - 0, /* address */ - 0, /* offset */ - shstrtab.size ()); /* size */ - - shstrsec.add_data (ELF_T_BYTE, - 1, - shstrtab.size (), - (void*) shstrtab.c_str ()); - - shstrsec.set_name (shstrtab_name); - - ::elf_setshstrndx (elf_, shstrsec.index ()); - ::elf_flagehdr (elf_, ELF_C_SET, ELF_F_DIRTY); - - if (elf_update (elf_, ELF_C_NULL) < 0) - libelf_error ("elf_update:layout: " + name_); - - ::elf_flagphdr (elf_, ELF_C_SET, ELF_F_DIRTY); - - if (::elf_update (elf_, ELF_C_WRITE) < 0) - libelf_error ("elf_update:write: " + name_); - } - - void - file::load_header () - { - check ("load_header"); - - if (!ehdr) - { - if (!writable) - ehdr = new elf_ehdr; - else - { - throw rld::error ("No ELF header; set the header first", - "elf:file:load_header: " + name_); - } - } - - if (::gelf_getehdr (elf_, ehdr) == 0) - error ("gelf_getehdr"); - } - - unsigned int - file::machinetype () const - { - check_ehdr ("machinetype"); - return ehdr->e_machine; - } - - unsigned int - file::type () const - { - check_ehdr ("type"); - return ehdr->e_type; - } - - unsigned int - file::object_class () const - { - check ("object_class"); - return oclass; - } - - unsigned int - file::data_type () const - { - check ("data_type"); - if (!ident_str) - throw rld::error ("No ELF ident str", "elf:file:data_type: " + name_); - return ident_str[EI_DATA]; - } - - bool - file::is_archive () const - { - check ("is_archive"); - return archive; - } - - bool - file::is_executable () const - { - check_ehdr ("is_executable"); - return ehdr->e_type != ET_REL; - } - - bool - file::is_relocatable() const - { - check_ehdr ("is_relocatable"); - return ehdr->e_type == ET_REL; - } - - int - file::section_count () const - { - check_ehdr ("section_count"); - return ehdr->e_shnum; - } - - void - file::load_sections () - { - if (secs.empty ()) - { - check ("load_sections_headers"); - for (int sn = 0; sn < section_count (); ++sn) - { - section sec (*this, sn); - secs[sec.name ()] = sec; - } - } - } - - void - file::get_sections (sections& filtered_secs, unsigned int type) - { - load_sections (); - for (section_table::iterator si = secs.begin (); - si != secs.end (); - ++si) - { - section& sec = (*si).second; - if ((type == 0) || (sec.type () == type)) - filtered_secs.push_back (&sec); - } - } - - section& - file::get_section (int index) - { - load_sections (); - for (section_table::iterator si = secs.begin (); - si != secs.end (); - ++si) - { - section& sec = (*si).second; - if (index == sec.index ()) - return sec; - } - - throw rld::error ("section index '" + rld::to_string (index) + "'not found", - "elf:file:get_section: " + name_); - } - - int - file::strings_section () const - { - check_ehdr ("strings_sections"); - return ehdr->e_shstrndx; - } - - void - file::load_symbols () - { - if (symbols.empty ()) - { - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:symbol: " << name () << std::endl; - - sections symbol_secs; - - get_sections (symbol_secs, SHT_SYMTAB); - - for (sections::iterator si = symbol_secs.begin (); - si != symbol_secs.end (); - ++si) - { - section& sec = *(*si); - int syms = sec.entries (); - - for (int s = 0; s < syms; ++s) - { - elf_sym esym; - - if (!::gelf_getsym (sec.data (), s, &esym)) - error ("gelf_getsym"); - - std::string name = get_string (sec.link (), esym.st_name); - symbols::symbol sym (s, name, esym); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:symbol: " << sym << std::endl; - - symbols.push_back (sym); - } - } - } - } - - void - file::get_symbols (symbols::pointers& filtered_syms, - bool unresolved, - bool local, - bool weak, - bool global) - { - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "elf:get-syms: unresolved:" << unresolved - << " local:" << local - << " weak:" << weak - << " global:" << global - << " " << name_ - << std::endl; - - load_symbols (); - - filtered_syms.clear (); - - for (symbols::bucket::iterator si = symbols.begin (); - si != symbols.end (); - ++si) - { - symbols::symbol& sym = *si; - - int stype = sym.type (); - int sbind = sym.binding (); - - /* - * If wanting unresolved symbols and the type is no-type and the - * section is undefined, or, the type is no-type or object or function - * and the bind is local and we want local symbols, or the bind is weak - * and we want weak symbols, or the bind is global and we want global - * symbols then add the filtered symbols container. - */ - bool add = false; - - if ((stype == STT_NOTYPE) && - (sbind == STB_GLOBAL) && - (sym.section_index () == SHN_UNDEF)) - { - if (unresolved) - add = true; - } - else - { - if (((stype == STT_NOTYPE) || - (stype == STT_OBJECT) || - (stype == STT_FUNC)) && - ((weak && (sbind == STB_WEAK)) || - (!unresolved && ((local && (sbind == STB_LOCAL)) || - (global && (sbind == STB_GLOBAL)))))) - add = true; - } - - if (add) - filtered_syms.push_back (&sym); - } - } - - const symbols::symbol& - file::get_symbol (const int index) const - { - for (symbols::bucket::const_iterator si = symbols.begin (); - si != symbols.end (); - ++si) - { - const symbols::symbol& sym = *si; - if (index == sym.index ()) - return sym; - } - - throw rld::error ("symbol index '" + rld::to_string (index) + "' not found", - "elf:file:get_symbol: " + name_); - } - - void - file::load_relocations () - { - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:reloc: " << name () << std::endl; - - sections rel_secs; - - get_sections (rel_secs, SHT_REL); - get_sections (rel_secs, SHT_RELA); - - for (sections::iterator si = rel_secs.begin (); - si != rel_secs.end (); - ++si) - { - section& sec = *(*si); - section& targetsec = get_section (sec.info ()); - int rels = sec.entries (); - bool rela = sec.type () == SHT_RELA; - - targetsec.set_reloc_type (rela); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:reloc: " << sec.name () - << " -> " << targetsec.name () - << std::endl; - - for (int r = 0; r < rels; ++r) - { - if (rela) - { - elf_rela erela; - - if (!::gelf_getrela (sec.data (), r, &erela)) - error ("gelf_getrela"); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:reloc: rela: offset: " << erela.r_offset - << " sym:" << GELF_R_SYM (erela.r_info) - << " type:" << GELF_R_TYPE (erela.r_info) - << " addend:" << erela.r_addend - << std::endl; - - /* - * The target section is updated with the fix up, and symbol - * section indicates the section offset being referenced by the - * fixup. - */ - - const symbols::symbol& sym = get_symbol (GELF_R_SYM (erela.r_info)); - - relocation reloc (sym, - erela.r_offset, - erela.r_info, - erela.r_addend); - - targetsec.add (reloc); - } - else - { - elf_rel erel; - - if (!::gelf_getrel (sec.data (), r, &erel)) - error ("gelf_getrel"); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "elf:reloc: rel: offset: " << erel.r_offset - << " sym:" << GELF_R_SYM (erel.r_info) - << " type:" << GELF_R_TYPE (erel.r_info) - << std::endl; - - const symbols::symbol& sym = get_symbol (GELF_R_SYM (erel.r_info)); - - relocation reloc (sym, erel.r_offset, erel.r_info); - - targetsec.add (reloc); - } - } - } - } - - std::string - file::get_string (int section, size_t offset) - { - check ("get_string"); - char* s = ::elf_strptr (elf_, section, offset); - if (!s) - error ("elf_strptr"); - return s; - } - - std::string - file::get_string (size_t offset) - { - check ("get_string"); - char* s = ::elf_strptr (elf_, strings_section (), offset); - if (!s) - error ("elf_strptr"); - return s; - } - - void - file::set_header (elf_half type, - int class_, - elf_half machinetype, - unsigned char datatype) - { - check_writable ("set_header"); - - if (ehdr) - throw rld::error ("ELF header already set", - "elf:file:set_header: " + name_); - - ehdr = (elf_ehdr*) ::gelf_newehdr (elf_, class_); - if (ehdr == 0) - error ("gelf_newehdr"); - - if (class_ == ELFCLASS32) - { - if((ehdr = (elf_ehdr*) ::elf32_getehdr (elf_)) == 0) - error ("elf32_getehdr"); - } - else if (::gelf_getehdr (elf_, ehdr) == 0) - error ("gelf_getehdr"); - - if (class_ == ELFCLASS32) - { - ((elf32_ehdr*)ehdr)->e_type = type; - ((elf32_ehdr*)ehdr)->e_machine = machinetype; - ((elf32_ehdr*)ehdr)->e_flags = 0; - ((elf32_ehdr*)ehdr)->e_ident[EI_DATA] = datatype; - ((elf32_ehdr*)ehdr)->e_version = EV_CURRENT; - } - else - { - ehdr->e_type = type; - ehdr->e_machine = machinetype; - ehdr->e_flags = 0; - ehdr->e_ident[EI_DATA] = datatype; - ehdr->e_version = EV_CURRENT; - } - - ::elf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY); - } - - void - file::add (section& sec) - { - check_writable ("add"); - secs[sec.name ()] = sec; - } - - void - file::add (program_header& phdr) - { - check_writable ("add"); - phdrs.push_back (phdr); - } - - elf* - file::get_elf () - { - return elf_; - } - - const std::string& - file::name () const - { - return name_; - } - - bool - file::is_writable () const - { - return writable; - } - - void - file::check (const char* where) const - { - if (!elf_ || (fd_ < 0)) - { - std::string w = where; - throw rld::error ("No ELF file or file descriptor", "elf:file:" + w); - } - } - - void - file::check_ehdr (const char* where) const - { - check (where); - if (!ehdr) - { - std::string w = where; - throw rld::error ("no elf header", "elf:file:" + w); - } - } - - void - file::check_phdr (const char* where) const - { - check (where); - if (!phdr) - { - std::string w = where; - throw rld::error ("no elf program header", "elf:file:" + w); - } - } - - void - file::check_writable (const char* where) const - { - check (where); - if (!writable) - { - std::string w = where; - throw rld::error ("not writable", "elf:file:" + w); - } - } - - void - file::error (const char* where) const - { - std::string w = where; - libelf_error (w + ": " + name_); - } - - const std::string - machine_type (unsigned int machinetype) - { - struct types_and_labels - { - const char* name; //< The RTEMS label. - unsigned int machinetype; //< The machine type. - }; - types_and_labels types_to_labels[] = - { - { "arm", EM_ARM }, - { "avr", EM_AVR }, - { "bfin", EM_BLACKFIN }, - { "h8300", EM_H8_300 }, - { "i386", EM_386 }, - /* { "m32c", EM_M32C }, Not in libelf I imported */ - { "m32r", EM_M32R }, - { "m68k", EM_68K }, - { "m68k", EM_COLDFIRE }, - { "mips", EM_MIPS }, - { "powerpc", EM_PPC }, - { "sh", EM_SH }, - { "sparc", EM_SPARC }, - { "sparc64", EM_SPARC }, - { 0, EM_NONE } - }; - - int m = 0; - while (types_to_labels[m].machinetype != EM_NONE) - { - if (machinetype == types_to_labels[m].machinetype) - return types_to_labels[m].name; - ++m; - } - - std::ostringstream what; - what << "unknown machine type: " << elf_object_machinetype; - throw rld::error (what, "machine-type"); - } - - const std::string - machine_type () - { - return machine_type (elf_object_machinetype); - } - - unsigned int - object_class () - { - return elf_object_class; - } - - unsigned int - object_machine_type () - { - return elf_object_machinetype; - } - - unsigned int - object_datatype () - { - return elf_object_datatype; - } - - void - check_file(const file& file) - { - if (elf_object_machinetype == EM_NONE) - elf_object_machinetype = file.machinetype (); - else if (file.machinetype () != elf_object_machinetype) - { - std::ostringstream oss; - oss << "elf:check_file:" << file.name () - << ": " << elf_object_machinetype << '/' << file.machinetype (); - throw rld::error ("Mixed machine types not supported.", oss.str ()); - } - - if (elf_object_class == ELFCLASSNONE) - elf_object_class = file.object_class (); - else if (file.object_class () != elf_object_class) - throw rld::error ("Mixed classes not allowed (32bit/64bit).", - "elf:check_file: " + file.name ()); - - if (elf_object_datatype == ELFDATANONE) - elf_object_datatype = file.data_type (); - else if (elf_object_datatype != file.data_type ()) - throw rld::error ("Mixed data types not allowed (LSB/MSB).", - "elf:check_file: " + file.name ()); - } - - } -} diff --git a/linkers/rld-elf.h b/linkers/rld-elf.h deleted file mode 100644 index fffe036..0000000 --- a/linkers/rld-elf.h +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker ELF module manages the libelf interface. - * - */ - -#if !defined (_RLD_ELF_H_) -#define _RLD_ELF_H_ - -#include -#include -#include - -#include - -namespace rld -{ - namespace elf - { - /** - * Forward decl. - */ - class file; - - /** - * A relocation record. - */ - class relocation - { - public: - /** - * Construct a relocation record. - * - * @param sym The symbol the relocation references. - * @param offset The offset in the section the relocation applies to. - * @param info The relocation info. - * @param addend The constant addend value. - */ - relocation (const symbols::symbol& sym, - elf_addr offset, - elf_xword info, - elf_sxword addend = 0); - - /** - * Default constructor. - */ - relocation (); - - /** - * The offset. - */ - elf_addr offset () const; - - /** - * The type of the relocation record. - */ - uint32_t type () const; - - /** - * The info. - */ - elf_xword info () const; - - /** - * The constant addend. - */ - elf_sxword addend () const; - - /** - * Return the symbol. - */ - const symbols::symbol& symbol () const; - - private: - const symbols::symbol* sym; //< The symbol reference. - elf_addr offset_; //< The offset in the section. - elf_xword info_; //< The record's information. - elf_sxword addend_; //< The constant addend value. - }; - - /** - * A container of relocation records. - */ - typedef std::vector < relocation > relocations; - - /** - * An ELF Section. The current implementation only supports a single data - * descriptor with a section. - */ - class section - { - public: - /** - * Construct the section getting the details from the ELF file given the - * section index. - * - * The section types are (from elf(3)): - * - * Section Type Library Type Description - * ------------ ------------ ----------- - * SHT_DYNAMIC ELF_T_DYN `.dynamic' section entries. - * SHT_DYNSYM ELF_T_SYM Symbols for dynamic linking. - * SHT_FINI_ARRAY ELF_T_ADDR Termination function pointers. - * SHT_GROUP ELF_T_WORD Section group marker. - * SHT_HASH ELF_T_HASH Symbol hashes. - * SHT_INIT_ARRAY ELF_T_ADDR Initialization function pointers. - * SHT_NOBITS ELF_T_BYTE Empty sections. See elf(5). - * SHT_NOTE ELF_T_NOTE ELF note records. - * SHT_PREINIT_ARRAY ELF_T_ADDR Pre-initialization function - * pointers. - * SHT_PROGBITS ELF_T_BYTE Machine code. - * SHT_REL ELF_T_REL ELF relocation records. - * SHT_RELA ELF_T_RELA Relocation records with addends. - * SHT_STRTAB ELF_T_BYTE String tables. - * SHT_SYMTAB ELF_T_SYM Symbol tables. - * SHT_SYMTAB_SHNDX ELF_T_WORD Used with extended section - * numbering. - * SHT_GNU_verdef ELF_T_VDEF Symbol version definitions. - * SHT_GNU_verneed ELF_T_VNEED Symbol versioning requirements. - * SHT_GNU_versym ELF_T_HALF Version symbols. - * SHT_SUNW_move ELF_T_MOVE ELF move records. - * SHT_SUNW_syminfo ELF_T_SYMINFO Additional symbol flags. - * - * @param file_ The ELF file this section is part of. - * @param index_ The section's index. - * @param name The section's name. - * @param type The section's type. - * @param alignment The section's alignment. - * @param flags The section's flags. - * @param addr The section's in-memory address. - * @param offset The section's offset in the file. - * @param size The section's file in bytes. - * @param link The section's header table link. - * @param info The section's extra information. - * @param entry_size The section's entry size. - */ - section (file& file_, - int index_, - const std::string& name, - elf_word type, - elf_xword alignment, - elf_xword flags, - elf_addr addr, - elf_off offset, - elf_xword size, - elf_word link = 0, - elf_word info = 0, - elf_xword entry_size = 0); - - /** - * Construct the section given the details. The ELF file must be - * writable. - * - * @param file_ The ELF file this section is part of. - * @param index The section's index in the ELF file. - */ - section (file& file_, int index); - - /** - * Copy constructor. - */ - section (const section& orig); - - /** - * Default constructor. - */ - section (); - - /** - * Add a data segment descriptor to the section if the file is writable. - * - * These are following data types (from elf(3)): - * - * ELF_T_ADDR Machine addresses. - * ELF_T_BYTE Byte data. The library will not attempt to translate - * byte data. - * ELF_T_CAP Software and hardware capability records. - * ELF_T_DYN Records used in a section of type SHT_DYNAMIC. - * ELF_T_EHDR ELF executable header. - * ELF_T_HALF 16-bit unsigned words. - * ELF_T_LWORD 64 bit unsigned words. - * ELF_T_MOVE ELF Move records. - * ELF_T_NOTE ELF Note structures. - * ELF_T_OFF File offsets. - * ELF_T_PHDR ELF program header table entries. - * ELF_T_REL ELF relocation entries. - * ELF_T_RELA ELF relocation entries with addends. - * ELF_T_SHDR ELF section header entries. - * ELF_T_SWORD Signed 32-bit words. - * ELF_T_SXWORD Signed 64-bit words. - * ELF_T_SYMINFO ELF symbol information. - * ELF_T_SYM ELF symbol table entries. - * ELF_T_VDEF Symbol version definition records. - * ELF_T_VNEED Symbol version requirement records. - * ELF_T_WORD Unsigned 32-bit words. - * ELF_T_XWORD Unsigned 64-bit words. - * - * @param type The type of data in the segment. - * @param alignment The in-file alignment of the data. Must be a power of 2. - * @param size The number of bytes in this data descriptor. - * @param buffer The data in memory. - * @param offset The offset within the containing section. Can be computed. - */ - void add_data (elf_type type, - elf_xword alignment, - elf_xword size, - void* buffer = 0, - elf_off offset = 0); - - /** - * The section's index in the ELF file. - * - * @return int The section number. - */ - int index () const; - - /** - * The name of the section. - * - * @return const std::string& The section's name. - */ - const std::string& name () const; - - /** - * The section's data. - */ - elf_data* data (); - - /** - * Get the type of the section. - */ - elf_word type () const; - - /** - * The section flags. - */ - elf_xword flags () const; - - /** - * In-memory address of the section. - */ - elf_addr address () const; - - /** - * Alignment constraint. - */ - elf_xword alignment () const; - - /** - * The file offset of the section. - */ - elf_off offset () const; - - /** - * The header table link. - */ - elf_word link () const; - - /** - * Extra information. - */ - elf_word info () const; - - /** - * Size of the section. - */ - elf_xword size () const; - - /** - * Size of the entries in the section. - */ - elf_xword entry_size () const; - - /** - * Number of entries. - */ - int entries () const; - - /** - * Return true if the relocation record have an addend field. - * - * @retval true The relocation record have the addend field. - */ - bool get_reloc_type () const; - - /** - * Set the name index if writable. This is normally done - * automatically when adding the section to the file. - */ - void set_name (unsigned int index); - - /** - * Set the type of relocation records. - * - * @param rela If true the records are rela type. - */ - void set_reloc_type (bool rela); - - /** - * Add a relocation. - * - * @param reloc The relocation record to add. - */ - void add (const relocation& reloc); - - /** - * Get the relocations. - */ - const relocations& get_relocations () const; - - private: - - /** - * Check the section is valid. - * - * @param where Where the check is being made. - */ - void check (const char* where) const; - - /** - * Check the section is valid and writable. - * - * @param where Where the check is being made. - */ - void check_writable (const char* where) const; - - file* file_; //< The ELF file. - int index_; //< The section header index. - std::string name_; //< The section's name. - elf_scn* scn; //< ELF private section data. - elf_shdr shdr; //< The section header. - elf_data* data_; //< The section's data. - bool rela; //< The type of relocation records. - relocations relocs; //< The relocation records. - }; - - /** - * Container of ELF section pointers. - */ - typedef std::list < section* > sections; - - /** - * Container of ELF section as a map, ie associative array. - */ - typedef std::map < std::string, section > section_table; - - /** - * An ELF program header. - */ - class program_header - { - public: - /** - * Construct a program header. - */ - program_header (); - - /** - * Desctruct a program header. - */ - ~program_header (); - - /** - * Set the program header. - * - * @param type The type of segment. - * @param flags The segment's flags. - * @param offset The offet to segment. - * @param filesz The segment size in the file. - * @param memsz The segment size in memory. - * @param align The segment alignment. - * @param vaddr The virtual address in memory. - * @param paddr The physical address if any. - */ - void set (elf_word type, - elf_word flags, - elf_off offset, - elf_xword filesz, - elf_xword memsz, - elf_xword align, - elf_addr vaddr, - elf_addr paddr = 0); - - private: - - elf_phdr phdr; //< The ELF program header. - }; - - /** - * A container of program headers. - */ - typedef std::list < program_header > program_headers; - - /** - * An ELF file. - */ - class file - { - public: - /** - * Construct an ELF file. - */ - file (); - - /** - * Destruct the ELF file object. - */ - ~file (); - - /** - * Begin using the ELF file. - * - * @param name The full name of the file. - * @param fd The file descriptor to read or write the file. - * @param writable The file is writeable. The default is false. - */ - void begin (const std::string& name, int fd, const bool writable = false); - - /** - * Begin using the ELF file in an archive. - * - * @param name The full name of the file. - * @param archive The file that is the archive. - * @param offset The offset of the ELF file in the archive. - */ - void begin (const std::string& name, file& archive, off_t offset); - - /** - * End using the ELF file. - */ - void end (); - - /** - * Write the ELF file creating it if it is writable. You should have - * added the sections and the data segment descriptors to the sections - * before calling write. - */ - void write (); - - /** - * Load the header. Done automatically. - */ - void load_header (); - - /** - * Get the machine type. - */ - unsigned int machinetype () const; - - /** - * Get the type of ELF file. - */ - unsigned int type () const; - - /** - * Get the class of the object file. - */ - unsigned int object_class () const; - - /** - * Get the data type, ie LSB or MSB. - */ - unsigned int data_type () const; - - /** - * Is the file an archive format file ? - */ - bool is_archive () const; - - /** - * Is the file an executable ? - */ - bool is_executable () const; - - /** - * Is the file relocatable ? - */ - bool is_relocatable() const; - - /** - * The number of sections in the file. - */ - int section_count () const; - - /** - * Load the sections. - */ - void load_sections (); - - /** - * Get a filtered container of the sections. The key is the section - * type. If the sections are not loaded they are loaded. If the type is 0 - * all sections are returned. - * - * @param filtered_secs The container the copy of the filtered sections - * are placed in. - * @param type The type of sections to filter on. If 0 all sections are - * matched. - */ - void get_sections (sections& filtered_secs, unsigned int type); - - /** - * Return the section with given index. - * - * @param index The section's index to look for. - * @retval section The section matching the index. - */ - section& get_section (int index); - - /** - * Return the index of the string section. - */ - int strings_section () const; - - /** - * Get the string from the specified section at the requested offset. - * - * @param section The section to search for the string. - * @param offset The offset in the string section. - * @return std::string The string. - */ - std::string get_string (int section, size_t offset); - - /** - * Get the string from the ELF header declared string section at the - * requested offset. - * - * @param offset The offset in the string section. - * @return std::string The string. - */ - std::string get_string (size_t offset); - - /** - * Load the symbols. - */ - void load_symbols (); - - /** - * Get a filtered container of symbols given the various types. If the - * symbols are not loaded they are loaded. - * - * @param filtered_syms The filtered symbols found in the file. This is a - * container of pointers. - * @param unresolved Return unresolved symbols. - * @param local Return local symbols. - * @param weak Return weak symbols. - * @param global Return global symbols. - */ - void get_symbols (rld::symbols::pointers& filtered_syms, - bool unresolved = false, - bool local = false, - bool weak = true, - bool global = true); - - /** - * Get the symbol by index in the symtabl section. - */ - const symbols::symbol& get_symbol (const int index) const; - - /** - * Load the relocation records. - */ - void load_relocations (); - - /** - * Clear the relocation records. - */ - void clear_relocations (); - - /** - * Set the ELF header. Must be writable. - * - * The classes are: - * ELFCLASSNONE This class is invalid. - * ELFCLASS32 This defines the 32-bit architecture. It sup- ports - * machines with files and virtual address spa- ces up to - * 4 Gigabytes. - * ELFCLASS64 This defines the 64-bit architecture. - * - * The types are: - * ET_NONE An unknown type. - * ET_REL A relocatable file. - * ET_EXEC An executable file. - * ET_DYN A shared object. - * ET_CORE A core file. - * - * The machine types are: - * TDB - * - * The datatypes are: - * ELFDATA2LSB Two's complement, little-endian. - * ELFDATA2MSB Two's complement, big-endian. - * - * @param type The type of ELF file, ie executable, relocatable etc. - * @param class_ The files ELF class. - * @param machinetype The type of machine code present in the ELF file. - * @param datatype The data type, ie LSB or MSB. - */ - void set_header (elf_half type, - int class_, - elf_half machinetype, - unsigned char datatype); - - /** - * Add a section to the ELF file if writable. - */ - void add (section& sec); - - /** - * Add a program header to the ELF file if writable. - */ - void add (program_header& phdr); - - /** - * Get the ELF reference. - */ - elf* get_elf (); - - /** - * Get the name of the file. - */ - const std::string& name () const; - - /** - * Is the file writable ? - */ - bool is_writable () const; - - private: - - /** - * Begin using the ELF file. - * - * @param name The full name of the file. - * @param fd The file descriptor to read or write the file. - * @param writable The file is writeable. It cannot be part of an archive. - * @param archive The archive's ELF handle or 0 if not an archive. - * @param offset The offset of the ELF file in the archive if elf is non-zero. - */ - void begin (const std::string& name, - int fd, - const bool writable, - file* archive, - off_t offset); - - /** - * Check if the file is usable. Throw an exception if not. - * - * @param where Where the check is performed. - */ - void check (const char* where) const; - - /** - * Check if the file is usable and writable. Throw an exception if not. - * - * @param where Where the check is performed. - */ - void check_writable (const char* where) const; - - /** - * Check if the ELF header is valid. Throw an exception if not. - * - * @param where Where the check is performed. - */ - void check_ehdr (const char* where) const; - - /** - * Check if the ELF program header is valid. Throw an exception if not. - * - * @param where Where the check is performed. - */ - void check_phdr (const char* where) const; - - /** - * Generate libelf error. - * - * @param where Where the error is generated. - */ - void error (const char* where) const; - - int fd_; //< The file handle. - std::string name_; //< The name of the file. - bool archive; //< The ELF file is part of an archive. - bool writable; //< The file is writeable. - elf* elf_; //< The ELF handle. - unsigned int mtype; //< The machine type. - unsigned int oclass; //< The object class. - const char* ident_str; //< The ELF file's ident string. - size_t ident_size; //< The size of the ident. - elf_ehdr* ehdr; //< The ELF header. - elf_phdr* phdr; //< The ELF program header. - section_table secs; //< The sections as a table. - program_headers phdrs; //< The program headers when creating - // ELF files. - rld::symbols::bucket symbols; //< The symbols. All tables point here. - }; - - /** - * Return the machine type label given the machine type. - * - * @param machinetype The ELF machine type. - */ - const std::string machine_type (unsigned int machinetype); - - /** - * Return the global machine type set by the check_file call as a string. - */ - const std::string machine_type (); - - /** - * Return the global class set by the check_file call. - */ - unsigned int object_class (); - - /** - * Return the global machine type set by the check_file call. - */ - unsigned int object_machine_type (); - - /** - * Return the global data type set by the check_file call. - */ - unsigned int object_datatype (); - - /** - * Check the file against the global machine type, object class and data - * type. If this is the first file checked it becomes the default all - * others are checked against. This is a simple way to make sure all files - * are the same type. - * - * @param file The check to check. - */ - void check_file(const file& file); - - } -} - -#endif diff --git a/linkers/rld-files.cpp b/linkers/rld-files.cpp deleted file mode 100644 index 03310e8..0000000 --- a/linkers/rld-files.cpp +++ /dev/null @@ -1,1586 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#if __WIN32__ -#define CREATE_MODE (S_IRUSR | S_IWUSR) -#define OPEN_FLAGS (O_BINARY) -#else -#define CREATE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) -#define OPEN_FLAGS (0) -#endif - -namespace rld -{ - namespace files - { - /** - * Scan the decimal number returning the value found. - */ - uint64_t - scan_decimal (const uint8_t* string, size_t len) - { - uint64_t value = 0; - - while (len && (*string != ' ')) - { - value *= 10; - value += *string - '0'; - ++string; - --len; - } - - return value; - } - - void - set_number (uint32_t value, uint8_t* string, size_t len, bool octal = false) - { - std::ostringstream oss; - if (octal) - oss << std::oct; - oss << value; - size_t l = oss.str ().length (); - if (l > len) - l = len; - memcpy (string, oss.str ().c_str (), l); - } - - file::file (const std::string& aname, - const std::string& oname, - off_t offset, - size_t size) - : aname_ (aname), - oname_ (oname), - offset_ (offset), - size_ (size) - { - } - - file::file (const std::string& path, bool is_object) - : offset_ (0), - size_ (0) - { - set (path, is_object); - } - - file::file () - : offset_ (0), - size_ (0) - { - } - - void - file::set (const std::string& path, bool is_object) - { - /* - * If there is a path look for a colon. If there is no colon we assume - * it is an object file. If the colon is the last character in the path - * it is just an archive. - */ - if (!path.empty ()) - { - bool get_size = false; - if (is_object) - { - size_t colon = path.find_last_of (':'); - if ((colon != std::string::npos) && (colon > RLD_DRIVE_SEPARATOR)) - { - aname_ = path.substr (0, colon - 1); - oname_ = path.substr (colon + 1); - // @todo Add offset scanning. - } - else - { - oname_ = path; - get_size = true; - } - } - else - { - aname_ = path; - get_size = true; - } - - if (get_size) - { - struct stat sb; - if (::stat (path.c_str (), &sb) == 0) - size_ = sb.st_size; - } - } - } - - bool - file::is_archive () const - { - return !aname_.empty () && oname_.empty (); - } - - bool - file::is_object () const - { - return !oname_.empty (); - } - - bool - file::is_valid () const - { - return !aname_.empty () || !oname_.empty (); - } - - bool - file::exists () const - { - /* - * No name set returns false. - */ - bool result = false; - const std::string p = path (); - if (!p.empty ()) - result = path::check_file (p); - return result; - } - - const std::string - file::path () const - { - if (!aname_.empty ()) - return aname_; - return oname_; - } - - const std::string - file::full () const - { - std::string f; - if (!aname_.empty ()) - { - f = aname_; - if (!oname_.empty ()) - f += ':'; - } - if (!oname_.empty ()) - f += oname_; - if (!aname_.empty () && !oname_.empty ()) - f += '@' + rld::to_string (offset_); - return f; - } - - const std::string - file::basename () const - { - return rld::path::basename (full ()); - } - - const std::string& - file::aname () const - { - return aname_; - } - - const std::string& - file::oname () const - { - return oname_; - } - - off_t - file::offset () const - { - return offset_; - } - - size_t - file::size () const - { - return size_; - } - - image::image (file& name) - : name_ (name), - references_ (0), - fd_ (-1), - symbol_refs (0), - writable (false) - { - } - - image::image (const std::string& path, bool is_object) - : name_ (path, is_object), - references_ (0), - fd_ (-1), - symbol_refs (0), - writable (false) - { - } - - image::image () - : references_ (0), - fd_ (-1), - symbol_refs (0), - writable (false) - { - } - - image::~image () - { - if (references_) - throw rld_error_at ("references when destructing image"); - if (fd_ >= 0) - ::close (fd_); - } - - void - image::open (file& name) - { - name_ = name; - open (); - } - - void - image::open (bool writable_) - { - const std::string path = name_.path (); - - if (path.empty ()) - throw rld::error ("No file name", "open:" + path); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_FILE) - std::cout << "image::open: " << name (). full () - << " refs:" << references_ + 1 - << " writable:" << (char*) (writable_ ? "yes" : "no") - << std::endl; - - if (fd_ < 0) - { - writable = writable_; - - if (writable) - fd_ = ::open (path.c_str (), OPEN_FLAGS | O_RDWR | O_CREAT | O_TRUNC, CREATE_MODE); - else - fd_ = ::open (path.c_str (), OPEN_FLAGS | O_RDONLY); - if (fd_ < 0) - throw rld::error (::strerror (errno), "open:" + path); - } - else - { - if (writable_ != writable) - throw rld::error ("Cannot change write status", "open:" + path); - } - - ++references_; - } - - void - image::close () - { - if (references_ > 0) - { - if (rld::verbose () >= RLD_VERBOSE_TRACE_FILE) - std::cout << "image::close: " << name ().full () - << " refs:" << references_ << std::endl; - - --references_; - if (references_ == 0) - { - ::close (fd_); - fd_ = -1; - } - } - } - - ssize_t - image::read (void* buffer_, size_t size) - { - uint8_t* buffer = static_cast (buffer_); - size_t have_read = 0; - size_t to_read = size; - while (have_read < size) - { - const ssize_t rsize = ::read (fd (), buffer, to_read); - if (rsize < 0) - throw rld::error (strerror (errno), "read:" + name ().path ()); - if (rsize == 0) - break; - have_read += rsize; - to_read -= rsize; - buffer += rsize; - } - return have_read; - } - - ssize_t - image::write (const void* buffer_, size_t size) - { - const uint8_t* buffer = static_cast (buffer_); - size_t have_written = 0; - size_t to_write = size; - while (have_written < size) - { - const ssize_t wsize = ::write (fd (), buffer, to_write); - if (wsize < 0) - throw rld::error (strerror (errno), "write:" + name ().path ()); - have_written += wsize; - to_write -= wsize; - buffer += wsize; - } - return have_written; - } - - void - image::seek (off_t offset) - { - if (::lseek (fd (), name_.offset () + offset, SEEK_SET) < 0) - throw rld::error (strerror (errno), "lseek:" + name ().path ()); - } - - bool - image::seek_read (off_t offset, uint8_t* buffer, size_t size) - { - seek (offset); - return size == (size_t) read (buffer, size); - } - - bool - image::seek_write (off_t offset, const void* buffer, size_t size) - { - seek (offset); - return size == (size_t) write (buffer, size); - } - - const file& - image::name () const - { - return name_; - } - - int - image::references () const - { - return references_; - } - - size_t - image::size () const - { - return name ().size (); - } - - int - image::fd () const - { - return fd_; - } - - rld::elf::file& - image::elf () - { - return elf_; - } - - void - image::symbol_referenced () - { - ++symbol_refs; - } - - int - image::symbol_references () const - { - return symbol_refs; - } - - void - copy_file (image& in, image& out, size_t size) - { - #define COPY_FILE_BUFFER_SIZE (8 * 1024) - uint8_t* buffer = 0; - - if (size == 0) - size = in.name ().size (); - - try - { - buffer = new uint8_t[COPY_FILE_BUFFER_SIZE]; - while (size) - { - /* - * @fixme the reading and writing are not POSIX; sigints could split them. - */ - - size_t l = size < COPY_FILE_BUFFER_SIZE ? size : COPY_FILE_BUFFER_SIZE; - ssize_t r = ::read (in.fd (), buffer, l); - - if (r < 0) - throw rld::error (::strerror (errno), "reading: " + in.name ().full ()); - - if (r == 0) - { - std::ostringstream oss; - oss << "reading: " + in.name ().full () << " (" << size << ')'; - throw rld::error ("input too short", oss.str ()); - } - - ssize_t w = ::write (out.fd (), buffer, r); - - if (w < 0) - throw rld::error (::strerror (errno), "writing: " + out.name ().full ()); - - if (w != r) - throw rld::error ("output trucated", "writing: " + out.name ().full ()); - - size -= r; - } - } - catch (...) - { - delete [] buffer; - throw; - } - - if (buffer) - delete [] buffer; - } - - /** - * Defines for the header of an archive. - */ - #define rld_archive_ident "!\n" - #define rld_archive_ident_size (sizeof (rld_archive_ident) - 1) - #define rld_archive_fhdr_base rld_archive_ident_size - #define rld_archive_fname (0) - #define rld_archive_fname_size (16) - #define rld_archive_mtime (16) - #define rld_archive_mtime_size (12) - #define rld_archive_uid (28) - #define rld_archive_uid_size (6) - #define rld_archive_gid (34) - #define rld_archive_gid_size (6) - #define rld_archive_mode (40) - #define rld_archive_mode_size (8) - #define rld_archive_size (48) - #define rld_archive_size_size (10) - #define rld_archive_magic (58) - #define rld_archive_magic_size (2) - #define rld_archive_fhdr_size (60) - #define rld_archive_max_file_size (1024) - - archive::archive (const std::string& path) - : image (path, false) - { - if (!name ().is_valid ()) - throw rld_error_at ("name is empty"); - if (!name ().is_archive ()) - throw rld_error_at ("name is not an archive: " + name ().oname ()); - } - - archive::~archive () - { - end (); - close (); - } - - void - archive::begin () - { - if (references () == 1) - { - elf ().begin (name ().full (), fd ()); - - /* - * Make sure it is an archive. - */ - if (!elf ().is_archive ()) - throw rld::error ("Not an archive.", - "archive-begin:" + name ().full ()); - } - } - - void - archive::end () - { - if (references () == 1) - elf ().end (); - } - - bool - archive::is (const std::string& path) const - { - return name ().path () == path; - } - - bool - archive::is_valid () - { - open (); - uint8_t header[rld_archive_ident_size]; - seek_read (0, &header[0], rld_archive_ident_size); - bool result = ::memcmp (header, rld_archive_ident, - rld_archive_ident_size) == 0 ? true : false; - close (); - return result; - } - - void - archive::load_objects (objects& objs) - { - off_t extended_file_names = 0; - off_t offset = rld_archive_fhdr_base; - size_t size = 0; - - while (true) - { - uint8_t header[rld_archive_fhdr_size]; - - if (!read_header (offset, &header[0])) - break; - - /* - * The archive file headers are always aligned to an even address. - */ - size = - (scan_decimal (&header[rld_archive_size], - rld_archive_size_size) + 1) & ~1; - - /* - * Check for the GNU extensions. - */ - if (header[0] == '/') - { - off_t extended_off; - - switch (header[1]) - { - case ' ': - /* - * Symbols table. Ignore the table. - */ - break; - case '/': - /* - * Extended file names table. Remember. - */ - extended_file_names = offset + rld_archive_fhdr_size; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* - * Offset into the extended file name table. If we do not have the - * offset to the extended file name table find it. - */ - extended_off = scan_decimal (&header[1], rld_archive_fname_size); - - if (extended_file_names == 0) - { - off_t off = offset; - while (extended_file_names == 0) - { - size_t esize = - (scan_decimal (&header[rld_archive_size], - rld_archive_size_size) + 1) & ~1; - off += esize + rld_archive_fhdr_size; - - if (!read_header (off, &header[0])) - throw rld::error ("No GNU extended file name section found", - "get-names:" + name ().path ()); - - if ((header[0] == '/') && (header[1] == '/')) - { - extended_file_names = off + rld_archive_fhdr_size; - break; - } - } - } - - if (extended_file_names) - { - /* - * We know the offset in the archive to the extended file. Read - * the name from the table and compare with the name we are - * after. - */ - char cname[rld_archive_max_file_size]; - seek_read (extended_file_names + extended_off, - (uint8_t*) &cname[0], rld_archive_max_file_size); - add_object (objs, cname, - offset + rld_archive_fhdr_size, size); - } - break; - default: - /* - * Ignore the file because we do not know what it it. - */ - break; - } - } - else - { - /* - * Normal archive name. - */ - add_object (objs, - (char*) &header[rld_archive_fname], - offset + rld_archive_fhdr_size, size); - } - - offset += size + rld_archive_fhdr_size; - } - } - - bool - archive::operator< (const archive& rhs) const - { - return name ().path () < rhs.name ().path (); - } - - bool - archive::read_header (off_t offset, uint8_t* header) - { - if (!seek_read (offset, header, rld_archive_fhdr_size)) - return false; - - if ((header[rld_archive_magic] != 0x60) || - (header[rld_archive_magic + 1] != 0x0a)) - throw rld::error ("Invalid header magic numbers at " + - rld::to_string (offset), "read-header:" + name ().path ()); - - return true; - } - - void - archive::add_object (objects& objs, const char* path, off_t offset, size_t size) - { - const char* end = path; - while ((*end != '\0') && (*end != '/') && (*end != '\n')) - ++end; - - std::string str; - str.append (path, end - path); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "archive::add-object: " << str << std::endl; - - file n (name ().path (), str, offset, size); - objs[n.full()] = new object (*this, n); - } - - void - archive::write_header (const std::string& name, - uint32_t mtime, - int uid, - int gid, - int mode, - size_t size) - { - uint8_t header[rld_archive_fhdr_size]; - - memset (header, ' ', sizeof (header)); - - size_t len = name.length (); - if (len > rld_archive_fname_size) - len = rld_archive_fname_size; - memcpy (&header[rld_archive_fname], &name[0], len); - - set_number (mtime, header + rld_archive_mtime, rld_archive_mtime_size); - set_number (uid, header + rld_archive_uid, rld_archive_uid_size); - set_number (gid, header + rld_archive_gid, rld_archive_gid_size); - set_number (mode, header + rld_archive_mode, rld_archive_mode_size, true); - set_number (size, header + rld_archive_size, rld_archive_size_size); - - header[rld_archive_magic] = 0x60; - header[rld_archive_magic + 1] = 0x0a; - - write (header, sizeof (header)); - } - - void - archive::create (object_list& objects) - { - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - std::cout << "archive::create: " << name ().full () - << ", objects: " << objects.size () << std::endl; - - open (true); - - try - { - seek_write (0, rld_archive_ident, rld_archive_ident_size); - - /* - * GNU extended filenames. - */ - std::string extended_file_names; - - for (object_list::iterator oi = objects.begin (); - oi != objects.end (); - ++oi) - { - object& obj = *(*oi); - const std::string& oname = path::basename (obj.name ().oname ()); - if (oname.length () >= rld_archive_fname_size) - extended_file_names += oname + '\n'; - } - - if (!extended_file_names.empty ()) - { - if (extended_file_names.length () & 1) - { - extended_file_names += ' '; - } - write_header ("//", 0, 0, 0, 0, extended_file_names.length ()); - write (extended_file_names.c_str (), extended_file_names.length ()); - } - - for (object_list::iterator oi = objects.begin (); - oi != objects.end (); - ++oi) - { - object& obj = *(*oi); - - obj.open (); - - try - { - std::string oname = path::basename (obj.name ().oname ()); - - /* - * Convert the file name to an offset into the extended file name - * table if the file name is too long for the header. - */ - - if (oname.length () >= rld_archive_fname_size) - { - size_t pos = extended_file_names.find (oname + '\n'); - if (pos == std::string::npos) - throw rld_error_at ("extended file name not found"); - std::ostringstream oss; - oss << '/' << pos; - oname = oss.str (); - } - else oname += '/'; - - write_header (oname, 0, 0, 0, 0666, (obj.name ().size () + 1) & ~1); - obj.seek (0); - copy_file (obj, *this); - if (obj.name ().size () & 1) - write ("\n", 1); - } - catch (...) - { - obj.close (); - throw; - } - - obj.close (); - } - } - catch (...) - { - close (); - throw; - } - - close (); - } - - relocation::relocation (const elf::relocation& er) - : offset (er.offset ()), - type (er.type ()), - info (er.info ()), - addend (er.addend ()), - symname (er.symbol ().name ()), - symtype (er.symbol ().type ()), - symsect (er.symbol ().section_index ()), - symvalue (er.symbol ().value ()), - symbinding (er.symbol ().binding ()) - { - } - - section::section (const elf::section& es) - : name (es.name ()), - index (es.index ()), - type (es.type ()), - size (es.size ()), - alignment (es.alignment ()), - link (es.link ()), - info (es.info ()), - flags (es.flags ()), - offset (es.offset ()), - rela (es.get_reloc_type ()) - { - } - - void - section::load_relocations (const elf::section& es) - { - const elf::relocations& es_relocs = es.get_relocations (); - for (elf::relocations::const_iterator ri = es_relocs.begin (); - ri != es_relocs.end (); - ++ri) - { - relocs.push_back (relocation (*ri)); - } - rela = es.get_reloc_type (); - } - - size_t - sum_sizes (const sections& secs) - { - size_t size = 0; - - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const section& sec = *si; - - if ((size % sec.alignment) != 0) - size -= (size % sec.alignment) + sec.alignment; - size += sec.size; - } - - return size; - } - - const section* - find (const sections& secs, const int index) - { - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const section& sec = *si; - - if (index == sec.index) - return &sec; - } - - return 0; - } - - object::object (archive& archive_, file& name_) - : image (name_), - archive_ (&archive_), - valid_ (false), - resolving_ (false), - resolved_ (false) - { - if (!name ().is_valid ()) - throw rld_error_at ("name is empty"); - } - - object::object (const std::string& path) - : image (path), - archive_ (0), - valid_ (false), - resolving_ (false), - resolved_ (false) - { - if (!name ().is_valid ()) - throw rld_error_at ("name is empty"); - } - - object::object () - : archive_ (0), - valid_ (false), - resolving_ (false), - resolved_ (false) - { - } - - object::~object () - { - end (); - close (); - } - - void - object::open (bool writable) - { - if (archive_) - { - if (writable) - throw rld_error_at ("object files in archives are not writable"); - archive_->open (); - } - else - image::open (writable); - } - - void - object::close () - { - if (archive_) - { - archive_->end (); - archive_->close (); - } - else - { - end (); - image::close (); - } - } - - void - object::begin () - { - /* - * Begin a session. - */ - - if (rld::verbose () >= RLD_VERBOSE_TRACE_FILE) - std::cout << "object:begin: " << name ().full () << " in-archive:" - << ((char*) (archive_ ? "yes" : "no")) << std::endl; - - if (archive_) - elf ().begin (name ().full (), archive_->elf(), name ().offset ()); - else - elf ().begin (name ().full (), fd (), is_writable ()); - - /* - * Cannot be an archive. - */ - if (elf ().is_archive ()) - throw rld::error ("Is an archive not an object file.", - "object-begin:" + name ().full ()); - - /* - * We only support executable or relocatable ELF files. - */ - if (!is_writable ()) - { - if (!elf ().is_executable () && !elf ().is_relocatable ()) - throw rld::error ("Invalid ELF type (only ET_EXEC/ET_REL supported).", - "object-begin:" + name ().full ()); - - elf::check_file (elf ()); - - /** - * We assume the ELF file is invariant over the linking process. - */ - - if (secs.empty ()) - { - elf::sections elf_secs; - - elf ().get_sections (elf_secs, 0); - - for (elf::sections::const_iterator esi = elf_secs.begin (); - esi != elf_secs.end (); - ++esi) - { - secs.push_back (section (*(*esi))); - } - } - } - - /* - * This is a valid object file. The file format checks out. - */ - valid_ = true; - } - - void - object::end () - { - if (rld::verbose () >= RLD_VERBOSE_TRACE_FILE) - std::cout << "object:end: " << name ().full () << std::endl; - - elf ().end (); - } - - bool - object::valid () const - { - return valid_; - } - - void - object::load_symbols (rld::symbols::table& symbols, bool local) - { - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: " << name ().full () << std::endl; - - rld::symbols::pointers syms; - - elf ().get_symbols (syms, false, local, false, true); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: exported: total " - << syms.size () << std::endl; - - for (symbols::pointers::iterator si = syms.begin (); - si != syms.end (); - ++si) - { - symbols::symbol& sym = *(*si); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: exported: " << sym << std::endl; - - sym.set_object (*this); - symbols.add_external (sym); - externals.push_back (&sym); - } - - elf ().get_symbols (syms, false, false, true, false); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: weak: total " - << syms.size () << std::endl; - - for (symbols::pointers::iterator si = syms.begin (); - si != syms.end (); - ++si) - { - symbols::symbol& sym = *(*si); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: weak: " << sym << std::endl; - - sym.set_object (*this); - symbols.add_weak (sym); - externals.push_back (&sym); - } - - elf ().get_symbols (syms, true, false, true, true); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - std::cout << "object:load-sym: unresolved: total " - << syms.size () << std::endl; - - for (symbols::pointers::iterator si = syms.begin (); - si != syms.end (); - ++si) - { - symbols::symbol& sym = *(*si); - - if (rld::verbose () >= RLD_VERBOSE_TRACE_SYMS) - { - std::cout << "object:load-sym: unresolved: "; - sym.output (std::cout); - std::cout << std::endl; - } - - unresolved[sym.name ()] = &sym; - } - } - - void - object::load_relocations () - { - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "object:load-relocs: " << name ().full () << std::endl; - - elf ().load_relocations (); - - for (sections::iterator si = secs.begin (); - si != secs.end (); - ++si) - { - section& sec = *si; - const elf::section& elf_sec = elf ().get_section (sec.index); - sec.load_relocations (elf_sec); - } - } - - int - object::references () const - { - if (archive_) - return archive_->references (); - return image::references (); - } - - size_t - object::size () const - { - if (archive_) - return archive_->size (); - return image::size (); - } - - int - object::fd () const - { - if (archive_) - return archive_->fd (); - return image::fd (); - } - - void - object::symbol_referenced () - { - image::symbol_referenced (); - if (archive_) - archive_->symbol_referenced (); - } - - archive* - object::get_archive () - { - return archive_; - } - - rld::symbols::symtab& - object::unresolved_symbols () - { - return unresolved; - } - - rld::symbols::pointers& - object::external_symbols () - { - return externals; - } - - void - object::get_sections (sections& filtered_secs, - uint32_t type, - uint64_t flags_in, - uint64_t flags_out) - { - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const section& sec = *si; - if ((type == 0) || (type == sec.type)) - { - if ((flags_in == 0) || - (((sec.flags & flags_in) == flags_in) && - ((sec.flags & flags_out) == 0))) - { - filtered_secs.push_back (sec); - } - } - } - } - - void - object::get_sections (sections& filtered_secs, const std::string& matching_name) - { - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const section& sec = *si; - if (sec.name == matching_name) - { - filtered_secs.push_back (sec); - } - } - } - - const section& - object::get_section (int index) const - { - for (sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const section& sec = *si; - if (sec.index == index) - return sec; - } - - throw rld::error ("Section index '" + rld::to_string (index) + - "' not found: " + name ().full (), "object::get-section"); - } - - void - object::resolve_set () - { - resolving_ = true; - } - - void - object::resolve_clear () - { - resolving_ = false; - } - - bool - object::resolving () const - { - return resolving_; - } - - void - object::resolved_set () - { - resolved_ = true; - } - - bool - object::resolved () const - { - return resolved_; - } - - cache::cache () - : opened (false) - { - } - - cache::~cache () - { - close (); - } - - void - cache::open () - { - if (!opened) - { - collect_object_files (); - archives_begin (); - opened = true; - } - } - - void - cache::close () - { - if (opened) - { - /* - * Must delete the object first as they could depend on archives. - */ - for (objects::iterator oi = objects_.begin (); oi != objects_.end (); ++oi) - delete (*oi).second; - for (archives::iterator ai = archives_.begin (); ai != archives_.end (); ++ai) - delete (*ai).second; - opened = false; - } - } - - void - cache::add (const std::string& path) - { - paths_.push_back (path); - input (path); - } - - void - cache::add (path::paths& paths__) - { - for (path::paths::iterator pi = paths__.begin(); - pi != paths__.end(); - ++pi) - add (*pi); - } - - void - cache::add_libraries (path::paths& paths__) - { - for (path::paths::iterator pi = paths__.begin(); - pi != paths__.end(); - ++pi) - input (*pi); - } - - void - cache::archive_begin (const std::string& path) - { - archives::iterator ai = archives_.find (path); - if (ai != archives_.end ()) - { - archive* ar = (*ai).second; - if (!ar->is_open ()) - { - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "cache:archive-begin: " << path << std::endl; - ar->open (); - ar->begin (); - } - } - } - - void - cache::archive_end (const std::string& path) - { - archives::iterator ai = archives_.find (path); - if (ai != archives_.end ()) - { - archive* ar = (*ai).second; - if (ar->is_open ()) - { - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "cache:archive-end: " << path << std::endl; - ar->end (); - ar->close (); - } - } - } - - void - cache::archives_begin () - { - for (archives::iterator ai = archives_.begin (); ai != archives_.end (); ++ai) - archive_begin (((*ai).second)->path ()); - } - - void - cache::archives_end () - { - for (archives::iterator ai = archives_.begin (); ai != archives_.end (); ++ai) - archive_end (((*ai).second)->path ()); - } - - void - cache::collect_object_files () - { - for (path::paths::iterator ni = paths_.begin (); ni != paths_.end (); ++ni) - collect_object_files (*ni); - } - - void - cache::collect_object_files (const std::string& path) - { - archive* ar = new archive (path); - - if (ar->is_valid ()) - { - try - { - ar->open (); - ar->load_objects (objects_); - ar->close (); - archives_[path] = ar; - } - catch (...) - { - delete ar; - throw; - } - } - else - { - delete ar; - object* obj = new object (path); - if (!obj->name ().exists ()) - { - delete obj; - throw rld::error ("'" + path + "', Not found or a regular file.", - "file-check"); - } - try - { - obj->open (); - obj->begin (); - obj->end (); - obj->close (); - objects_[path] = obj; - } - catch (...) - { - delete obj; - throw; - } - } - } - - void - cache::load_symbols (rld::symbols::table& symbols, bool local) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "cache:load-sym: object files: " << objects_.size () - << std::endl; - - for (objects::iterator oi = objects_.begin (); - oi != objects_.end (); - ++oi) - { - object* obj = (*oi).second; - obj->open (); - obj->begin (); - obj->load_symbols (symbols, local); - obj->end (); - obj->close (); - } - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "cache:load-sym: symbols: " << symbols.size () - << std::endl; - } - - void - cache::output_unresolved_symbols (std::ostream& out) - { - for (objects::iterator oi = objects_.begin (); - oi != objects_.end (); - ++oi) - { - object* obj = (*oi).second; - if (obj) - { - out << obj->name ().full () << ':' << std::endl; - rld::symbols::output (out, obj->unresolved_symbols ()); - } - } - } - - archives& - cache::get_archives () - { - return archives_; - } - - objects& - cache::get_objects () - { - return objects_; - } - - void - cache::get_objects (object_list& list) const - { - list.clear (); - for (path::paths::const_iterator pi = paths_.begin (); - pi != paths_.end (); - ++pi) - { - objects::const_iterator oi = objects_.find (*pi); - if (oi == objects_.end ()) - throw rld_error_at ("path not found in objects"); - list.push_back ((*oi).second); - } - } - - const path::paths& - cache::get_paths () const - { - return paths_; - } - - int - cache::archive_count () const - { - return archives_.size (); - } - - int - cache::object_count () const - { - return objects_.size (); - } - - int - cache::path_count () const - { - return paths_.size (); - } - - void - cache::get_archive_files (files& afiles) - { - for (archives::iterator ai = archives_.begin (); ai != archives_.end (); ++ai) - afiles.push_back ((*ai).second->name ().full ()); - } - - void - cache::get_object_files (files& ofiles) - { - for (objects::iterator oi = objects_.begin (); oi != objects_.end (); ++oi) - ofiles.push_back ((*oi).second->name ()); - } - - void - cache::output_archive_files (std::ostream& out) - { - for (archives::iterator ai = archives_.begin (); ai != archives_.end (); ++ai) - out << ' ' << (*ai).second->name ().full () << std::endl; - } - - void - cache::output_object_files (std::ostream& out) - { - for (objects::iterator oi = objects_.begin (); oi != objects_.end (); ++oi) - out << ' ' << (*oi).second->name ().full () << std::endl; - } - - void - cache::input (const std::string& path) - { - if (opened) - { - collect_object_files (path); - archive_begin (path); - } - } - - void - find_libraries (path::paths& libraries, - path::paths& libpaths, - path::paths& libs) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "Finding libraries:." << std::endl; - libraries.clear (); - for (path::paths::size_type l = 0; l < libs.size (); ++l) - { - std::string lib = "lib" + libs[l] + ".a"; - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - std::cout << " searching: " << lib << std::endl; - bool found = false; - for (path::paths::size_type p = 0; p < libpaths.size (); ++p) - { - std::string plib; - path::path_join (libpaths[p], lib, plib); - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - std::cout << " checking: " << plib << std::endl; - if (path::check_file (plib)) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " found: " << plib << std::endl; - libraries.push_back (plib); - found = true; - break; - } - } - - if (!found) - throw rld::error ("Not found", lib); - } - } - - } -} diff --git a/linkers/rld-files.h b/linkers/rld-files.h deleted file mode 100644 index 0c98cf1..0000000 --- a/linkers/rld-files.h +++ /dev/null @@ -1,988 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker file manages access the image contained in various file - * formats. - * - * The base element is a file. It references a object file that is either - * inside an archive or stand alone. You access a object file by constructing a - * handle. A handle is the object file with the specific file descriptor - * created when the archive or object file was opened. - * - * - */ - -#if !defined (_RLD_FILES_H_) -#define _RLD_FILES_H_ - -#include -#include -#include -#include - -#include -#include - -namespace rld -{ - namespace files - { - /** - * Container of files. - */ - typedef std::vector < file > files; - - /** - * Container of archive files. - */ - typedef std::map < const std::string, archive* > archives; - - /** - * Container of object files. - */ - typedef std::map < const std::string, object* > objects; - - /** - * Container list of object files. - */ - typedef std::list < object* > object_list; - - /** - * A file is a single object file that is either in an @ref archive or - * a separate stand alone @ref object file. - */ - class file - { - public: - /** - * Construct the file from the component parts when part of an archive. - * - * @param aname The archive name. - * @param oname The object file name. - * @param offset The offset in the archive the object file starts. - * @param size The size of the archive the object file starts. - */ - file (const std::string& aname, - const std::string& oname, - off_t offset, - size_t size); - - /** - * Construct the name by splitting the full path into an archive, - * object file name and offset. - * - * @param path The path to the image. - * @param is_object If true (default) the name is for an object file. - */ - file (const std::string& path, bool is_object = true); - - /** - * Contruct an empty file. - */ - file (); - - /** - * Set a name from the path. - * - * @param path The path to the image. - * @param is_object If true (default) the name is for an object file. - */ - void set (const std::string& path, bool is_object = true); - - /** - * Is an archive returns true if the file is in an archive. - * - * @retval true The object file is in an archive. - * @retval false The object file is stand alone. - */ - bool is_archive () const; - - /** - * Is object file stand alone. - * - * @retval true The object file is stand alone. - * @retval false The object could be part of an archive. - */ - bool is_object () const; - - /** - * Valid returns true if there is a valid name. - * - * @retval true There is a valid name. - * @retval false There is not name assigned. - */ - bool is_valid () const; - - /** - * Exists returns true if the archive or object file is present on disk - * and a regular file. - * - * @retval true The file is valid and a regular file. - * @retval false The file is either not present, not accessable or not a - * regular file. - */ - bool exists () const; - - /** - * The path maps to the real file on disk. The file may not be valid. - * - * @return const std::string The real path to the file on disk. - */ - const std::string path () const; - - /** - * The full path. - * - * @return const std::string The full path to the image. - */ - const std::string full () const; - - /** - * The base path. It is the basename of the full path. - * - * @return const std::string The basename of the full path to the image. - */ - const std::string basename () const; - - /** - * The archive name component. A length of 0 means there was not - * archive component. - * - * @return const std::string& The archive name. - */ - const std::string& aname () const; - - /** - * The object name. There is always an object name. - * - * @return const std::string& The object name. - */ - const std::string& oname () const; - - /** - * The object's offset in the archive or on disk. - * - * @return off_t The offset part of the file name. - */ - off_t offset () const; - - /** - * The object's size in the archive. - * - * @return size_t The size of the file in bytes. - */ - size_t size () const; - - private: - std::string aname_; //< The archive name. - std::string oname_; //< The object name. - off_t offset_; //< The object's offset in the archive. - size_t size_; //< The object's size in the archive or on disk. - }; - - /** - * Image is the base file type and lets us have a single container to hold - * the types of images we need to support. - */ - class image - { - public: - /** - * Construct the image. - * - * @param name The name of the image. - */ - image (file& name); - - /** - * Construct the image. - * - * @param path The file path. - * @param is_object If true (default) the name is for an object file. - */ - image (const std::string& path, bool is_object = true); - - /** - * Construct the image. - */ - image (); - - /** - * Destruct the image. - */ - virtual ~image (); - - /** - * Open the image. You can open the image more than once but you need to - * close it the same number of times. - * - * @param name The @ref file name. - */ - virtual void open (file& name); - - /** - * Open the image. You can open the image more than once but you need to - * close it the same number of times. - * - * @param writeable If true the image is open as writable. The default is - * false. - */ - virtual void open (bool writable = false); - - /** - * Close the image. - */ - virtual void close (); - - /** - * Read a block from the file. - * - * @param buffer The buffer to read the data into. - * @param size The amount of data to read. - * @return ssize_t The amount of data read. - */ - virtual ssize_t read (void* buffer, size_t size); - - /** - * Write a block from the file. - * - * @param buffer The buffer of data to write. - * @param size The amount of data to write. - * @return ssize_t The amount of data written. - */ - virtual ssize_t write (const void* buffer, size_t size); - - /** - * Seek to the offset in the image. - * - * @param offset The offset to seek too. - */ - virtual void seek (off_t offset); - - /** - * Seek and then read. - * - * @param offset The offset to seek too before reading. - * @param buffer The buffer to read the data into. - * @param size The amount of data to read. - * @retval true The data requested was read. - * @retval false The request data was not read. - */ - virtual bool seek_read (off_t offset, uint8_t* buffer, size_t size); - - /** - * Seek and then write. - * - * @param offset The offset to seek too before writing. - * @param buffer The buffer of data to write. - * @param size The amount of data to write. - * @retval true The data requested was written. - * @retval false The request data was not written. - */ - virtual bool seek_write (off_t offset, const void* buffer, size_t size); - - /** - * The name of the image. - * - * @param const file& The @ref file name of the image. - */ - const file& name () const; - - /** - * References to the image. - * - * @return int The number of references the image has. - */ - virtual int references () const; - - /** - * The file size. - * - * @return size_t The size of the image. - */ - virtual size_t size () const; - - /** - * The file descriptor. - * - * @return int The operating system file descriptor handle. - */ - virtual int fd () const; - - /** - * The ELF reference. - * - * @return elf::file& The @ref elf::file object of the image. - */ - elf::file& elf (); - - /** - * A symbol in the image has been referenced. - */ - virtual void symbol_referenced (); - - /** - * Return the number of symbol references. - * - * @return int The symbol references count. - */ - virtual int symbol_references () const; - - /** - * The path maps to the real file on disk. The file may not be valid. - * - * @return const std::string The real path to the file on disk. - */ - const std::string path () const { - return name ().path (); - } - - /** - * Is the image open ? - * - * @retval true The image is open. - * @retval false The image is not open. - */ - bool is_open () const { - return fd () != -1; - } - - /** - * Is the image writable ? - * - * @retval true The image is writable. - * @retval false The image is not writable. - */ - bool is_writable () const { - return writable; - } - - private: - - file name_; //< The name of the file. - int references_; //< The number of handles open. - int fd_; //< The file descriptor of the archive. - elf::file elf_; //< The libelf reference. - int symbol_refs; //< The number of symbols references made. - bool writable; //< The image is writable. - }; - - /** - * Copy the input section of the image to the output section. The file - * positions in the images must be set before making the call. - * - * @param in The input image. - * @param out The output image. - * @param size The amouint of data to copy. - */ - void copy (image& in, image& out, size_t size); - - /** - * The archive class proivdes access to object files that are held in a AR - * format file. GNU AR extensions are supported. The archive is a kind of - * @ref image and provides the container for the @ref object's that it - * contains. - */ - class archive: - public image - { - public: - /** - * Open a archive format file that contains ELF object files. - * - * @param name The name of the @ref archive. - */ - archive (const std::string& name); - - /** - * Close the archive. - */ - virtual ~archive (); - - /** - * Begin the ELF session. - */ - void begin (); - - /** - * End the ELF session. - */ - void end (); - - /** - * Match the archive name. - * - * @param name The name of the archive to check. - * @retval true The name matches. - * @retval false The name does not match. - */ - bool is (const std::string& name) const; - - /** - * Check this is a valid archive. - * - * @retval true It is a valid archive. - * @retval false It is not a valid archive. - */ - bool is_valid (); - - /** - * Load @ref object's from the @ref archive adding each to the provided - * @ref objects container. - * - * @param objs The container the loaded object files are added too. - */ - void load_objects (objects& objs); - - /** - * Get the name. - * - * @return const std::string& Return a reference to the archive's name. - */ - const std::string& get_name () const; - - /** - * Less than operator for the map container. It compares the name of the - * the @ref archive. - * - * @param rhs The right hand side of the '<' operator. - * @return true The right hand side is less than this archive. - * @return false The right hand side is greater than or equal to this - * archive. - */ - bool operator< (const archive& rhs) const; - - /** - * Create a new archive containing the given set of objects. If - * referening an existing archive it is overwritten. - * - * @param objects The list of objects to place in the archive. - */ - void create (object_list& objects); - - private: - - /** - * Read the archive header and check the magic number is valid. - * - * @param offset The offset in the file to read the header. - * @param header Read the header into here. There must be enough space. - * @retval true The header was read successfull and the magic number - * matched. - * @retval false The header could not be read from the @ref image. - */ - bool read_header (off_t offset, uint8_t* header); - - /** - * Add the object file from the archive to the object's container. - * - * @param objs The container to add the object to. - * @param name The name of the object file being added. - * @param offset The offset in the @ref archive of the object file. - * @param size The size of the object file. - */ - void add_object (objects& objs, - const char* name, - off_t offset, - size_t size); - - /** - * Write a file header into the archive. - * - * @param name The name of the archive. - * @param mtime The modified time of the archive. - * @param uid The user id of the archive. - * @param gid The group id of the archive. - * @param mode The mode of the archive. - * @param size The size of the archive. - */ - void write_header (const std::string& name, - uint32_t mtime, - int uid, - int gid, - int mode, - size_t size); - - /** - * Cannot copy via a copy constructor. - */ - archive (const archive& orig); - - /** - * Cannot assign using the assignment operator. - */ - archive& operator= (const archive& rhs); - }; - - /** - * A relocation record. We extract what we want because the elf::section - * class requires the image be left open as references are alive. We - * extract and keep the data we need to create the image. - */ - struct relocation - { - const uint32_t offset; //< The section offset. - const uint32_t type; //< The type of relocation record. - const uint32_t info; //< The ELF info field. - const int32_t addend; //< The constant addend. - const std::string symname; //< The name of the symbol. - const uint32_t symtype; //< The type of symbol. - const int symsect; //< The symbol's section symbol. - const uint32_t symvalue; //< The symbol's value. - const uint32_t symbinding;//< The symbol's binding. - - /** - * Construct from an ELF relocation record. - */ - relocation (const elf::relocation& er); - - private: - /** - * The default constructor is not allowed due to all elements being - * const. - */ - relocation (); - }; - - /** - * A container of relocations. - */ - typedef std::list < relocation > relocations; - - /** - * The sections attributes. We extract what we want because the - * elf::section class requires the image be left open as references are - * alive. We extract and keep the data we need to create the image. - */ - struct section - { - const std::string name; //< The name of the section. - const int index; //< The section's index in the object file. - const uint32_t type; //< The type of section. - const size_t size; //< The size of the section. - const uint32_t alignment; //< The alignment of the section. - const uint32_t link; //< The ELF link field. - const uint32_t info; //< The ELF info field. - const uint32_t flags; //< The ELF flags. - const off_t offset; //< The ELF file offset. - bool rela; //< Relocation records have the addend field. - relocations relocs; //< The sections relocations. - - /** - * Construct from an ELF section. - * - * @param es The ELF section to load the object file section from. - */ - section (const elf::section& es); - - /** - * Load the ELF relocations. - * - * @param es The ELF section to load the relocations from. - */ - void load_relocations (const elf::section& es); - - private: - /** - * The default constructor is not allowed due to all elements being - * const. - */ - section (); - }; - - /** - * A container of sections. - */ - typedef std::list < section > sections; - - /** - * Sum the sizes of a container of sections. - */ - size_t sum_sizes (const sections& secs); - - /** - * Find the section that matches the index in the sections provided. - */ - const section* find (const sections& secs, const int index); - - /** - * The object file cab be in an archive or a file. - */ - class object: - public image - { - public: - /** - * Construct an object image that is part of an archive. - * - * @param archive_ The archive the object file is part of. - * @param file_ The image file. - */ - object (archive& archive_, file& file_); - - /** - * Construct the object file. - * - * @param path The object file path. - */ - object (const std::string& path); - - /** - * Construct the object file. - */ - object (); - - /** - * Destruct the object file. - */ - virtual ~object (); - - /** - * Open the object file. - */ - virtual void open (bool writable = false); - - /** - * Close the object. - */ - virtual void close (); - - /** - * Begin the object file session. - */ - void begin (); - - /** - * End the object file session. - */ - void end (); - - /** - * If valid returns true the begin has been called and the object has - * been validated as being in a suitable format. - */ - bool valid () const; - - /** - * Load the symbols into the symbols table. - * - * @param symbols The symbol table to load. - * @param local Include local symbols. The default is not to. - */ - void load_symbols (symbols::table& symbols, bool local = false); - - /** - * Load the relocations. - */ - void load_relocations (); - - /** - * References to the image. - */ - virtual int references () const; - - /** - * The file size. - */ - virtual size_t size () const; - - /** - * The file descriptor. - */ - virtual int fd () const; - - /** - * A symbol in the image has been referenced. - */ - virtual void symbol_referenced (); - - /** - * The archive the object file is contained in. If 0 the object file is - * not contained in an archive. - */ - archive* get_archive (); - - /** - * Return the unresolved symbol table for this object file. - */ - symbols::symtab& unresolved_symbols (); - - /** - * Return the list external symbols. - */ - symbols::pointers& external_symbols (); - - /** - * Return a container sections that match the requested type and - * flags. The filtered section container is not cleared so any matching - * sections are appended. - * - * @param filtered_secs The container of the matching sections. - * @param type The section type. Must match. If 0 matches any. - * @param flags_in The sections flags that must be set. This is a - * mask. If 0 matches any. - * @param flags_out The sections flags that must be clear. This is a - * mask. If 0 this value is ignored. - */ - void get_sections (sections& filtered_secs, - uint32_t type = 0, - uint64_t flags_in = 0, - uint64_t flags_out = 0); - - /** - * Return a container sections that match the requested name. The - * filtered section container is not cleared so any matching sections are - * appended. - * - * @param filtered_secs The container of the matching sections. - * @param name The name of the section. - */ - void get_sections (sections& filtered_secs, const std::string& name); - - /** - * Get a section given an index number. - * - * @param index The section index to search for. - */ - const section& get_section (int index) const; - - /** - * Set the object file's resolving flag. - */ - void resolve_set (); - - /** - * Clear the object file's resolving flag. - */ - void resolve_clear (); - - /** - * The resolving state. - */ - bool resolving () const; - - /** - * Set the object file resolved flag. - */ - void resolved_set (); - - /** - * The resolved state. - */ - bool resolved () const; - - private: - archive* archive_; //< Points to the archive if part of an - // archive. - bool valid_; //< If true begin has run and finished. - symbols::symtab unresolved; //< This object's unresolved symbols. - symbols::pointers externals; //< This object's external symbols. - sections secs; //< The sections. - bool resolving_; //< The object is being resolved. - bool resolved_; //< The object has been resolved. - - /** - * Cannot copy via a copy constructor. - */ - object (const object& orig); - - /** - * Cannot assign using the assignment operator. - */ - object& operator= (const object& rhs); - }; - - /** - * A collection of objects files as a cache. This currently is not a cache - * but it could become one. - */ - class cache - { - public: - /** - * Construct the cache. - */ - cache (); - - /** - * Destruct the objects. - */ - virtual ~cache (); - - /** - * Open the cache by collecting the file names, loading object headers - * and loading the archive file names. - */ - void open (); - - /** - * Close the cache. - */ - void close (); - - /** - * Add a file path to the cache. - */ - void add (const std::string& path); - - /** - * Add a container of path to the cache. - */ - void add (path::paths& paths__); - - /** - * Add a container of path to the cache. - */ - void add_libraries (path::paths& paths__); - - /** - * Being a session on an archive. - */ - void archive_begin (const std::string& path); - - /** - * End a session on an archive. - */ - void archive_end (const std::string& path); - - /** - * Being sessions on all archives. - */ - void archives_begin (); - - /** - * End the archive sessions. - */ - void archives_end (); - - /** - * Collect the object names and add them to the cache. - */ - void collect_object_files (); - - /** - * Collect the object file names by verifing the paths to the files are - * valid or read the object file names contained in any archives. - */ - void collect_object_files (const std::string& path); - - /** - * Load the symbols into the symbol table. - * - * @param symbols The symbol table to load. - * @param locals Include local symbols. The default does not include them. - */ - void load_symbols (symbols::table& symbols, bool locals = false); - - /** - * Output the unresolved symbol table to the output stream. - */ - void output_unresolved_symbols (std::ostream& out); - - /** - * Get the archives. - */ - archives& get_archives (); - - /** - * Get the objects inlcuding those in archives. - */ - objects& get_objects (); - - /** - * Get the added objects. Does not include the ones in th archives. - */ - void get_objects (object_list& list) const; - - /** - * Get the paths. - */ - const path::paths& get_paths () const; - - /** - * Get the archive files. - */ - void get_archive_files (files& afiles); - - /** - * Get the object files including those in archives. - */ - void get_object_files (files& ofiles); - - /** - * Get the archive count. - */ - int archive_count () const; - - /** - * Get the object count. - */ - int object_count () const; - - /** - * Get the path count. - */ - int path_count () const; - - /** - * Output archive files. - */ - void output_archive_files (std::ostream& out); - - /** - * Output archive files. - */ - void output_object_files (std::ostream& out); - - protected: - - /** - * Input a path into the cache. - */ - virtual void input (const std::string& path); - - private: - path::paths paths_; //< The names of the files to process. - archives archives_; //< The archive files. - objects objects_; //< The object files. - bool opened; //< The cache is open. - }; - - /** - * Copy the in file to the out file. - * - * @param in The input file. - * @param out The output file. - * @param size The amount to copy. If 0 the whole on in is copied. - */ - void copy_file (image& in, image& out, size_t size = 0); - - /** - * Find the libraries given the list of libraries as bare name which - * have 'lib' and '.a' added. - */ - void find_libraries (path::paths& libraries, - path::paths& libpaths, - path::paths& libs); - - } -} - -#endif diff --git a/linkers/rld-outputter.cpp b/linkers/rld-outputter.cpp deleted file mode 100644 index 600aedc..0000000 --- a/linkers/rld-outputter.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_ld - * - * @brief RTEMS Linker. - * - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include "rld-process.h" - -namespace rld -{ - namespace outputter - { - int unlink (const char* path) - { -#if _WIN32 - return ::remove(path); -#else - return ::unlink (path); -#endif - } - - int link (const char* path1, const char* path2) - { -#if _WIN32 - return ::rename(path1, path2); -#else - return ::link (path1, path2); -#endif - } - - const std::string - script_text (const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache, - bool not_in_archive) - { - std::ostringstream out; - files::object_list objects; - files::object_list dep_copy (dependents); - - cache.get_objects (objects); - objects.merge (dep_copy); - objects.unique (); - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " E: " << entry << std::endl; - - out << "E: " << entry << std::endl; - - if (!exit.empty ()) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " e: " << exit << std::endl; - out << "e: " << exit << std::endl; - } - - for (files::object_list::iterator oi = objects.begin (); - oi != objects.end (); - ++oi) - { - files::object& obj = *(*oi); - std::string name = obj.name ().basename (); - - if (not_in_archive) - { - size_t pos = name.find (':'); - if (pos != std::string::npos) - name[pos] = '_'; - pos = name.find ('@'); - if (pos != std::string::npos) - name = name.substr (0, pos); - } - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " o: " << name << std::endl; - - out << "o:" << name << std::endl; - - symbols::symtab& unresolved = obj.unresolved_symbols (); - - int count = 0; - for (symbols::symtab::iterator ursi = unresolved.begin (); - ursi != unresolved.begin (); - ++ursi) - { - symbols::symbol& urs = *((*ursi).second); - - ++count; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " u: " << count << ':' << urs.name () << std::endl; - - out << " u:" << count << ':' << urs.name () << std::endl; - } - } - - return out.str (); - } - - void - metadata_object (files::object& metadata, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "metadata: " << metadata.name ().full () << std::endl; - - const std::string script = - script_text (entry, exit, dependents, cache, true); - - metadata.open (true); - metadata.begin (); - - elf::file& elf = metadata.elf (); - - elf.set_header (ET_EXEC, - elf::object_class (), - elf::object_datatype (), - elf::object_machine_type ()); - - elf::section md (elf, - elf.section_count () + 1, - ".rtemsmd", - SHT_STRTAB, - 1, - 0, - 0, - 0, - script.length ()); - - md.add_data (ELF_T_BYTE, - 1, - script.length (), - (void*) script.c_str ()); - - elf.add (md); - elf.write (); - - metadata.end (); - metadata.close (); - } - - void - archive (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "outputter:archive: " << name - << ", dependents: " << dependents.size () << std::endl; - - std::string ext = path::extension (name); - std::string mdname = - name.substr (0, name.length () - ext.length ()) + "-metadata.o"; - - files::object metadata (mdname); - - metadata_object (metadata, entry, exit, dependents, cache); - - files::object_list dep_copy (dependents); - files::object_list objects; - - cache.get_objects (objects); - objects.merge (dep_copy); - objects.push_front (&metadata); - objects.unique (); - - files::archive arch (name); - arch.create (objects); - } - - void - archivera (const std::string& name, - const files::object_list& dependents, - files::cache& cache, - bool ra_exist, - bool ra_rap) - { - files::object_list dep_copy (dependents); - files::object_list objects; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "outputter:archivera: " << name - << ", dependents: " << dependents.size () << std::endl; - - objects.clear (); - - files::object_list::iterator oli; - for (oli = dep_copy.begin (); oli != dep_copy.end (); ++oli) - { - files::object& object = *(*oli); - - if (ra_rap) - objects.push_back (&object); - else - { - if (object.get_archive ()) - objects.push_back (&object); - } - } - - bool exist = false; - files::object_list objects_tmp; - files::objects& objs = cache.get_objects (); - objects_tmp.clear (); - for (files::objects::iterator obi = objs.begin (); - obi != objs.end (); - ++obi) - { - files::object* obj = (*obi).second; - exist = false; - - /** - * Replace the elf object file in ra file with elf object file - * in collected object files, if exist. - */ - if (!ra_rap) - { - for (oli = objects.begin (); oli != objects.end (); ++oli) - { - files::object& object = *(*oli); - if (obj->name ().oname () == object.name ().oname ()) - { - exist = true; - break; - } - } - } - - if (!exist) - objects_tmp.push_back (obj); - } - - objects.merge (objects_tmp); - objects.unique (); - - if (objects.size ()) - { - if (ra_exist) - { - std::string new_name = "rld_XXXXXX"; - files::archive arch (new_name); - struct stat sb; - - arch.create (objects); - - if ((::stat (name.c_str (), &sb) >= 0) && S_ISREG (sb.st_mode)) - { - if (unlink (name.c_str ()) < 0) - std::cerr << "error: unlinking temp file: " << name << std::endl; - } - if (link (new_name.c_str (), name.c_str ()) < 0) - { - std::cerr << "error: linking temp file: " << name << std::endl; - } - if ((::stat (new_name.c_str (), &sb) >= 0) && S_ISREG (sb.st_mode)) - { - if (unlink (new_name.c_str ()) < 0) - std::cerr << "error: unlinking temp file: " << new_name << std::endl; - } - } - else - { - /* Create */ - files::archive arch (name); - arch.create (objects); - } - } - } - - void - script (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "outputter:script: " << name << std::endl; - - std::fstream out (name.c_str (), - std::ios_base::out | std::ios_base::trunc); - - /* - * Tag for the shell to use. - */ - out << "!# rls" << std::endl; - - try - { - out << script_text (entry, exit, dependents, cache, false); - } - catch (...) - { - out.close (); - throw; - } - - out.close (); - } - - void - elf_application (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "outputter:application: " << name << std::endl; - - files::object_list dep_copy (dependents); - files::object_list objects; - std::string header; - std::string script; - files::image app (name); - - header = "RELF,00000000,0001,none,00000000\n"; - header += '\0'; - - script = script_text (entry, exit, dependents, cache, true); - - cache.get_objects (objects); - objects.merge (dep_copy); - objects.unique (); - - app.open (true); - app.write (header.c_str (), header.size ()); - - #define APP_BUFFER_SIZE (128 * 1024) - - uint8_t* buffer = 0; - - try - { - buffer = new uint8_t[APP_BUFFER_SIZE]; - - for (files::object_list::iterator oi = objects.begin (); - oi != objects.end (); - ++oi) - { - files::object& obj = *(*oi); - - obj.open (); - - try - { - obj.seek (0); - - size_t in_size = obj.name ().size (); - - while (in_size) - { - size_t reading = - in_size < APP_BUFFER_SIZE ? in_size : APP_BUFFER_SIZE; - - app.write (buffer, obj.read (buffer, reading)); - - in_size -= reading; - } - } - catch (...) - { - obj.close (); - throw; - } - - obj.close (); - } - } - catch (...) - { - delete [] buffer; - app.close (); - throw; - } - - delete [] buffer; - - app.close (); - } - - bool in_archive (files::object* object) - { - if (object->get_archive ()) - return true; - return false; - } - - void - application (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache, - const symbols::table& symbols, - bool one_file) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "outputter:application: " << name << std::endl; - - files::object_list dep_copy (dependents); - files::object_list objects; - files::image app (name); - - if (!one_file) - dep_copy.remove_if (in_archive); - - cache.get_objects (objects); - objects.merge (dep_copy); - objects.sort (); - objects.unique (); - - app.open (true); - - try - { - rap::write (app, entry, exit, objects, symbols); - } - catch (...) - { - app.close (); - throw; - } - - app.close (); - } - - } -} diff --git a/linkers/rld-outputter.h b/linkers/rld-outputter.h deleted file mode 100644 index 7fe52b2..0000000 --- a/linkers/rld-outputter.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker outputter handles the various output formats. - * - */ - -#if !defined (_RLD_OUTPUTTER_H_) -#define _RLD_OUTPUTTER_H_ - -#include - -namespace rld -{ - namespace outputter - { - /** - * Output the object file list as a string. - * - * @param entry The name of the entry point symbol. - * @param exit The name of the exit point symbol. - * @param dependents The list of dependent object files - * @param cache The file cache for the link. Includes the object list - * the user requested. - * @return std::string The list as a text string. - */ - std::string script_text (const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache); - /** - * Output the object files as an archive format file with the metadata as - * the first ELF file. - * - * @param name The name of the archive. - * @param entry The name of the entry point symbol. - * @param exit The name of the exit point symbol. - * @param dependents The list of dependent object files - * @param cache The file cache for the link. Includes the object list - * the user requested. - */ - void archive (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache); - - void archivera (const std::string& name, - const files::object_list& dependents, - files::cache& cache, - bool ra_exist, - bool ra_rap); - - /** - * Output the object file list as a script. - * - * @param name The name of the script. - * @param entry The name of the entry point symbol. - * @param exit The name of the exit point symbol. - * @param dependents The list of dependent object files - * @param cache The file cache for the link. Includes the object list - * the user requested. - */ - void script (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache); - - /** - * Output the object files in an archive with the metadata. - * - * @param name The name of the script. - * @param entry The name of the entry point symbol. - * @param exit The name of the exit point symbol. - * @param dependents The list of dependent object files - * @param cache The file cache for the link. Includes the object list - * the user requested. - */ - void elf_application (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache); - - /** - * Output the object files in an archive with the metadata. - * - * @param name The name of the script. - * @param entry The name of the entry point symbol. - * @param exit The name of the exit point symbol. - * @param dependents The list of dependent object files - * @param cache The file cache for the link. Includes the object list - * the user requested. - * @param symbols The symbol table used to resolve the application. - */ - void application (const std::string& name, - const std::string& entry, - const std::string& exit, - const files::object_list& dependents, - const files::cache& cache, - const symbols::table& symbols, - bool one_file); - - } -} - -#endif diff --git a/linkers/rld-path.cpp b/linkers/rld-path.cpp deleted file mode 100644 index 1cdb586..0000000 --- a/linkers/rld-path.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -#include - -namespace rld -{ - namespace path - { - const std::string - basename (const std::string& name) - { - size_t b = name.find_last_of (RLD_PATH_SEPARATOR); - if (b != std::string::npos) - return name.substr (b + 1); - return name; - } - - const std::string - dirname (const std::string& name) - { - size_t b = name.find_last_of (RLD_PATH_SEPARATOR); - if (b != std::string::npos) - return name.substr (0, b); - return name; - } - - const std::string - extension (const std::string& name) - { - size_t b = name.find_last_of ('.'); - if (b != std::string::npos) - return name.substr (b); - return name; - } - - void - path_split (const std::string& path, paths& paths) - { - strings ps; - rld::split (ps, path, RLD_PATHSTR_SEPARATOR); - if (ps.size ()) - { - for (strings::iterator psi = ps.begin (); - psi != ps.end (); - ++psi) - { - if (check_directory (*psi)) - paths.push_back (*psi); - } - } - } - - void - path_join (const std::string& base, const std::string& part, std::string& joined) - { - if ((base[base.size () - 1] != RLD_PATH_SEPARATOR) && - (part[0] != RLD_PATH_SEPARATOR)) - joined = base + RLD_PATH_SEPARATOR + part; - else if ((base[base.size () - 1] == RLD_PATH_SEPARATOR) && - (part[0] == RLD_PATH_SEPARATOR)) - joined = base + &part[1]; - else - joined = base + part; - } - - void - path_join (const std::string& base, const paths& parts, std::string& joined) - { - joined = base; - for (paths::const_iterator pi = parts.begin (); - pi != parts.end (); - ++pi) - { - path_join (joined, *pi, joined); - } - } - - const std::string - path_abs (const std::string& path) - { - std::string apath; - - if (path[0] == RLD_PATH_SEPARATOR) - { - apath = path; - } - else - { - char* buf = 0; - try - { - buf = new char[32 * 1024]; - if (!::getcwd (buf, 132 * 1024)) - throw rld::error (::strerror (errno), "get current working directory"); - path_join (buf, path, apath); - } - catch (...) - { - delete [] buf; - throw; - } - } - - strings ps; - strings aps; - - rld::split (ps, apath, RLD_PATH_SEPARATOR); - - for (strings::iterator psi = ps.begin (); - psi != ps.end (); - ++psi) - { - const std::string& dir = *psi; - - if (dir.empty () || dir == ".") - { - /* do nothing */ - } - else if (dir == "..") - { - aps.pop_back (); - } - else - { - aps.push_back (dir); - } - } - - return RLD_PATH_SEPARATOR + rld::join (aps, RLD_PATH_SEPARATOR_STR); - } - - bool - check_file (const std::string& path) - { - struct stat sb; - if (::stat (path.c_str (), &sb) == 0) - if (S_ISREG (sb.st_mode)) - return true; - return false; - } - - bool - check_directory (const std::string& path) - { - struct stat sb; - if (::stat (path.c_str (), &sb) == 0) - if (S_ISDIR (sb.st_mode)) - return true; - return false; - } - - void - find_file (std::string& path, const std::string& name, paths& search_paths) - { - for (paths::iterator pi = search_paths.begin (); - pi != search_paths.end (); - ++pi) - { - path_join (*pi, name, path); - if (check_file (path)) - return; - } - path.clear (); - } - - void - unlink (const std::string& path, bool not_present_error) - { - struct stat sb; - if (::stat (path.c_str (), &sb) >= 0) - { - if (!S_ISREG (sb.st_mode)) - throw rld::error ("Not a regular file", "unlinking: " + path); - - int r; -#if _WIN32 - r = ::remove(path.c_str ()); -#else - r = ::unlink (path.c_str ()); -#endif - if (r < 0) - throw rld::error (::strerror (errno), "unlinking: " + path); - } - else - { - if (not_present_error) - throw rld::error ("Not found", "unlinking: " + path); - } - } - } -} diff --git a/linkers/rld-path.h b/linkers/rld-path.h deleted file mode 100644 index d73c59b..0000000 --- a/linkers/rld-path.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker Path to help manage paths. - * - */ - -#if !defined (_RLD_PATH_H_) -#define _RLD_PATH_H_ - -#include -#include -#include -#include - -#include - -namespace rld -{ - namespace path - { - /** - * Container of file paths. - */ - typedef std::vector < std::string > paths; - - /** - * Return the basename of the file name. - * - * @param name The full file name. - * @return const std::string The basename of the file. - */ - const std::string basename (const std::string& name); - - /** - * Return the dirname of the file name. - * - * @param name The full file name. - * @return const std::string The dirname of the file. - */ - const std::string dirname (const std::string& name); - - /** - * Return the extension of the file name. - * - * @param name The full file name. - * @return const std::string The extension of the file. - */ - const std::string extension (const std::string& name); - - /** - * Split a path from a string with the path seperator to the path - * container. Add only the paths that exist and ignore those that do not. - * - * @param path The paths as a single string delimited by the path - * separator. - * @param paths The split path paths. - */ - void path_split (const std::string& path, - paths& paths); - - /** - * Make a path by joining the base and part with required separator. - * - * @param base The path component to be joined. - * @param part The file name to add to the path. - * @param joined The joined path and file name with a path separator. - */ - void path_join (const std::string& base, - const std::string& part, - std::string& joined); - - /** - * Make a path by joining the parts with the base and the required - * separator. - * - * @param base The path component to be joined. - * @param parts The files to add to the path. - * @param joined The joined path and file name with a path separator. - */ - void path_join (const std::string& base, - const paths& parts, - std::string& joined); - - /** - * Return the absolute path given a path and using the current working - * directory. The path is flattened removing any '..' sequences. - * - * @param path The path to be return as absolute. - * @return const std::string The absolute path. - */ - const std::string path_abs (const std::string& path); - - /** - * Check the path is a file using a stat call. - * - * @param path The path to check. - * @retval true The path is valid. - * @retval false The path is not valid. - */ - bool check_file (const std::string& path); - - /** - * Check if the path is a directory. - * - * @param path The path to check. - * @retval false The path is not a directory. - * @retval true The path is a directory. - */ - bool check_directory (const std::string& path); - - /** - * Find the file given a container of paths and file names. - * - * @param path The path of the file if found else empty. - * @param name The name of the file to search for. - * @param search_paths The container of paths to search. - */ - void find_file (std::string& path, - const std::string& name, - paths& search_paths); - - /** - * Unlink the file. - * - * @param path The path of the file to unlink. - */ - void unlink (const std::string& path, bool not_present_error = false); - - } -} - -#endif diff --git a/linkers/rld-process.cpp b/linkers/rld-process.cpp deleted file mode 100644 index bfd6734..0000000 --- a/linkers/rld-process.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -#ifndef WIFEXITED -#define WIFEXITED(S) (((S) & 0xff) == 0) -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(S) (((S) & 0xff00) >> 8) -#endif -#ifndef WIFSIGNALED -#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) -#endif -#ifndef WTERMSIG -#define WTERMSIG(S) ((S) & 0x7f) -#endif -#ifndef WIFSTOPPED -#define WIFSTOPPED WIFEXITED -#endif -#ifndef WSTOPSIG -#define WSTOPSIG WEXITSTATUS -#endif - -#if __WIN32__ -#define CREATE_MODE (S_IRUSR | S_IWUSR) -#define OPEN_FLAGS (O_BINARY) -#else -#define CREATE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) -#define OPEN_FLAGS (0) -#endif - -#include - -#include "rld.h" -#include "rld-process.h" - -#include - -namespace rld -{ - namespace process - { - /** - * Global keep of temporary files if true. Used to help debug a system. - */ - bool keep_temporary_files = false; - - /** - * The temporary files. - */ - temporary_files temporaries; - - temporary_files::temporary_files () - { - } - - temporary_files::~temporary_files () - { - clean_up (); - } - - const std::string - temporary_files::get (const std::string& suffix, bool keep) - { - char* temp = ::make_temp_file (suffix.c_str ()); - - if (!temp) - throw rld::error ("bad temp name", "temp-file"); - - const std::string name = rld::find_replace (temp, - RLD_PATH_SEPARATOR_STR RLD_PATH_SEPARATOR_STR, - RLD_PATH_SEPARATOR_STR); - tempfile_ref ref (name, keep); - tempfiles.push_back (ref); - return name; - } - - void - temporary_files::unlink (const tempfile_ref& ref) - { - if (!keep_temporary_files && !ref.keep) - rld::path::unlink (ref.name); - } - - void - temporary_files::erase (const std::string& name) - { - for (tempfile_container::iterator tfi = tempfiles.begin (); - tfi != tempfiles.end (); - ++tfi) - { - if ((*tfi).name == name) - { - unlink (*tfi); - tempfiles.erase (tfi); - break; - } - } - } - - void - temporary_files::keep (const std::string& name) - { - for (tempfile_container::iterator tfi = tempfiles.begin (); - tfi != tempfiles.end (); - ++tfi) - { - if ((*tfi).name == name) - { - (*tfi).keep = true; - break; - } - } - } - - void - temporary_files::clean_up () - { - for (tempfile_container::iterator tfi = tempfiles.begin (); - tfi != tempfiles.end (); - ++tfi) - { - unlink (*tfi); - } - } - - tempfile::tempfile (const std::string& suffix, bool _keep) - : suffix (suffix), - overridden (false), - fd (-1), - level (0) - { - _name = temporaries.get (suffix, _keep); - } - - tempfile::~tempfile () - { - close (); - temporaries.erase (_name); - } - - void - tempfile::open (bool writable) - { - if (fd < 0) - { - bool ok = rld::path::check_file (_name); - int flags = writable ? O_RDWR : O_RDONLY; - int mode = writable ? CREATE_MODE : 0; - - if (writable && overridden) - { - flags |= O_CREAT | O_TRUNC | O_APPEND; - } - else - { - if (!ok) - throw rld::error ("Not found.", "tempfile open:" + _name); - } - - level = 0; - fd = ::open (_name.c_str (), flags, mode); - if (fd < 0) - throw rld::error (::strerror (errno), "tempfile open:" + _name); - } - } - - void - tempfile::close () - { - if (fd != -1) - { - ::close (fd); - fd = -1; - level = 0; - } - } - - void - tempfile::override (const std::string& name_) - { - if (fd >= 0) - throw rld::error ("Already open", "tempfile override"); - rld::path::unlink (_name); - overridden = true; - _name = name_ + suffix; - } - - void - tempfile::keep () - { - temporaries.keep (_name); - } - - const std::string& - tempfile::name () const - { - return _name; - } - - size_t - tempfile::size () - { - if (fd < 0) - return 0; - - struct stat sb; - if (::stat (_name.c_str (), &sb) == 0) - return sb.st_size; - - return 0; - } - - void - tempfile::read (std::string& all) - { - all.clear (); - if (fd != -1) - { - if (level) - all.append (buf, level); - level = 0; - while (true) - { - int read = ::read (fd, buf, sizeof (buf) ); - if (read < 0) - throw rld::error (::strerror (errno), "tempfile get read:" + _name); - else if (read == 0) - break; - else - all.append (buf, read); - } - } - } - - void - tempfile::read_line (std::string& line) - { - line.clear (); - if (fd != -1) - { - bool reading = true; - while (reading) - { - if (level < (sizeof (buf) - 1)) - { - memset (buf + level, 0, sizeof (buf) - level); - int read = ::read (fd, buf + level, sizeof (buf) - level - 1); - if (read < 0) - throw rld::error (::strerror (errno), "tempfile read:" + _name); - else if (read == 0) - reading = false; - else - level += read; - } - if (level) - { - char* lf = ::strchr (buf, '\n'); - int len = level; - if (lf) - len = lf - &buf[0] + 1; - if (lf || !reading) - { - line.append (buf, len); - level -= len; - } - if (level) - ::memmove (buf, &buf[len], level + 1); - reading = false; - } - } - } - } - - void - tempfile::write (const std::string& s) - { - const char* p = s.c_str (); - size_t l = s.length (); - while (l) - { - int written = ::write (fd, p, l); - if (written < 0) - throw rld::error (::strerror (errno), "tempfile write:" + _name); - if (written == 0) - break; - l -= written; - } - } - - void - tempfile::write_line (const std::string& s) - { - write (s); - write (RLD_LINE_SEPARATOR); - } - - void - tempfile::write_lines (const rld::strings& ss) - { - for (rld::strings::const_iterator ssi = ss.begin (); - ssi != ss.end (); - ++ssi) - { - write_line (*ssi); - } - } - - void - tempfile::output (std::ostream& out) - { - std::string prefix; - output (prefix, out); - } - - void - tempfile::output (const std::string& prefix, - std::ostream& out, - bool line_numbers) - { - if (fd == -1) - { - std::string line; - int lc = 0; - open (); - while (true) - { - read_line (line); - ++lc; - if (line.empty ()) - break; - if (!prefix.empty ()) - out << prefix << ": "; - if (line_numbers) - out << lc << ": "; - out << line << std::flush; - } - close (); - } - } - - void - set_keep_temporary_files () - { - keep_temporary_files = true; - } - - void - temporaries_clean_up () - { - temporaries.clean_up (); - } - - void - args_append (arg_container& args, const std::string& str) - { - rld::strings ss; - rld::split (ss, str); - for (rld::strings::iterator ssi = ss.begin (); - ssi != ss.end (); - ++ssi) - { - args.push_back (*ssi); - } - } - - status - execute (const std::string& pname, - const std::string& command, - const std::string& outname, - const std::string& errname) - { - arg_container args; - parse_command_line (command, args); - return execute (pname, args, outname, errname); - } - - status - execute (const std::string& pname, - const arg_container& args, - const std::string& outname, - const std::string& errname) - { - if (rld::verbose (RLD_VERBOSE_TRACE)) - { - std::cout << "execute: "; - for (size_t a = 0; a < args.size (); ++a) - std::cout << args[a] << ' '; - std::cout << std::endl; - } - - const char** cargs = new const char* [args.size () + 1]; - - for (size_t a = 0; a < args.size (); ++a) - cargs[a] = args[a].c_str (); - cargs[args.size ()] = 0; - - int err = 0; - int s = 0; - - const char* serr = pex_one (PEX_LAST | PEX_SEARCH, - args[0].c_str (), - (char* const*) cargs, - pname.c_str (), - outname.c_str (), - errname.c_str (), - &s, - &err); - - delete [] cargs; - - if (serr) - throw rld::error ("execute: " + args[0], serr); - else if (err) - throw rld::error ("execute: " + args[0], ::strerror (err)); - - status _status; - - if (rld::verbose (RLD_VERBOSE_TRACE)) - std::cout << "execute: status: "; - - if (WIFEXITED (s)) - { - _status.type = status::normal; - _status.code = WEXITSTATUS (s); - if (rld::verbose (RLD_VERBOSE_TRACE)) - std::cout << _status.code << std::endl; - } - else if (WIFSIGNALED (s)) - { - _status.type = status::signal; - _status.code = WTERMSIG (s); - if (rld::verbose (RLD_VERBOSE_TRACE)) - std::cout << "signal: " << _status.code << std::endl; - } - else if (WIFSTOPPED (s)) - { - _status.type = status::stopped; - _status.code = WSTOPSIG (s); - if (rld::verbose (RLD_VERBOSE_TRACE)) - std::cout << "stopped: " << _status.code << std::endl; - } - else - throw rld::error ("execute: " + args[0], "unknown status returned"); - - return _status; - } - - /* - * The code is based on this C file: - * http://cybertiggyr.com/pcm/src/parse.c - */ - void - parse_command_line (const std::string& command, arg_container& args) - { - enum pstate - { - pstate_discard_space, - pstate_accumulate_quoted, - pstate_accumulate_raw - }; - - args.clear (); - - const char quote = '"'; - const char escape = '\\'; - pstate state = pstate_discard_space; - size_t start = 0; - size_t i = 0; - - while (i < command.size ()) - { - switch (state) - { - case pstate_discard_space: - if (command[i] == quote) - { - ++i; - start = i; - state = pstate_accumulate_quoted; - } - else if (::isspace (command[i])) - { - ++i; - } - else /* includes escape */ - { - start = i; - state = pstate_accumulate_raw; - } - break; - - case pstate_accumulate_quoted: - if (command[i] == quote) - { - args.push_back (command.substr (start, i - 1)); - ++i; - state = pstate_discard_space; - } - else if ((command[i] == escape) && (command[i + 1] == quote)) - { - i += 2; - } - else /* includes space */ - { - ++i; - } - break; - - case pstate_accumulate_raw: - if (command[i] == quote) - { - throw rld::error ("quote in token", "command parse"); - } - else if ((command[i] == escape) && (command[i + 1] == quote)) - { - i += 2; - } - else if (::isspace (command[i])) - { - args.push_back (command.substr (start, i - 1)); - ++i; - state = pstate_discard_space; - } - else - { - ++i; - } - break; - } - } - } - } -} diff --git a/linkers/rld-process.h b/linkers/rld-process.h deleted file mode 100644 index ae89b15..0000000 --- a/linkers/rld-process.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief Process execute and various supporting parts. - * - */ - -#if !defined (_RLD_PEX_H_) -#define _RLD_PEX_H_ - -#include -#include -#include - -namespace rld -{ - namespace process - { - /** - * Temporary file is a name and keep state. - */ - struct tempfile_ref - { - const std::string name; //< The name of the tempfile. - bool keep; //< If true do not delete this file. - - tempfile_ref (const std::string& name, bool keep = false) - : name (name), - keep (keep) { - } - }; - - /** - * Manage temporary files. We keep these so we can delete them when - * we exit. - */ - class temporary_files - { - public: - /** - * Container of temporary file names. - */ - typedef std::list < tempfile_ref > tempfile_container; - - /** - * Construct the temporary files. - */ - temporary_files (); - - /** - * Destruct cleaning up. - */ - ~temporary_files (); - - /** - * Get a new temporary file name. - */ - const std::string get (const std::string& suffix = ".rldxx", - bool keep = false); - - /** - * Remove the temporary file. - */ - void erase (const std::string& name); - - /** - * Set the tempfile reference keep state to true. - */ - void keep (const std::string& name); - - /** - * Remove all temporary files. - */ - void clean_up (); - - private: - - /* - * Delete the tempfile given the reference if not keeping. - */ - void unlink (const tempfile_ref& ref); - - tempfile_container tempfiles; //< The temporary files. - - }; - - /** - * Handle the output files from the process. - */ - class tempfile - { - public: - - /** - * Get a temporary file name given a suffix. - */ - tempfile (const std::string& suffix = ".rldxx", bool keep = false); - - /** - * Clean up the temporary file. - */ - ~tempfile (); - - /** - * Open the temporary file. It can optionally be written too. - */ - void open (bool writable = false); - - /** - * Close the temporary file. - */ - void close (); - - /** - * Override the temp file name automatically assigned with this name. The - * suffix is appended. - */ - void override (const std::string& name); - - /** - * Set the temp file keep state to true so it is not deleted. - */ - void keep (); - - /** - * The name of the temp file. - */ - const std::string& name () const; - - /** - * Size of the file. - */ - size_t size (); - - /** - * Read all the file. - */ - void read (std::string& all); - - /** - * Read a line at a time. - */ - void read_line (std::string& line); - - /** - * Write the string to the file. - */ - void write (const std::string& s); - - /** - * Write the string as a line to the file. - */ - void write_line (const std::string& s); - - /** - * Write the strings to the file using a suitable line separator. - */ - void write_lines (const rld::strings& ss); - - /** - * Output the file. - */ - void output (const std::string& prefix, - std::ostream& out, - bool line_numbers = false); - - /** - * Output the file. - */ - void output (std::ostream& out); - - private: - - std::string _name; //< The name of the file. - const std::string suffix; //< The temp file's suffix. - bool overridden; //< The name is overridden; may no exist. - int fd; //< The file descriptor - char buf[256]; //< The read buffer. - size_t level; //< The level of data in the buffer. - }; - - /** - * Keep the temporary files. - */ - void set_keep_temporary_files (); - - /** - * Clean up the temporaryes. - */ - void temporaries_clean_up (); - - /** - * The arguments containter has a single argument per element. - */ - typedef std::vector < std::string > arg_container; - - /** - * Split a string and append to the arguments. - */ - void args_append (arg_container& args, const std::string& str); - - /** - * Execute result. - */ - struct status - { - enum types - { - normal, //< The process terminated normally by a call to _exit(2) or exit(3). - signal, //< The process terminated due to receipt of a signal. - stopped //< The process has not terminated, but has stopped and can be restarted. - }; - - types type; //< Type of status. - int code; //< The status code returned. - }; - - /** - * Execute a process and capture stdout and stderr. The first element is - * the program name to run. Return an error code. - */ - status execute (const std::string& pname, - const arg_container& args, - const std::string& outname, - const std::string& errname); - - /** - * Execute a process and capture stdout and stderr given a command line - * string. Return an error code. - */ - status execute (const std::string& pname, - const std::string& command, - const std::string& outname, - const std::string& errname); - - /** - * Parse a command line into arguments. It support quoting. - */ - void parse_command_line (const std::string& command, arg_container& args); - } -} - -#endif diff --git a/linkers/rld-rap.cpp b/linkers/rld-rap.cpp deleted file mode 100644 index 9b87279..0000000 --- a/linkers/rld-rap.cpp +++ /dev/null @@ -1,1668 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_ld - * - * @brief RTEMS Linker. - * - * @todo Set the RAP alignment as the max of all alignments. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include - -#include -#include -#include - -namespace rld -{ - namespace rap - { - - /** - * Output details or not. - */ - bool add_obj_details = true; - - /** - * Store the path of object files. - */ - std::string rpath; - - /** - * The names of the RAP sections. - */ - static const char* section_names[rap_secs] = - { - ".text", - ".const", - ".ctor", - ".dtor", - ".data", - ".bss" - }; - - /** - * RAP relocation record. This one does not have const fields. - */ - struct relocation - { - uint32_t offset; //< The offset in the section to apply the fixup. - uint32_t info; //< The ELF info record. - uint32_t addend; //< The ELF constant addend. - std::string symname; //< The symbol name if there is one. - uint32_t symtype; //< The type of symbol. - int symsect; //< The symbol's RAP section. - uint32_t symvalue; //< The symbol's default value. - uint32_t symbinding;//< The symbol's binding. - - /** - * Construct the relocation using the file relocation, the offset of the - * section in the target RAP section and the RAP section of the symbol. - */ - relocation (const files::relocation& reloc, const uint32_t offset); - }; - - /** - * Relocation records. - */ - typedef std::vector < relocation > relocations; - - /** - * Relocation symname sorter for the relocations container. - */ - class reloc_symname_compare - { - public: - bool operator () (const relocation& lhs, - const relocation& rhs) const { - return lhs.symname < rhs.symname; - } - }; - - /** - * Relocation offset sorter for the relocations container. - */ - class reloc_offset_compare - { - public: - bool operator () (const relocation& lhs, - const relocation& rhs) const { - if (lhs.symname == rhs.symname) - return lhs.offset < rhs.offset; - else return false; - } - }; - - /** - * An object section's offset, size and alignment. - */ - struct osection - { - std::string name; //< The name of the section. - uint32_t offset; //< The offset in the object file. - uint32_t size; //< The size of this section. - uint32_t align; //< The alignment. - uint32_t relocs; //< The number of relocations. - uint64_t flags; //< The flags. - - /** - * Construct the object section. - */ - osection (const std::string& name, - uint32_t offset, - uint32_t size, - uint32_t align, - uint32_t relocs, - uint64_t flags); - - /** - * Default constructor. - */ - osection (); - }; - - /** - * Map of object file section offsets keyed by the object file section - * index. This is used when adding the external symbols so the symbol's - * value can be adjusted by the offset of the section in the RAP section. - */ - typedef std::map < int, osection > osections; - - /** - * An ordered container of object section indexes. We need the same - * order so the alignments match up with the layout. - */ - typedef std::vector < int > osecindexes; - - /** - * Section detail will be written into RAP file - */ - struct section_detail - { - uint32_t name; //< The offset in the strtable. - uint32_t offset; //< The offset in the rap section. - uint32_t id; //< The rap id. - uint32_t size; //< The size of the section. - - /* Constructor */ - section_detail (uint32_t name, uint32_t offset, uint32_t id, uint32_t size); - }; - - /* - * A container of section detail - */ - typedef std::list < section_detail > section_details; - - /** - * The RAP section data. - */ - struct section - { - std::string name; //< The name of the section. - uint32_t offset; //< The offset of the section. - bool rela; //< The relocation record has an addend field. - relocations relocs; //< The relocations for this section. - osections osecs; //< The object section index. - osecindexes osindexes; //< The object section indexes in order. - - /** - * Default constructor. - */ - section (); - - /** - * Clear the section. - */ - void clear (); - - /** - * The size of the section given the offset. - */ - uint32_t size (uint32_t offset = 0) const; - - /** - * The alignment of the first section. - */ - uint32_t alignment () const; - - /** - * The alignment of the object section given its index. - */ - uint32_t alignment (int index) const; - - /** - * Set the offset of this section based on the previous section. - */ - void set_offset (const section& sec); - - /** - * Return the object section given the index. - */ - const osection& get_osection (int index) const; - - /** - * Output helper function to report the sections in an object file. This - * is useful when seeing the flags in the sections. - */ - void output (); - }; - - /** - * A symbol. This matches the symbol structure 'rtems_rtl_obj_sym_t' in the - * target code. - */ - struct external - { - /** - * Size of an external in the RAP file. - */ - static const uint32_t rap_size = sizeof (uint32_t) * 3; - - const uint32_t name; //< The string table's name index. - const sections sec; //< The section the symbols belongs to. - const uint32_t value; //< The offset from the section base. - const uint32_t data; //< The ELF st.info field. - - /** - * The constructor. - */ - external (const uint32_t name, - const sections sec, - const uint32_t value, - const uint32_t data); - - /** - * Copy constructor. - */ - external (const external& orig); - - }; - - /** - * A container of externals. - */ - typedef std::list < external > externals; - - /** - * The specific data for each object we need to collect to create the RAP - * format file. - */ - struct object - { - files::object& obj; //< The object file. - files::sections text; //< All executable code. - files::sections const_; //< All read only data. - files::sections ctor; //< The static constructor table. - files::sections dtor; //< The static destructor table. - files::sections data; //< All initialised read/write data. - files::sections bss; //< All uninitialised read/write data - files::sections symtab; //< All exported symbols. - files::sections strtab; //< All exported strings. - section secs[rap_secs]; //< The sections of interest. - - /** - * The constructor. Need to have an object file to create. - */ - object (files::object& obj); - - /** - * The copy constructor. - */ - object (const object& orig); - - /** - * Find the section type that matches the section index. - */ - sections find (const uint32_t index) const; - - /** - * The total number of relocations in the object file. - */ - uint32_t get_relocations () const; - - /** - * The total number of relocations for a specific RAP section in the - * object file. - */ - uint32_t get_relocations (int sec) const; - - /** - * Output the object file details.. - */ - void output (); - - private: - /** - * No default constructor allowed. - */ - object (); - }; - - /** - * A container of objects. - */ - typedef std::list < object > objects; - - /** - * The RAP image. - */ - class image - { - public: - /** - * Construct the image. - */ - image (); - - /** - * Load the layout data from the object files. - * - * @param app_objects The object files in the application. - * @param init The initialisation entry point label. - * @param fini The finish entry point label. - */ - void layout (const files::object_list& app_objects, - const std::string& init, - const std::string& fini); - - /** - * Collection the symbols from the object file. - * - * @param obj The object file to collection the symbol from. - */ - void collect_symbols (object& obj); - - /** - * Write the compressed output file. This is the top level write - * interface. - * - * @param comp The compressor. - */ - void write (compress::compressor& comp); - - /** - * Write the RAP section to the compressed output file given the object files. - * Check to make sure the size in the layout and the size written match. - * - * @param comp The compressor. - * @param sec The RAP setion to write. - */ - void write (compress::compressor& comp, sections sec); - - /** - * Write the sections to the compressed output file. The file sections - * are used to ensure the alignment. The offset is used to ensure the - * alignment of the first section of the object when it is written. - * - * @param comp The compressor. - * @param obj The object file the sections are part of. - * @param secs The container of file sections to write. - * @param offset The current offset in the RAP section. - */ - void write (compress::compressor& comp, - files::object& obj, - const files::sections& secs, - uint32_t& offset); - - /** - * Write the external symbols. - */ - void write_externals (compress::compressor& comp); - - /** - * Write the relocation records for all the object files. - */ - void write_relocations (compress::compressor& comp); - - /** - * Write the details of the files. - */ - void write_details (compress::compressor& comp); - - /** - * The total number of relocations for a specific RAP section in the - * image. - */ - uint32_t get_relocations (int sec) const; - - /** - * Clear the image values. - */ - void clear (); - - /** - * Report the RAP section's size. - */ - uint32_t section_size (sections sec) const; - - /** - * Find a symbol name in the string table. - */ - std::size_t find_in_strtab (const std::string& symname); - - private: - - objects objs; //< The RAP objects - uint32_t sec_size[rap_secs]; //< The sections of interest. - uint32_t sec_align[rap_secs]; //< The sections of interest. - bool sec_rela[rap_secs]; //< The sections of interest. - externals externs; //< The symbols in the image - uint32_t symtab_size; //< The size of the symbols. - std::string strtab; //< The strings table. - uint32_t relocs_size; //< The relocations size. - uint32_t init_off; //< The strtab offset to the init label. - uint32_t fini_off; //< The strtab offset to the fini label. - }; - - const char* - section_name (int sec) - { - if (sec < rap_secs) - return section_names[sec]; - throw rld::error ("Invalid section '" + rld::to_string (sec) + "'", - "rap::section-name"); - } - - /** - * Update the offset taking into account the alignment. - * - * @param offset The current offset. - * @param size The size to move the offset by. - * @param alignment The alignment of the offset. - * @return uint32_t The new aligned offset. - */ - uint32_t align_offset (uint32_t offset, uint32_t size, uint32_t alignment) - { - offset += size; - - if (alignment > 1) - { - uint32_t mask = alignment - 1; - if (offset & mask) - { - offset &= ~mask; - offset += alignment; - } - } - - return offset; - } - - relocation::relocation (const files::relocation& reloc, - const uint32_t offset) - : offset (reloc.offset + offset), - info (reloc.info), - addend (reloc.addend), - symname (reloc.symname), - symtype (reloc.symtype), - symsect (reloc.symsect), - symvalue (reloc.symvalue), - symbinding (reloc.symbinding) - { - } - - section_detail::section_detail (uint32_t name, - uint32_t offset, - uint32_t id, - uint32_t size) - : name (name), - offset (offset), - id (id), - size (size) - { - } - - osection::osection (const std::string& name, - uint32_t offset, - uint32_t size, - uint32_t align, - uint32_t relocs, - uint64_t flags) - : name (name), - offset (offset), - size (size), - align (align), - relocs (relocs), - flags (flags) - { - } - - osection::osection () - : offset (0), - size (0), - align (0), - relocs (0), - flags (0) - { - } - - section::section () - : offset (0), - rela (false) - { - } - - void - section::clear () - { - offset = 0; - rela = false; - } - - uint32_t - section::size (uint32_t offset_) const - { - uint32_t end = offset_; - if (end == 0) - end = offset; - for (size_t si = 0; si < osindexes.size (); ++si) - { - const osection& osec = get_osection (osindexes[si]); - end = align_offset (end, 0, osec.align); - end += osec.size; - } - return end - offset; - } - - uint32_t - section::alignment () const - { - if (!osindexes.empty ()) - { - const osection& osec = get_osection (osindexes[0]); - return osec.align; - } - return 0; - } - - uint32_t - section::alignment (int index) const - { - const osection& osec = get_osection (index); - return osec.align; - } - - void - section::set_offset (const section& sec) - { - uint32_t align = alignment (); - offset = align_offset (sec.offset, sec.size (), align); - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rap:section::set-offset: " << name - << " offset=" << offset - << " size=" << size () - << " align=" << align - << " sec.offset=" << sec.offset - << " sec.size=" << sec.size (sec.offset) - << std::endl; - } - - const osection& - section::get_osection (int index) const - { - osections::const_iterator osi = osecs.find (index); - if (osi == osecs.end ()) - throw rld::error ("Invalid object seciton index in '" + name +"': index=" + - rld::to_string (index), - "rap::section"); - return (*osi).second; - } - - /** - * Output helper function to report the sections in an object file. This is - * useful when seeing the flags in the sections. - */ - void - section::output () - { - if (!osindexes.empty ()) - { - std::cout << ' ' << name - << ": size: " << size (offset) - << " offset: " << offset - << " rela: " << (rela ? "yes" : "no") - << std::endl; - - for (osecindexes::const_iterator osi = osindexes.begin (); - osi != osindexes.end (); - ++osi) - { - const osection& osec = get_osection (*osi); - - if (osec.size) - { - #define SF(f, i, c) if (osec.flags & (f)) flags[i] = c - - std::string flags ("--------------"); - - SF (SHF_WRITE, 0, 'W'); - SF (SHF_ALLOC, 1, 'A'); - SF (SHF_EXECINSTR, 2, 'E'); - SF (SHF_MERGE, 3, 'M'); - SF (SHF_STRINGS, 4, 'S'); - SF (SHF_INFO_LINK, 5, 'I'); - SF (SHF_LINK_ORDER, 6, 'L'); - SF (SHF_OS_NONCONFORMING, 7, 'N'); - SF (SHF_GROUP, 8, 'G'); - SF (SHF_TLS, 9, 'T'); - SF (SHF_AMD64_LARGE, 10, 'a'); - SF (SHF_ENTRYSECT, 11, 'e'); - SF (SHF_COMDEF, 12, 'c'); - SF (SHF_ORDERED, 13, 'O'); - - std::cout << " " << std::left - << std::setw (15) << osec.name - << " " << flags - << " size: " << std::setw (5) << osec.size - << " align: " << std::setw (3) << osec.align - << " relocs: " << std::setw (4) << osec.relocs - << " offset: " << std::setw (5) << osec.offset - << std::hex - << " image: 0x" << offset + osec.offset - << std::dec << std::right << std::endl; - } - } - } - } - - /** - * Helper for for_each to merge the related object sections into the RAP - * section. - */ - class section_merge: - public std::unary_function < const files::section, void > - { - public: - - section_merge (object& obj, section& sec); - - ~section_merge (); - - void operator () (const files::section& fsec); - - private: - - object& obj; - section& sec; - }; - - section_merge::section_merge (object& obj, section& sec) - : obj (obj), - sec (sec) - { - sec.offset = 0; - sec.rela = false; - } - - section_merge::~section_merge () - { - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rap:section-merge: " << sec.name - << " size=" << sec.size () - << " offset=" << sec.offset - << " " << obj.obj.name ().full () << std::endl; - } - - void - section_merge::operator () (const files::section& fsec) - { - /* - * Align the size up to the next alignment boundary and use that as the - * offset for this object file section. - */ - uint32_t offset = align_offset (sec.size (), 0, fsec.alignment); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rap:section-merge: " << fsec.name - << " sec-size=" << sec.size () - << " relocs=" << fsec.relocs.size () - << " offset=" << offset - << " fsec.size=" << fsec.size - << " fsec.alignment=" << fsec.alignment - << " fsec.rela=" << fsec.rela - << " " << obj.obj.name ().full () << std::endl; - - /* - * Add the object file's section offset to the map. This is needed - * to adjust the external symbol offsets. - */ - osection osec (fsec.name, - offset, - fsec.size, - fsec.alignment, - fsec.relocs.size (), - fsec.flags); - sec.osecs[fsec.index] = osec; - sec.osindexes.push_back (fsec.index); - - uint32_t rc = 0; - - for (files::relocations::const_iterator fri = fsec.relocs.begin (); - fri != fsec.relocs.end (); - ++fri, ++rc) - { - const files::relocation& freloc = *fri; - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << " " << std::setw (2) << sec.relocs.size () - << '/' << std::setw (2) << rc - << std::hex << ": reloc.info=0x" << freloc.info << std::dec - << " reloc.offset=" << freloc.offset - << " reloc.addend=" << freloc.addend - << " reloc.symtype=" << freloc.symtype - << " reloc.symsect=" << freloc.symsect - << " reloc.symbinding=" << freloc.symbinding - << std::endl; - - sec.relocs.push_back (relocation (freloc, offset)); - } - - std::stable_sort (sec.relocs.begin (), - sec.relocs.end (), - reloc_symname_compare ()); - std::stable_sort (sec.relocs.begin (), - sec.relocs.end (), - reloc_offset_compare ()); - - if (fsec.rela == true) - sec.rela = fsec.rela; - } - - external::external (const uint32_t name, - const sections sec, - const uint32_t value, - const uint32_t data) - : name (name), - sec (sec), - value (value), - data (data) - { - } - - external::external (const external& orig) - : name (orig.name), - sec (orig.sec), - value (orig.value), - data (orig.data) - { - } - - object::object (files::object& obj) - : obj (obj) - { - /* - * Set up the names of the sections. - */ - for (int s = 0; s < rap_secs; ++s) - secs[s].name = section_names[s]; - - /* - * Get the relocation records. Collect the various section types from the - * object file into the RAP sections. Merge those sections into the RAP - * sections. - */ - - obj.open (); - try - { - obj.begin (); - obj.load_relocations (); - obj.end (); - } - catch (...) - { - obj.close (); - throw; - } - obj.close (); - - obj.get_sections (text, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); - obj.get_sections (const_, SHT_PROGBITS, SHF_ALLOC, SHF_WRITE | SHF_EXECINSTR); - obj.get_sections (ctor, ".ctors"); - obj.get_sections (dtor, ".dtors"); - obj.get_sections (data, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); - obj.get_sections (bss, SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - obj.get_sections (symtab, SHT_SYMTAB); - obj.get_sections (strtab, ".strtab"); - - std::for_each (text.begin (), text.end (), - section_merge (*this, secs[rap_text])); - std::for_each (const_.begin (), const_.end (), - section_merge (*this, secs[rap_const])); - std::for_each (ctor.begin (), ctor.end (), - section_merge (*this, secs[rap_ctor])); - std::for_each (dtor.begin (), dtor.end (), - section_merge (*this, secs[rap_dtor])); - std::for_each (data.begin (), data.end (), - section_merge (*this, secs[rap_data])); - std::for_each (bss.begin (), bss.end (), - section_merge (*this, secs[rap_bss])); - } - - object::object (const object& orig) - : obj (orig.obj), - text (orig.text), - const_ (orig.const_), - ctor (orig.ctor), - dtor (orig.dtor), - data (orig.data), - bss (orig.bss), - symtab (orig.symtab), - strtab (orig.strtab) - { - for (int s = 0; s < rap_secs; ++s) - secs[s] = orig.secs[s]; - } - - sections - object::find (const uint32_t index) const - { - const files::section* sec; - - sec = files::find (text, index); - if (sec) - return rap_text; - - sec = files::find (const_, index); - if (sec) - return rap_const; - - sec = files::find (ctor, index); - if (sec) - return rap_ctor; - - sec = files::find (dtor, index); - if (sec) - return rap_dtor; - - sec = files::find (data, index); - if (sec) - return rap_data; - - sec = files::find (bss, index); - if (sec) - return rap_bss; - - throw rld::error ("Section index '" + rld::to_string (index) + - "' not found: " + obj.name ().full (), "rap::object"); - } - - uint32_t - object::get_relocations () const - { - uint32_t relocs = 0; - for (int s = 0; s < rap_secs; ++s) - relocs += secs[s].relocs.size (); - return relocs; - } - - uint32_t - object::get_relocations (int sec) const - { - if ((sec < 0) || (sec >= rap_secs)) - throw rld::error ("Invalid section index '" + rld::to_string (sec), - "rap::relocations"); - return secs[sec].relocs.size (); - } - - void - object::output () - { - std::cout << "rap:object: " << obj.name ().full () << std::endl; - secs[rap_text].output (); - secs[rap_const].output (); - secs[rap_ctor].output (); - secs[rap_dtor].output (); - secs[rap_data].output (); - if (secs[rap_bss].size ()) - std::cout << " bss: size: " << secs[rap_bss].size () << std::endl; - } - - image::image () - { - clear (); - } - - void - image::layout (const files::object_list& app_objects, - const std::string& init, - const std::string& fini) - { - clear (); - - /* - * Create the local objects which contain the layout information. - */ - for (files::object_list::const_iterator aoi = app_objects.begin (); - aoi != app_objects.end (); - ++aoi) - { - files::object& app_obj = *(*aoi); - - if (!app_obj.valid ()) - throw rld::error ("Not valid: " + app_obj.name ().full (), - "rap::layout"); - - objs.push_back (object (app_obj)); - } - - for (objects::iterator oi = objs.begin (), poi = objs.begin (); - oi != objs.end (); - ++oi) - { - object& obj = *oi; - - /* - * Update the offsets in the object file. We need the object's offset - * to set the relocation offset's correctly as they are relative to the - * object file. - */ - if (oi != objs.begin ()) - { - object& pobj = *poi; - for (int s = 0; s < rap_secs; ++s) - { - obj.secs[s].set_offset (pobj.secs[s]); - sec_size[s] = obj.secs[s].offset + obj.secs[s].size (); - sec_align[s] = obj.secs[s].alignment (); - if (obj.secs[s].rela == true) - sec_rela[s] = obj.secs[s].rela; - } - ++poi; - } - else - { - for (int s = 0; s < rap_secs; ++s) - { - sec_size[s] = obj.secs[s].size (); - sec_align[s] = obj.secs[s].alignment (); - if (obj.secs[s].rela == true) - sec_rela[s] = true; - } - } - - collect_symbols (obj); - - relocs_size += obj.get_relocations (); - - if (rld::verbose () >= RLD_VERBOSE_DETAILS) - obj.output (); - } - - init_off = strtab.size () + 1; - strtab += '\0'; - strtab += init; - - fini_off = strtab.size () + 1; - strtab += '\0'; - strtab += fini; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - { - uint32_t total = (sec_size[rap_text] + sec_size[rap_const] + - sec_size[rap_data] + sec_size[rap_bss] + - symtab_size + strtab.size() + relocs_size); - std::cout << "rap::layout: total:" << total - << " text:" << sec_size[rap_text] - << " const:" << sec_size[rap_const] - << " ctor:" << sec_size[rap_ctor] - << " dtor:" << sec_size[rap_dtor] - << " data:" << sec_size[rap_data] - << " bss:" << sec_size[rap_bss] - << " symbols:" << symtab_size << " (" << externs.size () << ')' - << " strings:" << strtab.size () + 1 - << " relocs:" << relocs_size - << std::endl; - } - } - - void - image::collect_symbols (object& obj) - { - symbols::pointers& esyms = obj.obj.external_symbols (); - for (symbols::pointers::const_iterator ei = esyms.begin (); - ei != esyms.end (); - ++ei) - { - const symbols::symbol& sym = *(*ei); - - if ((sym.type () == STT_OBJECT) || (sym.type () == STT_FUNC) || (sym.type () == STT_NOTYPE)) - { - if ((sym.binding () == STB_GLOBAL) || (sym.binding () == STB_WEAK)) - { - int symsec = sym.section_index (); - - /* Ignore section index 0 */ - if (symsec == 0) - continue; - /* Ignore sparc common section */ - if ((elf::object_machine_type () == EM_SPARC) && (symsec == 65522)) - continue; - - sections rap_sec = obj.find (symsec); - section& sec = obj.secs[rap_sec]; - std::size_t name; - - /* - * See if the name is already in the string table. - */ - name = find_in_strtab (sym.name ()); - - if (name == std::string::npos) - { - name = strtab.size () + 1; - strtab += '\0'; - strtab += sym.name (); - } - - /* - * The symbol's value is the symbols value plus the offset of the - * object file's section offset in the RAP section. - */ - externs.push_back (external (name, - rap_sec, - sec.offset + sec.osecs[symsec].offset + - sym.value (), - sym.info ())); - - symtab_size += external::rap_size; - } - } - } - } - - void - image::write (compress::compressor& comp) - { - /* - * Start with the machine type so the target can check the applicatiion - * is ok and can be loaded. Add the init and fini labels to the string - * table and add the references to the string table next. Follow this - * with the section details then the string table and symbol table then - * finally the relocation records. - */ - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: machine=" << comp.transferred () << std::endl; - - comp << elf::object_machine_type () - << elf::object_datatype () - << elf::object_class (); - - /* - * The init and fini label offsets. Then the symbol table and string - * table sizes. - */ - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: header=" << comp.transferred () << std::endl; - - comp << init_off - << fini_off - << symtab_size - << (uint32_t) strtab.size () + 1 - << (uint32_t) 0; - - /* - * Output file details - */ - if (add_obj_details) - { - write_details (comp); - } - else - { - comp << (uint32_t)0; /* No file details */ - } - - /* - * The sections. - */ - for (int s = 0; s < rap_secs; ++s) - comp << sec_size[s] - << sec_align[s]; - - /* - * Output the sections from each object file. - */ - write (comp, rap_text); - write (comp, rap_const); - write (comp, rap_ctor); - write (comp, rap_dtor); - write (comp, rap_data); - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: strtab=" << comp.transferred () << std::endl; - - strtab += '\0'; - comp << strtab; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: symbols=" << comp.transferred () << std::endl; - - write_externals (comp); - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: relocs=" << comp.transferred () << std::endl; - - write_relocations (comp); - } - - /** - * Helper for for_each to write out the various sections. - */ - class section_writer: - public std::unary_function < object, void > - { - public: - - section_writer (image& img, - compress::compressor& comp, - sections sec); - - void operator () (object& obj); - - private: - - image& img; - compress::compressor& comp; - sections sec; - uint32_t offset; - }; - - section_writer::section_writer (image& img, - compress::compressor& comp, - sections sec) - : img (img), - comp (comp), - sec (sec), - offset (0) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "rap:output: " << section_names[sec] - << ": offset=" << comp.transferred () - << " size=" << img.section_size (sec) << std::endl; - } - - void - section_writer::operator () (object& obj) - { - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rap:writing: " << section_names[sec] << std::endl; - - switch (sec) - { - case rap_text: - img.write (comp, obj.obj, obj.text, offset); - break; - case rap_const: - img.write (comp, obj.obj, obj.const_, offset); - break; - case rap_ctor: - img.write (comp, obj.obj, obj.ctor, offset); - break; - case rap_dtor: - img.write (comp, obj.obj, obj.dtor, offset); - break; - case rap_data: - img.write (comp, obj.obj, obj.data, offset); - break; - default: - break; - } - } - - void - image::write (compress::compressor& comp, sections sec) - { - uint32_t image_offset = comp.transferred (); - - std::for_each (objs.begin (), objs.end (), - section_writer (*this, comp, sec)); - - uint32_t written = comp.transferred () - image_offset; - - if (written != sec_size[sec]) - { - std::string msg = "Image output size does not match layout size: "; - msg += section_names[sec]; - msg += ": layout-size=" + rld::to_string (sec_size[sec]); - msg += " image-size=" + rld::to_string (written); - throw rld::error (msg, "rap::write"); - } - } - - void - image::write (compress::compressor& comp, - files::object& obj, - const files::sections& secs, - uint32_t& offset) - { - uint32_t size = 0; - - obj.open (); - - try - { - obj.begin (); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rap:write sections: " << obj.name ().full () << std::endl; - - for (files::sections::const_iterator si = secs.begin (); - si != secs.end (); - ++si) - { - const files::section& sec = *si; - uint32_t unaligned_offset = offset + size; - - offset = align_offset (offset, size, sec.alignment); - - if (offset != unaligned_offset) - { - char ee = '\xee'; - for (uint32_t p = 0; p < (offset - unaligned_offset); ++p) - comp.write (&ee, 1); - } - - comp.write (obj, sec.offset, sec.size); - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << " sec: " << sec.index << ' ' << sec.name - << " offset=" << offset - << " size=" << sec.size - << " align=" << sec.alignment - << " padding=" << (offset - unaligned_offset) << std::endl; - - size = sec.size; - } - - offset += size; - - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << " total size=" << offset << std::endl; - - obj.end (); - } - catch (...) - { - obj.close (); - throw; - } - - obj.close (); - } - - void - image::write_externals (compress::compressor& comp) - { - int count = 0; - for (externals::const_iterator ei = externs.begin (); - ei != externs.end (); - ++ei, ++count) - { - const external& ext = *ei; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "rap:externs: " << count - << " name=" << &strtab[ext.name] << " (" << ext.name << ')' - << " section=" << section_names[ext.sec] - << " data=" << ext.data - << " value=0x" << std::hex << ext.value << std::dec - << std::endl; - - if ((ext.data & 0xffff0000) != 0) - throw rld::error ("Data value has data in bits higher than 15", - "rap::write-externs"); - - comp << (uint32_t) ((ext.sec << 16) | ext.data) - << ext.name - << ext.value; - } - } - - void - image::write_relocations (compress::compressor& comp) - { - for (int s = 0; s < rap_secs; ++s) - { - uint32_t count = get_relocations (s); - uint32_t sr = 0; - uint32_t header; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "rap:relocation: section:" << section_names[s] - << " relocs=" << count - << " rela=" << (char*) (sec_rela[s] ? "yes" : "no") - << std::endl; - - header = count; - header |= sec_rela[s] ? RAP_RELOC_RELA : 0; - - comp << header; - - for (objects::iterator oi = objs.begin (); - oi != objs.end (); - ++oi) - { - object& obj = *oi; - section& sec = obj.secs[s]; - relocations& relocs = sec.relocs; - uint32_t rc = 0; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << " relocs=" << sec.relocs.size () - << " sec.offset=" << sec.offset - << " sec.size=" << sec.size () - << " sec.align=" << sec.alignment () - << " " << obj.obj.name ().full () << std::endl; - - for (relocations::const_iterator ri = relocs.begin (); - ri != relocs.end (); - ++ri, ++sr, ++rc) - { - const relocation& reloc = *ri; - uint32_t info = GELF_R_TYPE (reloc.info); - uint32_t offset; - uint32_t addend = reloc.addend; - bool write_addend = sec.rela; - bool write_symname = false; - - offset = sec.offset + reloc.offset; - - if ((reloc.symtype == STT_SECTION) || (reloc.symbinding == STB_LOCAL)) - { - int rap_symsect = obj.find (reloc.symsect); - - /* - * Bit 31 clear, bits 30:8 RAP section index. - */ - info |= rap_symsect << 8; - - addend += (obj.secs[rap_symsect].offset + - obj.secs[rap_symsect].osecs[reloc.symsect].offset + - reloc.symvalue); - - write_addend = true; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << " " << std::setw (2) << sr - << '/' << std::setw (2) << rc - <<": rsym: sect=" << section_names[rap_symsect] - << " rap_symsect=" << rap_symsect - << " sec.offset=" << obj.secs[rap_symsect].offset - << " sec.osecs=" << obj.secs[rap_symsect].osecs[reloc.symsect].offset - << " (" << obj.obj.get_section (reloc.symsect).name << ')' - << " reloc.symsect=" << reloc.symsect - << " reloc.symvalue=" << reloc.symvalue - << " reloc.addend=" << reloc.addend - << " addend=" << addend - << std::endl; - } - else - { - /* - * Bit 31 must be set. Bit 30 determines the type of string and - * bits 29:8 the strtab offset or the size of the appended - * string. - */ - - info |= RAP_RELOC_STRING; - - std::size_t size = find_in_strtab (reloc.symname); - - if (size == std::string::npos) - { - /* - * Bit 30 clear, the size of the symbol name. - */ - info |= reloc.symname.size () << 8; - write_symname = true; - } - else - { - /* - * Bit 30 set, the offset in the strtab. - */ - info |= RAP_RELOC_STRING_EMBED | (size << 8); - } - } - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - { - std::cout << " " << std::setw (2) << sr << '/' - << std::setw (2) << rc - << std::hex << ": reloc: info=0x" << info << std::dec - << " offset=" << offset; - if (write_addend) - std::cout << " addend=" << addend; - if ((info & RAP_RELOC_STRING) != 0) - { - std::cout << " symname=" << reloc.symname; - if (write_symname) - std::cout << " (appended)"; - } - std::cout << std::hex - << " reloc.info=0x" << reloc.info << std::dec - << " reloc.offset=" << reloc.offset - << " reloc.symtype=" << reloc.symtype - << std::endl; - } - - comp << info << offset; - - if (write_addend) - comp << addend; - - if (write_symname) - comp << reloc.symname; - } - } - } - } - - void image::write_details (compress::compressor& comp) - { - - std::string strtable; - uint32_t pos = 0; - - section_details s_details; - - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - { - std::cout << "rap:file details" << std::endl - << " total " << objs.size () <<" files" << std::endl; - } - - comp << (uint32_t)(objs.size ()); - - /* rpath for rap file */ - if (rld::verbose () >= RLD_VERBOSE_TRACE) - { - std::cout << "rap:file rpath=" << rld::rap::rpath << std::endl; - } - - comp << (uint32_t)rld::rap::rpath.length (); - - if (rld::rap::rpath.length () > 0) - { - strtable += rld::rap::rpath; - } - - for (objects::iterator oi = objs.begin (); - oi != objs.end (); - ++oi) - { - object& obj = *oi; - - /* obj full name */ - strtable += obj.obj.name ().full (); - strtable += '\0'; - } - - pos = strtable.length (); - - uint32_t sec_num = 0; - for (objects::iterator oi = objs.begin (); - oi != objs.end (); - ++oi) - { - object& obj = *oi; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "file:" << obj.obj.name ().full () << std::endl; - - for (int s = 0; s < rap_secs; ++s) - { - section& sec = obj.secs[s]; - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - { - std::cout << "rap:section: " << sec.name << " " - "offset= " << sec.offset << std::endl; - } - - for (size_t si = 0; si < sec.osindexes.size (); ++si) - { - const osection& osec = sec.get_osection (sec.osindexes[si]); - - strtable += osec.name; - strtable += '\0'; - - /* sec.offset + osec.offset is the offset in the rap section */ - s_details.push_back (section_detail (pos, - sec.offset + osec.offset, - s, - osec.size)); - - pos = strtable.length (); - - if (rld::verbose () >= RLD_VERBOSE_TRACE) - { - std::cout << "osec.name=" << osec.name << " " - << "osec.offset=" << osec.offset << " " - << "osec.size=" << osec.size << std::endl; - } - } - } - - /* Output section numbers*/ - comp << (uint32_t)((s_details.size () - sec_num)); - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "sec_num:" << s_details.size () - sec_num << std::endl; - sec_num = s_details.size (); - } - - comp << (uint32_t)(strtable.size ()); - if (rld::verbose () >= RLD_VERBOSE_TRACE) - std::cout << "total detail size:" << strtable.size () << std::endl; - - comp << strtable; - - for (section_details::const_iterator si = s_details.begin (); - si != s_details.end (); - ++si) - { - const section_detail& sec_detail = *si; - comp << (uint32_t)(sec_detail.name); - - if (sec_detail.id > 0xf) - std::cout << "Out max rap section id 15\n" << std::endl; - - comp << (uint32_t)((sec_detail.id << 28) | sec_detail.offset); - comp << (uint32_t)(sec_detail.size); - } - } - - uint32_t - image::get_relocations (int sec) const - { - if ((sec < 0) || (sec >= rap_secs)) - throw rld::error ("Invalid section index '" + rld::to_string (sec), - "rap::image::relocations"); - - uint32_t relocs = 0; - - for (objects::const_iterator oi = objs.begin (); - oi != objs.end (); - ++oi) - { - const object& obj = *oi; - relocs += obj.get_relocations (sec); - } - - return relocs; - } - - void - image::clear () - { - for (int s = 0; s < rap_secs; ++s) - { - sec_size[s] = 0; - sec_align[s] = 0; - sec_rela[s] = false; - } - symtab_size = 0; - strtab.clear (); - relocs_size = 0; - init_off = 0; - fini_off = 0; - } - - uint32_t - image::section_size (sections sec) const - { - if ((sec < 0) || (sec >= rap_secs)) - throw rld::error ("Invalid section index '" + rld::to_string (sec), - "rap::image::section_size"); - return sec_size[sec]; - } - - std::size_t - image::find_in_strtab (const std::string& symname) - { - std::size_t pos = 0; - while (pos < strtab.size ()) - { - std::size_t off = strtab.find (symname, pos); - if (off == std::string::npos) - break; - if (::strlen (strtab.c_str () + off) == symname.size ()) - return off; - pos = off + 1; - } - return std::string::npos; - } - - void - write (files::image& app, - const std::string& init, - const std::string& fini, - const files::object_list& app_objects, - const symbols::table& /* symbols */) /* Add back for incremental - * linking */ - { - std::string header; - - header = "RAP,00000000,0002,LZ77,00000000\n"; - app.write (header.c_str (), header.size ()); - - compress::compressor compressor (app, 2 * 1024); - image rap; - - rap.layout (app_objects, init, fini); - rap.write (compressor); - - compressor.flush (); - - std::ostringstream length; - - length << std::setfill ('0') << std::setw (8) - << header.size () + compressor.compressed (); - - header.replace (4, 8, length.str ()); - - app.seek (0); - app.write (header.c_str (), header.size ()); - - if (rld::verbose () >= RLD_VERBOSE_INFO) - { - int pcent = (compressor.compressed () * 100) / compressor.transferred (); - int premand = (((compressor.compressed () * 1000) + 500) / - compressor.transferred ()) % 10; - std::cout << "rap: objects: " << app_objects.size () - << ", size: " << compressor.compressed () - << ", compression: " << pcent << '.' << premand << '%' - << std::endl; - } - } - - } -} diff --git a/linkers/rld-rap.h b/linkers/rld-rap.h deleted file mode 100644 index 19969e3..0000000 --- a/linkers/rld-rap.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker RTEMS Application (RAP) Format management. - * - */ - -#if !defined (_RLD_RAP_H_) -#define _RLD_RAP_H_ - -#include - -namespace rld -{ - namespace rap - { - /** - * Output details or not. - */ - extern bool add_obj_details; - - /** - * Store the path of object files. - */ - extern std::string rpath; - - /** - * The RAP relocation bit masks. - */ - #define RAP_RELOC_RELA (1UL << 31) - #define RAP_RELOC_STRING (1UL << 31) - #define RAP_RELOC_STRING_EMBED (1UL << 30) - - /** - * The sections of interest in a RAP file. - */ - enum sections - { - rap_text = 0, - rap_const = 1, - rap_ctor = 2, - rap_dtor = 3, - rap_data = 4, - rap_bss = 5, - rap_secs = 6 - }; - - /** - * Return the name of a section. - */ - const char* section_name (int sec); - - /** - * Write a RAP format file. - * - * The symbol table is provided to allow incremental linking at some point - * in the future. I suspect this will also require extra options being - * added to control symbol visibility in the RAP file. For example an - * "application" may be self contained and does not need to export any - * symbols therefore no symbols are added and the only ones are part of the - * relocation records to bind to base image symbols. Another case is the - * need for an application to export symbols because it is using dlopen to - * load modules. Here the symbols maybe 'all' or it could be a user - * maintained list that are exported. - * - * @param app The application image to write too. - * @param init The application's initialisation entry point. - * @param fini The application's finish entry point . - * @param objects The list of object files in the application. - * @param symbols The symbol table used to create the application. - */ - void write (files::image& app, - const std::string& init, - const std::string& fini, - const files::object_list& objects, - const symbols::table& symbols); - } -} - -#endif diff --git a/linkers/rld-resolver.cpp b/linkers/rld-resolver.cpp deleted file mode 100644 index d2a9f1e..0000000 --- a/linkers/rld-resolver.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_ld - * - * @brief RTEMS Linker. - * - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#include -#include - -namespace rld -{ - namespace resolver - { - static files::object* - get_object (files::cache& cache, - const std::string& fullname) - { - files::objects& objects = cache.get_objects (); - files::objects::iterator oi = objects.find (fullname); - if (oi == objects.end ()) - return 0; - return (*oi).second; - } - - static void - resolve_symbols (files::object_list& dependents, - files::cache& cache, - symbols::table& base_symbols, - symbols::table& symbols, - symbols::symtab& unresolved, - const std::string& fullname) - { - const std::string name = path::basename (fullname); - - static int nesting = 0; - - ++nesting; - - /* - * Find each unresolved symbol in the symbol table pointing the - * unresolved symbol's object file to the file that resolves the - * symbol. Record each object file that is found and when all unresolved - * symbols in this object file have been found iterate over the found - * object files resolving them. The 'urs' is the unresolved symbol and - * 'es' is the exported symbol. - */ - - files::object* object = get_object (cache, fullname); - - if (object) - { - if (object->resolved () || object->resolving ()) - { - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "resolver:resolving: " - << std::setw (nesting - 1) << ' ' - << name - << " is resolved or resolving" - << std::endl; - return; - } - object->resolve_set (); - } - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "resolver:resolving: " - << std::setw (nesting - 1) << ' ' - << name - << ", unresolved: " - << unresolved.size () - << std::endl; - - files::object_list objects; - - for (symbols::symtab::iterator ursi = unresolved.begin (); - ursi != unresolved.end (); - ++ursi) - { - symbols::symbol& urs = *((*ursi).second); - - if ((urs.binding () != STB_WEAK) && urs.object ()) - continue; - - symbols::symbol* es = base_symbols.find_external (urs.name ()); - bool base = true; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - { - std::cout << "resolver:resolve : " - << std::setw (nesting + 1) << ' ' - << " |- " << urs.name () << std::endl; - } - - if (!es) - { - es = symbols.find_external (urs.name ()); - if (!es) - { - es = symbols.find_weak (urs.name ()); - if (!es) - throw rld::error ("symbol not found: " + urs.name (), name); - } - base = false; - } - - symbols::symbol& esym = *es; - - if (rld::verbose () >= RLD_VERBOSE_INFO) - { - std::cout << "resolver:resolved : " - << std::setw (nesting + 1) << ' ' - << " | `--> "; - if (esym.object()) - { - std::cout << esym.object()->name ().basename (); - if (esym.object()->resolving ()) - std::cout << " (resolving)"; - else if (esym.object()->resolved ()) - std::cout << " (resolved)"; - else if (base) - std::cout << " (base)"; - else - std::cout << " (unresolved: " << objects.size () + 1 << ')'; - } - else - std::cout << "null"; - std::cout << std::endl; - } - - if (!base) - { - files::object& eobj = *esym.object (); - urs.set_object (eobj); - if (!eobj.resolved () && !eobj.resolving ()) - { - objects.push_back (&eobj); - objects.unique (); - } - } - - esym.referenced (); - } - - if (object) - { - object->resolve_clear (); - object->resolved_set (); - } - - /* - * Recurse into any references object files. - */ - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "resolver:resolved : " - << std::setw (nesting + 1) << ' ' - << " +-- referenced objects: " << objects.size () - << std::endl; - - for (files::object_list::iterator oli = objects.begin (); - oli != objects.end (); - ++oli) - { - files::object& obj = *(*oli); - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "resolver:resolving: " - << std::setw (nesting) << ' ' - << "] " << name << " ==> " - << obj.name ().basename () << std::endl; - resolve_symbols (dependents, cache, base_symbols, symbols, - obj.unresolved_symbols (), - obj.name ().full ()); - } - - --nesting; - - dependents.merge (objects); - dependents.unique (); - } - - void - resolve (files::object_list& dependents, - files::cache& cache, - symbols::table& base_symbols, - symbols::table& symbols, - symbols::symtab& undefined) - { - files::object_list objects; - cache.get_objects (objects); - - /* - * First resolve any undefined symbols that are forced by the linker or - * the user. - */ - resolver::resolve_symbols (dependents, cache, base_symbols, symbols, - undefined, "undefines"); - - /* - * Resolve the symbols in the object files. - */ - for (files::object_list::iterator oi = objects.begin (); - oi != objects.end (); - ++oi) - { - files::object& object = *(*oi); - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << "resolver:resolving: top: " - << object.name ().basename () << std::endl; - resolver::resolve_symbols (dependents, cache, base_symbols, symbols, - object.unresolved_symbols (), - object.name ().full ()); - } - } - } - -} diff --git a/linkers/rld-resolver.h b/linkers/rld-resolver.h deleted file mode 100644 index 3771f18..0000000 --- a/linkers/rld-resolver.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker resolver determines which object files are needed. - * - */ - -#if !defined (_RLD_RESOLVER_H_) -#define _RLD_RESOLVER_H_ - -#include -#include - -namespace rld -{ - namespace resolver - { - /** - * Resolve the dependences between object files. - * - * @param dependents The object modules dependent on the object files we - * are linking. - * @param cache The file cache. - * @param base_symbols The base image symbol table - * @param symbols The object file and library symbols - * @param undefined Extra undefined symbols dependent object files are - * added for. - */ - void resolve (files::object_list& dependents, - files::cache& cache, - symbols::table& base_symbols, - symbols::table& symbols, - symbols::symtab& undefined); - } -} - -#endif diff --git a/linkers/rld-rtems.cpp b/linkers/rld-rtems.cpp deleted file mode 100644 index d85f845..0000000 --- a/linkers/rld-rtems.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include - -namespace rld -{ - namespace rtems - { - static std::string _version = "4.11"; - static std::string _path; - static std::string _arch_bsp; - - static void - load_cc () - { - path::paths parts; - std::string rtems_pkgconfig; - std::string bsp; - - if (_path.empty ()) - throw rld::error ("Not set", "RTEMS path"); - - bsp = rtems_arch_bsp (); - - parts.push_back ("lib"); - parts.push_back ("pkgconfig"); - - rld::path::path_join (path (), parts, rtems_pkgconfig); - - if (!path::check_directory (rtems_pkgconfig)) - throw rld::error ("Invalid RTEMS path", path ()); - - rld::path::path_join (rtems_pkgconfig, bsp + ".pc", rtems_pkgconfig); - - if (!path::check_file (rtems_pkgconfig)) - throw rld::error ("RTEMS BSP not found", arch_bsp ()); - - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " rtems: " << _arch_bsp << ": " - << rtems_pkgconfig << std::endl; - - pkgconfig::package pkg (rtems_pkgconfig); - - /* - * Check the pc file matches what we ask for. - */ - std::string name; - if (!pkg.get ("name", name)) - throw rld::error ("RTEMS BSP no name in pkgconfig file", _arch_bsp); - - if (name != bsp) - throw rld::error ("RTEMS BSP does not match the name in pkgconfig file", - _arch_bsp); - - std::string flags; - - if (pkg.get ("CPPFLAGS", flags)) - { - rld::cc::append_flags (flags, arch (), path (), rld::cc::ft_cppflags); - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " rtems: " << arch_bsp () - << ": CPPFLAGS=" - << rld::cc::get_flags (rld::cc::ft_cppflags) - << std::endl; - } - - if (pkg.get ("CFLAGS", flags)) - { - rld::cc::append_flags (flags, arch (), path (), rld::cc::ft_cflags); - if (rld::verbose () >= RLD_VERBOSE_INFO) - { - std::cout << " rtems: " << arch_bsp () - << ": CFLAGS=" << rld::cc::get_flags (rld::cc::ft_cflags) - << std::endl; - std::cout << " rtems: " << _arch_bsp - << ": WARNINGS=" << rld::cc::get_flags (rld::cc::fg_warning_flags) - << std::endl; - std::cout << " rtems: " << arch_bsp () - << ": INCLUDES=" << rld::cc::get_flags (rld::cc::fg_include_flags) - << std::endl; - std::cout << " rtems: " << arch_bsp () - << ": MACHINES=" << rld::cc::get_flags (rld::cc::fg_machine_flags) - << std::endl; - std::cout << " rtems: " << arch_bsp () - << ": SPECS=" << rld::cc::get_flags (rld::cc::fg_spec_flags) - << std::endl; - } - } - - if (pkg.get ("CXXFLAGS", flags)) - { - rld::cc::append_flags (flags, arch (), path (), rld::cc::ft_cxxflags); - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " rtems: " << arch_bsp () - << ": CXXFLAGS=" << rld::cc::get_flags (rld::cc::ft_cxxflags) - << std::endl; - } - - if (pkg.get ("LDFLAGS", flags)) - { - rld::cc::append_flags (flags, arch (), path (), rld::cc::ft_ldflags); - if (rld::verbose () >= RLD_VERBOSE_INFO) - std::cout << " rtems: " << arch_bsp () - << ": LDFLAGS=" << rld::cc::get_flags (rld::cc::ft_ldflags) - << std::endl; - } - - rld::cc::set_exec_prefix (arch ()); - } - - void - set_version (const std::string& version_) - { - _version = version_; - } - - void - set_arch_bsp (const std::string& arch_bsp_) - { - _arch_bsp = arch_bsp_; - if (!_path.empty ()) - load_cc (); - } - - void - set_path (const std::string& path_) - { - _path = path_; - if (!_arch_bsp.empty ()) - load_cc (); - } - - const std::string - version () - { - return _version; - } - - const std::string - arch_bsp () - { - return _arch_bsp; - } - - const std::string - arch () - { - if (_arch_bsp.empty ()) - throw rld::error ("No arch/bsp name", "rtems: arch"); - std::string::size_type slash = _arch_bsp.find_first_of ('/'); - if (slash == std::string::npos) - throw rld::error ("Invalid BSP name", _arch_bsp); - return _arch_bsp.substr (0, slash); - std::string bsp = _arch_bsp.substr (slash + 1); - } - - const std::string - bsp () - { - if (_arch_bsp.empty ()) - throw rld::error ("No arch/bsp name", "rtems: bsp"); - std::string::size_type slash = _arch_bsp.find_first_of ('/'); - if (slash == std::string::npos) - throw rld::error ("Invalid BSP name", _arch_bsp); - return _arch_bsp.substr (slash + 1); - } - - const std::string - path () - { - return _path; - } - - const std::string - rtems_arch_prefix () - { - return arch () + "-rtems" + version (); - } - - const std::string - rtems_arch_bsp () - { - return rtems_arch_prefix () + '-' + bsp (); - } - - } -} diff --git a/linkers/rld-rtems.h b/linkers/rld-rtems.h deleted file mode 100644 index 04305ce..0000000 --- a/linkers/rld-rtems.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2011-2014, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief Support to manage RTEMS. - * - */ - -#if !defined (_RLD_RTEMS_H_) -#define _RLD_RTEMS_H_ - -#include - -namespace rld -{ - namespace rtems - { - /** - * Set the RTEMS version. - */ - void set_version (const std::string& version); - - /** - * Set the arch/bsp string. - */ - void set_arch_bsp (const std::string& arch_bsp); - - /** - * Set the path to RTEMS. - */ - void set_path (const std::string& path); - - /** - * Get the RTEMS version. - */ - const std::string version (); - - /** - * Return the arch/bsp string. - */ - const std::string arch_bsp (); - - /** - * Return the architecture given an arch/bsp string. - */ - const std::string arch (); - - /** - * Return the bsp given an arch/bsp string. - */ - const std::string bsp (); - - /** - * Get the RTEMS path. - */ - const std::string path (); - - /** - * Return the RTEMS BSP prefix. - */ - const std::string rtems_arch_prefix (); - - /** - * Return the arch/bsp as an RTEMS prefix and BSP string. - */ - const std::string rtems_arch_bsp (); - } -} - -#endif diff --git a/linkers/rld-symbols.cpp b/linkers/rld-symbols.cpp deleted file mode 100644 index 3464017..0000000 --- a/linkers/rld-symbols.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker symbols manages the symbols from all the object files. - * - */ - -#include - -#include - -#include - -#include - -namespace rld -{ - namespace symbols - { - /** - * Get the demangled name. - */ - static void - denamgle_name (std::string& name, std::string& demangled) - { - char* demangled_name = ::cplus_demangle (name.c_str (), - DMGL_ANSI | DMGL_PARAMS); - if (demangled_name) - { - demangled = demangled_name; - ::free (demangled_name); - } - } - - symbol::symbol () - : index_ (-1), - object_ (0), - references_ (0) - { - memset (&esym_, 0, sizeof (esym_)); - } - - symbol::symbol (int index, - const std::string& name, - files::object& object, - const elf::elf_sym& esym) - : index_ (index), - name_ (name), - object_ (&object), - esym_ (esym), - references_ (0) - { - if (!object_) - throw rld_error_at ("object pointer is 0"); - if (is_cplusplus ()) - denamgle_name (name_, demangled_); - } - - symbol::symbol (int index, - const std::string& name, - const elf::elf_sym& esym) - : index_ (index), - name_ (name), - object_ (0), - esym_ (esym), - references_ (0) - { - if (is_cplusplus ()) - denamgle_name (name_, demangled_); - } - - symbol::symbol (const std::string& name, - const elf::elf_addr value) - : index_ (-1), - name_ (name), - object_ (0), - references_ (0) - { - memset (&esym_, 0, sizeof (esym_)); - esym_.st_value = value; - } - - symbol::symbol (const char* name, - const elf::elf_addr value) - : index_ (-1), - name_ (name), - object_ (0), - references_ (0) - { - memset (&esym_, 0, sizeof (esym_)); - esym_.st_value = value; - } - - int - symbol::index () const - { - return index_; - } - - const std::string& - symbol::name () const - { - return name_; - } - - const std::string& - symbol::demangled () const - { - return demangled_; - } - - bool - symbol::is_cplusplus () const - { - return (name_[0] == '_') && (name_[1] == 'Z'); - } - - int - symbol::type () const - { - return GELF_ST_TYPE (esym_.st_info); - } - - int - symbol::binding () const - { - return GELF_ST_BIND (esym_.st_info); - } - - int - symbol::section_index () const - { - return esym_.st_shndx; - } - - elf::elf_addr - symbol::value () const - { - return esym_.st_value; - } - - uint32_t - symbol::info () const - { - return esym_.st_info; - } - - rld::files::object* - symbol::object () const - { - return object_; - } - - void - symbol::set_object (rld::files::object& obj) - { - object_ = &obj; - } - - const elf::elf_sym& - symbol::esym () const - { - return esym_; - } - - void - symbol::referenced () - { - ++references_; - if (object_) - object_->symbol_referenced (); - } - - bool - symbol::operator< (const symbol& rhs) const - { - return name_ < rhs.name_; - } - - void - symbol::output (std::ostream& out) const - { - const elf::elf_sym& es = esym (); - - std::string binding; - int binding_val = GELF_ST_BIND (es.st_info); - switch (binding_val) - { - case STB_LOCAL: - binding = "STB_LOCAL "; - break; - case STB_GLOBAL: - binding = "STB_GLOBAL"; - break; - case STB_WEAK: - binding = "STB_WEAK "; - break; - default: - if ((binding_val >= STB_LOPROC) && (binding_val <= STB_HIPROC)) - binding = "STB_LOPROC(" + rld::to_string (binding_val) + ")"; - else - binding = "STB_INVALID(" + rld::to_string (binding_val) + ")"; - break; - } - - std::string type; - int type_val = GELF_ST_TYPE (es.st_info); - switch (type_val) - { - case STT_NOTYPE: - type = "STT_NOTYPE "; - break; - case STT_OBJECT: - type = "STT_OBJECT "; - break; - case STT_FUNC: - type = "STT_FUNC "; - break; - case STT_SECTION: - type = "STT_SECTION"; - break; - case STT_FILE: - type = "STT_FILE "; - break; - default: - if ((type_val >= STT_LOPROC) && (type_val <= STT_HIPROC)) - type = "STT_LOPROC(" + rld::to_string (type_val) + ")"; - else - type = "STT_INVALID(" + rld::to_string (type_val) + ")"; - break; - } - - out << std::setw (4) << index_ - << ' ' << binding - << ' ' << type - << ' ' << std::setw(6) << es.st_shndx - << " 0x" << std::setw (8) << std::setfill ('0') << std::hex - << es.st_value - << std::dec << std::setfill (' ') - << ' ' << std::setw (7) << es.st_size - << ' '; - - if (is_cplusplus ()) - out << demangled (); - else - out << name (); - - if (object ()) - out << " (" << object ()->name ().basename () << ')'; - } - - table::table () - { - } - - table::~table () - { - } - - void - table::add_external (symbol& sym) - { - _externals[sym.name ()] = &sym; - } - - void - table::add_weak (symbol& sym) - { - _weaks[sym.name ()] = &sym; - } - - symbol* - table::find_external (const std::string& name) - { - symtab::iterator sti = _externals.find (name); - if (sti == _externals.end ()) - return 0; - return (*sti).second; - } - - symbol* - table::find_weak (const std::string& name) - { - symtab::iterator sti = _weaks.find (name); - if (sti == _weaks.end ()) - return 0; - return (*sti).second; - } - - size_t - table::size () const - { - return _externals.size () + _weaks.size (); - } - - const symtab& - table::externals () const - { - return _externals; - } - - const symtab& - table::weaks () const - { - return _weaks; - } - - void - load (bucket& bucket_, table& table_) - { - for (bucket::iterator sbi = bucket_.begin (); - sbi != bucket_.end (); - ++sbi) - { - table_.add_external (*sbi); - } - } - - void - load (bucket& bucket_, symtab& table_) - { - for (bucket::iterator sbi = bucket_.begin (); - sbi != bucket_.end (); - ++sbi) - { - symbol& sym = *sbi; - table_[sym.name ()] = &sym; - } - } - - size_t - referenced (pointers& symbols) - { - size_t used = 0; - for (pointers::iterator sli = symbols.begin (); - sli != symbols.end (); - ++sli) - { - symbol& sym = *(*sli); - if (sym.references ()) - ++used; - } - - return used; - } - - void - output (std::ostream& out, const table& symbols) - { - out << "Externals:" << std::endl; - output (out, symbols.externals ()); - out << "Weaks:" << std::endl; - output (out, symbols.weaks ()); - } - - void - output (std::ostream& out, const symtab& symbols) - { - std::cout << " No. Scope Type Address Size Name" << std::endl; - int index = 0; - for (symtab::const_iterator si = symbols.begin (); - si != symbols.end (); - ++si) - { - const symbol& sym = *((*si).second); - out << std::setw (5) << index << ' ' << sym << std::endl; - ++index; - } - } - - } -} diff --git a/linkers/rld-symbols.h b/linkers/rld-symbols.h deleted file mode 100644 index 5405d2f..0000000 --- a/linkers/rld-symbols.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker symbols manages the symbols from all the object files. - * - */ - -#if !defined (_RLD_SYMBOLS_H_) -#define _RLD_SYMBOLS_H_ - -#include -#include -#include -#include - -#include - -namespace rld -{ - /** - * Forward declarations. - */ - namespace files - { - class object; - } - - namespace symbols - { - /** - * A symbol. - */ - class symbol - { - public: - /** - * Default constructor. No symbol has been defined. - */ - symbol (); - - /** - * Construct an exported symbol with a object file. - */ - symbol (int index, - const std::string& name, - files::object& object, - const elf::elf_sym& esym); - - /** - * Construct a symbol with no object file and an ELF index. - */ - symbol (int index, const std::string& name, const elf::elf_sym& esym); - - /** - * Construct a linker symbol that is internally created. - */ - symbol (const std::string& name, - const elf::elf_addr value = 0); - - /** - * Construct a linker symbol that is internally created. - */ - symbol (const char* name, - elf::elf_addr value = 0); - - /** - * The symbol's index in the symtab section of the ELF file. - */ - int index () const; - - /** - * The symbol's name. - */ - const std::string& name () const; - - /** - * The symbol's demangled name. - */ - const std::string& demangled () const; - - /** - * Is the symbol a C++ name ? - */ - bool is_cplusplus () const; - - /** - * The symbol's type. - */ - int type () const; - - /** - * The symbol's binding, ie local, weak, or global. - */ - int binding () const; - - /** - * The symbol's section index. - */ - int section_index () const; - - /** - * The value of the symbol. - */ - elf::elf_addr value () const; - - /** - * The data of the symbol. - */ - uint32_t info () const; - - /** - * The symbol's object file name. - */ - files::object* object () const; - - /** - * Set the symbol's object file name. Used when resolving unresolved - * symbols. - */ - void set_object (files::object& obj); - - /** - * The ELF symbol. - */ - const elf::elf_sym& esym () const; - - /** - * Return the number of references. - */ - int references () const { - return references_; - } - - /** - * Return the number of references. - */ - void referenced (); - - /** - * Less than operator for the map container. - */ - bool operator< (const symbol& rhs) const; - - /** - * Output to the a stream. - */ - void output (std::ostream& out) const; - - private: - - int index_; //< The symbol's index in the ELF file. - std::string name_; //< The name of the symbol. - std::string demangled_; //< If a C++ symbol the demangled name. - files::object* object_; //< The object file containing the symbol. - elf::elf_sym esym_; //< The ELF symbol. - int references_; //< The number of times if it referenced. - }; - - /** - * Container of symbols. A bucket of symbols. - */ - typedef std::list < symbol > bucket; - - /** - * References to symbols. Should always point to symbols held in a bucket. - */ - typedef std::list < symbol* > pointers; - - /** - * A symbols table is a map container of symbols. Should always point to - * symbols held in a bucket. - */ - typedef std::map < std::string, symbol* > symtab; - - /** - * A symbols contains a symbol table of externals and weak symbols. - */ - class table - { - public: - /** - * Construct a table. - */ - table (); - - /** - * Destruct a table. - */ - ~table (); - - /** - * Add an external symbol. - */ - void add_external (symbol& sym); - - /** - * Add a weak symbol. - */ - void add_weak (symbol& sym); - - /** - * Find an external symbol. - */ - symbol* find_external (const std::string& name); - - /** - * Find an weak symbol. - */ - symbol* find_weak (const std::string& name); - - /** - * Return the size of the symbols loaded. - */ - size_t size () const; - - /** - * Return the externals symbol table. - */ - const symtab& externals () const; - - /** - * Return the weaks symbol table. - */ - const symtab& weaks () const; - - private: - - /** - * Cannot copy a table. - */ - table (const table& orig); - - /** - * A table of external symbols. - */ - symtab _externals; - - /** - * A table of weak symbols. - */ - symtab _weaks; - }; - - /** - * Load a table from a buckey. - */ - void load (bucket& bucket_, table& table_); - - /** - * Load a table from a buckey. - */ - void load (bucket& bucket_, symtab& table_); - - /** - * Given a container of symbols return how many are referenced. - */ - size_t referenced (pointers& symbols); - - /** - * Output the symbol table. - */ - void output (std::ostream& out, const table& symbols); - - /** - * Output the symbol table. - */ - void output (std::ostream& out, const symtab& symbols); - } -} - -/** - * Output stream operator. - */ -static inline std::ostream& operator<< (std::ostream& out, - const rld::symbols::symbol& sym) { - sym.output (out); - return out; -} - -#endif diff --git a/linkers/rld.cpp b/linkers/rld.cpp deleted file mode 100644 index c3368f9..0000000 --- a/linkers/rld.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems_ld - * - * @brief RTEMS Linker. - * - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include - -#include - -#define RLD_VERSION_MAJOR (1) -#define RLD_VERSION_MINOR (0) -#define RLD_VERSION_RELEASE (0) - -namespace rld -{ - static int verbose_level = 0; - - /** - * The program's command line. - */ - static std::string cmdline; - - /** - * The program name as set by the caller. - */ - static std::string progname; - - /** - * The option container. - */ - typedef std::vector < std::string > library_container; - - /** - * The libraries the user provided on the command line. - */ - static library_container libpaths; - - /** - * The libraries pass on the command line. - */ - static library_container libs; - - /** - * The libraries. - */ - static library_container libraries; - - /** - * The output passed on the command line. - */ - //static std::string output; - - bool - starts_with(const std::string& s1, const std::string& s2) - { - return s2.size () <= s1.size () && s1.compare (0, s2.size (), s2) == 0; - } - - const std::string - ltrim (const std::string& s) - { - std::string t = s; - t.erase (t.begin (), - std::find_if (t.begin (), t.end (), - std::not1 (std::ptr_fun < int, int > (std::isspace)))); - return t; - } - - const std::string - rtrim (const std::string& s) - { - std::string t = s; - t.erase (std::find_if (t.rbegin (), t.rend (), - std::not1 (std::ptr_fun < int, int > (std::isspace))).base(), - t.end()); - return t; - } - - const std::string - trim (const std::string& s) - { - return ltrim (rtrim (s)); - } - - const std::string - dequote (const std::string& s) - { - if (!s.empty ()) - { - char front = s[0]; - char back = s[s.length () - 1]; - if ((front == '"') || (front == '\'')) - { - if (front != back) - throw rld::error ("invalid quoting", "string: " + s); - return s.substr (1, s.length () - (1 + 1)); - } - } - return s; - } - - const std::string - find_replace(const std::string& sin, - const std::string& out, - const std::string& in) - { - std::string s = sin; - size_t pos = 0; - while ((pos = s.find (out, pos)) != std::string::npos) - { - s.replace (pos, out.length (), in); - pos += in.length (); - } - return s; - } - - const strings - split (strings& se, - const std::string& s, - char delimiter, - bool strip_quotes, - bool strip_whitespace, - bool empty) - { - std::stringstream ss(s); - std::string e; - se.clear (); - while (std::getline (ss, e, delimiter)) - { - if (strip_whitespace) - e = trim (e); - if (strip_quotes) - e = dequote (e); - if (empty || !e.empty ()) - { - se.push_back (e); - } - } - return se; - } - - const std::string - join (const strings& ss, const std::string& separator) - { - std::string s; - for (strings::const_iterator ssi = ss.begin (); - ssi != ss.end (); - ++ssi) - { - s += *ssi; - if ((ssi + 1) != ss.end ()) - s += separator; - } - return s; - } - - const std::string - tolower (const std::string& sin) - { - std::string s = sin; - std::transform (s.begin (), s.end (), s.begin (), ::tolower); - return s; - } - - void - verbose_inc () - { - ++verbose_level; - } - - int - verbose (int level) - { - return verbose_level && (verbose_level >= level) ? verbose_level : 0; - } - - const std::string - version () - { - std::string v = (rld::to_string (RLD_VERSION_MAJOR) + '.' + - rld::to_string (RLD_VERSION_MINOR) + '.' + - rld::to_string (RLD_VERSION_RELEASE)); - return v; - } - - const std::string - rtems_version () - { - return rld::to_string (RTEMS_VERSION); - } - - void - set_cmdline (int argc, char* argv[]) - { - cmdline.clear (); - for (int arg = 0; arg < argc; ++arg) - { - std::string a = argv[arg]; - cmdline += ' ' + a; - } - cmdline = rld::trim (cmdline); - } - - const std::string - get_cmdline () - { - return cmdline; - } - - void - set_progname (const std::string& progname_) - { - progname = rld::path::path_abs (progname_); - } - - const std::string - get_progname () - { - return progname; - } - - const std::string - get_program_name () - { - return rld::path::basename (progname); - } - - const std::string - get_program_path () - { - return rld::path::dirname (progname); - } - - const std::string - get_prefix () - { - std::string pp = get_program_path (); - if (rld::path::basename (pp) == "bin") - return rld::path::dirname (pp); - return ""; - } - - void - map (rld::files::cache& cache, rld::symbols::table& symbols) - { - std::cout << "Archive files : " << cache.archive_count () << std::endl; - std::cout << "Object files : " << cache.object_count () << std::endl; - std::cout << "Exported symbols : " << symbols.size () << std::endl; - - std::cout << "Archives:" << std::endl; - cache.output_archive_files (std::cout); - std::cout << "Objects:" << std::endl; - cache.output_object_files (std::cout); - - std::cout << "Exported symbols:" << std::endl; - rld::symbols::output (std::cout, symbols); - std::cout << "Unresolved symbols:" << std::endl; - cache.output_unresolved_symbols (std::cout); - } - - void - warn_unused_externals (rld::files::object_list& objects) - { - bool first = true; - for (rld::files::object_list::iterator oli = objects.begin (); - oli != objects.end (); - ++oli) - { - rld::files::object& object = *(*oli); - rld::symbols::pointers& externals = object.external_symbols (); - - if (rld::symbols::referenced (externals) != externals.size ()) - { - if (first) - { - std::cout << "Unreferenced externals in object files:" << std::endl; - first = false; - } - - std::cout << ' ' << object.name ().basename () << std::endl; - - for (rld::symbols::pointers::iterator sli = externals.begin (); - sli != externals.end (); - ++sli) - { - rld::symbols::symbol& sym = *(*sli); - if (sym.references () == 0) - std::cout << " " << sym.name () << std::endl; - } - } - } - } - -} diff --git a/linkers/rld.h b/linkers/rld.h deleted file mode 100644 index 7bd940b..0000000 --- a/linkers/rld.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2011, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup rtems-ld - * - * @brief RTEMS Linker readies the RTEMS object files for dynamic linking. - * - */ - -#if !defined (_RLD_H_) -#define _RLD_H_ - -#include -#include -#include -#include -#include -#include -#include - -/** - * Path handling for Windows. - */ -#if __WIN32__ -#define RLD_PATH_SEPARATOR '\\' -#define RLD_PATH_SEPARATOR_STR "\\" -#define RLD_PATHSTR_SEPARATOR ';' -#define RLD_PATHSTR_SEPARATOR_STR ";" -#define RLD_DRIVE_SEPARATOR (1) -#define RLD_LINE_SEPARATOR "\r\n" -#else -#define RLD_PATH_SEPARATOR '/' -#define RLD_PATH_SEPARATOR_STR "/" -#define RLD_PATHSTR_SEPARATOR ':' -#define RLD_PATHSTR_SEPARATOR_STR ":" -#define RLD_DRIVE_SEPARATOR (0) -#define RLD_LINE_SEPARATOR "\n" -#endif - -namespace rld -{ - /** - * Forward declarations. - */ - namespace files - { - class file; - class image; - class archive; - class object; - } -} - -#include -#include -#include -#include - -/** - * The debug levels. - */ -#define RLD_VERBOSE_OFF (0) -#define RLD_VERBOSE_INFO (1) -#define RLD_VERBOSE_DETAILS (2) -#define RLD_VERBOSE_TRACE (3) -#define RLD_VERBOSE_TRACE_SYMS (4) -#define RLD_VERBOSE_TRACE_FILE (5) -#define RLD_VERBOSE_FULL_DEBUG (6) - -namespace rld -{ - /** - * General error. - */ - struct error - { - const std::string what; - const std::string where; - - error (const std::ostringstream& what, const std::string& where) : - what (what.str ()), where (where) { - } - - error (const std::string& what, const std::string& where) : - what (what), where (where) { - } - }; - - /** - * A convenience macro to make where a file and line number. - */ - #define rld_error_at(_what) \ - rld::error (_what, std::string (__FILE__) + ":" + to_string (__LINE__)) - - /** - * Convert a supported type to a string. - */ - template - std::string to_string (T t, std::ios_base & (*f)(std::ios_base&) = std::dec) - { - std::ostringstream oss; - oss << f << t; - return oss.str(); - } - - /** - * A container of strings. - */ - typedef std::vector < std::string > strings; - - /** - * Does a string start with another string ? - */ - bool starts_with(const std::string& s1, const std::string& s2); - - /** - * Trim from start. - */ - const std::string ltrim (const std::string& s); - - /** - * Trim from end. - */ - const std::string rtrim (const std::string& s); - - /** - * Trim from both ends. - */ - const std::string trim (const std::string& s); - - /** - * Dequote a string. - */ - const std::string dequote (const std::string& s); - - /** - * Find and replace. - */ - const std::string find_replace(const std::string& sin, - const std::string& out, - const std::string& in); - - /** - * Split the string in a contain of strings based on the the - * delimiter. Optionally trim any white space or include empty string. - * - * @todo The split should optionally honour string quoting. - */ - const strings split (strings& se, - const std::string& s, - char delimiter = ' ', - bool strip_quotes = true, - bool strip_whitespace = true, - bool empty = false); - - /** - * Join the strings together with the separator. - */ - const std::string join (const strings& ss, const std::string& separator); - - /** - * Convert a string to lower case. - */ - const std::string tolower (const std::string& sin); - - /** - * Increment the verbose level. - */ - void verbose_inc (); - - /** - * Return the verbose level. Setting the flag more than once raises the - * level. - */ - int verbose (int level = 0); - - /** - * The version string. - */ - const std::string version (); - - /** - * Container of strings to hold the results of a split. - */ - typedef std::vector < std::string > strings; - - /** - * Set the command line. - */ - void set_cmdline (int argc, char* argv[]); - - /** - * Get the command line. - */ - const std::string get_cmdline (); - - /** - * Set the progname. - */ - void set_progname (const std::string& progname); - - /** - * Get the progname. This is an absolute path. - */ - const std::string get_progname (); - - /** - * Get the program name. - */ - const std::string get_program_name (); - - /** - * Get the program path. - */ - const std::string get_program_path (); - - /** - * Get the current install prefix. If the path to the executable has 'bin' as - * the executable's parent directory it is assumed the executable has been - * installed under a standard PREFIX. If "bin" is not found return the - * executable's absolute path. - */ - const std::string get_prefix (); - - /** - * Map of the symbol table. - */ - void map (rld::files::cache& cache, rld::symbols::table& symbols); - - /** - * Warn if externals in referenced object files are not used. - */ - void warn_unused_externals (rld::files::object_list& objects); -} - -#endif diff --git a/linkers/rtems-utils.cpp b/linkers/rtems-utils.cpp deleted file mode 100644 index 8fda105..0000000 --- a/linkers/rtems-utils.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup RLD - * - * @brief A memory dump routine. - * - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include - -namespace rtems -{ - namespace utils - { - void - dump (const void* addr, - size_t length, - size_t size, - bool real, - size_t line_length, - uint32_t offset) - { - char* data; - size_t b = 0; - uint8_t d8 = 0; - uint16_t d16 = 0; - uint32_t d32 = 0; - uint64_t d64 = 0; - - const uint8_t* addr8 = static_cast (addr); - - data = new char[line_length]; - - try - { - std::cout << std::hex << std::setfill ('0'); - - while (true) - { - if (((b % line_length) == 0) || (b >= length)) - { - if (b) - { - size_t line = b % line_length; - - if (line) - { - size_t remaining = line_length - line; - remaining = (remaining * 2) + (remaining / size); - std::cout << std::setfill (' ') - << std::setw (remaining) << ' ' - << std::setfill ('0'); - } - else - line = line_length; - - std::cout << ' '; - - for (size_t c = 0; c < line; c++) - { - if ((data[c] < 0x20) || (data[c] > 0x7e)) - std::cout << '.'; - else - std::cout << data[c]; - } - - if (b >= length) - { - std::cout << std::dec << std::setfill (' ') - << std::endl << std::flush; - break; - } - - std::cout << std::endl; - } - - if (real) - std::cout << std::setw (sizeof(void*)) << (uint64_t) (addr8 + b); - else - std::cout << std::setw (8) << (uint32_t) (offset + b); - } - - if ((b & (line_length - 1)) == (line_length >> 1)) - std::cout << "-"; - else - std::cout << " "; - - switch (size) - { - case sizeof (uint8_t): - default: - d8 = *(addr8 + b); - std::cout << std::setw (2) << (uint32_t) d8; - data[(b % line_length) + 0] = d8; - break; - - case sizeof (uint16_t): - d16 = *((const uint16_t*) (addr8 + b)); - std::cout << std::setw (4) << d16; - data[(b % line_length) + 0] = (uint8_t) (d16 >> 8); - data[(b % line_length) + 1] = (uint8_t) d16; - break; - - case sizeof (uint32_t): - d32 = *((const uint32_t*) (addr8 + b)); - std::cout << std::setw (8) << d32; - for (int i = sizeof (uint32_t); i > 0; --i) - { - data[(b % line_length) + i] = (uint8_t) d32; - d32 >>= 8; - } - break; - - case sizeof (uint64_t): - d64 = *((const uint64_t*) (addr8 + b)); - std::cout << std::setw (16) << d64; - for (int i = sizeof (uint64_t); i > 0; --i) - { - data[(b % line_length) + i] = (uint8_t) d64; - d64 >>= 8; - } - break; - } - b += size; - } - } - catch (...) - { - delete [] data; - throw; - } - - delete [] data; - - std::cout << std::dec << std::setfill (' '); - } - } -} diff --git a/linkers/rtems-utils.h b/linkers/rtems-utils.h deleted file mode 100644 index 9918570..0000000 --- a/linkers/rtems-utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012, Chris Johns - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @file - * - * @ingroup RLD - * - * @brief A memory dump routine. - * - */ - -#if !defined (_MEMORY_DUMP_H_) -#define _MEMORY_DUMP_H_ - -#include - -namespace rtems -{ - namespace utils - { - /** - * Hex display memory. - * - * @param addr The address of the memory to display. - * @param length The number of elements to display. - * @param size The size of the data element. - * @param real Use the real address based on addr. - * @param line_length Number of elements per line. - * @param offset The printed offset. - */ - void dump (const void* addr, - size_t length, - size_t size, - bool real = false, - size_t line_length = 16, - uint32_t offset = 0); - } -} - -#endif diff --git a/linkers/wscript b/linkers/wscript index 9ab4685..5dd151c 100644 --- a/linkers/wscript +++ b/linkers/wscript @@ -7,52 +7,17 @@ version_major = 1 version_minor = 0 version_revision = 0 -# -# Waf system setup. Allow more than one build in the same tree. -# -top = '.' -out = 'build-' + sys.platform - def options(opt): opt.load("g++") opt.load("gcc") - opt.add_option('--rtems-version', - default = '4.11', - dest='rtems_version', - help = 'Set the RTEMS version') - opt.add_option('--c-opts', - default = '-O2', - dest='c_opts', - help = 'Set build options, default: -O2.') - opt.add_option('--show-commands', - action = 'store_true', - default = False, - dest = 'show_commands', - help = 'Print the commands as strings.') def configure(conf): - try: - conf.load("doxygen", tooldir = 'waf-tools') - except: - pass conf.load("g++") conf.load("gcc") - conf_libiberty(conf) - conf_libelf(conf) - - conf.check(header_name='sys/wait.h', features = 'c', mandatory = False) - conf.check_cc(function_name='kill', header_name="signal.h", - features = 'c', mandatory = False) - conf.write_config_header('config.h') conf.env.C_OPTS = conf.options.c_opts.split(',') conf.env.RTEMS_VERSION = conf.options.rtems_version - - if conf.options.show_commands: - show_commands = 'yes' - else: - show_commands = 'no' - conf.env.SHOW_COMMANDS = show_commands + conf.write_config_header('config.h') def build(bld): # @@ -63,67 +28,24 @@ def build(bld): doxyfile = 'rtl-host.conf') return - if bld.env.SHOW_COMMANDS == 'yes': - output_command_line() - # - # The include paths. + # The local configuration. # - bld.includes = ['elftoolchain/libelf', 'elftoolchain/common', 'libiberty'] - if sys.platform == 'win32': - bld.includes += ['win32'] + conf = {} # # Build flags. # - bld.warningflags = ['-Wall', '-Wextra', '-pedantic'] - bld.optflags = bld.env.C_OPTS - bld.cflags = ['-pipe', '-g'] + bld.optflags - bld.cxxflags = ['-pipe', '-g'] + bld.optflags - bld.linkflags = ['-g'] - - # - # Create each of the modules as object files each with their own - # configurations. - # - bld_fastlz(bld) - bld_libelf(bld) - bld_libiberty(bld) - - # - # RLD source. - # - rld_source = ['ConvertUTF.c', - 'pkgconfig.cpp', - 'rld-config.cpp', - 'rld-elf.cpp', - 'rld-files.cpp', - 'rld-cc.cpp', - 'rld-compression.cpp', - 'rld-outputter.cpp', - 'rld-path.cpp', - 'rld-process.cpp', - 'rld-resolver.cpp', - 'rld-rtems.cpp', - 'rld-symbols.cpp', - 'rld-rap.cpp', - 'rld.cpp'] - - # - # RTEMS Utilities. - # - rtems_utils = ['rtems-utils.cpp'] - - # - # RTL static library - # - bld.stlib(target = 'rld', - source = rld_source + rtems_utils, - defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags) + rtemstoolkit = '../rtemstoolkit' + conf['includes'] = [rtemstoolkit, + rtemstoolkit + '/elftoolchain/libelf', + rtemstoolkit + '/elftoolchain/common', + rtemstoolkit + '/libiberty'] + conf['warningflags'] = ['-Wall', '-Wextra', '-pedantic'] + conf['optflags'] = bld.env.C_OPTS + conf['cflags'] = ['-pipe', '-g'] + conf['optflags'] + conf['cxxflags'] = ['-pipe', '-g'] + conf['optflags'] + conf['linkflags'] = ['-g'] # # The list of modules. @@ -136,10 +58,10 @@ def build(bld): bld.program(target = 'rtems-ld', source = ['rtems-ld.cpp'], defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags, + includes = ['.'] + conf['includes'], + cflags = conf['cflags'] + conf['warningflags'], + cxxflags = conf['cxxflags'] + conf['warningflags'], + linkflags = conf['linkflags'], use = modules) # @@ -148,10 +70,10 @@ def build(bld): bld.program(target = 'rtems-ra', source = ['rtems-ra.cpp'], defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags, + includes = ['.'] + conf['includes'], + cflags = conf['cflags'] + conf['warningflags'], + cxxflags = conf['cxxflags'] + conf['warningflags'], + linkflags = conf['linkflags'], use = modules) # @@ -160,10 +82,10 @@ def build(bld): bld.program(target = 'rtems-tld', source = ['rtems-tld.cpp'], defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags, + includes = ['.'] + conf['includes'], + cflags = conf['cflags'] + conf['warningflags'], + cxxflags = conf['cxxflags'] + conf['warningflags'], + linkflags = conf['linkflags'], use = modules) bld.install_files('${PREFIX}/share/rtems/trace-linker', ['rtems.ini', 'rtld-base.ini']) @@ -174,10 +96,10 @@ def build(bld): bld.program(target = 'rtems-syms', source = ['rtems-syms.cpp'], defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags, + includes = ['.'] + conf['includes'], + cflags = conf['cflags'] + conf['warningflags'], + cxxflags = conf['cxxflags'] + conf['warningflags'], + linkflags = conf['linkflags'], use = modules) # @@ -186,212 +108,11 @@ def build(bld): bld.program(target = 'rtems-rap', source = ['rtems-rapper.cpp'], defines = ['HAVE_CONFIG_H=1', 'RTEMS_VERSION=' + bld.env.RTEMS_VERSION], - includes = ['.'] + bld.includes, - cflags = bld.cflags + bld.warningflags, - cxxflags = bld.cxxflags + bld.warningflags, - linkflags = bld.linkflags, + includes = ['.'] + conf['includes'], + cflags = conf['cflags'] + conf['warningflags'], + cxxflags = conf['cxxflags'] + conf['warningflags'], + linkflags = conf['linkflags'], use = modules) -def rebuild(ctx): - import waflib.Options - waflib.Options.commands.extend(['clean', 'build']) - def tags(ctx): ctx.exec_command('etags $(find . -name \*.[sSch])', shell = True) - -# -# Libelf module. -# -def conf_libelf(conf): - pass - -def bld_fastlz(bld): - bld(target = 'fastlz', - features = 'c', - source = 'fastlz.c', - cflags = bld.cflags, - defines = ['FASTLZ_LEVEL=1']) - -def bld_libelf(bld): - libelf = 'elftoolchain/libelf/' - - # - # Work around the ${SRC} having Windows slashes which the MSYS m4 does not - # understand. - # - if sys.platform == 'win32': - m4_rule = 'type ${SRC} | m4 -D SRCDIR=../linkers/' + libelf[:-1] + '> ${TGT}"' - includes = ['win32'] - else: - m4_rule = 'm4 -D SRCDIR=../linkers/' + libelf[:-1] + ' ${SRC} > ${TGT}' - includes = [] - - bld(target = 'libelf_convert.c', source = libelf + 'libelf_convert.m4', rule = m4_rule) - bld(target = 'libelf_fsize.c', source = libelf + 'libelf_fsize.m4', rule = m4_rule) - bld(target = 'libelf_msize.c', source = libelf + 'libelf_msize.m4', rule = m4_rule) - - host_source = [] - - if sys.platform == 'linux2': - common = 'elftoolchain/common/' - bld(target = common + 'native-elf-format.h', - source = common + 'native-elf-format', - name = 'native-elf-format', - rule = './${SRC} > ${TGT}') - bld.add_group () - elif sys.platform == 'win32': - host_source += [libelf + 'mmap_win32.c'] - - bld.stlib(target = 'elf', - features = 'c', - uses = ['native-elf-format'], - includes = [bld.bldnode.abspath(), 'elftoolchain/libelf', 'elftoolchain/common'] + includes, - cflags = bld.cflags, - source =[libelf + 'elf.c', - libelf + 'elf_begin.c', - libelf + 'elf_cntl.c', - libelf + 'elf_end.c', - libelf + 'elf_errmsg.c', - libelf + 'elf_errno.c', - libelf + 'elf_data.c', - libelf + 'elf_fill.c', - libelf + 'elf_flag.c', - libelf + 'elf_getarhdr.c', - libelf + 'elf_getarsym.c', - libelf + 'elf_getbase.c', - libelf + 'elf_getident.c', - libelf + 'elf_hash.c', - libelf + 'elf_kind.c', - libelf + 'elf_memory.c', - libelf + 'elf_next.c', - libelf + 'elf_rand.c', - libelf + 'elf_rawfile.c', - libelf + 'elf_phnum.c', - libelf + 'elf_shnum.c', - libelf + 'elf_shstrndx.c', - libelf + 'elf_scn.c', - libelf + 'elf_strptr.c', - libelf + 'elf_update.c', - libelf + 'elf_version.c', - libelf + 'gelf_cap.c', - libelf + 'gelf_checksum.c', - libelf + 'gelf_dyn.c', - libelf + 'gelf_ehdr.c', - libelf + 'gelf_getclass.c', - libelf + 'gelf_fsize.c', - libelf + 'gelf_move.c', - libelf + 'gelf_phdr.c', - libelf + 'gelf_rel.c', - libelf + 'gelf_rela.c', - libelf + 'gelf_shdr.c', - libelf + 'gelf_sym.c', - libelf + 'gelf_syminfo.c', - libelf + 'gelf_symshndx.c', - libelf + 'gelf_xlate.c', - libelf + 'libelf_align.c', - libelf + 'libelf_allocate.c', - libelf + 'libelf_ar.c', - libelf + 'libelf_ar_util.c', - libelf + 'libelf_checksum.c', - libelf + 'libelf_data.c', - libelf + 'libelf_ehdr.c', - libelf + 'libelf_extended.c', - libelf + 'libelf_phdr.c', - libelf + 'libelf_shdr.c', - libelf + 'libelf_xlate.c', - 'libelf_convert.c', - 'libelf_fsize.c', - 'libelf_msize.c'] + host_source) - -# -# Libiberty module. -# -def conf_libiberty(conf): - conf.check(header_name='alloca.h', features = 'c', mandatory = False) - conf.check(header_name='fcntl.h', features = 'c', mandatory = False) - conf.check(header_name='process.h', features = 'c', mandatory = False) - conf.check(header_name='stdlib.h', features = 'c') - conf.check(header_name='string.h', features = 'c') - conf.check(header_name='strings.h', features = 'c', mandatory = False) - conf.check(header_name='sys/file.h', features = 'c', mandatory = False) - conf.check(header_name='sys/stat.h', features = 'c', mandatory = False) - conf.check(header_name='sys/time.h', features = 'c', mandatory = False) - conf.check(header_name='sys/types.h', features = 'c', mandatory = False) - conf.check(header_name='sys/wait.h', features = 'c', mandatory = False) - conf.check(header_name='unistd.h', features = 'c', mandatory = False) - conf.check(header_name='vfork.h', features = 'c', mandatory = False) - - conf.check_cc(function_name='getrusage', - header_name="sys/time.h sys/resource.h", - features = 'c', mandatory = False) - - conf.write_config_header('libiberty/config.h') - -def bld_libiberty(bld): - if sys.platform == 'win32': - pex_host = 'libiberty/pex-win32.c' - else: - pex_host = 'libiberty/pex-unix.c' - bld.stlib(target = 'iberty', - features = 'c', - includes = ['libiberty'], - cflags = bld.cflags, - defines = ['HAVE_CONFIG_H=1'], - source =['libiberty/concat.c', - 'libiberty/cplus-dem.c', - 'libiberty/cp-demangle.c', - 'libiberty/make-temp-file.c', - 'libiberty/mkstemps.c', - 'libiberty/safe-ctype.c', - 'libiberty/stpcpy.c', - 'libiberty/pex-common.c', - 'libiberty/pex-one.c', - pex_host]) - -# -# From the demos. Use this to get the command to cut+paste to play. -# -def output_command_line(): - # first, display strings, people like them - from waflib import Utils, Logs - from waflib.Context import Context - def exec_command(self, cmd, **kw): - subprocess = Utils.subprocess - kw['shell'] = isinstance(cmd, str) - if isinstance(cmd, str): - Logs.info('%s' % cmd) - else: - Logs.info('%s' % ' '.join(cmd)) # here is the change - Logs.debug('runner_env: kw=%s' % kw) - try: - if self.logger: - self.logger.info(cmd) - kw['stdout'] = kw['stderr'] = subprocess.PIPE - p = subprocess.Popen(cmd, **kw) - (out, err) = p.communicate() - if out: - self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1')) - if err: - self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1')) - return p.returncode - else: - p = subprocess.Popen(cmd, **kw) - return p.wait() - except OSError: - return -1 - Context.exec_command = exec_command - - # Change the outputs for tasks too - from waflib.Task import Task - def display(self): - return '' # no output on empty strings - - Task.__str__ = display - -# -# The doxy command. -# -from waflib import Build -class doxy(Build.BuildContext): - fun = 'build' - cmd = 'doxy' -- cgit v1.2.3